]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix is_gimple_condexpr vs is_gimple_condexpr_for_cond
authorRichard Biener <rguenther@suse.de>
Mon, 11 Apr 2022 10:18:48 +0000 (12:18 +0200)
committerRichard Biener <rguenther@suse.de>
Fri, 29 Apr 2022 10:13:48 +0000 (12:13 +0200)
The following fixes wrongly used is_gimple_condexpr and makes
canonicalize_cond_expr_cond honor either, delaying final checking
to callers where all but two in ifcombine are doing the correct
thing already.

This fixes bugs but is now mainly in preparation for making
COND_EXPRs in GIMPLE assignments no longer have a GENERIC expression
as condition operand like we already transitioned VEC_COND_EXPR earlier.

2022-04-11  Richard Biener  <rguenther@suse.de>

* gimple-expr.cc (is_gimple_condexpr): Adjust comment.
(canonicalize_cond_expr_cond): Move here from gimple.cc,
allow both COND_EXPR and GIMPLE_COND forms.
* gimple-expr.h (canonicalize_cond_expr_cond): Declare.
* gimple.cc (canonicalize_cond_expr_cond): Remove here.
* gimple.h (canonicalize_cond_expr_cond): Likewise.
* gimple-loop-versioning.cc (loop_versioning::version_loop):
Use is_gimple_condexpr_for_cond.
* tree-parloops.cc (gen_parallel_loop): Likewise.
* tree-ssa-ifcombine.cc (ifcombine_ifandif): Check for
a proper cond expr after canonicalize_cond_expr_cond.
Use is_gimple_condexpr_for_cond where appropriate.
* tree-ssa-loop-manip.cc (determine_exit_conditions): Likewise.
* tree-vect-loop-manip.cc (slpeel_add_loop_guard): Likewise.

gcc/gimple-expr.cc
gcc/gimple-expr.h
gcc/gimple-loop-versioning.cc
gcc/gimple.cc
gcc/gimple.h
gcc/tree-parloops.cc
gcc/tree-ssa-ifcombine.cc
gcc/tree-ssa-loop-manip.cc
gcc/tree-vect-loop-manip.cc

index 5faaf43eaf506081938c2afc2efd3fc15db28207..5d10c24ed1b26dbd091a35f9c4216c301f0a6a2d 100644 (file)
@@ -614,7 +614,8 @@ is_gimple_condexpr_1 (tree t, bool allow_traps, bool allow_cplx)
              && is_gimple_val (TREE_OPERAND (t, 1))));
 }
 
-/* Return true if T is a GIMPLE condition.  */
+/* Return true if T is a condition operand in a GIMPLE assignment
+   with a COND_EXPR RHS.  */
 
 bool
 is_gimple_condexpr (tree t)
@@ -632,6 +633,50 @@ is_gimple_condexpr_for_cond (tree t)
   return is_gimple_condexpr_1 (t, false, true);
 }
 
+/* Canonicalize a tree T for use in a COND_EXPR as conditional.  Returns
+   a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
+   we failed to create one.  */
+
+tree
+canonicalize_cond_expr_cond (tree t)
+{
+  /* Strip conversions around boolean operations.  */
+  if (CONVERT_EXPR_P (t)
+      && (truth_value_p (TREE_CODE (TREE_OPERAND (t, 0)))
+         || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
+            == BOOLEAN_TYPE))
+    t = TREE_OPERAND (t, 0);
+
+  /* For !x use x == 0.  */
+  if (TREE_CODE (t) == TRUTH_NOT_EXPR)
+    {
+      tree top0 = TREE_OPERAND (t, 0);
+      t = build2 (EQ_EXPR, TREE_TYPE (t),
+                 top0, build_int_cst (TREE_TYPE (top0), 0));
+    }
+  /* For cmp ? 1 : 0 use cmp.  */
+  else if (TREE_CODE (t) == COND_EXPR
+          && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
+          && integer_onep (TREE_OPERAND (t, 1))
+          && integer_zerop (TREE_OPERAND (t, 2)))
+    {
+      tree top0 = TREE_OPERAND (t, 0);
+      t = build2 (TREE_CODE (top0), TREE_TYPE (t),
+                 TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
+    }
+  /* For x ^ y use x != y.  */
+  else if (TREE_CODE (t) == BIT_XOR_EXPR)
+    t = build2 (NE_EXPR, TREE_TYPE (t),
+               TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
+
+  /* We don't know where this will be used so allow both traps and
+     _Complex.  The caller is responsible for more precise checking.  */
+  if (is_gimple_condexpr_1 (t, true, true))
+    return t;
+
+  return NULL_TREE;
+}
+
 /* Return true if T is a gimple address.  */
 
 bool
index 0697126e689554d5365bcdbfebde9f60d6ff0773..ba53b80843709da52faac4df828bab81d57c147b 100644 (file)
@@ -56,6 +56,7 @@ extern bool is_gimple_mem_ref_addr (tree);
 extern void flush_mark_addressable_queue (void);
 extern void mark_addressable (tree);
 extern bool is_gimple_reg_rhs (tree);
+extern tree canonicalize_cond_expr_cond (tree);
 
 /* Return true if a conversion from either type of TYPE1 and TYPE2
    to the other is not required.  Otherwise return false.  */
index 3175a1e52498d8bdbae9e368161be2c0b085c50d..5838ce733eb0c491e1599e81a2b1a4baaad34932 100644 (file)
@@ -1681,7 +1681,8 @@ loop_versioning::version_loop (class loop *loop)
 
   /* Convert the condition into a suitable gcond.  */
   gimple_seq stmts = NULL;
-  cond = force_gimple_operand_1 (cond, &stmts, is_gimple_condexpr, NULL_TREE);
+  cond = force_gimple_operand_1 (cond, &stmts, is_gimple_condexpr_for_cond,
+                                NULL_TREE);
 
   /* Version the loop.  */
   initialize_original_copy_tables ();
index 9e62da4265b2a8a02121d574ddfad2095d8048ad..b70ab4d25230374f0c90f93d77f9caf8d57587ee 100644 (file)
@@ -2380,48 +2380,6 @@ const unsigned char gimple_rhs_class_table[] = {
 #undef DEFTREECODE
 #undef END_OF_BASE_TREE_CODES
 
-/* Canonicalize a tree T for use in a COND_EXPR as conditional.  Returns
-   a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
-   we failed to create one.  */
-
-tree
-canonicalize_cond_expr_cond (tree t)
-{
-  /* Strip conversions around boolean operations.  */
-  if (CONVERT_EXPR_P (t)
-      && (truth_value_p (TREE_CODE (TREE_OPERAND (t, 0)))
-          || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
-            == BOOLEAN_TYPE))
-    t = TREE_OPERAND (t, 0);
-
-  /* For !x use x == 0.  */
-  if (TREE_CODE (t) == TRUTH_NOT_EXPR)
-    {
-      tree top0 = TREE_OPERAND (t, 0);
-      t = build2 (EQ_EXPR, TREE_TYPE (t),
-                 top0, build_int_cst (TREE_TYPE (top0), 0));
-    }
-  /* For cmp ? 1 : 0 use cmp.  */
-  else if (TREE_CODE (t) == COND_EXPR
-          && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
-          && integer_onep (TREE_OPERAND (t, 1))
-          && integer_zerop (TREE_OPERAND (t, 2)))
-    {
-      tree top0 = TREE_OPERAND (t, 0);
-      t = build2 (TREE_CODE (top0), TREE_TYPE (t),
-                 TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
-    }
-  /* For x ^ y use x != y.  */
-  else if (TREE_CODE (t) == BIT_XOR_EXPR)
-    t = build2 (NE_EXPR, TREE_TYPE (t),
-               TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
-  
-  if (is_gimple_condexpr (t))
-    return t;
-
-  return NULL_TREE;
-}
-
 /* Build a GIMPLE_CALL identical to STMT but skipping the arguments in
    the positions marked by the set ARGS_TO_SKIP.  */
 
index 77a5a07e9b5a2a447f2e2e82e0455cb69994aa6c..6b1e89ad74e6b22dd534ff48e48fef688032f844 100644 (file)
@@ -1611,7 +1611,6 @@ bool gimple_could_trap_p (const gimple *);
 bool gimple_assign_rhs_could_trap_p (gimple *);
 extern void dump_gimple_statistics (void);
 unsigned get_gimple_rhs_num_ops (enum tree_code);
-extern tree canonicalize_cond_expr_cond (tree);
 gcall *gimple_call_copy_skip_args (gcall *, bitmap);
 extern bool gimple_compare_field_offset (tree, tree);
 extern tree gimple_unsigned_type (tree);
index 7fcb0d527d5f79dc47fcda736ac0acd99a738b09..da1069683a3edd1c435074fb170668c6547eeb1d 100644 (file)
@@ -3070,7 +3070,7 @@ gen_parallel_loop (class loop *loop,
        = force_gimple_operand (many_iterations_cond, &stmts, false, NULL_TREE);
       if (stmts)
        gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
-      if (!is_gimple_condexpr (many_iterations_cond))
+      if (!is_gimple_condexpr_for_cond (many_iterations_cond))
        {
          many_iterations_cond
            = force_gimple_operand (many_iterations_cond, &stmts,
index ce9bbebf948032d1b8cdaebff2e69ad0e960f173..3a4ab694b7172e4c5cdb2a26cd8517437aa40f47 100644 (file)
@@ -432,6 +432,12 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
       t = canonicalize_cond_expr_cond (t);
       if (!t)
        return false;
+      if (!is_gimple_condexpr_for_cond (t))
+       {
+         gsi = gsi_for_stmt (inner_cond);
+         t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr_for_cond,
+                                         NULL, true, GSI_SAME_STMT);
+       }
       gimple_cond_set_condition_from_tree (inner_cond, t);
       update_stmt (inner_cond);
 
@@ -512,6 +518,12 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
       t = canonicalize_cond_expr_cond (t);
       if (!t)
        return false;
+      if (!is_gimple_condexpr_for_cond (t))
+       {
+         gsi = gsi_for_stmt (inner_cond);
+         t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr_for_cond,
+                                         NULL, true, GSI_SAME_STMT);
+       }
       gimple_cond_set_condition_from_tree (inner_cond, t);
       update_stmt (inner_cond);
 
@@ -593,8 +605,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
              result_inv = false;
            }
          gsi = gsi_for_stmt (inner_cond);
-         t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, true,
-                                         GSI_SAME_STMT);
+         t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr_for_cond,
+                                         NULL, true, GSI_SAME_STMT);
         }
       if (result_inv)
        t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
index 770cbd2ec7949bc5ac9830ec188a5899894a21c4..66964254cb5a489358b34a30827e50f625020f38 100644 (file)
@@ -1096,7 +1096,7 @@ determine_exit_conditions (class loop *loop, class tree_niter_desc *desc,
   /* cond now may be a gimple comparison, which would be OK, but also any
      other gimple rhs (say a && b).  In this case we need to force it to
      operand.  */
-  if (!is_gimple_condexpr (cond))
+  if (!is_gimple_condexpr_for_cond (cond))
     {
       cond = force_gimple_operand (cond, &stmts, true, NULL_TREE);
       if (stmts)
index 3eddda66a66940136f93dc20df517ccc3fb5a1d0..1d4337eb2612f8e5d6eccb84c34578c219f66bbb 100644 (file)
@@ -1260,8 +1260,8 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond,
   enter_e->flags |= EDGE_FALSE_VALUE;
   gsi = gsi_last_bb (guard_bb);
 
-  cond = force_gimple_operand_1 (cond, &gimplify_stmt_list, is_gimple_condexpr,
-                                NULL_TREE);
+  cond = force_gimple_operand_1 (cond, &gimplify_stmt_list,
+                                is_gimple_condexpr_for_cond, NULL_TREE);
   if (gimplify_stmt_list)
     gsi_insert_seq_after (&gsi, gimplify_stmt_list, GSI_NEW_STMT);
 
@@ -3478,8 +3478,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
     {
       gimple_seq tem = NULL;
       cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
-                                         &tem,
-                                         is_gimple_condexpr, NULL_TREE);
+                                         &tem, is_gimple_condexpr_for_cond,
+                                         NULL_TREE);
       gimple_seq_add_seq (&cond_expr_stmt_list, tem);
     }
 
@@ -3521,7 +3521,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
 
   cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
                                      &gimplify_stmt_list,
-                                     is_gimple_condexpr, NULL_TREE);
+                                     is_gimple_condexpr_for_cond, NULL_TREE);
   gimple_seq_add_seq (&cond_expr_stmt_list, gimplify_stmt_list);
 
   /* Compute the outermost loop cond_expr and cond_expr_stmt_list are