Commit 744eb39667 for qemu.org
commit 744eb39667b6d562fa68cd63c6600779f717df40
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Tue Feb 3 15:51:17 2026 +0100
tcg/optimize: possibly expand deposit into zero with shifts
Use tcg_op_imm_match to choose between expanding with AND+SHL vs SHL+SHR.
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260303010833.1115741-8-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 59761c2c84..b1abec69a5 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -1743,14 +1743,38 @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
goto done;
}
- /* Lower invalid deposit into zero as AND + SHL. */
+ /* Lower invalid deposit into zero as AND + SHL or SHL + SHR. */
if (!valid) {
- op2 = opt_insert_before(ctx, op, INDEX_op_and, 3);
- op2->args[0] = ret;
- op2->args[1] = arg2;
- op2->args[2] = arg_new_constant(ctx, len_mask);
- fold_and(ctx, op2);
+ if (TCG_TARGET_extract_valid(ctx->type, 0, len)) {
+ /* EXTRACT (at 0) + SHL */
+ op2 = opt_insert_before(ctx, op, INDEX_op_extract, 4);
+ op2->args[0] = ret;
+ op2->args[1] = arg2;
+ op2->args[2] = 0;
+ op2->args[3] = len;
+ } else if (tcg_op_imm_match(INDEX_op_and, ctx->type, len_mask)) {
+ /* AND + SHL */
+ op2 = opt_insert_before(ctx, op, INDEX_op_and, 3);
+ op2->args[0] = ret;
+ op2->args[1] = arg2;
+ op2->args[2] = arg_new_constant(ctx, len_mask);
+ } else {
+ /* SHL + SHR */
+ int shl = width - len;
+ int shr = width - len - ofs;
+
+ op2 = opt_insert_before(ctx, op, INDEX_op_shl, 3);
+ op2->args[0] = ret;
+ op2->args[1] = arg2;
+ op2->args[2] = arg_new_constant(ctx, shl);
+
+ op->opc = INDEX_op_shr;
+ op->args[1] = ret;
+ op->args[2] = arg_new_constant(ctx, shr);
+ goto done;
+ }
+ /* Finish the (EXTRACT|AND) + SHL cases. */
op->opc = INDEX_op_shl;
op->args[1] = ret;
op->args[2] = arg_new_constant(ctx, ofs);