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

Reply via email to