aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2024-09-06 12:22:41 -0700
committerRichard Henderson <richard.henderson@linaro.org>2024-09-22 06:54:49 +0200
commit1f106544fd87fd12566c8c5e12251067e2bc9f78 (patch)
tree99bcb2516a84ca39886e0afe63bcf4d231309cd4
parent141125e08cf422e22d40b0114a265c83d888767a (diff)
downloadqemu-1f106544fd87fd12566c8c5e12251067e2bc9f78.zip
qemu-1f106544fd87fd12566c8c5e12251067e2bc9f78.tar.gz
qemu-1f106544fd87fd12566c8c5e12251067e2bc9f78.tar.bz2
tcg/optimize: Optimize cmp_vec and cmpsel_vec
Place immediate values second in the comparison. Place destination matches first in the true/false values. All of this mirrors what we do for integer setcond and movcond. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--tcg/optimize.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/tcg/optimize.c b/tcg/optimize.c
index cf31179..f11f576 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -2422,6 +2422,36 @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
return tcg_opt_gen_movi(ctx, op, op->args[0], i);
}
+static bool fold_cmp_vec(OptContext *ctx, TCGOp *op)
+{
+ /* Canonicalize the comparison to put immediate second. */
+ if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
+ op->args[3] = tcg_swap_cond(op->args[3]);
+ }
+ return false;
+}
+
+static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op)
+{
+ /* If true and false values are the same, eliminate the cmp. */
+ if (args_are_copies(op->args[3], op->args[4])) {
+ return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[3]);
+ }
+
+ /* Canonicalize the comparison to put immediate second. */
+ if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
+ op->args[5] = tcg_swap_cond(op->args[5]);
+ }
+ /*
+ * Canonicalize the "false" input reg to match the destination,
+ * so that the tcg backend can implement "move if true".
+ */
+ if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
+ op->args[5] = tcg_invert_cond(op->args[5]);
+ }
+ return false;
+}
+
static bool fold_sextract(OptContext *ctx, TCGOp *op)
{
uint64_t z_mask, s_mask, s_mask_old;
@@ -2928,6 +2958,12 @@ void tcg_optimize(TCGContext *s)
case INDEX_op_setcond2_i32:
done = fold_setcond2(&ctx, op);
break;
+ case INDEX_op_cmp_vec:
+ done = fold_cmp_vec(&ctx, op);
+ break;
+ case INDEX_op_cmpsel_vec:
+ done = fold_cmpsel_vec(&ctx, op);
+ break;
CASE_OP_32_64(sextract):
done = fold_sextract(&ctx, op);
break;