]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/97255 - missing vector bool pattern of SRAed bool
authorRichard Biener <rguenther@suse.de>
Thu, 1 Oct 2020 07:29:32 +0000 (09:29 +0200)
committerRichard Biener <rguenther@suse.de>
Mon, 12 Oct 2020 06:52:51 +0000 (08:52 +0200)
SRA tends to use VIEW_CONVERT_EXPR when replacing bool fields with
unsigned char fields.  Those are not handled in vector bool pattern
detection causing vector true values to leak.  The following fixes
this by turning those into b ? 1 : 0 as well.

2020-10-01  Richard Biener  <rguenther@suse.de>

PR tree-optimization/97255
* tree-vect-patterns.c (vect_recog_bool_pattern): Also handle
VIEW_CONVERT_EXPR.

* g++.dg/vect/pr97255.cc: New testcase.

gcc/testsuite/g++.dg/vect/pr97255.cc [new file with mode: 0644]
gcc/tree-vect-patterns.c

diff --git a/gcc/testsuite/g++.dg/vect/pr97255.cc b/gcc/testsuite/g++.dg/vect/pr97255.cc
new file mode 100644 (file)
index 0000000..efb7f53
--- /dev/null
@@ -0,0 +1,44 @@
+// { dg-require-effective-target c++11 }
+// { dg-additional-options "-O3" }
+
+template<class T, unsigned N>
+class Array{
+public:
+    T& operator[](unsigned x) {return m_arr[x];}
+private:
+    T m_arr[N];
+};
+
+int
+__attribute__((noipa))
+logicalOr(Array< char, 4 > in1[60],
+          Array< bool, 4 > out[60])
+{
+  for (unsigned k0 = 0u; k0 < 60u; ++k0) {
+      Array< char, 4 > in1m = in1[k0];
+      Array< bool, 4 > x;
+      for (unsigned k1 = 0u; k1 < 4u; ++k1) {
+          char in1s = in1m[k1];
+          x[k1] = in1s != char(0) || in1s != char(0);
+      }
+      out[k0] = x;
+  }
+  return out[0][0];
+}
+
+
+int main()
+{
+  Array< char, 4 > In1[60]{};
+  Array< bool, 4 > Out7[60]{};
+
+  for( int i = 0; i < 60; ++i){
+      for( int j = 0; j < 4; ++j){
+          In1[i][j] = 240 - i*4 - j;
+      }
+  }
+
+  if (logicalOr(In1, Out7) != 1)
+    __builtin_abort ();
+  return 0;
+}
index dd0c19dc5e50e3cc11e0aa1a86a22114fdee20c5..ae5dc5c422609fc42b92297a13b2df59f88b2f99 100644 (file)
@@ -4025,14 +4025,18 @@ vect_recog_bool_pattern (stmt_vec_info stmt_vinfo, tree *type_out)
 
   var = gimple_assign_rhs1 (last_stmt);
   lhs = gimple_assign_lhs (last_stmt);
+  rhs_code = gimple_assign_rhs_code (last_stmt);
+
+  if (rhs_code == VIEW_CONVERT_EXPR)
+    var = TREE_OPERAND (var, 0);
 
   if (!VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (var)))
     return NULL;
 
   hash_set<gimple *> bool_stmts;
 
-  rhs_code = gimple_assign_rhs_code (last_stmt);
-  if (CONVERT_EXPR_CODE_P (rhs_code))
+  if (CONVERT_EXPR_CODE_P (rhs_code)
+      || rhs_code == VIEW_CONVERT_EXPR)
     {
       if (! INTEGRAL_TYPE_P (TREE_TYPE (lhs))
          || TYPE_PRECISION (TREE_TYPE (lhs)) == 1)