This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++ ABI and ILP64


"Markus F.X.J. Oberhumer" <markus@oberhumer.com> writes:

> I agree - but note that in many cases the compiler is not allowed to
> make such optimizations under LP64.
>
> If you consider the example below, "(base[off] << shift)" must be
> promoted and computed in int/unsigned int, and the "cltq"
> instruction can only be omitted in ILP64.

I'm pretty sure the as-if rule allows the optimization you want in
LP64 mode.  Your example code is

> char *foo(char* base, long off, long shift) {
>    return base + (base[off] << shift);
> }

base[off] provably has a value in the range -128 .. 127, so there is
no concern about the value loaded from memory being truncated.
Therefore, the only difference between these two code sequences

>    0:	0f be 04 3e          	movsbl (%rsi,%rdi,1),%eax
>    4:	48 89 d1             	mov    %rdx,%rcx
>    7:	d3 e0                	shl    %cl,%eax
>    9:	48 98                	cltq   
>    b:	48 8d 04 07          	lea    (%rdi,%rax,1),%rax
>    f:	c3                   	retq   

>    0:	48 0f be 04 3e       	movsbq (%rsi,%rdi,1),%rax
>    5:	48 89 d1             	mov    %rdx,%rcx
>    8:	48 d3 e0             	shl    %cl,%rax
>    b:	48 8d 04 07          	lea    (%rdi,%rax,1),%rax
>    f:	c3                   	retq   

is that the first will reduce the left-shift count modulo 32 and the
second will reduce it modulo 64.  But shifting left by more than 31
(sizeof(int)*CHAR_BIT) is undefined behavior, so the compiler is
entitled to generate the second sequence for LP64.

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]