[Bug rtl-optimization/84660] New: Combine doing wrong optimization for 64 bits with SHIFT_COUNT_TRUNCATED target

npickito at gmail dot com gcc-bugzilla@gcc.gnu.org
Fri Mar 2 06:54:00 GMT 2018


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

            Bug ID: 84660
           Summary: Combine doing wrong optimization for 64 bits with
                    SHIFT_COUNT_TRUNCATED target
           Product: gcc
           Version: 7.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: npickito at gmail dot com
                CC: andrew at sifive dot com, palmer at dabbelt dot com,
                    wilson at tuliptree dot org
  Target Milestone: ---
            Target: riscv64imafd-elf-newlib

Option: -O3

Testcase:
unsigned int foo(const unsigned int op003) __attribute__((noinline, noclone));
unsigned int foo(const unsigned int op003) {

  return (0xFFFF & (0xd066 << ( (0x2f ^ (0x1 & op003))  % 16 )));
}

unsigned int op0 = 0;

int main() {

        op0 = foo(0x1);
        __builtin_printf("op0 = %08x \n", op0);

        return 0;
}

Expect result: op0 = 00008000

What's wrong?
foo was optimized to return 0 directly. 

Before combine: (x.c.260r.ud_dce)
(insn 2 4 3 2 (set (reg/v:DI 78 [ op003 ])
        (reg:DI 10 a0 [ op003 ])) "x.c":2 131 {*movdi_64bit}
     (expr_list:REG_DEAD (reg:DI 10 a0 [ op003 ])
        (nil)))
(note 3 2 7 2 NOTE_INSN_FUNCTION_BEG)
(insn 7 3 9 2 (set (reg:DI 81)
        (and:DI (reg/v:DI 78 [ op003 ])
            (const_int 1 [0x1]))) "x.c":4 70 {anddi3}
     (expr_list:REG_DEAD (reg/v:DI 78 [ op003 ])
        (nil)))
(insn 9 7 11 2 (set (reg:DI 83)
        (xor:DI (reg:DI 81)
            (const_int 47 [0x2f]))) "x.c":4 72 {xordi3}
     (expr_list:REG_DEAD (reg:DI 81)
        (nil)))
(insn 11 9 12 2 (set (reg:DI 85)
        (and:DI (reg:DI 83)
            (const_int 15 [0xf]))) "x.c":4 70 {anddi3}
     (expr_list:REG_DEAD (reg:DI 83)
        (nil)))
(insn 12 11 13 2 (set (reg:SI 88)
        (const_int 53248 [0xd000])) "x.c":4 132 {*movsi_internal}
     (nil))
(insn 13 12 14 2 (set (reg:SI 87)
        (plus:SI (reg:SI 88)
            (const_int 102 [0x66]))) "x.c":4 3 {addsi3}
     (expr_list:REG_DEAD (reg:SI 88)
        (expr_list:REG_EQUAL (const_int 53350 [0xd066])
            (nil))))
(insn 14 13 15 2 (set (reg:SI 86)
        (ashift:SI (reg:SI 87)
            (subreg:SI (reg:DI 85) 0))) "x.c":4 146 {ashlsi3}
     (expr_list:REG_DEAD (reg:SI 87)
        (expr_list:REG_DEAD (reg:DI 85)
            (nil))))
(insn 11 9 12 2 (set (reg:DI 85)
        (and:DI (reg:DI 83)
            (const_int 15 [0xf]))) "x.c":4 70 {anddi3}
     (expr_list:REG_DEAD (reg:DI 83)
        (nil)))
(insn 15 14 16 2 (set (reg:DI 91)
        (const_int 65536 [0x10000])) "x.c":4 131 {*movdi_64bit}
     (nil))
(insn 16 15 17 2 (set (reg:DI 90)
        (plus:DI (reg:DI 91)
            (const_int -1 [0xffffffffffffffff]))) "x.c":4 4 {adddi3}
     (expr_list:REG_DEAD (reg:DI 91)
        (expr_list:REG_EQUAL (const_int 65535 [0xffff])
            (nil))))
(insn 17 16 18 2 (set (reg:DI 89)
        (and:DI (subreg:DI (reg:SI 86) 0)
            (reg:DI 90))) "x.c":4 70 {anddi3}
     (expr_list:REG_DEAD (reg:DI 90)
        (expr_list:REG_DEAD (reg:SI 86)
            (nil))))
(insn 18 17 23 2 (set (reg:DI 92)
        (sign_extend:DI (subreg:SI (reg:DI 89) 0))) "x.c":4 86 {extendsidi2}
     (expr_list:REG_DEAD (reg:DI 89)
        (nil)))
(insn 23 18 24 2 (set (reg/i:DI 10 a0)
        (reg:DI 92)) "x.c":5 131 {*movdi_64bit}
     (expr_list:REG_DEAD (reg:DI 92)
        (nil)))

After combine: (x.c.262r.ce2)
(insn 23 18 24 2 (set (reg/i:DI 10 a0)
        (const_int 0 [0])) "x.c":5 131 {*movdi_64bit} 
     (nil))

What's happen during combine:
...
Trying 11 -> 14:
Successfully matched this instruction:
(set (reg:SI 86)
    (ashift:SI (reg:SI 87)
        (subreg:SI (reg:DI 83) 0)))
allowing combination of insns 11 and 14
original costs 4 + 4 = 8
replacement cost 4
deferring deletion of insn with uid = 11.
modifying insn i3    14: r86:SI=r87:SI<<r83:DI#0
      REG_DEAD r83:DI
      REG_DEAD r87:SI
deferring rescan insn with uid = 14.
...
Trying 15, 16 -> 17:
Successfully matched this instruction:
(set (reg:DI 89)
    (zero_extend:DI (subreg:HI (reg:SI 86) 0)))
allowing combination of insns 15, 16 and 17
original costs 4 + 4 + 4 = 12
replacement cost 8
deferring deletion of insn with uid = 16.
deferring deletion of insn with uid = 15.
modifying insn i3    17: r89:DI=zero_extend(r86:SI#0)
      REG_DEAD r86:SI
deferring rescan insn with uid = 17.
...
Trying 9, 14 -> 17:
Successfully matched this instruction:
(set (reg:DI 89)
    (const_int 0 [0]))
allowing combination of insns 9, 14 and 17
original costs 4 + 4 + 8 = 16
replacement cost 4
deferring deletion of insn with uid = 14.
deferring deletion of insn with uid = 9.
deferring deletion of insn with uid = 12.
deferring deletion of insn with uid = 13.
deferring deletion of insn with uid = 7.
modifying insn i3    17: r89:DI=0
deferring rescan insn with uid = 17.


More information about the Gcc-bugs mailing list