# Why is there no ashl/lshl?

There is a distinction between logical/arithmetic shift right, but why
not for shift left?

I'm also a bit confused by one example in the reference manual:
<result> = lshr i8 -2, 1 ; yields {i8}:result = 0x7FFFFFFF
Is this an error in the manual? The result is supposed to be an i8 yet a
i32 is shown.

Hi,

There is a distinction between logical/arithmetic shift right, but why
not for shift left?

The arithmetic right shift has the nice property that it preserves the
fact that x >> 1 == x/2 for negative signed numbers (unlike the
logical shift). Either because of this or because of other uses I
can't think of right now almost all modern CPUs implement it in
hardware, and hence LLVM has an instruction for it.

In contrast, it's not quite clear what an arithmetic left-shift would
be. If you want to keep x << 1 == x*2 then the logical one already
does this. If you want to define it to shift in the least-significant
bit at each stage then some concrete use is needed; I can't think of a
common one.

I'm also a bit confused by one example in the reference manual:
<result> = lshr i8 -2, 1 ; yields {i8}:result = 0x7FFFFFFF
Is this an error in the manual? The result is supposed to be an i8 yet a
i32 is shown.

I think so. I've changed it to 0x7F.

Cheers.

Tim.

Hi Tim,

There is a distinction between logical/arithmetic shift right, but why
not for shift left?

The arithmetic right shift has the nice property that it preserves the
fact that x >> 1 == x/2 for negative signed numbers (unlike the
logical shift).

except when x is -1.

That said, this is correct: the reason for distinct signed and unsigned
right shifts is basically the same reason we have signed and unsigned
division instructions.

The reason that we don't have distinct signed and unsigned left shift
operators is the same reason we don't have signed and unsigned multiplication
instructions.

Ciao, Duncan.

From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu]
On Behalf Of Tim Northover
In contrast, it's not quite clear what an arithmetic left-shift would
be. If you want to keep x << 1 == x*2 then the logical one already
does this.

Only if the left-most (shiftcount + 1) bits are all-0 or all-1.
I've used machines that distinguished logical and arithmetic left shift
to detect when this condition fails (arith shift would trap).

--paulr

LLVM IR doesn't expose flags (except in specific overflow detecting intrinsics).

-Chris

x a>> 1 == (x/2 rounded toward negative infinity)

which for positive numbers people think of as "truncated"
which people sometimes mistake for "rounded toward zero"

Pedantically yours,
--paulr