aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-expr.cc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-04-11 12:18:48 +0200
committerRichard Biener <rguenther@suse.de>2022-04-29 12:13:48 +0200
commitc090743b2ae0095f792371c7cbeb3cf6e2978f5d (patch)
tree3526e923d4e83fd10ccb3f13dc23214b24203c86 /gcc/gimple-expr.cc
parent4aa61e08ade43fa1e94dc0e951f11739bbd2ae40 (diff)
downloadgcc-c090743b2ae0095f792371c7cbeb3cf6e2978f5d.zip
gcc-c090743b2ae0095f792371c7cbeb3cf6e2978f5d.tar.gz
gcc-c090743b2ae0095f792371c7cbeb3cf6e2978f5d.tar.bz2
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.
Diffstat (limited to 'gcc/gimple-expr.cc')
-rw-r--r--gcc/gimple-expr.cc47
1 files changed, 46 insertions, 1 deletions
diff --git a/gcc/gimple-expr.cc b/gcc/gimple-expr.cc
index 5faaf43..5d10c24 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