tree-optimization/109154 - improve if-conversion for vectorization
authorRichard Biener <rguenther@suse.de>
Tue, 28 Mar 2023 13:20:22 +0000 (15:20 +0200)
committerRichard Biener <rguenther@suse.de>
Wed, 29 Mar 2023 06:33:00 +0000 (08:33 +0200)
With multi-argument PHIs and now doing VN on the if-converted blocks
the optimization of CSEing condition and negated condition doesn't
work well anymore.  The following restores this a little bit for
the case of a single inverted condition into a COND_EXPR where
we can instead swap the COND_EXPR arms.  The same optimization
is already done for the case of two-argument PHIs.

This avoids one comparison/mask for the testcase at hand.

PR tree-optimization/109154
* tree-if-conv.cc (gen_phi_arg_condition): Handle single
inverted condition specially by inverting at the caller.
(gen_phi_arg_condition): Swap COND_EXPR arms if requested.

gcc/tree-if-conv.cc

index ca1abd8..3494dcc 100644 (file)
@@ -1873,11 +1873,12 @@ convert_scalar_cond_reduction (gimple *reduc, gimple_stmt_iterator *gsi,
   return rhs;
 }
 
-/* Produce condition for all occurrences of ARG in PHI node.  */
+/* Produce condition for all occurrences of ARG in PHI node.  Set *INVERT
+   as to whether the condition is inverted.  */
 
 static tree
 gen_phi_arg_condition (gphi *phi, vec<int> *occur,
-                      gimple_stmt_iterator *gsi)
+                      gimple_stmt_iterator *gsi, bool *invert)
 {
   int len;
   int i;
@@ -1885,6 +1886,7 @@ gen_phi_arg_condition (gphi *phi, vec<int> *occur,
   tree c;
   edge e;
 
+  *invert = false;
   len = occur->length ();
   gcc_assert (len > 0);
   for (i = 0; i < len; i++)
@@ -1896,6 +1898,13 @@ gen_phi_arg_condition (gphi *phi, vec<int> *occur,
          cond = c;
          break;
        }
+      /* If we have just a single inverted predicate, signal that and
+        instead invert the COND_EXPR arms.  */
+      if (len == 1 && TREE_CODE (c) == TRUTH_NOT_EXPR)
+       {
+         c = TREE_OPERAND (c, 0);
+         *invert = true;
+       }
       c = force_gimple_operand_gsi (gsi, unshare_expr (c),
                                    true, NULL_TREE, true, GSI_SAME_STMT);
       if (cond != NULL_TREE)
@@ -2116,9 +2125,14 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi)
            lhs = make_temp_ssa_name (type, NULL, "_ifc_");
          else
            lhs = res;
-         cond = gen_phi_arg_condition (phi, indexes, gsi);
-         rhs = fold_build_cond_expr (type, unshare_expr (cond),
-                                     arg0, arg1);
+         bool invert;
+         cond = gen_phi_arg_condition (phi, indexes, gsi, &invert);
+         if (invert)
+           rhs = fold_build_cond_expr (type, unshare_expr (cond),
+                                       arg1, arg0);
+         else
+           rhs = fold_build_cond_expr (type, unshare_expr (cond),
+                                       arg0, arg1);
          new_stmt = gimple_build_assign (lhs, rhs);
          gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
          update_stmt (new_stmt);