The following adds missing support for bool to float conversion which
can be exposed via C++ __builtin_bit_cast.  It also corrects a too
lose check in vectorizable_conversion which would have resolved the
ICE but left us with the missed optimization.

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

        PR tree-optimization/122647
        * tree-vect-stmts.cc (vectorizable_conversion): Fix guard on
        bool to non-bool conversion.
        * tree-vect-patterns.cc (vect_recog_bool_pattern): Also handle
        FLOAT_EXPR from bool.

        * g++.dg/vect/pr122647.cc: New testcase.
---
 gcc/testsuite/g++.dg/vect/pr122647.cc | 18 ++++++++++++++++++
 gcc/tree-vect-patterns.cc             | 10 ++++++----
 gcc/tree-vect-stmts.cc                |  2 +-
 3 files changed, 25 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/vect/pr122647.cc

diff --git a/gcc/testsuite/g++.dg/vect/pr122647.cc 
b/gcc/testsuite/g++.dg/vect/pr122647.cc
new file mode 100644
index 00000000000..d7203bd7a3d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/pr122647.cc
@@ -0,0 +1,18 @@
+// { dg-do compile }
+
+void av(float *au)
+{
+  for (int i = 0; i < 1024; ++i)
+  {
+    float t = i;
+    int tt = __builtin_bit_cast(int, t);
+    bool t1 = tt;
+    float t2 = t1;
+    int t3 = __builtin_bit_cast(int, t2);
+    bool t4 = t3;
+    float t5 = t5;
+    au[i] = t4;
+  }
+}
+
+// { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" { target { 
{ vect_uintfloat_cvt && vect_float } && vect_bool_cmp } } } }
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 878a045c436..db510e5f9b9 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -5991,10 +5991,10 @@ vect_recog_bool_pattern (vec_info *vinfo,
   hash_set<gimple *> bool_stmts;
 
   if (CONVERT_EXPR_CODE_P (rhs_code)
-      || rhs_code == VIEW_CONVERT_EXPR)
+      || rhs_code == VIEW_CONVERT_EXPR
+      || rhs_code == FLOAT_EXPR)
     {
-      if (! INTEGRAL_TYPE_P (TREE_TYPE (lhs))
-         || VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (lhs)))
+      if (VECT_SCALAR_BOOLEAN_TYPE_P (TREE_TYPE (lhs)))
        return NULL;
       vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (lhs));
 
@@ -6023,7 +6023,9 @@ vect_recog_bool_pattern (vec_info *vinfo,
                                  pattern_stmt, new_vectype);
 
          lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
-         pattern_stmt = gimple_build_assign (lhs, CONVERT_EXPR, tmp);
+         pattern_stmt
+           = gimple_build_assign (lhs, (rhs_code == FLOAT_EXPR
+                                        ? FLOAT_EXPR : CONVERT_EXPR), tmp);
        }
 
       *type_out = vectype;
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index ff58a4e38fa..87d17db8a67 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -5400,7 +5400,7 @@ vectorizable_conversion (vec_info *vinfo,
     }
 
   if (VECTOR_BOOLEAN_TYPE_P (vectype_out)
-      && !VECTOR_BOOLEAN_TYPE_P (vectype_in))
+      != VECTOR_BOOLEAN_TYPE_P (vectype_in))
     {
       if (dump_enabled_p ())
        dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-- 
2.51.0

Reply via email to