aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2016-04-04 08:11:46 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2016-04-04 08:11:46 +0000
commitf13355da300a1f58d0bb7bc4094921dda4169de2 (patch)
tree7935347ce5b6c092f866678ad2ba3afec0644e24
parentdbc3f125582d235892b41db38f7aa3647ee3378b (diff)
downloadgcc-f13355da300a1f58d0bb7bc4094921dda4169de2.zip
gcc-f13355da300a1f58d0bb7bc4094921dda4169de2.tar.gz
gcc-f13355da300a1f58d0bb7bc4094921dda4169de2.tar.bz2
re PR middle-end/70307 (ICE: in gimplify_expr, at gimplify.c:10915 on valid code)
PR c/70307 * c-fold.c (c_fully_fold_internal): Handle VEC_COND_EXPR. * gcc.dg/torture/pr70307.c: New test. From-SVN: r234706
-rw-r--r--gcc/c/ChangeLog5
-rw-r--r--gcc/c/c-fold.c20
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70307.c62
4 files changed, 92 insertions, 0 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index b52b414..56e0b4d 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,8 @@
+2016-04-04 Marek Polacek <polacek@redhat.com>
+
+ PR c/70307
+ * c-fold.c (c_fully_fold_internal): Handle VEC_COND_EXPR.
+
2016-03-31 Marek Polacek <polacek@redhat.com>
PR c/70297
diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c
index f07917f..6c82f24 100644
--- a/gcc/c/c-fold.c
+++ b/gcc/c/c-fold.c
@@ -528,6 +528,26 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
*maybe_const_itself &= op2_const_self;
goto out;
+ case VEC_COND_EXPR:
+ orig_op0 = op0 = TREE_OPERAND (expr, 0);
+ orig_op1 = op1 = TREE_OPERAND (expr, 1);
+ orig_op2 = op2 = TREE_OPERAND (expr, 2);
+ op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
+ maybe_const_itself, for_int_const);
+ STRIP_TYPE_NOPS (op0);
+ op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
+ maybe_const_itself, for_int_const);
+ STRIP_TYPE_NOPS (op1);
+ op2 = c_fully_fold_internal (op2, in_init, maybe_const_operands,
+ maybe_const_itself, for_int_const);
+ STRIP_TYPE_NOPS (op2);
+
+ if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
+ ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
+ else
+ ret = fold (expr);
+ goto out;
+
case EXCESS_PRECISION_EXPR:
/* Each case where an operand with excess precision may be
encountered must remove the EXCESS_PRECISION_EXPR around
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ffee4f7..a8bd711 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-04-04 Marek Polacek <polacek@redhat.com>
+
+ PR c/70307
+ * gcc.dg/torture/pr70307.c: New test.
+
2016-04-03 Oleg Endo <olegendo@gcc.gnu.org>
PR target/70416
diff --git a/gcc/testsuite/gcc.dg/torture/pr70307.c b/gcc/testsuite/gcc.dg/torture/pr70307.c
new file mode 100644
index 0000000..d47c4b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70307.c
@@ -0,0 +1,62 @@
+/* PR c/70307 */
+/* { dg-do compile } */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+v4si foo (v4si);
+
+v4si
+fn1 (int i)
+{
+ return i <= (v4si){(0, 0)};
+}
+
+v4si
+fn2 (int i)
+{
+ v4si r;
+ r = i <= (v4si){(0, 0)};
+ return r;
+}
+
+v4si
+fn3 (int i)
+{
+ return foo (i <= (v4si){(0, 0)});
+}
+
+v4si
+fn4 (int i)
+{
+ struct S { v4si v; };
+ struct S s = { .v = i <= (v4si){(0, 0)} };
+ return s.v;
+}
+
+v4si
+fn5 (int i)
+{
+ return (v4si){(1, i++)} == (v4si){(0, 0)};
+}
+
+v4si
+fn6 (int i)
+{
+ v4si r;
+ r = (v4si){(1, i++)} == (v4si){(0, 0)};
+ return r;
+}
+
+v4si
+fn7 (int i)
+{
+ return foo ((v4si){(1, i++)} == (v4si){(0, 0)});
+}
+
+v4si
+fn8 (int i)
+{
+ struct S { v4si v; };
+ struct S s = { .v = (v4si){(1, i++)} == (v4si){(0, 0)} };
+ return s.v;
+}