Commit b8e48b98 by Jakub Jelinek Committed by Jakub Jelinek

re PR rtl-optimization/19579 (-march=i686 generates a bogus program for x86*)

	PR rtl-optimization/19579
	* ifcvt.c (noce_try_cmove_arith): If emitting instructions to set up
	both A and B, see if they don't clobber registers the other expr uses.

	* gcc.c-torture/execute/20050124-1.c: New test.

From-SVN: r94234
parent 8dac1b21
2005-01-26 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/19579
* ifcvt.c (noce_try_cmove_arith): If emitting instructions to set up
both A and B, see if they don't clobber registers the other expr uses.
2005-01-25 J"orn Rennecke <joern.rennecke@st.com>
* real.c (do_add): Initialize signalling and canonical members.
......
......@@ -1229,6 +1229,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
rtx a = if_info->a;
rtx b = if_info->b;
rtx x = if_info->x;
rtx orig_a, orig_b;
rtx insn_a, insn_b;
rtx tmp, target;
int is_mem = 0;
......@@ -1304,6 +1305,9 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
start_sequence ();
orig_a = a;
orig_b = b;
/* If either operand is complex, load it into a register first.
The best way to do this is to copy the original insn. In this
way we preserve any clobbers etc that the insn may have had.
......@@ -1335,7 +1339,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
}
if (! general_operand (b, GET_MODE (b)))
{
rtx set;
rtx set, last;
if (no_new_pseudos)
goto end_seq_and_fail;
......@@ -1343,9 +1347,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
if (is_mem)
{
tmp = gen_reg_rtx (GET_MODE (b));
tmp = emit_insn (gen_rtx_SET (VOIDmode,
tmp,
b));
tmp = gen_rtx_SET (VOIDmode, tmp, b);
}
else if (! insn_b)
goto end_seq_and_fail;
......@@ -1355,8 +1357,22 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
tmp = copy_rtx (insn_b);
set = single_set (tmp);
SET_DEST (set) = b;
tmp = emit_insn (PATTERN (tmp));
tmp = PATTERN (tmp);
}
/* If insn to set up A clobbers any registers B depends on, try to
swap insn that sets up A with the one that sets up B. If even
that doesn't help, punt. */
last = get_last_insn ();
if (last && modified_in_p (orig_b, last))
{
tmp = emit_insn_before (tmp, get_insns ());
if (modified_in_p (orig_a, tmp))
goto end_seq_and_fail;
}
else
tmp = emit_insn (tmp);
if (recog_memoized (tmp) < 0)
goto end_seq_and_fail;
}
......
2005-01-26 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/19579
* gcc.c-torture/execute/20050124-1.c: New test.
2005-01-18 Jan Hubicka <jh@suse.cz>
PR tree-optimize/19337
......
/* PR rtl-optimization/19579 */
extern void abort (void);
int
foo (int i, int j)
{
int k = i + 1;
if (j)
{
if (k > 0)
k++;
else if (k < 0)
k--;
}
return k;
}
int
main (void)
{
if (foo (-2, 0) != -1)
abort ();
if (foo (-1, 0) != 0)
abort ();
if (foo (0, 0) != 1)
abort ();
if (foo (1, 0) != 2)
abort ();
if (foo (-2, 1) != -2)
abort ();
if (foo (-1, 1) != 0)
abort ();
if (foo (0, 1) != 2)
abort ();
if (foo (1, 1) != 3)
abort ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment