aboutsummaryrefslogtreecommitdiff
path: root/gcc/ccmp.cc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2024-01-23 17:42:51 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2024-01-23 17:42:51 +0000
commit06ee648e9bb8c121fbd93659f81d3380dba8be09 (patch)
treeb11f086d76a5dcb8dd149b4afacb2a7747382b81 /gcc/ccmp.cc
parentcc082cf97e21dad37c4983572218a22ce0c3036c (diff)
downloadgcc-06ee648e9bb8c121fbd93659f81d3380dba8be09.zip
gcc-06ee648e9bb8c121fbd93659f81d3380dba8be09.tar.gz
gcc-06ee648e9bb8c121fbd93659f81d3380dba8be09.tar.bz2
aarch64/expr: Use ccmp when the outer expression is used twice [PR100942]
Ccmp is not used if the result of the and/ior is used by both a GIMPLE_COND and a GIMPLE_ASSIGN. This improves the code generation here by using ccmp in this case. Two changes is required, first we need to allow the outer statement's result be used more than once. The second change is that during the expansion of the gimple, we need to try using ccmp. This is needed because we don't use expand the ssa name of the lhs but rather expand directly from the gimple. A small note on the ccmp_4.c testcase, we should be able to get slightly better than with this patch but it is one extra instruction compared to before. PR target/100942 gcc/ChangeLog: * ccmp.cc (ccmp_candidate_p): Add outer argument. Allow if the outer is true and the lhs is used more than once. (expand_ccmp_expr): Update call to ccmp_candidate_p. * expr.h (expand_expr_real_gassign): Declare. * expr.cc (expand_expr_real_gassign): New function, split out from... (expand_expr_real_1): ...here. * cfgexpand.cc (expand_gimple_stmt_1): Use expand_expr_real_gassign. gcc/testsuite/ChangeLog: * gcc.target/aarch64/ccmp_3.c: New test. * gcc.target/aarch64/ccmp_4.c: New test. * gcc.target/aarch64/ccmp_5.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com> Co-Authored-By: Richard Sandiford <richard.sandiford@arm.com>
Diffstat (limited to 'gcc/ccmp.cc')
-rw-r--r--gcc/ccmp.cc12
1 files changed, 7 insertions, 5 deletions
diff --git a/gcc/ccmp.cc b/gcc/ccmp.cc
index 09d6b55..7cb525a 100644
--- a/gcc/ccmp.cc
+++ b/gcc/ccmp.cc
@@ -90,9 +90,10 @@ ccmp_tree_comparison_p (tree t, basic_block bb)
If all checks OK in expand_ccmp_expr, it emits insns in prep_seq, then
insns in gen_seq. */
-/* Check whether G is a potential conditional compare candidate. */
+/* Check whether G is a potential conditional compare candidate; OUTER is true if
+ G is the outer most AND/IOR. */
static bool
-ccmp_candidate_p (gimple *g)
+ccmp_candidate_p (gimple *g, bool outer = false)
{
tree lhs, op0, op1;
gimple *gs0, *gs1;
@@ -109,8 +110,9 @@ ccmp_candidate_p (gimple *g)
lhs = gimple_assign_lhs (g);
op0 = gimple_assign_rhs1 (g);
op1 = gimple_assign_rhs2 (g);
- if ((TREE_CODE (op0) != SSA_NAME) || (TREE_CODE (op1) != SSA_NAME)
- || !has_single_use (lhs))
+ if ((TREE_CODE (op0) != SSA_NAME) || (TREE_CODE (op1) != SSA_NAME))
+ return false;
+ if (!outer && !has_single_use (lhs))
return false;
bb = gimple_bb (g);
@@ -284,7 +286,7 @@ expand_ccmp_expr (gimple *g, machine_mode mode)
rtx_insn *last;
rtx tmp;
- if (!ccmp_candidate_p (g))
+ if (!ccmp_candidate_p (g, true))
return NULL_RTX;
last = get_last_insn ();