[Bug rtl-optimization/83565] RTL combine pass breaks shift result (at least on ia64)

slyfox at inbox dot ru gcc-bugzilla@gcc.gnu.org
Sat Dec 23 14:47:00 GMT 2017


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83565

--- Comment #1 from Sergei Trofimovich <slyfox at inbox dot ru> ---
Here is disassembled dump of gcc -O1 result (it's slightly easier to reason
about than gcc's assembly output):

Dump of assembler code for function bug:
   0x40000000000005f0 <+0>:     [MII]       mov r14=r12
   // store 'ss=0xffffffff' on stack
   0x40000000000005f1 <+1>:                 mov r15=-1;;
   0x40000000000005f2 <+2>:                 nop.i 0x0

   // store 'd=0xeeeeeeee' on stack
   0x4000000000000600 <+16>:    [MLX]       st4.rel [r14]=r15,4
   0x4000000000000601 <+17>:                movl r15=0xffffffffeeeeeeee;;

   // reload 'd'
   0x4000000000000610 <+32>:    [MMI]       st4.rel [r14]=r15 
   0x4000000000000611 <+33>:                ld4.acq r15=[r14]
   0x4000000000000612 <+34>:                nop.i 0x0

   // u32 tt = d & 0x00800000;
   0x4000000000000620 <+48>:    [MLX]       nop.m 0x0
   0x4000000000000621 <+49>:                movl r14=0x800000;;
   0x4000000000000630 <+64>:    [MMI]       and r15=r14,r15;;

   // u32 r  = tt << 8;
   0x4000000000000631 <+65>:                nop.m 0x0
   0x4000000000000632 <+66>:                dep.z r14=r15,8,24
   0x4000000000000640 <+80>:    [MMI]       ld4.acq r8=[r12]
   // *result = tt;
   0x4000000000000641 <+81>:                st4 [r32]=r15
   0x4000000000000642 <+82>:                nop.i 0x0;;

   // rotate
   //r = (r >> 31)
   //  | (r <<  1);
   0x4000000000000650 <+96>:    [MII]       nop.m 0x0
   0x4000000000000651 <+97>:                mix4.r r14=r14,r14;;
   0x4000000000000652 <+98>:                shr.u r14=r14,31;;

   // u32 u = r^ss;
   0x4000000000000660 <+112>:   [MMI]       xor r8=r8,r14;;
   0x4000000000000661 <+113>:               nop.m 0x0

   // u32 off = u >> 1;
   // Note how we use 32 bits after 1-bit shift.
   0x4000000000000662 <+114>:               extr.u r8=r8,1,32
   0x4000000000000670 <+128>:   [MIB]       nop.m 0x0
   0x4000000000000671 <+129>:               nop.i 0x0
   0x4000000000000672 <+130>:               br.ret.sptk.many b0;;


Here 'extr.u r8=r8,1,32' should be 'extr.u r8=r8,1,31' to yield correct result.
But something in RTK combine pass decided to expand 31 to 32.


More information about the Gcc-bugs mailing list