aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/i386/i386-expand.cc46
-rw-r--r--gcc/testsuite/gcc.target/i386/cmov10.c21
2 files changed, 41 insertions, 26 deletions
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 3eddbc9..4fd7c3c 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -3284,8 +3284,8 @@ ix86_expand_int_movcc (rtx operands[])
|| negate_cc_compare_p
|| ix86_expand_carry_flag_compare (code, op0, op1, &compare_op))
{
- /* Detect overlap between destination and compare sources. */
- rtx tmp = out;
+ /* Place comparison result in its own pseudo. */
+ rtx tmp = gen_reg_rtx (mode);
if (negate_cc_compare_p)
{
@@ -3295,7 +3295,6 @@ ix86_expand_int_movcc (rtx operands[])
emit_insn (gen_x86_negsi_ccc (gen_reg_rtx (SImode),
gen_lowpart (SImode, op0)));
- tmp = gen_reg_rtx (mode);
if (mode == DImode)
emit_insn (gen_x86_movdicc_0_m1_neg (tmp));
else
@@ -3337,9 +3336,6 @@ ix86_expand_int_movcc (rtx operands[])
}
diff = ct - cf;
- if (reg_overlap_mentioned_p (out, compare_op))
- tmp = gen_reg_rtx (mode);
-
if (mode == DImode)
emit_insn (gen_x86_movdicc_0_m1 (tmp, flags, compare_op));
else
@@ -3358,6 +3354,11 @@ ix86_expand_int_movcc (rtx operands[])
tmp = emit_store_flag (tmp, code, op0, op1, VOIDmode, 0, -1);
}
+ /* Add a REG_EQUAL note to allow condition to be shared. */
+ rtx note = gen_rtx_fmt_ee (code, mode, op0, op1);
+ set_unique_reg_note (get_last_insn (), REG_EQUAL,
+ gen_rtx_NEG (mode, note));
+
if (diff == 1)
{
/*
@@ -3368,9 +3369,8 @@ ix86_expand_int_movcc (rtx operands[])
* Size 5 - 8.
*/
if (ct)
- tmp = expand_simple_binop (mode, PLUS,
- tmp, GEN_INT (ct),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
+ tmp = expand_simple_binop (mode, PLUS, tmp, GEN_INT (ct),
+ NULL_RTX, 1, OPTAB_DIRECT);
}
else if (cf == -1)
{
@@ -3381,9 +3381,8 @@ ix86_expand_int_movcc (rtx operands[])
*
* Size 8.
*/
- tmp = expand_simple_binop (mode, IOR,
- tmp, GEN_INT (ct),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
+ tmp = expand_simple_binop (mode, IOR, tmp, GEN_INT (ct),
+ NULL_RTX, 1, OPTAB_DIRECT);
}
else if (diff == -1 && ct)
{
@@ -3395,11 +3394,10 @@ ix86_expand_int_movcc (rtx operands[])
*
* Size 8 - 11.
*/
- tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
+ tmp = expand_simple_unop (mode, NOT, tmp, NULL_RTX, 1);
if (cf)
- tmp = expand_simple_binop (mode, PLUS,
- copy_rtx (tmp), GEN_INT (cf),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
+ tmp = expand_simple_binop (mode, PLUS, tmp, GEN_INT (cf),
+ NULL_RTX, 1, OPTAB_DIRECT);
}
else
{
@@ -3417,22 +3415,18 @@ ix86_expand_int_movcc (rtx operands[])
{
cf = ct;
ct = 0;
- tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
+ tmp = expand_simple_unop (mode, NOT, tmp, NULL_RTX, 1);
}
- tmp = expand_simple_binop (mode, AND,
- copy_rtx (tmp),
+ tmp = expand_simple_binop (mode, AND, tmp,
gen_int_mode (cf - ct, mode),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
+ NULL_RTX, 1, OPTAB_DIRECT);
if (ct)
- tmp = expand_simple_binop (mode, PLUS,
- copy_rtx (tmp), GEN_INT (ct),
- copy_rtx (tmp), 1, OPTAB_DIRECT);
+ tmp = expand_simple_binop (mode, PLUS, tmp, GEN_INT (ct),
+ NULL_RTX, 1, OPTAB_DIRECT);
}
- if (!rtx_equal_p (tmp, out))
- emit_move_insn (copy_rtx (out), copy_rtx (tmp));
-
+ emit_move_insn (out, tmp);
return true;
}
diff --git a/gcc/testsuite/gcc.target/i386/cmov10.c b/gcc/testsuite/gcc.target/i386/cmov10.c
new file mode 100644
index 0000000..142b4d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cmov10.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+int a, b, c, d;
+
+int foo(int x)
+{
+ if (x == 0) {
+ a = 3;
+ b = 1;
+ c = 4;
+ d = 1;
+ } else {
+ a = 5;
+ b = 9;
+ c = 2;
+ d = 7;
+ }
+ return x;
+}
+/* { dg-final { scan-assembler-times "cmpl" 1 } } */
+/* { dg-final { scan-assembler-times "sbbl" 1 } } */