[PATCH] tcg/optimize: Fix s_mask computation for shifts
Jacob Young <[email protected]> Tue, 04 Aug 2026 02:27:23 -0400
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
Previously, we would produce an incorrect smask in this case:
t1.smask = 0xffffffff80000000
shr_i32 t0,t1,$0x1
t0.smask = 0xffffffffc0000000
because `do_constant_folding` would produce `smask = 0x40000000` which
was passed unchanged to `fold_masks_zos` which would then update with
`s_mask |= INT32_MIN;`, producing the incorrect result above.
Reproducer (i386 assembly):
.text
.globl _start
_start:
movw $0x4000, %ax
addw %ax, %ax
cwtl
shrl %eax
xorl %ebx, %ebx
cmpw $-0x3fff, %ax
setnl %bl
movl $1, %eax
int $0x80
Signed-off-by: Jacob Young <[email protected]>
---
tcg/optimize.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tcg/optimize.c b/tcg/optimize.c
index fcdef25bee..96f7841afa 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -2658,6 +2658,14 @@ static bool fold_shift(OptContext *ctx, TCGOp *op)
o_mask = do_constant_folding(op->opc, ctx->type, o_mask, sh);
s_mask = do_constant_folding(op->opc, ctx->type, s_mask, sh);
+ /*
+ * If the bit shifted into the result sign was not in the
+ * input s_mask, then no bits are known to match it.
+ */
+ if ((int64_t)s_mask >= 0) {
+ s_mask = 0;
+ }
+
return fold_masks_zos(ctx, op, z_mask, o_mask, s_mask);
}
--
2.55.0