diff options
author | Jakub Jelinek <jakub@redhat.com> | 2002-04-19 23:09:16 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2002-04-19 23:09:16 +0200 |
commit | 0f2a345797590236bd204906e511ff28beda52fe (patch) | |
tree | 423689570f0515c9ab3975c78ddffc115a639b7c /gcc | |
parent | ce5e43d03eab3681671efc777b479a5855dc5906 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 112 |
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), |