On Thu, Mar 17, 2016 at 01:32:15PM +0000, Joern Rennecke wrote: > > Note that during register allocation / reload, REGNO equivalence is > > generally wrong, > as it fails to distinguish between the frame pointer and a hard register that > has the > same regno as the frame pointer which has been created as a register > allocation for > a pseudo register when the frame pointer is being eliminated. > lra_get_elimination_hard_regno actually gets this wrong (as well as the > interfaces - > there is no rtx value available, so it'd be very hard to fix), which means > that targets > can't use safely lra with frame pointer elimination and matching constraints, > unless > they use a separate soft frame pointer. > If you want to decide automagically if you'd run into an ambiguity with > register > elimination, you have to check if either side of the comparison appears in > regs_eliminate_1[i].from for 0 <= i < ARRAY_SIZE(regs_eliminate_1) . > Unfortunately, although rarely encountered, it is possible to use the frame > pointer > in a mode other than Pmode, and once cleanup_subreg_operands is done with such > a reference, an equality check with frame_pointer_rtx will fail.
Sure. Which is why the trunk now uses the old behavior of replace_rtx unless you ask for different one through extra argument. In epiphany.md, I see (define_peephole2 [(parallel [(set (match_operand:WMODE 0 "gpr_operand" "") (match_operand:WMODE 1 "" "")) (clobber (match_operand 8 "cc_operand"))]) (match_operand 2 "" "") (set (match_operand:WMODE2 3 "gpr_operand" "") (match_operand:WMODE2 9 "gpr_operand" "")) (set (match_dup 3) (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator" [(match_operand 6 "cc_operand") (match_operand 7 "const0_operand")]) (match_operand:WMODE2 4 "nonmemory_operand" "") (match_dup 3)))] "REGNO (operands[0]) == REGNO (operands[9]) && peep2_reg_dead_p (3, operands[0]) && !reg_set_p (operands[0], operands[2]) && !reg_set_p (operands[3], operands[2]) && !reg_overlap_mentioned_p (operands[3], operands[2])" [(parallel [(set (match_dup 10) (match_dup 1)) (clobber (match_dup 8))]) (match_dup 2) (set (match_dup 3) (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))] { operands[10] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3], <WMODE2:MODE>mode, 0); replace_rtx (operands[2], operands[9], operands[3]); replace_rtx (operands[2], operands[0], operands[10]); gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[2])); }) and peephole2s are after RA, and I bet you rely on the replacements to be done no matter if there is pointer equality or just REGNO equality (and, can there be different modes or just one?). sh.md has something similar. Jakub