aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Nemet <anemet@caviumnetworks.com>2009-07-18 21:46:01 +0000
committerAdam Nemet <nemet@gcc.gnu.org>2009-07-18 21:46:01 +0000
commitb641d7fca3c917bd40da5de8e9f16876bdd4a5df (patch)
treea58b9ea723f1b744b052635b30e5dc9e99b20305
parentb95d6ac9ca9decd3568e49662744987d78116681 (diff)
downloadgcc-b641d7fca3c917bd40da5de8e9f16876bdd4a5df.zip
gcc-b641d7fca3c917bd40da5de8e9f16876bdd4a5df.tar.gz
gcc-b641d7fca3c917bd40da5de8e9f16876bdd4a5df.tar.bz2
combine.c (simplify_shift_const_1): Split code to determine shift_mode into ...
* combine.c (simplify_shift_const_1): Split code to determine shift_mode into ... (try_widen_shift_mode): ... here. Allow widening for ASHIFTRT if the new bits shifted in are identical to the old sign bit. testsuite/ * gcc.target/mips/octeon-exts-7.c: New test. * gcc.target/mips/octeon-exts-2.c: Revert previous change. * gcc.target/mips/octeon-exts-5.c: Likewise. From-SVN: r149778
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/combine.c53
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/mips/octeon-exts-2.c5
-rw-r--r--gcc/testsuite/gcc.target/mips/octeon-exts-5.c5
-rw-r--r--gcc/testsuite/gcc.target/mips/octeon-exts-7.c17
6 files changed, 72 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1c09316..9643005 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2009-07-18 Adam Nemet <anemet@caviumnetworks.com>
+
+ * combine.c (simplify_shift_const_1): Split code to determine
+ shift_mode into ...
+ (try_widen_shift_mode): ... here. Allow widening for ASHIFTRT if the
+ new bits shifted in are identical to the old sign bit.
+
2009-07-18 Richard Guenther <rguenther@suse.de>
PR c/40787
diff --git a/gcc/combine.c b/gcc/combine.c
index a781484..a0157df 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -8982,6 +8982,42 @@ merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1,
return 1;
}
+/* A helper to simplify_shift_const_1 to determine the mode we can perform
+ the shift in. The original shift operation CODE is performed on OP in
+ ORIG_MODE. Return the wider mode MODE if we can perform the operation
+ in that mode. Return ORIG_MODE otherwise. */
+
+static enum machine_mode
+try_widen_shift_mode (enum rtx_code code, rtx op,
+ enum machine_mode orig_mode, enum machine_mode mode)
+{
+ if (orig_mode == mode)
+ return mode;
+ gcc_assert (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (orig_mode));
+
+ /* In general we can't perform in wider mode for right shift and rotate. */
+ switch (code)
+ {
+ case ASHIFTRT:
+ /* We can still widen if the bits brought in from the left are identical
+ to the sign bit of ORIG_MODE. */
+ if (num_sign_bit_copies (op, mode)
+ > (unsigned) (GET_MODE_BITSIZE (mode)
+ - GET_MODE_BITSIZE (orig_mode)))
+ return mode;
+ /* fall through */
+ case LSHIFTRT:
+ case ROTATE:
+ return orig_mode;
+
+ case ROTATERT:
+ gcc_unreachable ();
+
+ default:
+ return mode;
+ }
+}
+
/* Simplify a shift of VAROP by COUNT bits. CODE says what kind of shift.
The result of the shift is RESULT_MODE. Return NULL_RTX if we cannot
simplify it. Otherwise, return a simplified value.
@@ -9041,13 +9077,7 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
count = bitsize - count;
}
- /* We need to determine what mode we will do the shift in. If the
- shift is a right shift or a ROTATE, we must always do it in the mode
- it was originally done in. Otherwise, we can do it in MODE, the
- widest mode encountered. */
- shift_mode
- = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
- ? result_mode : mode);
+ shift_mode = try_widen_shift_mode (code, varop, result_mode, mode);
/* Handle cases where the count is greater than the size of the mode
minus 1. For ASHIFT, use the size minus one as the count (this can
@@ -9645,14 +9675,7 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
break;
}
- /* We need to determine what mode to do the shift in. If the shift is
- a right shift or ROTATE, we must always do it in the mode it was
- originally done in. Otherwise, we can do it in MODE, the widest mode
- encountered. The code we care about is that of the shift that will
- actually be done, not the shift that was originally requested. */
- shift_mode
- = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
- ? result_mode : mode);
+ shift_mode = try_widen_shift_mode (code, varop, result_mode, mode);
/* We have now finished analyzing the shift. The result should be
a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places. If
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ac30e5b..3200817 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2009-07-18 Adam Nemet <anemet@caviumnetworks.com>
+
+ * gcc.target/mips/octeon-exts-7.c: New test.
+ * gcc.target/mips/octeon-exts-2.c: Revert previous change.
+ * gcc.target/mips/octeon-exts-5.c: Likewise.
+
2009-07-18 Richard Guenther <rguenther@suse.de>
PR testsuite/40798
diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-2.c b/gcc/testsuite/gcc.target/mips/octeon-exts-2.c
index 42f2a3f..fc5df63 100644
--- a/gcc/testsuite/gcc.target/mips/octeon-exts-2.c
+++ b/gcc/testsuite/gcc.target/mips/octeon-exts-2.c
@@ -1,7 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O -march=octeon -meb -dp" } */
-/* Don't match exts in sign-extension. */
-/* { dg-final { scan-assembler-times "\texts\t\[^\\n\]*extv" 4 } } */
+/* { dg-options "-O -march=octeon -meb" } */
+/* { dg-final { scan-assembler-times "\texts\t" 4 } } */
struct bar
{
diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-5.c b/gcc/testsuite/gcc.target/mips/octeon-exts-5.c
index 6ec7ac7..e7a4738 100644
--- a/gcc/testsuite/gcc.target/mips/octeon-exts-5.c
+++ b/gcc/testsuite/gcc.target/mips/octeon-exts-5.c
@@ -1,8 +1,7 @@
/* -mel version of octeon-exts-2.c. */
/* { dg-do compile } */
-/* { dg-options "-O -march=octeon -mel -dp" } */
-/* Don't match exts in sign-extension. */
-/* { dg-final { scan-assembler-times "\texts\t\[^\\n\]*extv" 4 } } */
+/* { dg-options "-O -march=octeon -mel" } */
+/* { dg-final { scan-assembler-times "\texts\t" 4 } } */
struct bar
{
diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-7.c b/gcc/testsuite/gcc.target/mips/octeon-exts-7.c
new file mode 100644
index 0000000..04805d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/octeon-exts-7.c
@@ -0,0 +1,17 @@
+/* Remove the redundant sign-extension after the sign-extraction. */
+/* { dg-do compile } */
+/* { dg-options "-O -march=octeon -mgp64" } */
+/* { dg-final { scan-assembler-times "\texts\t" 1 } } */
+/* { dg-final { scan-assembler-not "sll|sra" } } */
+
+struct bar
+{
+ long long a:18;
+ long long b:14;
+};
+
+NOMIPS16 int
+f1 (struct bar *s)
+{
+ return s->b;
+}