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

            Bug ID: 81291
           Summary: [5/6/7/8 Regression] wrong code with -O2
                    -fno-rerun-cse-after-loop -fno-tree-ter -fno-tree-vrp
                    -funroll-loops due to improper carry
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: zsojka at seznam dot cz
  Target Milestone: ---
              Host: x86_64-pc-linux-gnu
            Target: powerpc-unknown-linux-gnu
             Build: x86_64-pc-linux-gnu

Created attachment 41667
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41667&action=edit
reduced testcase

Output:
$ powerpc-unknown-linux-gnu-gcc -O2 -fno-rerun-cse-after-loop -fno-tree-ter
-fno-tree-vrp -funroll-loops testcase.c
$ qemu-ppc ./a.out 
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted

The wrong value of "x" is 0x0000000100000000. It seems to be created as:
$ cat testcase.c
...
        li 11,1  # _20,
 # testcase.c:11:   a %= ~(u64)0;
        sth 8,a@l(7)     # aD.2487, a.0_1
 # testcase.c:10:   b = (u64)-a > a;
        sth 10,b@l(6)    # bD.2488, _7
 # testcase.c:13: }
        adde 3,3,11      #, c.4_12, _20
        blr
...
eg. r11 is unconditionally set to 1, which seems to be wrong.

It is visible at least after combine; before combine, there is:
$ cat testcase.c.260r.ud_dce
...
(insn 45 88 47 6 (parallel [
            (set (reg:SI 179 [+4 ])
                (minus:SI (const_int 0 [0])
                    (reg:SI 167 [ _8+4 ])))
            (set (reg:SI 76 ca)
                (leu:SI (reg:SI 167 [ _8+4 ])
                    (const_int 0 [0])))
        ]) "testcase.c":11 104 {subfsi3_carry}
     (expr_list:REG_UNUSED (reg:SI 76 ca)
        (nil)))
...
(insn 66 63 67 6 (parallel [
            (set (reg:SI 175 [ _20+4 ])
                (plus:SI (reg:SI 130 [ d.5_10+-2 ])
                    (reg:SI 133 [ e.7_14+-2 ])))
            (set (reg:SI 76 ca)
                (ltu:SI (plus:SI (reg:SI 130 [ d.5_10+-2 ])
                        (reg:SI 133 [ e.7_14+-2 ]))
                    (reg:SI 130 [ d.5_10+-2 ])))
        ]) 78 {addsi3_carry}
     (expr_list:REG_DEAD (reg:SI 133 [ e.7_14+-2 ])
        (expr_list:REG_DEAD (reg:SI 130 [ d.5_10+-2 ])
            (nil))))
(insn 67 66 68 6 (parallel [
            (set (reg:SI 174 [ _20 ])
                (plus:SI (plus:SI (reg:SI 179 [+4 ])
                        (reg:SI 179 [+4 ]))
                    (reg:SI 76 ca)))
            (clobber (reg:SI 76 ca))
        ]) 83 {*addsi3_carry_in_internal}
     (expr_list:REG_DEAD (reg:SI 179 [+4 ])
        (expr_list:REG_DEAD (reg:SI 76 ca)
            (expr_list:REG_UNUSED (reg:SI 76 ca)
                (nil)))))
...

And after combine:
$ cat testcase.c.261r.combine
...
Trying 45 -> 67:
Failed to match this instruction:
(parallel [
        (set (reg:SI 174 [ _20 ])
            (const_int 1 [0x1]))
        (clobber (reg:SI 76 ca))
    ])
Successfully matched this instruction:
(set (reg:SI 174 [ _20 ])
    (const_int 1 [0x1]))
allowing combination of insns 45 and 67
original costs 0 + 8 = 0
replacement cost 4
deferring deletion of insn with uid = 45.
deferring deletion of insn with uid = 45.
modifying insn i3    67: r174:SI=0x1
deferring rescan insn with uid = 67.
...
(note 45 88 47 6 NOTE_INSN_DELETED)
...
(insn 66 63 67 6 (parallel [
            (set (reg:SI 175 [ _20+4 ])
                (plus:SI (reg:SI 130 [ d.5_10+-2 ])
                    (reg:SI 133 [ e.7_14+-2 ])))
            (set (reg:SI 76 ca)
                (ltu:SI (plus:SI (reg:SI 130 [ d.5_10+-2 ])
                        (reg:SI 133 [ e.7_14+-2 ]))
                    (reg:SI 130 [ d.5_10+-2 ])))
        ]) 78 {addsi3_carry}
     (expr_list:REG_DEAD (reg:SI 133 [ e.7_14+-2 ])
        (expr_list:REG_DEAD (reg:SI 130 [ d.5_10+-2 ])
            (nil))))
(insn 67 66 68 6 (set (reg:SI 174 [ _20 ])
        (const_int 1 [0x1])) 479 {*movsi_internal1}
     (nil))
...

I don't see how 45 and 67 can be combined when 67 is using reg 76 which is set
by insn 66, but I also do not really understand why insn 67 was present in the
first place (it does r179+r179+ca; why? which is (0-r167)+(0-r167)+ca, which is
0-0+0-0+ca, which is "ca" from insn 66, but value of "ca" from insn 45 (=(0==0)
-> =1) is taken?)

Reply via email to