[Bug middle-end/54154] New: cprop_hardreg generates redundant instructions
Paulo.Matos at csr dot com
gcc-bugzilla@gcc.gnu.org
Wed Aug 1 14:33:00 GMT 2012
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: unassigned@gcc.gnu.org
ReportedBy: Paulo.Matos@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.
More information about the Gcc-bugs
mailing list