public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] ipa/102714 - IPA SRA eliding volatile
@ 2021-10-29  2:20 duan.db
  0 siblings, 0 replies; 2+ messages in thread
From: duan.db @ 2021-10-29  2:20 UTC (permalink / raw)
  To: gcc-patches; +Cc: rguenther

[-- Attachment #1: Type: text/plain, Size: 145 bytes --]

Hi.
This patch fix the pr102714 in the trunk.
Should we backport this patch to gcc-10?  If needed, an adapted patch is attached.

Thanks,
Bo Duan

[-- Attachment #2: 0001-Subject-PATCH-ipa-102714-IPA-SRA-eliding-volatile.patch --]
[-- Type: application/octet-stream, Size: 6102 bytes --]

From 19a5768bf2806f5339bec050eaf17b01ea56d1be Mon Sep 17 00:00:00 2001
From: Richard Biener <rguenther@suse.de>
Date: Fri, 29 Oct 2021 09:48:43 +0800
Subject: [PATCH] Subject: [PATCH] ipa/102714 - IPA SRA eliding volatile

The following fixes the volatileness check of IPA SRA which was
looking at the innermost reference when checking TREE_THIS_VOLATILE
but the reference to check is the outermost one.

2021-10-13  Richard Biener  <rguenther@suse.de>

        PR ipa/102714
        * ipa-sra.c (ptr_parm_has_nonarg_uses): Fix volatileness
        check.

        * gcc.dg/ipa/pr102714.c: New testcase.
---
 gcc/ipa-sra.c                       |  40 +++++-----
 gcc/testsuite/gcc.dg/ipa/pr102714.c | 117 ++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/pr102714.c

diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c
index 1cb30afc38c..8ad57493ea6 100644
--- a/gcc/ipa-sra.c
+++ b/gcc/ipa-sra.c
@@ -986,15 +986,17 @@ ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm,
       if (gimple_assign_single_p (stmt))
 	{
 	  tree rhs = gimple_assign_rhs1 (stmt);
-	  while (handled_component_p (rhs))
-	    rhs = TREE_OPERAND (rhs, 0);
-	  if (TREE_CODE (rhs) == MEM_REF
-	      && TREE_OPERAND (rhs, 0) == name
-	      && integer_zerop (TREE_OPERAND (rhs, 1))
-	      && types_compatible_p (TREE_TYPE (rhs),
-				     TREE_TYPE (TREE_TYPE (name)))
-	      && !TREE_THIS_VOLATILE (rhs))
-	    uses_ok++;
+	  if (!TREE_THIS_VOLATILE (rhs))
+	    {
+	      while (handled_component_p (rhs))
+		rhs = TREE_OPERAND (rhs, 0);
+	      if (TREE_CODE (rhs) == MEM_REF
+		  && TREE_OPERAND (rhs, 0) == name
+		  && integer_zerop (TREE_OPERAND (rhs, 1))
+		  && types_compatible_p (TREE_TYPE (rhs),
+					 TREE_TYPE (TREE_TYPE (name))))
+		uses_ok++;
+	    }
 	}
       else if (is_gimple_call (stmt))
 	{
@@ -1028,15 +1030,17 @@ ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm,
 		  continue;
 		}
 
-	      while (handled_component_p (arg))
-		arg = TREE_OPERAND (arg, 0);
-	      if (TREE_CODE (arg) == MEM_REF
-		  && TREE_OPERAND (arg, 0) == name
-		  && integer_zerop (TREE_OPERAND (arg, 1))
-		  && types_compatible_p (TREE_TYPE (arg),
-					 TREE_TYPE (TREE_TYPE (name)))
-		  && !TREE_THIS_VOLATILE (arg))
-		uses_ok++;
+	      if (!TREE_THIS_VOLATILE (arg))
+		{
+		  while (handled_component_p (arg))
+		    arg = TREE_OPERAND (arg, 0);
+		  if (TREE_CODE (arg) == MEM_REF
+		      && TREE_OPERAND (arg, 0) == name
+		      && integer_zerop (TREE_OPERAND (arg, 1))
+		      && types_compatible_p (TREE_TYPE (arg),
+					     TREE_TYPE (TREE_TYPE (name))))
+		    uses_ok++;
+		}
 	    }
 	}
 
diff --git a/gcc/testsuite/gcc.dg/ipa/pr102714.c b/gcc/testsuite/gcc.dg/ipa/pr102714.c
new file mode 100644
index 00000000000..65dd86f5c15
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr102714.c
@@ -0,0 +1,117 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-strict-aliasing -fdump-ipa-sra-details -fdump-tree-optimized" } */
+
+typedef _Bool bool;
+
+enum {
+ false = 0,
+ true = 1
+};
+
+struct xarray {
+ unsigned int xa_lock;
+ unsigned int xa_flags;
+ void * xa_head;
+
+};
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+struct callback_head {
+ struct callback_head *next;
+ void (*func)(struct callback_head *head);
+} __attribute__((aligned(sizeof(void *))));
+
+struct xa_node {
+ unsigned char shift;
+ unsigned char offset;
+ unsigned char count;
+ unsigned char nr_values;
+ struct xa_node *parent;
+ struct xarray *array;
+ union {
+  struct list_head private_list;
+  struct callback_head callback_head;
+ };
+ void *slots[(1UL << (0 ? 4 : 6))];
+ union {
+  unsigned long tags[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
+  unsigned long marks[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
+ };
+};
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long shift_maxindex(unsigned int shift)
+{
+ return ((1UL << (0 ? 4 : 6)) << shift) - 1;
+}
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long node_maxindex(const struct xa_node *node)
+{
+ return shift_maxindex(node->shift);
+}
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) struct xa_node *entry_to_node(void *ptr)
+{
+ return (void *)((unsigned long)ptr & ~2UL);
+}
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) bool radix_tree_is_internal_node(void *ptr)
+{
+ return ((unsigned long)ptr & 3UL) ==
+    2UL;
+}
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) void *xa_mk_internal(unsigned long v)
+{
+ return (void *)((v << 2) | 2);
+}
+
+static unsigned radix_tree_load_root(const struct xarray *root,
+  struct xa_node **nodep, unsigned long *maxindex)
+{
+ struct xa_node *node =
+ ({
+    typeof(root->xa_head) ________p1 = ({(*(const volatile typeof(root->xa_head) *)&(root->xa_head)); });
+    ((typeof(*root->xa_head) *)(________p1));
+ });
+
+ *nodep = node;
+
+ if (__builtin_expect(!!(radix_tree_is_internal_node(node)), 1)) {
+  node = entry_to_node(node);
+  *maxindex = node_maxindex(node);
+  return node->shift + (0 ? 4 : 6);
+ }
+
+ *maxindex = 0;
+ return 0;
+}
+
+void *__radix_tree_lookup(const struct xarray *root,
+     unsigned long index, struct xa_node **nodep,
+     void ***slotp)
+{
+ struct xa_node *node, *parent;
+ unsigned long maxindex;
+
+ restart:
+ parent = ((void *)0);
+ radix_tree_load_root(root, &node, &maxindex);
+ while (radix_tree_is_internal_node(node)) {
+
+  parent = entry_to_node(node);
+  if (node == xa_mk_internal(256))
+   goto restart;
+  if (parent->shift == 0)
+   break;
+ }
+ if (nodep)
+  *nodep = parent;
+
+ return node;
+}
+
+/* { dg-final { scan-ipa-dump-not "IPA_PARAM_OP_SPLIT" "sra" } } */
+/* { dg-final { scan-tree-dump " ={v} " "optimized" } } */
-- 
2.19.1.6.gb485710b


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH] ipa/102714 - IPA SRA eliding volatile
@ 2021-10-13  9:26 Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2021-10-13  9:26 UTC (permalink / raw)
  To: gcc-patches

The following fixes the volatileness check of IPA SRA which was
looking at the innermost reference when checking TREE_THIS_VOLATILE
but the reference to check is the outermost one.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

2021-10-13  Richard Biener  <rguenther@suse.de>

	PR ipa/102714
	* ipa-sra.c (ptr_parm_has_nonarg_uses): Fix volatileness
	check.

	* gcc.dg/ipa/pr102714.c: New testcase.
---
 gcc/ipa-sra.c                       |  40 +++++-----
 gcc/testsuite/gcc.dg/ipa/pr102714.c | 117 ++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/pr102714.c

diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c
index 965e246d788..88036590425 100644
--- a/gcc/ipa-sra.c
+++ b/gcc/ipa-sra.c
@@ -1005,15 +1005,17 @@ ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm,
       if (gimple_assign_single_p (stmt))
 	{
 	  tree rhs = gimple_assign_rhs1 (stmt);
-	  while (handled_component_p (rhs))
-	    rhs = TREE_OPERAND (rhs, 0);
-	  if (TREE_CODE (rhs) == MEM_REF
-	      && TREE_OPERAND (rhs, 0) == name
-	      && integer_zerop (TREE_OPERAND (rhs, 1))
-	      && types_compatible_p (TREE_TYPE (rhs),
-				     TREE_TYPE (TREE_TYPE (name)))
-	      && !TREE_THIS_VOLATILE (rhs))
-	    uses_ok++;
+	  if (!TREE_THIS_VOLATILE (rhs))
+	    {
+	      while (handled_component_p (rhs))
+		rhs = TREE_OPERAND (rhs, 0);
+	      if (TREE_CODE (rhs) == MEM_REF
+		  && TREE_OPERAND (rhs, 0) == name
+		  && integer_zerop (TREE_OPERAND (rhs, 1))
+		  && types_compatible_p (TREE_TYPE (rhs),
+					 TREE_TYPE (TREE_TYPE (name))))
+		uses_ok++;
+	    }
 	}
       else if (is_gimple_call (stmt))
 	{
@@ -1047,15 +1049,17 @@ ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm,
 		  continue;
 		}
 
-	      while (handled_component_p (arg))
-		arg = TREE_OPERAND (arg, 0);
-	      if (TREE_CODE (arg) == MEM_REF
-		  && TREE_OPERAND (arg, 0) == name
-		  && integer_zerop (TREE_OPERAND (arg, 1))
-		  && types_compatible_p (TREE_TYPE (arg),
-					 TREE_TYPE (TREE_TYPE (name)))
-		  && !TREE_THIS_VOLATILE (arg))
-		uses_ok++;
+	      if (!TREE_THIS_VOLATILE (arg))
+		{
+		  while (handled_component_p (arg))
+		    arg = TREE_OPERAND (arg, 0);
+		  if (TREE_CODE (arg) == MEM_REF
+		      && TREE_OPERAND (arg, 0) == name
+		      && integer_zerop (TREE_OPERAND (arg, 1))
+		      && types_compatible_p (TREE_TYPE (arg),
+					     TREE_TYPE (TREE_TYPE (name))))
+		    uses_ok++;
+		}
 	    }
 	}
 
diff --git a/gcc/testsuite/gcc.dg/ipa/pr102714.c b/gcc/testsuite/gcc.dg/ipa/pr102714.c
new file mode 100644
index 00000000000..65dd86f5c15
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr102714.c
@@ -0,0 +1,117 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-strict-aliasing -fdump-ipa-sra-details -fdump-tree-optimized" } */
+
+typedef _Bool bool;
+
+enum {
+ false = 0,
+ true = 1
+};
+
+struct xarray {
+ unsigned int xa_lock;
+ unsigned int xa_flags;
+ void * xa_head;
+
+};
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+struct callback_head {
+ struct callback_head *next;
+ void (*func)(struct callback_head *head);
+} __attribute__((aligned(sizeof(void *))));
+
+struct xa_node {
+ unsigned char shift;
+ unsigned char offset;
+ unsigned char count;
+ unsigned char nr_values;
+ struct xa_node *parent;
+ struct xarray *array;
+ union {
+  struct list_head private_list;
+  struct callback_head callback_head;
+ };
+ void *slots[(1UL << (0 ? 4 : 6))];
+ union {
+  unsigned long tags[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
+  unsigned long marks[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
+ };
+};
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long shift_maxindex(unsigned int shift)
+{
+ return ((1UL << (0 ? 4 : 6)) << shift) - 1;
+}
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long node_maxindex(const struct xa_node *node)
+{
+ return shift_maxindex(node->shift);
+}
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) struct xa_node *entry_to_node(void *ptr)
+{
+ return (void *)((unsigned long)ptr & ~2UL);
+}
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) bool radix_tree_is_internal_node(void *ptr)
+{
+ return ((unsigned long)ptr & 3UL) ==
+    2UL;
+}
+
+static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) void *xa_mk_internal(unsigned long v)
+{
+ return (void *)((v << 2) | 2);
+}
+
+static unsigned radix_tree_load_root(const struct xarray *root,
+  struct xa_node **nodep, unsigned long *maxindex)
+{
+ struct xa_node *node =
+ ({
+    typeof(root->xa_head) ________p1 = ({(*(const volatile typeof(root->xa_head) *)&(root->xa_head)); });
+    ((typeof(*root->xa_head) *)(________p1));
+ });
+
+ *nodep = node;
+
+ if (__builtin_expect(!!(radix_tree_is_internal_node(node)), 1)) {
+  node = entry_to_node(node);
+  *maxindex = node_maxindex(node);
+  return node->shift + (0 ? 4 : 6);
+ }
+
+ *maxindex = 0;
+ return 0;
+}
+
+void *__radix_tree_lookup(const struct xarray *root,
+     unsigned long index, struct xa_node **nodep,
+     void ***slotp)
+{
+ struct xa_node *node, *parent;
+ unsigned long maxindex;
+
+ restart:
+ parent = ((void *)0);
+ radix_tree_load_root(root, &node, &maxindex);
+ while (radix_tree_is_internal_node(node)) {
+
+  parent = entry_to_node(node);
+  if (node == xa_mk_internal(256))
+   goto restart;
+  if (parent->shift == 0)
+   break;
+ }
+ if (nodep)
+  *nodep = parent;
+
+ return node;
+}
+
+/* { dg-final { scan-ipa-dump-not "IPA_PARAM_OP_SPLIT" "sra" } } */
+/* { dg-final { scan-tree-dump " ={v} " "optimized" } } */
-- 
2.31.1

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-10-29  2:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-29  2:20 [PATCH] ipa/102714 - IPA SRA eliding volatile duan.db
  -- strict thread matches above, loose matches on Subject: below --
2021-10-13  9:26 Richard Biener

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).