This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: C++ ABI and ILP64
On Thursday 16 December 2004 21:03, Zack Weinberg wrote:
> "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.
I don't think that's true - consider base[off] == 0x10 and shift == 31.
Then (base[off] << shift) under LP64 has to be 0, so this optimization is only
valid under ILP64.
--
Markus F.X.J. Oberhumer
http://www.oberhumer.com/