summaryrefslogtreecommitdiff
path: root/sys-devel/gcc/files/gcc-14.0.0_pre20231022-PR111860.patch
blob: 42deb046d0f37603cc569d94ab3724ea4be7dff4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
https://gcc.gnu.org/PR111860
https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=9ed6b22eb4188c57bb3f5cdba5a7effa95395186

From 9ed6b22eb4188c57bb3f5cdba5a7effa95395186 Mon Sep 17 00:00:00 2001
From: Tamar Christina <tamar.christina@arm.com>
Date: Mon, 23 Oct 2023 14:07:20 +0100
Subject: [PATCH] middle-end: don't keep .MEM guard nodes for PHI nodes who
 dominate loop [PR111860]

The previous patch tried to remove PHI nodes that dominated the first loop,
however the correct fix is to only remove .MEM nodes.

This patch thus makes the condition a bit stricter and only tries to remove
MEM phi nodes.

I couldn't figure out a way to easily determine if a particular PHI is vUSE
related, so the patch does:

1. check if the definition is a vDEF and not defined in main loop.
2. check if the definition is a PHI and not defined in main loop.
3. check if the definition is a default definition.

For no 2 and 3 we may misidentify the PHI, in both cases the value is defined
outside of the loop version block which also makes it ok to remove.

gcc/ChangeLog:

	PR tree-optimization/111860
	* tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg):
	Drop .MEM nodes only.

gcc/testsuite/ChangeLog:

	PR tree-optimization/111860
	* gcc.dg/vect/pr111860-2.c: New test.
	* gcc.dg/vect/pr111860-3.c: New test.
---
 gcc/testsuite/gcc.dg/vect/pr111860-2.c | 17 +++++++++++++++++
 gcc/testsuite/gcc.dg/vect/pr111860-3.c | 17 +++++++++++++++++
 gcc/tree-vect-loop-manip.cc            | 21 ++++++++++++++++++++-
 3 files changed, 54 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr111860-2.c
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr111860-3.c

diff --git a/gcc/testsuite/gcc.dg/vect/pr111860-2.c b/gcc/testsuite/gcc.dg/vect/pr111860-2.c
new file mode 100644
index 000000000000..07f64ffb5318
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr111860-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-sink -ftree-vectorize" } */
+int buffer_ctrl_ctx_0, buffer_ctrl_p1, buffer_ctrl_cmd;
+
+int
+buffer_ctrl (long ret, int i)
+{
+  switch (buffer_ctrl_cmd)
+    {
+    case 1:
+      buffer_ctrl_ctx_0 = 0;
+      for (; i; i++)
+	if (buffer_ctrl_p1)
+	  ret++;
+    }
+  return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr111860-3.c b/gcc/testsuite/gcc.dg/vect/pr111860-3.c
new file mode 100644
index 000000000000..07f64ffb5318
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr111860-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-sink -ftree-vectorize" } */
+int buffer_ctrl_ctx_0, buffer_ctrl_p1, buffer_ctrl_cmd;
+
+int
+buffer_ctrl (long ret, int i)
+{
+  switch (buffer_ctrl_cmd)
+    {
+    case 1:
+      buffer_ctrl_ctx_0 = 0;
+      for (; i; i++)
+	if (buffer_ctrl_p1)
+	  ret++;
+    }
+  return ret;
+}
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index d67c94700144..43ca985c53ce 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -1626,12 +1626,31 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
 	  edge temp_e = redirect_edge_and_branch (exit, new_preheader);
 	  flush_pending_stmts (temp_e);
 	}
-
       /* Record the new SSA names in the cache so that we can skip materializing
 	 them again when we fill in the rest of the LCSSA variables.  */
       for (auto phi : new_phis)
 	{
 	  tree new_arg = gimple_phi_arg (phi, 0)->def;
+
+	  if (!SSA_VAR_P (new_arg))
+	    continue;
+	  /* If the PHI MEM node dominates the loop then we shouldn't create
+	      a new LC-SSSA PHI for it in the intermediate block.   */
+	  /* A MEM phi that consitutes a new DEF for the vUSE chain can either
+	     be a .VDEF or a PHI that operates on MEM. And said definition
+	     must not be inside the main loop.  Or we must be a parameter.
+	     In the last two cases we may remove a non-MEM PHI node, but since
+	     they dominate both loops the removal is unlikely to cause trouble
+	     as the exits must already be using them.  */
+	  if (virtual_operand_p (new_arg)
+	      && (SSA_NAME_IS_DEFAULT_DEF (new_arg)
+		  || !flow_bb_inside_loop_p (loop,
+				gimple_bb (SSA_NAME_DEF_STMT (new_arg)))))
+	    {
+	      auto gsi = gsi_for_stmt (phi);
+	      remove_phi_node (&gsi, true);
+	      continue;
+	    }
 	  new_phi_args.put (new_arg, gimple_phi_result (phi));
 
 	  if (TREE_CODE (new_arg) != SSA_NAME)
-- 
2.39.3