Commit c9349965ce for qemu.org
commit c9349965ce4a1548a0b19dc3cf859a461d525f6b
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Wed May 20 14:51:39 2026 +0200
tcg: Optimize INDEX_op_mul[us]2 for 0 and 1
Zero operands produce a zero high and low product. One operands produce
a copy of the other operand and a zero or sign extension in the high
half.
Fold those cases during TCG optimization so wide-multiply idioms used by
target translators can collapse before code generation.
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260520125139.13352-3-philmd@linaro.org>
diff --git a/tcg/optimize.c b/tcg/optimize.c
index ef5eb2cf17..fcdef25bee 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -2212,6 +2212,34 @@ static bool fold_multiply2(OptContext *ctx, TCGOp *op)
tcg_opt_gen_movi(ctx, op2, rh, h);
return true;
}
+
+ if (b == 0) {
+ op2 = opt_insert_before(ctx, op, 0, 2);
+ tcg_opt_gen_movi(ctx, op2, rl, 0);
+ tcg_opt_gen_movi(ctx, op, rh, 0);
+ return true;
+ }
+ if (b == 1) {
+ op2 = opt_insert_before(ctx, op, 0, 2);
+ tcg_opt_gen_mov(ctx, op2, rl, op->args[2]);
+
+ switch (op->opc) {
+ case INDEX_op_mulu2:
+ tcg_opt_gen_movi(ctx, op, rh, 0);
+ break;
+ case INDEX_op_muls2:
+ op->opc = INDEX_op_sar;
+ op->args[0] = rh;
+ op->args[1] = rl;
+ op->args[2] =
+ arg_new_constant(ctx, tcg_type_size(ctx->type) * 8 - 1);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ return true;
+ }
}
return finish_folding(ctx, op);
}