diff --git a/cranelift/codegen/src/isa/aarch64/lower.rs b/cranelift/codegen/src/isa/aarch64/lower.rs index 77d96e85b3..1da3d41328 100644 --- a/cranelift/codegen/src/isa/aarch64/lower.rs +++ b/cranelift/codegen/src/isa/aarch64/lower.rs @@ -435,8 +435,10 @@ pub(crate) fn put_input_in_rs_immlogic>( pub(crate) fn put_input_in_reg_immshift>( ctx: &mut C, input: InsnInput, + shift_width_bits: usize, ) -> ResultRegImmShift { if let Some(imm_value) = input_to_const(ctx, input) { + let imm_value = imm_value & ((shift_width_bits - 1) as u64); if let Some(immshift) = ImmShift::maybe_from_u64(imm_value) { return ResultRegImmShift::ImmShift(immshift); } diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index efcee9b36d..82eb35f13f 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -460,7 +460,7 @@ pub(crate) fn lower_insn_to_regs>( }; let rd = get_output_reg(ctx, outputs[0]); let rn = put_input_in_reg(ctx, inputs[0], narrow_mode); - let rm = put_input_in_reg_immshift(ctx, inputs[1]); + let rm = put_input_in_reg_immshift(ctx, inputs[1], ty_bits(ty)); let alu_op = match op { Opcode::Ishl => choose_32_64(ty, ALUOp::Lsl32, ALUOp::Lsl64), Opcode::Ushr => choose_32_64(ty, ALUOp::Lsr32, ALUOp::Lsr64), @@ -513,7 +513,7 @@ pub(crate) fn lower_insn_to_regs>( NarrowValueMode::ZeroExtend64 }, ); - let rm = put_input_in_reg_immshift(ctx, inputs[1]); + let rm = put_input_in_reg_immshift(ctx, inputs[1], ty_bits(ty)); if ty_bits_size == 32 || ty_bits_size == 64 { let alu_op = choose_32_64(ty, ALUOp::RotR32, ALUOp::RotR64); diff --git a/cranelift/filetests/filetests/vcode/aarch64/shift-op.clif b/cranelift/filetests/filetests/vcode/aarch64/shift-op.clif index 2b72b9951f..f484a3e54d 100644 --- a/cranelift/filetests/filetests/vcode/aarch64/shift-op.clif +++ b/cranelift/filetests/filetests/vcode/aarch64/shift-op.clif @@ -15,3 +15,17 @@ block0(v0: i64): ; nextln: mov sp, fp ; nextln: ldp fp, lr, [sp], #16 ; nextln: ret + +function %f(i32) -> i32 { +block0(v0: i32): + v1 = iconst.i32 53 + v2 = ishl.i32 v0, v1 + return v2 +} + +; check: stp fp, lr, [sp, #-16]! +; nextln: mov fp, sp +; nextln: lsl w0, w0, #21 +; nextln: mov sp, fp +; nextln: ldp fp, lr, [sp], #16 +; nextln: ret