------- Additional Comments From steven at gcc dot gnu dot org 2005-09-18 14:27 ------- Not being even closely an RTL guru (as you can see in this bug audit trail ;-) I'd propose the following patch: Index: cse.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cse.c,v retrieving revision 1.360 diff -u -3 -p -r1.360 cse.c --- cse.c 6 Sep 2005 08:52:51 -0000 1.360 +++ cse.c 18 Sep 2005 14:19:02 -0000 @@ -2999,7 +2999,8 @@ find_best_addr (rtx insn, rtx *loc, enum p = p->next_same_value, count++) if (! p->flag && (REG_P (p->exp) - || exp_equiv_p (p->exp, p->exp, 1, false))) + || (GET_CODE (p->exp) != EXPR_LIST + && exp_equiv_p (p->exp, p->exp, 1, false)))) { rtx new = simplify_gen_binary (GET_CODE (*loc), Pmode, p->exp, op1); Rationale: We start with this: (insn 16 15 20 0 (set (reg:DI 62) (reg:DI 0 ax)) 81 {*movdi_1_rex64} (nil) (insn_list:REG_RETVAL 14 (expr_list:REG_EQUAL (expr_list:REG_DEP_TRUE (use (mem:BLK (scratch) [0 A8])) (expr_list:REG_DEP_TRUE (symbol_ref:DI ("strlen") [flags 0x41] <function_decl 0x2a9590d500 strlen>) (expr_list:REG_DEP_TRUE (symbol_ref:DI ("savecallsin") [flags 0x2] <var_decl 0x2a95a3cdc0 savecallsin>) (nil)))) (nil)))) (insn 20 16 21 0 (set (reg:CCZ 17 flags) (compare:CCZ (mem/s:QI (plus:DI (plus:DI (reg:DI 62) (reg/f:DI 60)) (const_int -1 [0xffffffffffffffff])) [0 savecallsin S1 A8]) (const_int 47 [0x2f]))) 10 {*cmpqi_1} (nil) (expr_list:REG_EQUAL (compare:CCZ (mem/s:QI (plus:DI (reg:DI 62) (const:DI (plus:DI (symbol_ref:DI ("savecallsin") [flags 0x2] <var_decl 0x2a95a3cdc0 savecallsin>) (const_int -1 [0xffffffffffffffff])))) [0 savecallsin S1 A8]) (const_int 47 [0x2f])) (nil))) and then we try to replace (reg:DI 62) with the rediculous EXPR_LIST. That doesn't make any sense at all, to begin with (and the fact that we find that the new address with the EXPR_LIST is cheaper is equally stupid). exp_equiv_p is right that the canonicalized p->exp would be equal (nothing is volatile, etc.). I guess the only proper way to prevent forming this new address is by disallowing propagation of EXPR_LISTs completely. It never makes sense to have an address containing an EXPR_LIST anyway.
-- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23943