http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54154
Bug #: 54154 Summary: cprop_hardreg generates redundant instructions Classification: Unclassified Product: gcc Version: 4.6.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: paulo.ma...@csr.com Created attachment 27922 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27922 Before cprop_hardreg Hello, I have touched this subject before: * http://gcc.gnu.org/ml/gcc/2010-08/msg00347.html * http://gcc.gnu.org/ml/gcc/2011-03/msg00214.html and it looks like a long standing issue so I am wary of reporting a bug but I think I did find the culprit code. So, unless you consider this a feature somehow I reckon it's a bug. cprop_hardreg grabs an insn chain and through forward propagation of registers ends up generating redundant passes where the src and dest are the same (same regnumber, same mode). Consider the program (obtained using creduce): int a; int fn1 (); void fn2 (); int fn3 (); int fn4 () { if (fn1 ()) return 0; a = fn3 (); if (a != (1 << (32 - (9 + 9))) - 1) fn2 (0, a); return (1 << (32 - (9 + 9))) - 1; } Now, after compiling for my backend with -Os I get before cprop_hardreg (after ce3) [real logs attached]: #8 reg AL <- call fn1 #50/51 if_then_else AL != 0 goto label 34 #12 AL <- call fn3 #13 AH <- AL #14 mem sym a <- AH #48/49 if_then_else AH == 16383 goto label 38 #17 AL <- 0 #19 call fn2 #4 AL <- 16383 #43 jump label 20 label 34: #3 AL <- 0 #45 jump label 20 label 38: #5 AL <- AH label 20: return the number after '#' is the insn number. cprop_hardreg decided to replace AH with AL so the top of cprop_hardreg shows: rescanning insn with uid = 14. deleting insn with uid = 14. insn 14: replaced reg 0 with 1 insn 48: replaced reg 0 with 1 rescanning insn with uid = 48. deleting insn with uid = 48. rescanning insn with uid = 5. deleting insn with uid = 5. insn 5: replaced reg 0 with 1 reg 0 is AH and reg 1 is AL. When you replace in insn 5, AH by AL you get the insn AL <- AL and that's #5 after cprop_hardreg. I find it strange that there's no code checking if set dest is equal to replacement and if it is, simply remove insn. I think this is a bug and should be fixed.