diff mbox series

gimple-fold: Fix ICE in maybe_canonicalize_mem_ref_addr on debug stmt [PR96354]

Message ID 20200804083919.GY2363@tucnak
State New
Headers show
Series gimple-fold: Fix ICE in maybe_canonicalize_mem_ref_addr on debug stmt [PR96354] | expand

Commit Message

Jakub Jelinek Aug. 4, 2020, 8:39 a.m. UTC
Hi!

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.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

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.


	Jakub

Comments

Richard Biener Aug. 4, 2020, 9:11 a.m. UTC | #1
On Tue, 4 Aug 2020, Jakub Jelinek wrote:

> Hi!
> 
> 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.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 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.
> 
> --- gcc/gimple-fold.c.jj	2020-07-28 15:39:09.908757602 +0200
> +++ gcc/gimple-fold.c	2020-08-03 13:23:57.579436442 +0200
> @@ -4875,7 +4875,7 @@ replace_stmt_with_simplification (gimple
>  /* 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,
>  	  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;
> --- gcc/testsuite/g++.dg/opt/pr96354.C.jj	2020-07-29 11:25:15.701164242 +0200
> +++ gcc/testsuite/g++.dg/opt/pr96354.C	2020-07-29 11:26:16.490291018 +0200
> @@ -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);
> +    }
> +}
> 
> 	Jakub
> 
>
diff mbox series

Patch

--- gcc/gimple-fold.c.jj	2020-07-28 15:39:09.908757602 +0200
+++ gcc/gimple-fold.c	2020-08-03 13:23:57.579436442 +0200
@@ -4875,7 +4875,7 @@  replace_stmt_with_simplification (gimple
 /* 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,
 	  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;
--- gcc/testsuite/g++.dg/opt/pr96354.C.jj	2020-07-29 11:25:15.701164242 +0200
+++ gcc/testsuite/g++.dg/opt/pr96354.C	2020-07-29 11:26:16.490291018 +0200
@@ -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);
+    }
+}