aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2009-10-28 10:27:15 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2009-10-28 10:27:15 +0000
commit5d49d0ea6c8f48d3bf36fc3d4e7c3984a7bf8157 (patch)
treec38260869bb0cdd6998d12a09d64ae13ccd20f1d
parent582021baa76be44ef884eebd0f7ab99599f4b890 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/combine.c51
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arm/thumb-bitfld1.c19
4 files changed, 60 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 17793bf..db1d1c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
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.
+
+2009-10-28 Paolo Bonzini <bonzini@gnu.org>
+
PR rtl-optimization/40741
* config/arm/arm.c (thumb1_rtx_costs): IOR or XOR with
a small constant is cheap.
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;
+ }
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aa64dab..1d59b71 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2009-10-28 Paolo Bonzini <bonzini@gnu.org>
+ PR rtl-optimization/39715
+ * gcc.target/arm/thumb-bitfld1.c: New.
+
+2009-10-28 Paolo Bonzini <bonzini@gnu.org>
+
PR rtl-optimization/40741
* gcc.target/arm/thumb-branch1.c: New.
diff --git a/gcc/testsuite/gcc.target/arm/thumb-bitfld1.c b/gcc/testsuite/gcc.target/arm/thumb-bitfld1.c
new file mode 100644
index 0000000..7741b4f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb-bitfld1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -mthumb -march=armv5t" } */
+
+struct foo
+{
+ unsigned b31 : 1;
+ unsigned b30 : 1;
+ unsigned b29 : 1;
+ unsigned b28 : 1;
+ unsigned rest : 28;
+};
+foo(a)
+ struct foo a;
+{
+ return a.b30;
+}
+
+/* { dg-final { scan-assembler-times "lsl" 1 } } */
+/* { dg-final { scan-assembler-times "lsr" 1 } } */