aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-03-05 07:04:14 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-03-05 07:04:14 +0100
commit86efb5cd550babd6bf69ead21cc73f0012c55a97 (patch)
tree19a88c3e3d27c85213863432bf8347f0776184b1
parent85f5dbea3df7d0a97401259a273db2b8d02119e8 (diff)
downloadgcc-86efb5cd550babd6bf69ead21cc73f0012c55a97.zip
gcc-86efb5cd550babd6bf69ead21cc73f0012c55a97.tar.gz
gcc-86efb5cd550babd6bf69ead21cc73f0012c55a97.tar.bz2
re PR rtl-optimization/56494 (ICE in simplify_truncation, at simplify-rtx.c:619)
PR rtl-optimization/56494 * simplify-rtx.c (simplify_truncation): If C is narrower than A, optimize (truncate:A (subreg:B (truncate:C X) 0)) into (subreg:A (truncate:C X) 0) instead of (truncate:A X). * gcc.dg/pr56494.c: New test. From-SVN: r196451
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/simplify-rtx.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr56494.c13
4 files changed, 34 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3abc676..2678b16 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2013-03-05 Jakub Jelinek <jakub@redhat.com>
+ PR rtl-optimization/56494
+ * simplify-rtx.c (simplify_truncation): If C is narrower than A,
+ optimize (truncate:A (subreg:B (truncate:C X) 0)) into
+ (subreg:A (truncate:C X) 0) instead of (truncate:A X).
+
PR middle-end/56461
* sel-sched-ir.c (free_sched_pools): Release
succs_info_pool.stack[succs_info_pool.max_top] vectors too
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 3f04b8b..43700cf 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -757,8 +757,17 @@ simplify_truncation (enum machine_mode mode, rtx op,
&& SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (op)))
&& GET_CODE (SUBREG_REG (op)) == TRUNCATE
&& subreg_lowpart_p (op))
- return simplify_gen_unary (TRUNCATE, mode, XEXP (SUBREG_REG (op), 0),
- GET_MODE (XEXP (SUBREG_REG (op), 0)));
+ {
+ rtx inner = XEXP (SUBREG_REG (op), 0);
+ if (GET_MODE_PRECISION (mode)
+ <= GET_MODE_PRECISION (GET_MODE (SUBREG_REG (op))))
+ return simplify_gen_unary (TRUNCATE, mode, inner, GET_MODE (inner));
+ else
+ /* If subreg above is paradoxical and C is narrower
+ than A, return (subreg:A (truncate:C X) 0). */
+ return simplify_gen_subreg (mode, SUBREG_REG (op),
+ GET_MODE (SUBREG_REG (op)), 0);
+ }
/* (truncate:A (truncate:B X)) is (truncate:A X). */
if (GET_CODE (op) == TRUNCATE)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 19c64d6..4529bcf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/56494
+ * gcc.dg/pr56494.c: New test.
+
2013-01-04 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/pr56424.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr56494.c b/gcc/testsuite/gcc.dg/pr56494.c
new file mode 100644
index 0000000..e73d674
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr56494.c
@@ -0,0 +1,13 @@
+/* PR rtl-optimization/56494 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftracer -w" } */
+
+char a;
+short b;
+void bar (int);
+
+void
+foo (void)
+{
+ bar ((!!b ? : (a *= a / 0)) >= (a = b));
+}