aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-04-19 23:09:16 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2002-04-19 23:09:16 +0200
commit0f2a345797590236bd204906e511ff28beda52fe (patch)
tree423689570f0515c9ab3975c78ddffc115a639b7c /gcc
parentce5e43d03eab3681671efc777b479a5855dc5906 (diff)
downloadgcc-0f2a345797590236bd204906e511ff28beda52fe.zip
gcc-0f2a345797590236bd204906e511ff28beda52fe.tar.gz
gcc-0f2a345797590236bd204906e511ff28beda52fe.tar.bz2
re PR rtl-optimization/3756 (gcc wishlist: arithmetic right shift for ternary operator)
PR optimization/3756 * config/i386/i386.c (ix86_expand_int_movcc): Optimize x = ((int) y < 0) ? cst1 : cst2. From-SVN: r52539
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c112
2 files changed, 105 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fc37d48..b9dee8f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2002-04-19 Jakub Jelinek <jakub@redhat.com>
+ PR optimization/3756
+ * config/i386/i386.c (ix86_expand_int_movcc): Optimize
+ x = ((int) y < 0) ? cst1 : cst2.
+
+2002-04-19 Jakub Jelinek <jakub@redhat.com>
+
PR c/6358
* function.c: Reapply patch for c/6358.
(expand_function_end): Copy decl_rtl's mode, not
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 275a465..41ec025 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -8131,6 +8131,61 @@ ix86_expand_int_movcc (operands)
code = reverse_condition (code);
}
}
+
+ compare_code = NIL;
+ if (GET_MODE_CLASS (GET_MODE (ix86_compare_op0)) == MODE_INT
+ && GET_CODE (ix86_compare_op1) == CONST_INT)
+ {
+ if (ix86_compare_op1 == const0_rtx
+ && (code == LT || code == GE))
+ compare_code = code;
+ else if (ix86_compare_op1 == constm1_rtx)
+ {
+ if (code == LE)
+ compare_code = LT;
+ else if (code == GT)
+ compare_code = GE;
+ }
+ }
+
+ /* Optimize dest = (op0 < 0) ? -1 : cf. */
+ if (compare_code != NIL
+ && GET_MODE (ix86_compare_op0) == GET_MODE (out)
+ && (cf == -1 || ct == -1))
+ {
+ /* If lea code below could be used, only optimize
+ if it results in a 2 insn sequence. */
+
+ if (! (diff == 1 || diff == 2 || diff == 4 || diff == 8
+ || diff == 3 || diff == 5 || diff == 9)
+ || (compare_code == LT && ct == -1)
+ || (compare_code == GE && cf == -1))
+ {
+ /*
+ * notl op1 (if necessary)
+ * sarl $31, op1
+ * orl cf, op1
+ */
+ if (ct != -1)
+ {
+ cf = ct;
+ ct = -1;
+ code = reverse_condition (code);
+ }
+
+ out = emit_store_flag (out, code, ix86_compare_op0,
+ ix86_compare_op1, VOIDmode, 0, -1);
+
+ out = expand_simple_binop (mode, IOR,
+ out, GEN_INT (cf),
+ out, 1, OPTAB_DIRECT);
+ if (out != operands[0])
+ emit_move_insn (operands[0], out);
+
+ return 1; /* DONE */
+ }
+ }
+
if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
|| diff == 3 || diff == 5 || diff == 9)
&& (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf))))
@@ -8223,27 +8278,58 @@ ix86_expand_int_movcc (operands)
ct = cf;
cf = 0;
if (FLOAT_MODE_P (GET_MODE (ix86_compare_op0)))
+ /* We may be reversing unordered compare to normal compare,
+ that is not valid in general (we may convert non-trapping
+ condition to trapping one), however on i386 we currently
+ emit all comparisons unordered. */
+ code = reverse_condition_maybe_unordered (code);
+ else
+ {
+ code = reverse_condition (code);
+ if (compare_code != NIL)
+ compare_code = reverse_condition (compare_code);
+ }
+ }
+
+ if (compare_code != NIL)
+ {
+ /* notl op1 (if needed)
+ sarl $31, op1
+ andl (cf-ct), op1
+ addl ct, op1
+
+ For x < 0 (resp. x <= -1) there will be no notl,
+ so if possible swap the constants to get rid of the
+ complement.
+ True/false will be -1/0 while code below (store flag
+ followed by decrement) is 0/-1, so the constants need
+ to be exchanged once more. */
+
+ if (compare_code == GE || !cf)
{
- /* We may be reversing unordered compare to normal compare,
- that is not valid in general (we may convert non-trapping
- condition to trapping one), however on i386 we currently
- emit all comparisons unordered. */
- compare_code = reverse_condition_maybe_unordered (compare_code);
- code = reverse_condition_maybe_unordered (code);
+ code = reverse_condition (code);
+ compare_code = LT;
}
else
{
- compare_code = reverse_condition (compare_code);
- code = reverse_condition (code);
+ HOST_WIDE_INT tmp = cf;
+ cf = ct;
+ ct = tmp;
}
+
+ out = emit_store_flag (out, code, ix86_compare_op0,
+ ix86_compare_op1, VOIDmode, 0, -1);
}
+ else
+ {
+ out = emit_store_flag (out, code, ix86_compare_op0,
+ ix86_compare_op1, VOIDmode, 0, 1);
- out = emit_store_flag (out, code, ix86_compare_op0,
- ix86_compare_op1, VOIDmode, 0, 1);
+ out = expand_simple_binop (mode, PLUS,
+ out, constm1_rtx,
+ out, 1, OPTAB_DIRECT);
+ }
- out = expand_simple_binop (mode, PLUS,
- out, constm1_rtx,
- out, 1, OPTAB_DIRECT);
out = expand_simple_binop (mode, AND,
out,
gen_int_mode (cf - ct, mode),