diff mbox series

Fix is_gimple_condexpr vs is_gimple_condexpr_for_cond

Message ID 20220429093833.67CCD13AE0@imap2.suse-dmz.suse.de
State New
Headers show
Series Fix is_gimple_condexpr vs is_gimple_condexpr_for_cond | expand

Commit Message

Richard Biener April 29, 2022, 9:38 a.m. UTC
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.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

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            | 47 ++++++++++++++++++++++++++++++++++-
 gcc/gimple-expr.h             |  1 +
 gcc/gimple-loop-versioning.cc |  3 ++-
 gcc/gimple.cc                 | 42 -------------------------------
 gcc/gimple.h                  |  1 -
 gcc/tree-parloops.cc          |  2 +-
 gcc/tree-ssa-ifcombine.cc     | 16 ++++++++++--
 gcc/tree-ssa-loop-manip.cc    |  2 +-
 gcc/tree-vect-loop-manip.cc   | 10 ++++----
 9 files changed, 70 insertions(+), 54 deletions(-)
diff mbox series

Patch

diff --git a/gcc/gimple-expr.cc b/gcc/gimple-expr.cc
index 5faaf43eaf5..5d10c24ed1b 100644
--- a/gcc/gimple-expr.cc
+++ b/gcc/gimple-expr.cc
@@ -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
diff --git a/gcc/gimple-expr.h b/gcc/gimple-expr.h
index 0697126e689..ba53b808437 100644
--- a/gcc/gimple-expr.h
+++ b/gcc/gimple-expr.h
@@ -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.  */
diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
index 3175a1e5249..5838ce733eb 100644
--- a/gcc/gimple-loop-versioning.cc
+++ b/gcc/gimple-loop-versioning.cc
@@ -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 ();
diff --git a/gcc/gimple.cc b/gcc/gimple.cc
index 9e62da4265b..b70ab4d2523 100644
--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc
@@ -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.  */
 
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 77a5a07e9b5..6b1e89ad74e 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -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);
diff --git a/gcc/tree-parloops.cc b/gcc/tree-parloops.cc
index 7fcb0d527d5..da1069683a3 100644
--- a/gcc/tree-parloops.cc
+++ b/gcc/tree-parloops.cc
@@ -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,
diff --git a/gcc/tree-ssa-ifcombine.cc b/gcc/tree-ssa-ifcombine.cc
index ce9bbebf948..3a4ab694b71 100644
--- a/gcc/tree-ssa-ifcombine.cc
+++ b/gcc/tree-ssa-ifcombine.cc
@@ -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);
diff --git a/gcc/tree-ssa-loop-manip.cc b/gcc/tree-ssa-loop-manip.cc
index 770cbd2ec79..66964254cb5 100644
--- a/gcc/tree-ssa-loop-manip.cc
+++ b/gcc/tree-ssa-loop-manip.cc
@@ -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)
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 3eddda66a66..1d4337eb261 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -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