aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-08-04 11:31:44 +0200
committerJakub Jelinek <jakub@redhat.com>2020-08-04 11:31:44 +0200
commitfabe0ede9db9fa95832b2329d3d6156711905e20 (patch)
treeb59578cbcce2710686dd48ab104a570cd247d2f8 /gcc
parentd79d9445d69a20a0e0361fb47584bbb8f5c6e84b (diff)
downloadgcc-fabe0ede9db9fa95832b2329d3d6156711905e20.zip
gcc-fabe0ede9db9fa95832b2329d3d6156711905e20.tar.gz
gcc-fabe0ede9db9fa95832b2329d3d6156711905e20.tar.bz2
gimple-fold: Fix ICE in maybe_canonicalize_mem_ref_addr on debug stmt [PR96354]
In debug stmts, we are less strict about what is and what is not accepted there, so this patch just punts on optimization of a debug stmt rather than ICEing. 2020-08-04 Jakub Jelinek <jakub@redhat.com> PR debug/96354 * gimple-fold.c (maybe_canonicalize_mem_ref_addr): Add IS_DEBUG argument. Return false instead of gcc_unreachable if it is true and get_addr_base_and_unit_offset returns NULL. (fold_stmt_1) <case GIMPLE_DEBUG>: Adjust caller. * g++.dg/opt/pr96354.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimple-fold.c10
-rw-r--r--gcc/testsuite/g++.dg/opt/pr96354.C24
2 files changed, 31 insertions, 3 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 81c77f7..4368817 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -4875,7 +4875,7 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
/* Canonicalize MEM_REFs invariant address operand after propagation. */
static bool
-maybe_canonicalize_mem_ref_addr (tree *t)
+maybe_canonicalize_mem_ref_addr (tree *t, bool is_debug = false)
{
bool res = false;
tree *orig_t = t;
@@ -4939,7 +4939,11 @@ maybe_canonicalize_mem_ref_addr (tree *t)
base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
&coffset);
if (!base)
- gcc_unreachable ();
+ {
+ if (is_debug)
+ return false;
+ gcc_unreachable ();
+ }
TREE_OPERAND (*t, 0) = build_fold_addr_expr (base);
TREE_OPERAND (*t, 1) = int_const_binop (PLUS_EXPR,
@@ -5119,7 +5123,7 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
if (*val
&& (REFERENCE_CLASS_P (*val)
|| TREE_CODE (*val) == ADDR_EXPR)
- && maybe_canonicalize_mem_ref_addr (val))
+ && maybe_canonicalize_mem_ref_addr (val, true))
changed = true;
}
break;
diff --git a/gcc/testsuite/g++.dg/opt/pr96354.C b/gcc/testsuite/g++.dg/opt/pr96354.C
new file mode 100644
index 0000000..601ce2a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr96354.C
@@ -0,0 +1,24 @@
+// PR debug/96354
+// { dg-do compile }
+// { dg-options "-O2 -g -fopenmp-simd" }
+
+template <int N> struct A { typedef double T[N]; };
+template <int N> struct B { typename A<N>::T b; double *baz () { return b; } };
+template <int N> struct C { B<N> d; C (); };
+template <int N> C<N>::C () { double c = *d.baz (); }
+template <int N> void operator- (C<N>, const C<N> &);
+template <int> struct D {};
+template <int N, int M> C<N> foo (D<N>, C<M>) { C<N> t; return t; }
+int e;
+struct E { D<3> d; void bar (); };
+
+void
+E::bar ()
+{
+#pragma omp simd
+ for (int i = 0; i < e; i++)
+ {
+ C<3> f, g;
+ g - foo (d, f);
+ }
+}