summaryrefslogtreecommitdiff
path: root/0058-Backport-tree-optimization-95393-fold-MIN-MAX_EXPR-g.patch
blob: 0edbcb0f799ed49b926628525af71672a7b41520 (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
From b9ac0cc69aab3c8d662d5b0a9ed43d971c13ac70 Mon Sep 17 00:00:00 2001
From: Richard Biener <rguenther@suse.de>
Date: Fri, 29 May 2020 09:25:53 +0200
Subject: [PATCH 10/35] [Backport] tree-optimization/95393 - fold MIN/MAX_EXPR
 generated by phiopt

Reference: https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=07852a81f58532c63a57631d7c3757fc6bcea17d

This makes sure to fold generated stmts so they do not survive
until RTL expansion and cause awkward code generation.

2020-05-29  Richard Biener <rguenther@suse.de>

	PR tree-optimization/95393
	* tree-ssa-phiopt.c (minmax_replacement): Use gimple_build
	to build the min/max expression so we simplify cases like
	MAX(0, s) immediately.

	* gcc.dg/tree-ssa/phi-opt-21.c: New testcase.
	* g++.dg/vect/slp-pr87105.cc: Adjust.
---
 gcc/testsuite/g++.dg/vect/slp-pr87105.cc   |  2 +-
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c | 15 +++++++++++++
 gcc/tree-ssa-phiopt.c                      | 25 +++++++++++-----------
 3 files changed, 29 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c

diff --git a/gcc/testsuite/g++.dg/vect/slp-pr87105.cc b/gcc/testsuite/g++.dg/vect/slp-pr87105.cc
index 5518f319b..d07b1cd46 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr87105.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr87105.cc
@@ -102,4 +102,4 @@ void quadBoundingBoxA(const Point bez[3], Box& bBox) noexcept {
 // { dg-final { scan-tree-dump-times "basic block part vectorized" 1 "slp2" { xfail { { ! vect_element_align } && { ! vect_hw_misalign } } } } }
 // It's a bit awkward to detect that all stores were vectorized but the
 // following more or less does the trick
-// { dg-final { scan-tree-dump "vect_iftmp\[^\r\m\]* = MIN" "slp2" { xfail { { ! vect_element_align } && { ! vect_hw_misalign } } } } }
+// { dg-final { scan-tree-dump "vect_\[^\r\m\]* = MIN" "slp2" { xfail { { ! vect_element_align } && { ! vect_hw_misalign } } } } }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c
new file mode 100644
index 000000000..9f3d56957
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-phiopt4-details" } */
+
+int f(unsigned s)
+{
+  int i;
+  for (i = 0; i < s; ++i)
+    ;
+
+  return i;
+}
+
+/* { dg-final { scan-tree-dump "converted to straightline code" "phiopt4" } } */
+/* Make sure we fold the detected MAX<s, 0>.  */
+/* { dg-final { scan-tree-dump-not "MAX" "phiopt4" } } */
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index fca32222f..269eda21c 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "case-cfn-macros.h"
 #include "tree-eh.h"
+#include "gimple-fold.h"
 #include "internal-fn.h"
 
 static unsigned int tree_ssa_phiopt_worker (bool, bool, bool);
@@ -1414,7 +1415,6 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
 {
   tree result, type, rhs;
   gcond *cond;
-  gassign *new_stmt;
   edge true_edge, false_edge;
   enum tree_code cmp, minmax, ass_code;
   tree smaller, alt_smaller, larger, alt_larger, arg_true, arg_false;
@@ -1738,19 +1738,20 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
       gsi_move_before (&gsi_from, &gsi);
     }
 
-  /* Create an SSA var to hold the min/max result.  If we're the only
-     things setting the target PHI, then we  can clone the PHI
-     variable.  Otherwise we must create a new one.  */
-  result = PHI_RESULT (phi);
-  if (EDGE_COUNT (gimple_bb (phi)->preds) == 2)
-    result = duplicate_ssa_name (result, NULL);
-  else
-    result = make_ssa_name (TREE_TYPE (result));
-
   /* Emit the statement to compute min/max.  */
-  new_stmt = gimple_build_assign (result, minmax, arg0, arg1);
+  gimple_seq stmts = NULL;
+  tree phi_result = PHI_RESULT (phi);
+  result = gimple_build (&stmts, minmax, TREE_TYPE (phi_result), arg0, arg1);
+  /* Duplicate range info if we're the only things setting the target PHI.  */
+  if (!gimple_seq_empty_p (stmts)
+      && EDGE_COUNT (gimple_bb (phi)->preds) == 2
+      && !POINTER_TYPE_P (TREE_TYPE (phi_result))
+      && SSA_NAME_RANGE_INFO (phi_result))
+    duplicate_ssa_name_range_info (result, SSA_NAME_RANGE_TYPE (phi_result),
+				   SSA_NAME_RANGE_INFO (phi_result));
+
   gsi = gsi_last_bb (cond_bb);
-  gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
+  gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
 
   replace_phi_edge_with_variable (cond_bb, e1, phi, result);
 
-- 
2.27.0.windows.1