Index: llvm/lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- llvm/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -6010,7 +6010,7 @@ // If the shift amount is greater than 32 or has a greater bitwidth than 64 // then do the default optimisation if (ShAmt->getValueType(0).getSizeInBits() > 64 || - (Con && Con->getZExtValue() >= 32)) + (Con && (Con->getZExtValue() == 0 || Con->getZExtValue() >= 32))) return SDValue(); // Extract the lower 32 bits of the shift amount if it's not an i32 Index: llvm/lib/Target/ARM/ARMInstrMVE.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrMVE.td +++ llvm/lib/Target/ARM/ARMInstrMVE.td @@ -475,16 +475,16 @@ tGPROdd:$RdaHi_src, rGPR:$Rm))]>; def MVE_ASRLi : MVE_ScalarShiftDRegImm<"asrl", 0b10, ?, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi, (ARMasrl tGPREven:$RdaLo_src, - tGPROdd:$RdaHi_src, (i32 imm:$imm)))]>; + tGPROdd:$RdaHi_src, (i32 long_shift:$imm)))]>; def MVE_LSLLr : MVE_ScalarShiftDRegReg<"lsll", 0b0, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi, (ARMlsll tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, rGPR:$Rm))]>; def MVE_LSLLi : MVE_ScalarShiftDRegImm<"lsll", 0b00, ?, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi, (ARMlsll tGPREven:$RdaLo_src, - tGPROdd:$RdaHi_src, (i32 imm:$imm)))]>; + tGPROdd:$RdaHi_src, (i32 long_shift:$imm)))]>; def MVE_LSRL : MVE_ScalarShiftDRegImm<"lsrl", 0b01, ?, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi, (ARMlsrl tGPREven:$RdaLo_src, - tGPROdd:$RdaHi_src, (i32 imm:$imm)))]>; + tGPROdd:$RdaHi_src, (i32 long_shift:$imm)))]>; def MVE_SQRSHRL : MVE_ScalarShiftDRegRegWithSat<"sqrshrl", 0b1>; def MVE_SQSHLL : MVE_ScalarShiftDRegImm<"sqshll", 0b11, 0b1>; Index: llvm/lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrThumb2.td +++ llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -45,7 +45,8 @@ let RenderMethod = "addImmOperands"; let DiagnosticString = "operand must be an immediate in the range [1,32]"; } -def long_shift : Operand { +def long_shift : Operand, + ImmLeaf 0 && Imm <= 32; }]> { let ParserMatchClass = mve_shift_imm; let DecoderMethod = "DecodeLongShiftOperand"; } Index: llvm/test/CodeGen/Thumb2/lsll0.ll =================================================================== --- llvm/test/CodeGen/Thumb2/lsll0.ll +++ llvm/test/CodeGen/Thumb2/lsll0.ll @@ -6,18 +6,14 @@ ; CHECK: @ %bb.0: @ %entry ; CHECK-NEXT: vldrw.u32 q0, [r0] ; CHECK-NEXT: vmov r1, s2 -; CHECK-NEXT: sxth r2, r1 -; CHECK-NEXT: asrs r1, r2, #31 -; CHECK-NEXT: lsll r2, r1, #0 -; CHECK-NEXT: rsbs r1, r2, #0 ; CHECK-NEXT: vmov r2, s0 ; CHECK-NEXT: sxth r1, r1 -; CHECK-NEXT: asr.w r12, r1, #31 ; CHECK-NEXT: sxth r2, r2 -; CHECK-NEXT: asrs r3, r2, #31 -; CHECK-NEXT: lsll r2, r3, #0 +; CHECK-NEXT: rsbs r1, r1, #0 ; CHECK-NEXT: rsbs r2, r2, #0 +; CHECK-NEXT: sxth r1, r1 ; CHECK-NEXT: sxth r2, r2 +; CHECK-NEXT: asr.w r12, r1, #31 ; CHECK-NEXT: asrs r3, r2, #31 ; CHECK-NEXT: strd r2, r3, [r0] ; CHECK-NEXT: strd r1, r12, [r0, #8]