diff options
author | Andrew Pinski <quic_apinski@quicinc.com> | 2024-01-23 17:42:51 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2024-01-23 17:42:51 +0000 |
commit | 06ee648e9bb8c121fbd93659f81d3380dba8be09 (patch) | |
tree | b11f086d76a5dcb8dd149b4afacb2a7747382b81 /gcc/expr.cc | |
parent | cc082cf97e21dad37c4983572218a22ce0c3036c (diff) | |
download | gcc-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/expr.cc')
-rw-r--r-- | gcc/expr.cc | 103 |
1 files changed, 58 insertions, 45 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc index 502518d..ee822c1 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -11038,6 +11038,62 @@ stmt_is_replaceable_p (gimple *stmt) return false; } +/* A subroutine of expand_expr_real_1. Expand gimple assignment G, + which is known to set an SSA_NAME result. The other arguments are + as for expand_expr_real_1. */ + +rtx +expand_expr_real_gassign (gassign *g, rtx target, machine_mode tmode, + enum expand_modifier modifier, rtx *alt_rtl, + bool inner_reference_p) +{ + separate_ops ops; + rtx r; + location_t saved_loc = curr_insn_location (); + auto loc = gimple_location (g); + if (loc != UNKNOWN_LOCATION) + set_curr_insn_location (loc); + tree lhs = gimple_assign_lhs (g); + ops.code = gimple_assign_rhs_code (g); + ops.type = TREE_TYPE (lhs); + switch (get_gimple_rhs_class (ops.code)) + { + case GIMPLE_TERNARY_RHS: + ops.op2 = gimple_assign_rhs3 (g); + /* Fallthru */ + case GIMPLE_BINARY_RHS: + ops.op1 = gimple_assign_rhs2 (g); + + /* Try to expand conditonal compare. */ + if (targetm.gen_ccmp_first) + { + gcc_checking_assert (targetm.gen_ccmp_next != NULL); + r = expand_ccmp_expr (g, TYPE_MODE (ops.type)); + if (r) + break; + } + /* Fallthru */ + case GIMPLE_UNARY_RHS: + ops.op0 = gimple_assign_rhs1 (g); + ops.location = loc; + r = expand_expr_real_2 (&ops, target, tmode, modifier); + break; + case GIMPLE_SINGLE_RHS: + { + r = expand_expr_real (gimple_assign_rhs1 (g), target, + tmode, modifier, alt_rtl, + inner_reference_p); + break; + } + default: + gcc_unreachable (); + } + set_curr_insn_location (saved_loc); + if (REG_P (r) && !REG_EXPR (r)) + set_reg_attrs_for_decl_rtl (lhs, r); + return r; +} + rtx expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, enum expand_modifier modifier, rtx *alt_rtl, @@ -11201,51 +11257,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp))) g = SSA_NAME_DEF_STMT (exp); if (g) - { - rtx r; - location_t saved_loc = curr_insn_location (); - loc = gimple_location (g); - if (loc != UNKNOWN_LOCATION) - set_curr_insn_location (loc); - ops.code = gimple_assign_rhs_code (g); - switch (get_gimple_rhs_class (ops.code)) - { - case GIMPLE_TERNARY_RHS: - ops.op2 = gimple_assign_rhs3 (g); - /* Fallthru */ - case GIMPLE_BINARY_RHS: - ops.op1 = gimple_assign_rhs2 (g); - - /* Try to expand conditonal compare. */ - if (targetm.gen_ccmp_first) - { - gcc_checking_assert (targetm.gen_ccmp_next != NULL); - r = expand_ccmp_expr (g, mode); - if (r) - break; - } - /* Fallthru */ - case GIMPLE_UNARY_RHS: - ops.op0 = gimple_assign_rhs1 (g); - ops.type = TREE_TYPE (gimple_assign_lhs (g)); - ops.location = loc; - r = expand_expr_real_2 (&ops, target, tmode, modifier); - break; - case GIMPLE_SINGLE_RHS: - { - r = expand_expr_real (gimple_assign_rhs1 (g), target, - tmode, modifier, alt_rtl, - inner_reference_p); - break; - } - default: - gcc_unreachable (); - } - set_curr_insn_location (saved_loc); - if (REG_P (r) && !REG_EXPR (r)) - set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (exp), r); - return r; - } + return expand_expr_real_gassign (as_a<gassign *> (g), target, tmode, + modifier, alt_rtl, inner_reference_p); ssa_name = exp; decl_rtl = get_rtx_for_ssa_name (ssa_name); |