The testcase: int g = 20; int d = 0; short fn2 (int p1, int p2) { return p2 >= 2 || 5 >> p2 ? p1 : p1 << p2; } int main () { int result = 0; lbl_2582: if (g) { for (int c = -3; c; c++) result = fn2 (1, g); } else { for (int i = 0; i < 2; i += 2) if (d) goto lbl_2582; } if (result != 1) __builtin_abort (); return 0; } used to (erroneously) abort on aarch64-none-linux-gnu with -O3 after r235808 but stopped aborting with r242550. It still passes after the fix r242689 but I'm not sure if the bug has just gone latent. To reproduce on aarch64 you'll have to revert r242689 and r242550.
Thanks for reporting. I will investigate.
Should reproduce still with -ftree-loop-if-convert after r242550?
(In reply to Richard Biener from comment #2) > Should reproduce still with -ftree-loop-if-convert after r242550? Yes it does with 242837. Thanks
I think it's a combine issue reveal by that change. I am testing a patch for public discussion, guess Segher may have better solutions.
(insn 37 35 39 7 (set (reg:SI 96) (sign_extend:SI (subreg:QI (reg:SI 95) 0))) 86 {*extendqisi2_aarch64} (expr_list:REG_DEAD (reg:SI 95) (nil))) (insn 39 37 40 7 (set (reg:CC 66 cc) (compare:CC (reg:SI 96) (const_int 0 [0]))) 392 {cmpsi} (expr_list:REG_DEAD (reg:SI 96) (nil))) (insn 40 39 41 7 (set (reg:HI 93) (if_then_else:HI (ne (reg:CC 66 cc) (const_int 0 [0])) (subreg/s/u:HI (reg:SI 81 [ iftmp.0_17 ]) 0) (reg:HI 97))) 443 {*cmovhi_insn} (expr_list:REG_DEAD (reg:CC 66 cc) (expr_list:REG_EQUAL (if_then_else:HI (ne (reg:CC 66 cc) (const_int 0 [0])) (subreg/s/u:HI (reg:SI 81 [ iftmp.0_17 ]) 0) (const_int 1 [0x1])) (nil)))) --------------> Trying 37 -> 39: Failed to match this instruction: (set (reg:CC 66 cc) (reg:CC 66 cc)) Successfully matched this instruction: (set (reg:HI 93) (if_then_else:HI (le (reg:CC 66 cc) (const_int 0 [0])) (subreg/s/u:HI (reg:SI 81 [ iftmp.0_17 ]) 0) (reg:HI 97))) allowing combination of insns 37 and 39 original costs 4 + 4 = 12 replacement cost 8 deferring deletion of insn with uid = 37. modifying other_insn 40: r93:HI={(cc:CC<=0)?r81:SI#0:r97:HI} REG_DEAD cc:CC REG_EQUAL {(cc:CC!=0)?r81:SI#0:0x1} deferring rescan insn with uid = 40. modifying insn i3 39: cc:CC=cc:CC deferring rescan insn with uid = 39. Note after combine: 40: r93:HI={(cc:CC<=0)?r81:SI#0:r97:HI} REG_DEAD cc:CC REG_EQUAL {(cc:CC!=0)?r81:SI#0:0x1} cc register has been changed, and (cc<=0) != (cc!=0).
So do you think combiner should throw away the REG_EQUAL note in that case, or something different?
(In reply to Jakub Jelinek from comment #6) > So do you think combiner should throw away the REG_EQUAL note in that case, > or something different? It's invalid after transformation, so should be discarded in this case. What I am not sure is that how to tell invalid ones from all notes and keep others. I sent a proposed patch for discussion before @https://gcc.gnu.org/ml/gcc-patches/2016-12/msg00026.html Thanks.
Bernd. There's a belief this may be a combiner issue, so it might be something you'd want to poke at. I can still trigger this failure on the trunk using -ftree-loop-if-convert on an aarch64 native. If you need access to an aarch64 system, let me know, I've got one provisioned.
Ok, I'll look.
I am leaning toward accepting Bin's patch, but testing whether that hurts generated code too much still hasn't finished.
Looks like other_insn is only used for cases where we rewrite cc sets in this way, so Bin's patch does look reasonably narrow. We could maybe record the CC reg being changed and only discard reg notes, but in my testing I've not been able to produce code generation differences except for the testcase. Let's wait for Segher's testing, but I think the patch is OK.
Sorry, long pause while editing that comment made me leave out part of what I was trying to say - I meant only discard notes that reference the CC reg. But it seems an unnecessary complication.
Author: amker Date: Fri Jan 27 14:42:23 2017 New Revision: 244979 URL: https://gcc.gnu.org/viewcvs?rev=244979&root=gcc&view=rev Log: PR rtl-optimization/78559 * combine.c (try_combine): Discard REG_EQUAL and REG_EQUIV for other_insn in combine. gcc/testsuite PR rtl-optimization/78559 * gcc.c-torture/execute/pr78559.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/execute/pr78559.c Modified: trunk/gcc/ChangeLog trunk/gcc/combine.c trunk/gcc/testsuite/ChangeLog
Fixed by Bin's patch on the trunk.
*** Bug 98269 has been marked as a duplicate of this bug. ***