public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-37] Fix is_gimple_condexpr vs is_gimple_condexpr_for_cond
@ 2022-04-29 10:14 Richard Biener
  0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2022-04-29 10:14 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c090743b2ae0095f792371c7cbeb3cf6e2978f5d

commit r13-37-gc090743b2ae0095f792371c7cbeb3cf6e2978f5d
Author: Richard Biener <rguenther@suse.de>
Date:   Mon Apr 11 12:18:48 2022 +0200

    Fix is_gimple_condexpr vs is_gimple_condexpr_for_cond
    
    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.

Diff:
---
 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 --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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-04-29 10:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-29 10:14 [gcc r13-37] Fix is_gimple_condexpr vs is_gimple_condexpr_for_cond Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).