diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2009-10-28 10:27:15 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gcc.gnu.org> | 2009-10-28 10:27:15 +0000 |
commit | 5d49d0ea6c8f48d3bf36fc3d4e7c3984a7bf8157 (patch) | |
tree | c38260869bb0cdd6998d12a09d64ae13ccd20f1d /gcc/combine.c | |
parent | 582021baa76be44ef884eebd0f7ab99599f4b890 (diff) | |
download | gcc-5d49d0ea6c8f48d3bf36fc3d4e7c3984a7bf8157.zip gcc-5d49d0ea6c8f48d3bf36fc3d4e7c3984a7bf8157.tar.gz gcc-5d49d0ea6c8f48d3bf36fc3d4e7c3984a7bf8157.tar.bz2 |
re PR target/39715 ([cond-optab] extra sign extensions on Thumb)
2009-10-28 Paolo Bonzini <bonzini@gnu.org>
PR rtl-optimization/39715
* combine.c (simplify_comparison): Use extensions to
widen comparisons. Try an ANDing first.
testsuite:
2009-10-28 Paolo Bonzini <bonzini@gnu.org>
PR rtl-optimization/39715
* gcc.target/arm/thumb-bitfld1.c: New.
From-SVN: r153651
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 2311755..80c538e 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -11467,6 +11467,22 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) { int zero_extended; + /* If this is a test for negative, we can make an explicit + test of the sign bit. Test this first so we can use + a paradoxical subreg to extend OP0. */ + + if (op1 == const0_rtx && (code == LT || code == GE) + && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) + { + op0 = simplify_gen_binary (AND, tmode, + gen_lowpart (tmode, op0), + GEN_INT ((HOST_WIDE_INT) 1 + << (GET_MODE_BITSIZE (mode) + - 1))); + code = (code == LT) ? NE : EQ; + break; + } + /* If the only nonzero bits in OP0 and OP1 are those in the narrower mode and this is an equality or unsigned comparison, we can use the wider mode. Similarly for sign-extended @@ -11497,27 +11513,20 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) XEXP (op0, 0)), gen_lowpart (tmode, XEXP (op0, 1))); - - op0 = gen_lowpart (tmode, op0); - if (zero_extended && CONST_INT_P (op1)) - op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode)); - op1 = gen_lowpart (tmode, op1); - break; - } - - /* If this is a test for negative, we can make an explicit - test of the sign bit. */ - - if (op1 == const0_rtx && (code == LT || code == GE) - && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) - { - op0 = simplify_gen_binary (AND, tmode, - gen_lowpart (tmode, op0), - GEN_INT ((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (mode) - - 1))); - code = (code == LT) ? NE : EQ; - break; + else + { + if (zero_extended) + { + op0 = simplify_gen_unary (ZERO_EXTEND, tmode, op0, mode); + op1 = simplify_gen_unary (ZERO_EXTEND, tmode, op1, mode); + } + else + { + op0 = simplify_gen_unary (SIGN_EXTEND, tmode, op0, mode); + op1 = simplify_gen_unary (SIGN_EXTEND, tmode, op1, mode); + } + break; + } } } |