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>
Richard Henderson committed
Feb 3, 2026 at 15:51 UTC
744eb39667b6d562fa68cd63c6600779f717df40
1 file changed
+30
-6
tcg/optimize.c
+30
-6
@@ -1743,14 +1743,38 @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
1743
goto done;
1744
}
1745
1746
- /* Lower invalid deposit into zero as AND + SHL. */
1746
+ /* Lower invalid deposit into zero as AND + SHL or SHL + SHR. */
1747
if (!valid) {
1748
- op2 = opt_insert_before(ctx, op, INDEX_op_and, 3);
1749
- op2->args[0] = ret;
1750
- op2->args[1] = arg2;
1751
- op2->args[2] = arg_new_constant(ctx, len_mask);
1752
- fold_and(ctx, op2);
1748
+ if (TCG_TARGET_extract_valid(ctx->type, 0, len)) {
1749
+ /* EXTRACT (at 0) + SHL */
1750
+ op2 = opt_insert_before(ctx, op, INDEX_op_extract, 4);
1751
+ op2->args[0] = ret;
1752
+ op2->args[1] = arg2;
1753
+ op2->args[2] = 0;
1754
+ op2->args[3] = len;
1755
+ } else if (tcg_op_imm_match(INDEX_op_and, ctx->type, len_mask)) {
1756
+ /* AND + SHL */
1757
+ op2 = opt_insert_before(ctx, op, INDEX_op_and, 3);
1758
+ op2->args[0] = ret;
1759
+ op2->args[1] = arg2;
1760
+ op2->args[2] = arg_new_constant(ctx, len_mask);
1761
+ } else {
1762
+ /* SHL + SHR */
1763
+ int shl = width - len;
1764
+ int shr = width - len - ofs;
1765
+
1766
+ op2 = opt_insert_before(ctx, op, INDEX_op_shl, 3);
1767
+ op2->args[0] = ret;
1768
+ op2->args[1] = arg2;
1769
+ op2->args[2] = arg_new_constant(ctx, shl);
1770
+
1771
+ op->opc = INDEX_op_shr;
1772
+ op->args[1] = ret;
1773
+ op->args[2] = arg_new_constant(ctx, shr);
1774
+ goto done;
1775
+ }
1776
1777
+ /* Finish the (EXTRACT|AND) + SHL cases. */
1778
op->opc = INDEX_op_shl;
1779
op->args[1] = ret;
1780
op->args[2] = arg_new_constant(ctx, ofs);