Message ID | alpine.LSU.2.11.1602101400100.31122@t29.fhfr.qr |
---|---|
State | New |
Headers | show |
On 02/10/2016 02:04 PM, Richard Biener wrote: > where noce_try_store_flag_constants identifies > > (plus:SI (reg/v:SI 160 [ mod_tlen ]) > (reg/v:SI 224 [ <retval> ])) > > as "common" and then tries to detect the case where setting the > result would clobber that value. It doesn't seem to expect > anything else than regs that can be equal to the destination though > which is clearly an oversight. > /* If we have x := test ? x + 3 : x + 4 then move the original > x out of the way while we store flags. */ > - if (common && rtx_equal_p (common, if_info->x)) > + if (common && reg_mentioned_p (if_info->x, common)) > { > - common = gen_reg_rtx (mode); > - noce_emit_move_insn (common, if_info->x); > + rtx tem = gen_reg_rtx (mode); > + noce_emit_move_insn (tem, common); > + common = tem; > } I'm not so sure noce_emit_move_insn will reliably handle an arbitrary expression. I think a more conservative fix would be to disable this transform if common is not a reg. Bernd
Index: gcc/ifcvt.c =================================================================== --- gcc/ifcvt.c (revision 233262) +++ gcc/ifcvt.c (working copy) @@ -1381,10 +1381,11 @@ noce_try_store_flag_constants (struct no /* If we have x := test ? x + 3 : x + 4 then move the original x out of the way while we store flags. */ - if (common && rtx_equal_p (common, if_info->x)) + if (common && reg_mentioned_p (if_info->x, common)) { - common = gen_reg_rtx (mode); - noce_emit_move_insn (common, if_info->x); + rtx tem = gen_reg_rtx (mode); + noce_emit_move_insn (tem, common); + common = tem; } target = noce_emit_store_flag (if_info, if_info->x, reversep, normalize);