I was working on a a patch for PR 21596, and it seems to have triggered
a bug in fwprop on x86 in mainline.
The testcase is simple:
register int *reg __asm__("%edi");
int test () { return *--reg <= 0; }
I've attached the patch for TER which changes the tree produced in
mainline from:
reg.0 = reg;
reg.27 = reg.0 - 4B;
reg = reg.27;
return *reg.27 <= 0;
to
reg.27 = reg - 4B;
reg = reg.27;
return *reg.27 <= 0;
which eliminates one extraneous copy.
Going into fwprop1, the rtl looks like:
(insn 7 5 8 2 (parallel [
(set (reg:SI 58 [ reg.27 ])
(plus:SI (reg/v:SI 5 di [ reg ])
(const_int -4 [0xfffffffc])))
(clobber (reg:CC 17 flags))
]) 148 {*addsi_1} (nil)
(nil))
(insn 8 7 9 2 (set (reg/v:SI 5 di [ reg ])
(reg:SI 58 [ reg.27 ])) 34 {*movsi_1} (nil)
(nil))
(insn 9 8 10 2 (set (reg:CCNO 17 flags)
(compare:CCNO (mem:SI (reg:SI 58 [ reg.27 ]) [3 S4 A32])
(const_int 0 [0x0]))) 0 {*cmpsi_ccno_1} (nil)
(nil))
and fwprop decides to propagate:
(compare:CCNO (mem:SI (reg:SI 58 [ reg.27 ]) [3 S4 A32])
(const_int 0 [0x0]))
with (compare:CCNO (mem:SI (plus:SI (reg/v:SI 5 di [ reg ])
(const_int -4 [0xfffffffc])) [3 S4 A32])
(const_int 0 [0x0]))
resulting in:
(insn 7 5 8 2 (parallel [
(set (reg:SI 58 [ reg.27 ])
(plus:SI (reg/v:SI 5 di [ reg ])
(const_int -4 [0xfffffffc])))
(clobber (reg:CC 17 flags))
]) 148 {*addsi_1} (nil)
(nil))
(insn 8 7 9 2 (set (reg/v:SI 5 di [ reg ])
(reg:SI 58 [ reg.27 ])) 34 {*movsi_1} (nil)
(nil))
(insn 9 8 10 2 (set (reg:CCNO 17 flags)
(compare:CCNO (mem:SI (plus:SI (reg/v:SI 5 di [ reg ])
(const_int -4 [0xfffffffc])) [3 S4 A32])
(const_int 0 [0x0]))) 0 {*cmpsi_ccno_1} (nil)
(nil))
note that it has propagated 'di - 4' past insn 8 which sets di to di
-4.
The compare in insn 9 is now comparing an additional -4 offset to di,
which is wrong.
It would be really sweet if we propagated the 'di - 4' into insn 8, then
recognized that di is now the value of SI 58, and propagated di into the
compare. insn 7 would be dead and we'd get the code the PR is looking
for :-)
Andrew
2007-03-05 Andrew MacLeod <[EMAIL PROTECTED]>
* tree-ssa-ter.c (find_replaceable_in_bb): Allow expression replacement
of same basename variables for stmts with a single ssa_name use.
Index: tree-ssa-ter.c
===================================================================
*** tree-ssa-ter.c (revision 122131)
--- tree-ssa-ter.c (working copy)
*************** find_replaceable_in_bb (temp_expr_table_
*** 555,565 ****
--- 555,567 ----
var_map map = tab->map;
ssa_op_iter iter;
bool stmt_replaceable;
+ bool single_use_stmt;
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{
stmt = bsi_stmt (bsi);
ann = stmt_ann (stmt);
+ single_use_stmt = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE) != NULL_TREE;
stmt_replaceable = is_replaceable_p (stmt);
/* Determine if this stmt finishes an existing expression. */
*************** find_replaceable_in_bb (temp_expr_table_
*** 577,583 ****
/* See if the root variables are the same. If they are, we
do not want to do the replacement to avoid problems with
code size, see PR tree-optimization/17549. */
! if (!bitmap_empty_p (vars))
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF)
{
if (bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def))))
--- 579,590 ----
/* See if the root variables are the same. If they are, we
do not want to do the replacement to avoid problems with
code size, see PR tree-optimization/17549. */
!
! /* If this stmt is not accumulating more than one variable (ie,
! it has a single use), then an exponential growth rate is not
! possible. This makes it safe to allow TER to proceed. See
! PR tree-optimization/21596. */
! if (!bitmap_empty_p (vars) && !single_use_stmt)
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF)
{
if (bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def))))