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?)