[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 --- Comment #9 from Jakub Jelinek --- Author: jakub Date: Mon Feb 13 15:39:59 2017 New Revision: 245390 URL: https://gcc.gnu.org/viewcvs?rev=245390&root=gcc&view=rev Log: PR rtl-optimization/79388 PR rtl-optimization/79450 * combine.c (distribute_notes): When removing TEM_INSN for which corresponding dest has last value recorded, invalidate that last value. * gcc.c-torture/execute/pr79388.c: New test. * gcc.c-torture/execute/pr79450.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/execute/pr79388.c trunk/gcc/testsuite/gcc.c-torture/execute/pr79450.c Modified: trunk/gcc/ChangeLog trunk/gcc/combine.c trunk/gcc/testsuite/ChangeLog
[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 --- Comment #8 from Jakub Jelinek --- --- gcc/combine.c.jj2017-01-30 09:31:48.0 +0100 +++ gcc/combine.c 2017-02-10 12:16:18.507855160 +0100 @@ -14288,6 +14288,11 @@ distribute_notes (rtx notes, rtx_insn *f NULL_RTX, NULL_RTX, NULL_RTX); distribute_links (LOG_LINKS (tem_insn)); + unsigned int regno = REGNO (XEXP (note, 0)); + reg_stat_type *rsp = ®_stat[regno]; + if (rsp->last_set == tem_insn) + record_value_for_reg (XEXP (note, 0), NULL, NULL_RTX); + SET_INSN_DELETED (tem_insn); if (tem_insn == i2) i2 = NULL; fixes both testcases by making sure that if we delete the instruction that is still considered to be the setter of the last value, we also invalidate what we've remembered for it. No idea whether this is the right spot or right way to invalidate that though. Segher?
[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 --- Comment #7 from Jakub Jelinek --- Another testcase from the other PR (-O): unsigned int foo (unsigned char x, unsigned long long y) { do { x &= !y; x %= 24; } while (x < y); return x + y; } int main (void) { unsigned int x = foo (1, 0); if (x != 1) __builtin_abort (); return 0; }
[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 --- Comment #6 from Jakub Jelinek --- *** Bug 79450 has been marked as a duplicate of this bug. ***
[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 --- Comment #5 from Jakub Jelinek --- At -O2 vrp would normally optimize this already much earlier.
[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 Jakub Jelinek changed: What|Removed |Added CC||segher at gcc dot gnu.org --- Comment #4 from Jakub Jelinek --- (gdb) p debug_rtx (reg_stat.m_vec.m_vecdata[91].last_set) (insn 21 20 22 2 (parallel [ (set (reg/v:SI 91 [ p ]) (and:SI (reg/v:SI 91 [ p ]) (const_int 65534 [0xfffe]))) (clobber (reg:CC 17 flags)) ]) "pr79388.c":11 389 {*andsi_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) looks correct, but (gdb) p debug_rtx (reg_stat.m_vec.m_vecdata[91].last_set_value) (and:SI (const_int 0 [0]) (const_int 65534 [0xfffe])) looks wrong. The problem is that during: #1 0x01849ddc in record_value_for_reg (reg=0x7fffefc124b0, insn=0x7fffefad2700, value=0x7fffefc12570) at ../../gcc/combine.c:12959 #2 0x0184a105 in record_dead_and_set_regs_1 (dest=0x7fffefc124b0, setter=0x7fffefc12588, data=0x7fffefad2700) at ../../gcc/combine.c:13059 #3 0x00e16e6f in note_stores (x=0x7fffefc12588, fun=0x184a052 , data=0x7fffefad2700) at ../../gcc/rtlanal.c:1846 #4 0x00e16eba in note_stores (x=0x7fffefbefa10, fun=0x184a052 , data=0x7fffefad2700) at ../../gcc/rtlanal.c:1851 #5 0x0184a48a in record_dead_and_set_regs (insn=0x7fffefad2700) at ../../gcc/combine.c:13140 on insn 21 we have dest (reg/v:SI 91 [ p ]) and value (and:SI (reg/v:SI 91 [ p ]) (const_int 65534 [0xfffe])), and get_last_value on the REG 91 is wrong: (gdb) p debug_rtx (reg_stat.m_vec.m_vecdata[91].last_set_value) (const_int 0 [0]) $122 = void (gdb) p debug_rtx (reg_stat.m_vec.m_vecdata[91].last_set) (note 16 15 18 2 NOTE_INSN_DELETED) insn 16 is former: (insn 16 15 18 2 (parallel [ (set (reg/v:SI 91 [ p ]) (lshiftrt:SI (subreg:SI (reg:DI 98) 0) (const_int 15 [0xf]))) (clobber (reg:CC 17 flags)) ]) "pr79388.c":11 542 {*lshrsi3_1} (expr_list:REG_DEAD (reg:DI 98) (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_EQUAL (udiv:SI (reg:SI 89 [ _7 ]) (const_int 65535 [0x])) (nil) so it seems something forgot to invalidate the last value or something similar. REG_N_SETS (91) is 3. Segher, any ideas?
[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 --- Comment #3 from Jakub Jelinek --- This happens because apparently nonzero_bits ((reg/v:SI 91 [ p ]), SImode) returns 0.
[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 --- Comment #2 from Jakub Jelinek --- Seems this goes wrong during combine. Before it is able to figure out that (p & 0xfffe) is identical to (p & 0xfffe) % 0x (correct), and so we get: (note 4 0 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (insn 2 4 3 2 (set (reg/v:SI 91 [ p ]) (reg:SI 5 di [ p ])) "pr79388.c":8 82 {*movsi_internal} (expr_list:REG_DEAD (reg:SI 5 di [ p ]) (nil))) (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG) (note 6 3 7 2 NOTE_INSN_DELETED) (note 7 6 9 2 NOTE_INSN_DELETED) (note 9 7 11 2 NOTE_INSN_DELETED) (note 11 9 12 2 NOTE_INSN_DELETED) (note 12 11 14 2 NOTE_INSN_DELETED) (note 14 12 15 2 NOTE_INSN_DELETED) (note 15 14 16 2 NOTE_INSN_DELETED) (note 16 15 18 2 NOTE_INSN_DELETED) (note 18 16 20 2 NOTE_INSN_DELETED) (note 20 18 21 2 NOTE_INSN_DELETED) (insn 21 20 22 2 (parallel [ (set (reg/v:SI 91 [ p ]) (and:SI (reg/v:SI 91 [ p ]) (const_int 65534 [0xfffe]))) (clobber (reg:CC 17 flags)) ]) "pr79388.c":11 389 {*andsi_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (nil))) (insn 22 21 23 2 (set (mem/c:SI (symbol_ref:DI ("c") [flags 0x2] ) [1 c+0 S4 A32]) (reg/v:SI 91 [ p ])) "pr79388.c":12 82 {*movsi_internal} (nil)) (insn 23 22 24 2 (set (reg:SI 103 [ a ]) (mem/c:SI (symbol_ref:DI ("a") [flags 0x2] ) [1 a+0 S4 A32])) "pr79388.c":13 82 {*movsi_internal} (nil)) (insn 24 23 29 2 (parallel [ (set (reg:SI 102) (plus:SI (reg/v:SI 91 [ p ]) (reg:SI 103 [ a ]))) (clobber (reg:CC 17 flags)) ]) "pr79388.c":13 215 {*addsi_1} (expr_list:REG_DEAD (reg:SI 103 [ a ]) (expr_list:REG_DEAD (reg/v:SI 91 [ p ]) (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_EQUAL (plus:SI (reg/v:SI 91 [ p ]) (mem/c:SI (symbol_ref:DI ("a") [flags 0x2] ) [1 a+0 S4 A32])) (nil)) (insn 29 24 30 2 (set (reg/i:SI 0 ax) (reg:SI 102)) "pr79388.c":14 82 {*movsi_internal} (expr_list:REG_DEAD (reg:SI 102) (nil))) (insn 30 29 0 2 (use (reg/i:SI 0 ax)) "pr79388.c":14 -1 (nil)) But then try_combine is called with i3 24 and i2 23 and for some reason turns that into a load from the mem alone (as if (reg:SI 91) is 0).
[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 Jakub Jelinek changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2017-02-06 CC||jakub at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Jakub Jelinek --- Started with r226901.
[Bug rtl-optimization/79388] [6/7 Regression] wrong code with -O -fno-tree-coalesce-vars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79388 Richard Biener changed: What|Removed |Added Priority|P3 |P2 Target Milestone|--- |6.4