public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: Richard Biener <rguenther@suse.de>,
	"Joseph S. Myers" <joseph@codesourcery.com>,
	Eric Botcazou <botcazou@adacore.com>,
	gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] tree: Fix up save_expr [PR52339]
Date: Fri, 5 May 2023 15:40:53 +0200	[thread overview]
Message-ID: <ZFUHZTeSnS6l5uIH@tucnak> (raw)
In-Reply-To: <4070a6dd-0e14-1cdd-dc59-62578fea965e@redhat.com>

On Fri, May 05, 2023 at 07:38:45AM -0400, Jason Merrill wrote:
> On 5/5/23 06:45, Jakub Jelinek wrote:
> > +  if (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t))
> > +    {
> > +      /* Return true for const qualified vars, but for members or array
> > +	 elements without side-effects return true only if the base
> > +	 object is a decl.  If the base is e.g. a pointer dereference,
> > +	 what the pointer points to could be deallocated or the pointer
> > +	 could be changed.  See PR52339.  */
> > +      tree base = get_base_address (t);
> > +      if (DECL_P (base))
> > +	return true;
> 
> So I think the above is correct.

Ok, will test it with testsuite adjustments for the Ada testcases.
See below.

> > +      /* As an exception, allow pointer dereferences as long as the pointer
> > +	 is invariant.  */
> > +      if (TREE_CODE (base) == INDIRECT_REF
> > +	  && tree_invariant_p_1 (get_base_address (TREE_OPERAND (base, 0))))
> > +	return true;
> 
> And this is unsafe.

Ok, idea withdrawn.

Had further look at the vect6.adb case, but I think it is for the Ada people
to analyze.

The *.original dump differences there are as I said instead of using
r.P_BOUNDS->LB0
r.P_BOUNDS->UB0
x.P_BOUNDS->LB0
x.P_BOUNDS->UB0
wrap those into SAVE_EXPR in various places (that is the expected part,
that is what the patch was about), but also:
-        SAVE_EXPR <x.P_BOUNDS->LB0 < r.P_BOUNDS->LB0 || x.P_BOUNDS->UB0 > r.P_BOUNDS->UB0>;
         <<< Unknown tree: loop_stmt
           I.0 != (unsigned long) vect6__add__L_1__T3b___U
           I.0 = I.0 + 1;
           i = (vect6_pkg__index_type) I.0;
-          if ((SAVE_EXPR <x.P_BOUNDS->LB0 < r.P_BOUNDS->LB0 || x.P_BOUNDS->UB0 > r.P_BOUNDS->UB0>) && .BUILTIN_EXPECT (r.P_BOUNDS->LB0 > i || r.P_BOUNDS->UB0 < i, 0, 15))
+          if (SAVE_EXPR <r.P_BOUNDS->LB0> > i || SAVE_EXPR <r.P_BOUNDS->UB0> < i)
             {
               .gnat_rcheck_CE_Index_Check ("vect6.adb", 9);
             }
So, if the {x,r}.P_BOUNDS->{U,B}B0 expressions aren't wrapped into
SAVE_EXPRs, something in the FE decides to evaluate
x.P_BOUNDS->LB0 < r.P_BOUNDS->LB0 || x.P_BOUNDS->UB0 > r.P_BOUNDS->UB0
expression into a temporary before the loop and && the bounds condition
inside of the loop with it, while with the patch that doesn't happen.
And, that turns out in loop unswitching being successful without my patch
and not with my patch, where we can vectorize the unswitched loop without
the .gnat_rcheck_CE_Index_Check call.

Perhaps ada/gcc-interface/utils2.cc (gnat_invariant_expr) could be taught
to handle SAVE_EXPR by looking at its operand?
--- gcc/ada/gcc-interface/utils2.cc.jj	2023-01-16 23:19:05.539727388 +0100
+++ gcc/ada/gcc-interface/utils2.cc	2023-05-05 15:37:30.193990948 +0200
@@ -3332,6 +3332,7 @@ gnat_invariant_expr (tree expr)
 	case IMAGPART_EXPR:
 	case VIEW_CONVERT_EXPR:
 	CASE_CONVERT:
+	case SAVE_EXPR:
 	  break;
 
 	case INDIRECT_REF:
fixes the vect{1,2,3,4,5,6}.adb regressions but not the
loop_optimization21.adb one.  But I'm afraid I really have no idea what
that code is doing.

2023-05-05  Jakub Jelinek  <jakub@redhat.com>

	PR c++/52339
	* tree.cc (tree_invariant_p_1): For TREE_READONLY (t) without
	side-effects, only return true if DECL_P (get_base_address (t)).

	* g++.dg/opt/pr52339.C: New test.
	* gcc.c-torture/execute/pr52339-1.c: New test.
	* gcc.c-torture/execute/pr52339-2.c: New test.
	* gnat.dg/loop_optimization21.adb: Adjust expected match count.
	* gnat.dg/vect1.adb: Likewise.
	* gnat.dg/vect2.adb: Likewise.
	* gnat.dg/vect3.adb: Likewise.
	* gnat.dg/vect4.adb: Likewise.
	* gnat.dg/vect5.adb: Likewise.
	* gnat.dg/vect6.adb: Likewise.

--- gcc/tree.cc.jj	2023-05-01 09:59:46.686293833 +0200
+++ gcc/tree.cc	2023-05-05 10:19:19.061827355 +0200
@@ -3876,10 +3876,21 @@ tree_invariant_p_1 (tree t)
 {
   tree op;
 
-  if (TREE_CONSTANT (t)
-      || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t)))
+  if (TREE_CONSTANT (t))
     return true;
 
+  if (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t))
+    {
+      /* Return true for const qualified vars, but for members or array
+	 elements without side-effects return true only if the base
+	 object is a decl.  If the base is e.g. a pointer dereference,
+	 what the pointer points to could be deallocated or the pointer
+	 could be changed.  See PR52339.  */
+      tree base = get_base_address (t);
+      if (DECL_P (base))
+	return true;
+    }
+
   switch (TREE_CODE (t))
     {
     case SAVE_EXPR:
--- gcc/testsuite/g++.dg/opt/pr52339.C.jj	2023-05-04 15:23:20.459935705 +0200
+++ gcc/testsuite/g++.dg/opt/pr52339.C	2023-05-04 15:22:35.640578681 +0200
@@ -0,0 +1,19 @@
+// PR c++/52339
+// { dg-do run { target c++11 } }
+
+
+struct B;
+struct A { B *b; };
+struct B {
+  A *a;
+  B () : a(new A{this}) {}
+  ~B () { delete a; }
+};
+ 
+int
+main ()
+{
+  B *b = new B;
+  const A *a = b->a;
+  delete a->b;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr52339-1.c.jj	2023-05-04 15:22:59.177241023 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr52339-1.c	2023-05-04 15:20:19.820527142 +0200
@@ -0,0 +1,29 @@
+/* PR c++/52339 */
+
+struct S { int a; };
+
+void
+bar (int *p, struct S *q)
+{
+  __builtin_free (q);
+}
+
+int
+foo (const struct S *p, struct S *q)
+{
+  int b[p->a];
+  bar (b, q);
+  return sizeof (b);
+}
+
+int
+main ()
+{
+  struct S *p = __builtin_malloc (sizeof (struct S));
+  if (!p)
+    return 0;
+  p->a = 42;
+  if (foo (p, p) != 42 * sizeof (int))
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr52339-2.c.jj	2022-11-21 10:04:00.210677046 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr52339-2.c	2023-05-04 19:34:08.581686806 +0200
@@ -0,0 +1,20 @@
+/* PR c++/52339 */
+
+struct S { int a; };
+
+int
+foo (const struct S *p)
+{
+  int b[p->a];
+  ++p;
+  return sizeof (b);
+}
+
+int
+main ()
+{
+  struct S s[] = { { 42 }, { 43 } };
+  if (foo (s) != 42 * sizeof (int))
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/gnat.dg/loop_optimization21.adb.jj	2020-01-14 20:02:48.316586870 +0100
+++ gcc/testsuite/gnat.dg/loop_optimization21.adb	2023-05-05 15:26:47.908115394 +0200
@@ -17,4 +17,4 @@ package body Loop_Optimization21 is
 
 end Loop_Optimization21;
 
--- { dg-final { scan-tree-dump-times "Index_Check" 1 "optimized" } }
+-- { dg-final { scan-tree-dump-times "Index_Check" 2 "optimized" } }
--- gcc/testsuite/gnat.dg/vect1.adb.jj	2020-01-14 20:02:48.345586436 +0100
+++ gcc/testsuite/gnat.dg/vect1.adb	2023-05-05 15:27:15.012730339 +0200
@@ -124,4 +124,4 @@ package body Vect1 is
 
 end Vect1;
 
--- { dg-final { scan-tree-dump-times "vectorized 1 loops" 15 "vect"  } }
+-- { dg-final { scan-tree-dump-times "vectorized 1 loops" 13 "vect"  } }
--- gcc/testsuite/gnat.dg/vect2.adb.jj	2020-01-14 20:02:48.345586436 +0100
+++ gcc/testsuite/gnat.dg/vect2.adb	2023-05-05 15:27:24.393597068 +0200
@@ -124,4 +124,4 @@ package body Vect2 is
 
 end Vect2;
 
--- { dg-final { scan-tree-dump-times "vectorized 1 loops" 15 "vect"  } }
+-- { dg-final { scan-tree-dump-times "vectorized 1 loops" 13 "vect"  } }
--- gcc/testsuite/gnat.dg/vect3.adb.jj	2020-01-14 20:02:48.345586436 +0100
+++ gcc/testsuite/gnat.dg/vect3.adb	2023-05-05 15:27:29.166529269 +0200
@@ -124,4 +124,4 @@ package body Vect3 is
 
 end Vect3;
 
--- { dg-final { scan-tree-dump-times "vectorized 1 loops" 15 "vect"  } }
+-- { dg-final { scan-tree-dump-times "vectorized 1 loops" 13 "vect"  } }
--- gcc/testsuite/gnat.dg/vect4.adb.jj	2020-01-14 20:02:48.345586436 +0100
+++ gcc/testsuite/gnat.dg/vect4.adb	2023-05-05 15:27:39.016389337 +0200
@@ -124,4 +124,4 @@ package body Vect4 is
 
 end Vect4;
 
--- { dg-final { scan-tree-dump-times "vectorized 1 loops" 15 "vect"  } }
+-- { dg-final { scan-tree-dump-times "vectorized 1 loops" 14 "vect"  } }
--- gcc/testsuite/gnat.dg/vect5.adb.jj	2020-01-14 20:02:48.346586421 +0100
+++ gcc/testsuite/gnat.dg/vect5.adb	2023-05-05 15:27:41.941347785 +0200
@@ -124,4 +124,4 @@ package body Vect5 is
 
 end Vect5;
 
--- { dg-final { scan-tree-dump-times "vectorized 1 loops" 15 "vect"  } }
+-- { dg-final { scan-tree-dump-times "vectorized 1 loops" 14 "vect"  } }
--- gcc/testsuite/gnat.dg/vect6.adb.jj	2020-01-14 20:02:48.346586421 +0100
+++ gcc/testsuite/gnat.dg/vect6.adb	2023-05-05 15:27:45.053303574 +0200
@@ -124,4 +124,4 @@ package body Vect6 is
 
 end Vect6;
 
--- { dg-final { scan-tree-dump-times "vectorized 1 loops" 15 "vect"  } }
+-- { dg-final { scan-tree-dump-times "vectorized 1 loops" 14 "vect"  } }


	Jakub


  reply	other threads:[~2023-05-05 13:41 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-05  9:04 Jakub Jelinek
2023-05-05  9:55 ` Jakub Jelinek
2023-05-05 10:45   ` Jakub Jelinek
2023-05-05 11:38     ` Jason Merrill
2023-05-05 13:40       ` Jakub Jelinek [this message]
2023-05-05 17:32         ` Jason Merrill
2023-05-05 17:52           ` Jakub Jelinek
2023-05-08  6:23             ` Richard Biener
2023-05-08 15:18               ` Jakub Jelinek
2023-05-09  9:25             ` Eric Botcazou
2023-05-13 10:58             ` Eric Botcazou
2023-05-29  3:14               ` Jason Merrill
2023-05-30  8:03                 ` Eric Botcazou
2023-05-30  8:23                   ` Jakub Jelinek
2023-05-30 20:36                     ` Jason Merrill
2023-05-30 20:51                       ` Jakub Jelinek
2023-05-30 21:08                         ` Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZFUHZTeSnS6l5uIH@tucnak \
    --to=jakub@redhat.com \
    --cc=botcazou@adacore.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=joseph@codesourcery.com \
    --cc=rguenther@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).