x64/ARM64/MIPS64: Fix constant bit shift code generation.

Reported by Sergey Kaplun. #1480
This commit is contained in:
Mike Pall 2026-07-07 11:07:19 +02:00
parent a2bde60819
commit acb223497d
3 changed files with 7 additions and 4 deletions

View File

@ -1549,7 +1549,8 @@ static void asm_bitshift(ASMState *as, IRIns *ir, A64Ins ai, A64Shift sh)
int32_t shmask = irt_is64(ir->t) ? 63 : 31;
if (irref_isk(ir->op2)) { /* Constant shifts. */
Reg left, dest = ra_dest(as, ir, RSET_GPR);
int32_t shift = (IR(ir->op2)->i & shmask);
IRIns *irr = IR(ir->op2);
int32_t shift = ((irr->o == IR_KINT ? irr->i : (int32_t)ir_kint64(irr)->u64) & shmask);
IRIns *irl = IR(ir->op1);
if (shmask == 63) ai += A64I_UBFMx - A64I_UBFMw;

View File

@ -2089,7 +2089,8 @@ static void asm_bitshift(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik)
{
Reg dest = ra_dest(as, ir, RSET_GPR);
if (irref_isk(ir->op2)) { /* Constant shifts. */
uint32_t shift = (uint32_t)IR(ir->op2)->i;
IRIns *irr = IR(ir->op2);
uint32_t shift = (uint32_t)(LJ_32 || irr->o == IR_KINT) ? (uint32_t)irr->i : (uint32_t)ir_kint64(irr)->u64;
if (LJ_64 && irt_is64(ir->t)) mik |= (shift & 32) ? MIPSI_D32 : MIPSI_D;
emit_dta(as, mik, dest, ra_hintalloc(as, ir->op1, dest, RSET_GPR),
(shift & 31));

View File

@ -2318,9 +2318,10 @@ static void asm_bitshift(ASMState *as, IRIns *ir, x86Shift xs, x86Op xv)
IRIns *irr = IR(rref);
Reg dest;
if (irref_isk(rref)) { /* Constant shifts. */
int shift;
int32_t shift;
dest = ra_dest(as, ir, RSET_GPR);
shift = irr->i & (irt_is64(ir->t) ? 63 : 31);
shift = (LJ_32 || irr->o == IR_KINT) ? irr->i : (int32_t)ir_kint64(irr)->u64;
shift &= (irt_is64(ir->t) ? 63 : 31);
if (!xv && shift && (as->flags & JIT_F_BMI2)) {
Reg left = asm_fuseloadm(as, ir->op1, RSET_GPR, irt_is64(ir->t));
if (left != dest) { /* BMI2 rotate right by constant. */