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))))