diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -2326,7 +2326,7 @@ auto BitfieldInst = MIB.buildInstr(Opc, {I.getOperand(0)}, {I.getOperand(1)}) .addImm(LSB) - .addImm(Width); + .addImm(LSB + Width - 1); I.eraseFromParent(); return constrainSelectedInstRegOperands(*BitfieldInst, TII, TRI, RBI); } diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp @@ -262,7 +262,7 @@ return false; MatchInfo = [=](MachineIRBuilder &B) { auto Cst1 = B.buildConstant(Ty, ShiftImm); - auto Cst2 = B.buildConstant(Ty, ShiftImm + Width - 1); + auto Cst2 = B.buildConstant(Ty, Width); B.buildInstr(TargetOpcode::G_SBFX, {Dst}, {ShiftSrc, Cst1, Cst2}); }; return true; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/form-bitfield-extract-from-sextinreg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/form-bitfield-extract-from-sextinreg.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/form-bitfield-extract-from-sextinreg.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/form-bitfield-extract-from-sextinreg.mir @@ -15,7 +15,7 @@ ; CHECK: liveins: $w0 ; CHECK: %x:_(s32) = COPY $w0 ; CHECK: %lsb:_(s32) = G_CONSTANT i32 5 - ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 14 + ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 10 ; CHECK: %sext_inreg:_(s32) = G_SBFX %x, %lsb(s32), [[C]] ; CHECK: $w0 = COPY %sext_inreg(s32) ; CHECK: RET_ReallyLR implicit $w0 @@ -38,7 +38,7 @@ ; CHECK: liveins: $w0 ; CHECK: %x:_(s32) = COPY $w0 ; CHECK: %lsb:_(s32) = G_CONSTANT i32 5 - ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 14 + ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 10 ; CHECK: %sext_inreg:_(s32) = G_SBFX %x, %lsb(s32), [[C]] ; CHECK: $w0 = COPY %sext_inreg(s32) ; CHECK: RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir @@ -13,7 +13,7 @@ ; CHECK-LABEL: name: sbfx_s32 ; CHECK: liveins: $w0 ; CHECK: %copy:gpr32 = COPY $w0 - ; CHECK: %sbfx:gpr32 = SBFMWri %copy, 0, 10 + ; CHECK: %sbfx:gpr32 = SBFMWri %copy, 0, 9 ; CHECK: $w0 = COPY %sbfx ; CHECK: RET_ReallyLR implicit $w0 %copy:gpr(s32) = COPY $w0 @@ -35,7 +35,7 @@ ; CHECK-LABEL: name: sbfx_s64 ; CHECK: liveins: $x0 ; CHECK: %copy:gpr64 = COPY $x0 - ; CHECK: %sbfx:gpr64 = SBFMXri %copy, 0, 10 + ; CHECK: %sbfx:gpr64 = SBFMXri %copy, 0, 9 ; CHECK: $x0 = COPY %sbfx ; CHECK: RET_ReallyLR implicit $x0 %copy:gpr(s64) = COPY $x0 @@ -47,7 +47,7 @@ ... --- -name: sbfx_s32_31_31 +name: sbfx_s32_31_1 legalized: true regBankSelected: true tracksRegLiveness: true @@ -56,7 +56,7 @@ liveins: $w0 ; This is just an asr, so it's okay. - ; CHECK-LABEL: name: sbfx_s32_31_31 + ; CHECK-LABEL: name: sbfx_s32_31_1 ; CHECK: liveins: $w0 ; CHECK: %copy:gpr32 = COPY $w0 ; CHECK: %sbfx:gpr32 = SBFMWri %copy, 31, 31 @@ -64,7 +64,47 @@ ; CHECK: RET_ReallyLR implicit $w0 %copy:gpr(s32) = COPY $w0 %cst1:gpr(s32) = G_CONSTANT i32 31 - %cst2:gpr(s32) = G_CONSTANT i32 31 + %cst2:gpr(s32) = G_CONSTANT i32 1 %sbfx:gpr(s32) = G_SBFX %copy, %cst1, %cst2 $w0 = COPY %sbfx RET_ReallyLR implicit $w0 +--- +name: sbfx_s32_10_5 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0 + ; CHECK-LABEL: name: sbfx_s32_10_5 + ; CHECK: liveins: $w0 + ; CHECK: %copy:gpr32 = COPY $w0 + ; CHECK: %sbfx:gpr32 = SBFMWri %copy, 10, 14 + ; CHECK: $w0 = COPY %sbfx + ; CHECK: RET_ReallyLR implicit $w0 + %copy:gpr(s32) = COPY $w0 + %cst1:gpr(s32) = G_CONSTANT i32 10 + %cst2:gpr(s32) = G_CONSTANT i32 5 + %sbfx:gpr(s32) = G_SBFX %copy, %cst1, %cst2 + $w0 = COPY %sbfx + RET_ReallyLR implicit $w0 +--- +name: sbfx_s64_10_5 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: name: sbfx_s64_10_5 + ; CHECK: liveins: $x0 + ; CHECK: %copy:gpr64 = COPY $x0 + ; CHECK: %sbfx:gpr64 = SBFMXri %copy, 10, 14 + ; CHECK: $x0 = COPY %sbfx + ; CHECK: RET_ReallyLR implicit $x0 + %copy:gpr(s64) = COPY $x0 + %cst1:gpr(s64) = G_CONSTANT i64 10 + %cst2:gpr(s64) = G_CONSTANT i64 5 + %sbfx:gpr(s64) = G_SBFX %copy, %cst1, %cst2 + $x0 = COPY %sbfx + RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir @@ -13,7 +13,7 @@ ; CHECK-LABEL: name: ubfx_s32 ; CHECK: liveins: $w0 ; CHECK: %copy:gpr32 = COPY $w0 - ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 0, 10 + ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 0, 9 ; CHECK: $w0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $w0 %copy:gpr(s32) = COPY $w0 @@ -35,7 +35,7 @@ ; CHECK-LABEL: name: ubfx_s64 ; CHECK: liveins: $x0 ; CHECK: %copy:gpr64 = COPY $x0 - ; CHECK: %ubfx:gpr64 = UBFMXri %copy, 0, 10 + ; CHECK: %ubfx:gpr64 = UBFMXri %copy, 0, 9 ; CHECK: $x0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $x0 %copy:gpr(s64) = COPY $x0 @@ -47,7 +47,7 @@ ... --- -name: ubfx_s32_31_31 +name: ubfx_s32_31_1 legalized: true regBankSelected: true tracksRegLiveness: true @@ -57,7 +57,7 @@ ; This is just a lsr, so it's okay. - ; CHECK-LABEL: name: ubfx_s32_31_31 + ; CHECK-LABEL: name: ubfx_s32_31_1 ; CHECK: liveins: $w0 ; CHECK: %copy:gpr32 = COPY $w0 ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 31, 31 @@ -65,7 +65,49 @@ ; CHECK: RET_ReallyLR implicit $w0 %copy:gpr(s32) = COPY $w0 %cst1:gpr(s32) = G_CONSTANT i32 31 - %cst2:gpr(s32) = G_CONSTANT i32 31 + %cst2:gpr(s32) = G_CONSTANT i32 1 %ubfx:gpr(s32) = G_UBFX %copy, %cst1, %cst2 $w0 = COPY %ubfx RET_ReallyLR implicit $w0 +--- +name: ubfx_s32_10_5 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $w0 + ; CHECK-LABEL: name: ubfx_s32_10_5 + ; CHECK: liveins: $w0 + ; CHECK: %copy:gpr32 = COPY $w0 + ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 10, 14 + ; CHECK: $w0 = COPY %ubfx + ; CHECK: RET_ReallyLR implicit $w0 + %copy:gpr(s32) = COPY $w0 + %cst1:gpr(s32) = G_CONSTANT i32 10 + %cst2:gpr(s32) = G_CONSTANT i32 5 + %ubfx:gpr(s32) = G_UBFX %copy, %cst1, %cst2 + $w0 = COPY %ubfx + RET_ReallyLR implicit $w0 + +... +--- +name: ubfx_s64_10_5 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $x0 + ; CHECK-LABEL: name: ubfx_s64_10_5 + ; CHECK: liveins: $x0 + ; CHECK: %copy:gpr64 = COPY $x0 + ; CHECK: %ubfx:gpr64 = UBFMXri %copy, 10, 14 + ; CHECK: $x0 = COPY %ubfx + ; CHECK: RET_ReallyLR implicit $x0 + %copy:gpr(s64) = COPY $x0 + %cst1:gpr(s64) = G_CONSTANT i64 10 + %cst2:gpr(s64) = G_CONSTANT i64 5 + %ubfx:gpr(s64) = G_UBFX %copy, %cst1, %cst2 + $x0 = COPY %ubfx + RET_ReallyLR implicit $x0