Index: llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -2032,6 +2032,21 @@ Observer.changedInstr(MI); return Legalized; + case TargetOpcode::G_SBFX: + case TargetOpcode::G_UBFX: + Observer.changingInstr(MI); + + if (TypeIdx == 0 ) { + widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT); + widenScalarDst(MI, WideTy); + } else { + widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT); + widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ZEXT); + } + + Observer.changedInstr(MI); + return Legalized; + case TargetOpcode::G_SHL: Observer.changingInstr(MI); Index: llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.h =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.h +++ llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.h @@ -109,6 +109,7 @@ bool selectG_PTR_ADD(MachineInstr &I) const; bool selectG_IMPLICIT_DEF(MachineInstr &I) const; bool selectG_INSERT(MachineInstr &I) const; + bool selectG_SBFX_UBFX(MachineInstr &I) const; bool selectInterpP1F16(MachineInstr &MI) const; bool selectWritelane(MachineInstr &MI) const; Index: llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp @@ -754,6 +754,66 @@ return true; } +bool AMDGPUInstructionSelector::selectG_SBFX_UBFX(MachineInstr &MI) const { + Register DstReg = MI.getOperand(0).getReg(); + Register SrcReg = MI.getOperand(1).getReg(); + Register OffsetReg = MI.getOperand(2).getReg(); + Register WidthReg = MI.getOperand(3).getReg(); + + bool IsSigned = MI.getOpcode() == TargetOpcode::G_SBFX; + unsigned Is64 = MRI->getType(MI.getOperand(0).getReg()).getSizeInBits() == 64; + + const DebugLoc &DL = MI.getDebugLoc(); + MachineBasicBlock *MBB = MI.getParent(); + + const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI); + // The scslar bitfield extract instructions pack the offset and width into a + // 32-bit value. + if (DstRB->getID() == AMDGPU::SGPRRegBankID) { + unsigned Opc = IsSigned ? (Is64 ? AMDGPU::S_BFE_I64 : AMDGPU::S_BFE_I32) + : (Is64 ? AMDGPU::S_BFE_U64 : AMDGPU::S_BFE_U32); + + Register TmpReg0 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass); + Register TmpReg1 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass); + Register TmpReg2 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass); + + // Zero the high bits of the register with the offset so that it can be + // combined with the width. + auto MIB = BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::S_AND_B32), TmpReg0) + .addReg(OffsetReg) + .addImm(maskTrailingOnes(6)); + constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); + // Shift the width to the high 16-bits. + MIB = BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::S_LSHL_B32), TmpReg1) + .addReg(WidthReg) + .addImm(16); + constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); + // Combine the width and offset into the same register. + MIB = BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::S_OR_B32), TmpReg2) + .addReg(TmpReg1) + .addReg(TmpReg0); + constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); + // Generate the bitfield extract instruction. + MIB = BuildMI(*MBB, &MI, DL, TII.get(Opc), DstReg) + .addReg(SrcReg) + .addReg(TmpReg2); + constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); + } else { + // The vector bitfield extract instructions have different operands for the + // offset and width values. + if (Is64) + return false; + unsigned Opc = IsSigned ? AMDGPU::V_BFE_I32_e64 : AMDGPU::V_BFE_U32_e64; + auto MIB = BuildMI(*MBB, &MI, DL, TII.get(Opc), DstReg) + .addReg(SrcReg) + .addReg(OffsetReg) + .addReg(WidthReg); + constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); + } + MI.eraseFromParent(); + return true; +} + bool AMDGPUInstructionSelector::selectInterpP1F16(MachineInstr &MI) const { if (STI.getLDSBankCount() != 16) return selectImpl(MI, *CoverageInfo); @@ -3169,6 +3229,9 @@ return selectBVHIntrinsic(I); case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FADD: return selectAMDGPU_BUFFER_ATOMIC_FADD(I); + case AMDGPU::G_SBFX: + case AMDGPU::G_UBFX: + return selectG_SBFX_UBFX(I); default: return selectImpl(I, *CoverageInfo); } Index: llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -1630,6 +1630,12 @@ .minScalar(0, S32) .lower(); + getActionDefinitionsBuilder({G_SBFX, G_UBFX}) + .legalFor({{S32, S32}, {S64, S32}}) + .clampScalar(1, S32, S32) + .clampScalar(0, S32, S64) + .widenScalarToNextPow2(0); + getActionDefinitionsBuilder({ // TODO: Verify V_BFI_B32 is generated from expanded bit ops G_FCOPYSIGN, Index: llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp +++ llvm/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp @@ -3465,6 +3465,8 @@ case AMDGPU::G_UMIN: case AMDGPU::G_UMAX: case AMDGPU::G_SHUFFLE_VECTOR: + case AMDGPU::G_SBFX: + case AMDGPU::G_UBFX: if (isSALUMapping(MI)) return getDefaultMappingSOP(MI); LLVM_FALLTHROUGH; Index: llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-sbfx.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-sbfx.mir @@ -0,0 +1,199 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=instruction-select -verify-machineinstrs -o - %s | FileCheck -check-prefix=WAVE64 %s +# RUN: llc -march=amdgcn -mcpu=gfx1010 -run-pass=instruction-select -verify-machineinstrs -o - %s | FileCheck -check-prefix=WAVE32 %s + +--- +name: sbfx_s32_sii +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $sgpr0 + ; WAVE64-LABEL: name: sbfx_s32_sii + ; WAVE64: liveins: $sgpr0 + ; WAVE64: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; WAVE64: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2 + ; WAVE64: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 10 + ; WAVE64: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_MOV_B32_]], 63, implicit-def $scc + ; WAVE64: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[S_MOV_B32_1]], 16, implicit-def $scc + ; WAVE64: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE64: [[S_BFE_I32_:%[0-9]+]]:sreg_32 = S_BFE_I32 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE64: S_ENDPGM 0, implicit [[S_BFE_I32_]] + ; WAVE32-LABEL: name: sbfx_s32_sii + ; WAVE32: liveins: $sgpr0 + ; WAVE32: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; WAVE32: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2 + ; WAVE32: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 10 + ; WAVE32: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_MOV_B32_]], 63, implicit-def $scc + ; WAVE32: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[S_MOV_B32_1]], 16, implicit-def $scc + ; WAVE32: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE32: [[S_BFE_I32_:%[0-9]+]]:sreg_32 = S_BFE_I32 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE32: S_ENDPGM 0, implicit [[S_BFE_I32_]] + %0:sgpr(s32) = COPY $sgpr0 + %1:sgpr(s32) = G_CONSTANT i32 2 + %2:sgpr(s32) = G_CONSTANT i32 10 + %3:sgpr(s32) = G_SBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... + +--- +name: sbfx_s64_sii +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $sgpr0_sgpr1 + ; WAVE64-LABEL: name: sbfx_s64_sii + ; WAVE64: liveins: $sgpr0_sgpr1 + ; WAVE64: [[COPY:%[0-9]+]]:sreg_64 = COPY $sgpr0_sgpr1 + ; WAVE64: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0 + ; WAVE64: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 10 + ; WAVE64: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_MOV_B32_]], 63, implicit-def $scc + ; WAVE64: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[S_MOV_B32_1]], 16, implicit-def $scc + ; WAVE64: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE64: [[S_BFE_I64_:%[0-9]+]]:sreg_64 = S_BFE_I64 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE64: S_ENDPGM 0, implicit [[S_BFE_I64_]] + ; WAVE32-LABEL: name: sbfx_s64_sii + ; WAVE32: liveins: $sgpr0_sgpr1 + ; WAVE32: [[COPY:%[0-9]+]]:sreg_64 = COPY $sgpr0_sgpr1 + ; WAVE32: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0 + ; WAVE32: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 10 + ; WAVE32: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_MOV_B32_]], 63, implicit-def $scc + ; WAVE32: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[S_MOV_B32_1]], 16, implicit-def $scc + ; WAVE32: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE32: [[S_BFE_I64_:%[0-9]+]]:sreg_64 = S_BFE_I64 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE32: S_ENDPGM 0, implicit [[S_BFE_I64_]] + %0:sgpr(s64) = COPY $sgpr0_sgpr1 + %1:sgpr(s32) = G_CONSTANT i32 0 + %2:sgpr(s32) = G_CONSTANT i32 10 + %3:sgpr(s64) = G_SBFX %0, %1, %2 + S_ENDPGM 0, implicit %3 +... + +--- +name: sbfx_s32_sss +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $sgpr0, $sgpr1, $sgpr2 + ; WAVE64-LABEL: name: sbfx_s32_sss + ; WAVE64: liveins: $sgpr0, $sgpr1, $sgpr2 + ; WAVE64: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; WAVE64: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; WAVE64: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], 63, implicit-def $scc + ; WAVE64: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[COPY2]], 16, implicit-def $scc + ; WAVE64: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE64: [[S_BFE_I32_:%[0-9]+]]:sreg_32 = S_BFE_I32 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE64: S_ENDPGM 0, implicit [[S_BFE_I32_]] + ; WAVE32-LABEL: name: sbfx_s32_sss + ; WAVE32: liveins: $sgpr0, $sgpr1, $sgpr2 + ; WAVE32: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; WAVE32: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; WAVE32: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], 63, implicit-def $scc + ; WAVE32: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[COPY2]], 16, implicit-def $scc + ; WAVE32: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE32: [[S_BFE_I32_:%[0-9]+]]:sreg_32 = S_BFE_I32 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE32: S_ENDPGM 0, implicit [[S_BFE_I32_]] + %0:sgpr(s32) = COPY $sgpr0 + %1:sgpr(s32) = COPY $sgpr1 + %2:sgpr(s32) = COPY $sgpr2 + %3:sgpr(s32) = G_SBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... +--- +name: sbfx_s64_sss +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $sgpr0_sgpr1, $sgpr2, $sgpr3 + ; WAVE64-LABEL: name: sbfx_s64_sss + ; WAVE64: liveins: $sgpr0_sgpr1, $sgpr2, $sgpr3 + ; WAVE64: [[COPY:%[0-9]+]]:sreg_64 = COPY $sgpr0_sgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; WAVE64: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; WAVE64: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], 63, implicit-def $scc + ; WAVE64: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[COPY2]], 16, implicit-def $scc + ; WAVE64: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE64: [[S_BFE_I64_:%[0-9]+]]:sreg_64 = S_BFE_I64 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE64: S_ENDPGM 0, implicit [[S_BFE_I64_]] + ; WAVE32-LABEL: name: sbfx_s64_sss + ; WAVE32: liveins: $sgpr0_sgpr1, $sgpr2, $sgpr3 + ; WAVE32: [[COPY:%[0-9]+]]:sreg_64 = COPY $sgpr0_sgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; WAVE32: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; WAVE32: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], 63, implicit-def $scc + ; WAVE32: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[COPY2]], 16, implicit-def $scc + ; WAVE32: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE32: [[S_BFE_I64_:%[0-9]+]]:sreg_64 = S_BFE_I64 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE32: S_ENDPGM 0, implicit [[S_BFE_I64_]] + %0:sgpr(s64) = COPY $sgpr0_sgpr1 + %1:sgpr(s32) = COPY $sgpr2 + %2:sgpr(s32) = COPY $sgpr3 + %3:sgpr(s64) = G_SBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... +--- +name: sbfx_s32_vii +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0 + ; WAVE64-LABEL: name: sbfx_s32_vii + ; WAVE64: liveins: $vgpr0 + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec + ; WAVE64: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec + ; WAVE64: [[V_BFE_I32_e64_:%[0-9]+]]:vgpr_32 = V_BFE_I32_e64 [[COPY]], [[V_MOV_B32_e32_]], [[V_MOV_B32_e32_1]], implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_BFE_I32_e64_]] + ; WAVE32-LABEL: name: sbfx_s32_vii + ; WAVE32: liveins: $vgpr0 + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec + ; WAVE32: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec + ; WAVE32: [[V_BFE_I32_e64_:%[0-9]+]]:vgpr_32 = V_BFE_I32_e64 [[COPY]], [[V_MOV_B32_e32_]], [[V_MOV_B32_e32_1]], implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_BFE_I32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = G_CONSTANT i32 2 + %2:vgpr(s32) = G_CONSTANT i32 10 + %3:vgpr(s32) = G_SBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... + +--- +name: sbfx_s32_vvv +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0, $vgpr1, $vgpr2 + ; WAVE64-LABEL: name: sbfx_s32_vvv + ; WAVE64: liveins: $vgpr0, $vgpr1, $vgpr2 + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; WAVE64: [[V_BFE_I32_e64_:%[0-9]+]]:vgpr_32 = V_BFE_I32_e64 [[COPY]], [[COPY1]], [[COPY2]], implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_BFE_I32_e64_]] + ; WAVE32-LABEL: name: sbfx_s32_vvv + ; WAVE32: liveins: $vgpr0, $vgpr1, $vgpr2 + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; WAVE32: [[V_BFE_I32_e64_:%[0-9]+]]:vgpr_32 = V_BFE_I32_e64 [[COPY]], [[COPY1]], [[COPY2]], implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_BFE_I32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s32) = COPY $vgpr2 + %3:vgpr(s32) = G_SBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... Index: llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-ubfx.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/inst-select-ubfx.mir @@ -0,0 +1,199 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=instruction-select -verify-machineinstrs -o - %s | FileCheck -check-prefix=WAVE64 %s +# RUN: llc -march=amdgcn -mcpu=gfx1010 -run-pass=instruction-select -verify-machineinstrs -o - %s | FileCheck -check-prefix=WAVE32 %s + +--- +name: ubfx_s32_sii +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $sgpr0 + ; WAVE64-LABEL: name: ubfx_s32_sii + ; WAVE64: liveins: $sgpr0 + ; WAVE64: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; WAVE64: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2 + ; WAVE64: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 10 + ; WAVE64: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_MOV_B32_]], 63, implicit-def $scc + ; WAVE64: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[S_MOV_B32_1]], 16, implicit-def $scc + ; WAVE64: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE64: [[S_BFE_U32_:%[0-9]+]]:sreg_32 = S_BFE_U32 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE64: S_ENDPGM 0, implicit [[S_BFE_U32_]] + ; WAVE32-LABEL: name: ubfx_s32_sii + ; WAVE32: liveins: $sgpr0 + ; WAVE32: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; WAVE32: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 2 + ; WAVE32: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 10 + ; WAVE32: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_MOV_B32_]], 63, implicit-def $scc + ; WAVE32: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[S_MOV_B32_1]], 16, implicit-def $scc + ; WAVE32: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE32: [[S_BFE_U32_:%[0-9]+]]:sreg_32 = S_BFE_U32 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE32: S_ENDPGM 0, implicit [[S_BFE_U32_]] + %0:sgpr(s32) = COPY $sgpr0 + %1:sgpr(s32) = G_CONSTANT i32 2 + %2:sgpr(s32) = G_CONSTANT i32 10 + %3:sgpr(s32) = G_UBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... + +--- +name: ubfx_s64_sii +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $sgpr0_sgpr1 + ; WAVE64-LABEL: name: ubfx_s64_sii + ; WAVE64: liveins: $sgpr0_sgpr1 + ; WAVE64: [[COPY:%[0-9]+]]:sreg_64 = COPY $sgpr0_sgpr1 + ; WAVE64: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0 + ; WAVE64: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 10 + ; WAVE64: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_MOV_B32_]], 63, implicit-def $scc + ; WAVE64: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[S_MOV_B32_1]], 16, implicit-def $scc + ; WAVE64: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE64: [[S_BFE_U64_:%[0-9]+]]:sreg_64 = S_BFE_U64 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE64: S_ENDPGM 0, implicit [[S_BFE_U64_]] + ; WAVE32-LABEL: name: ubfx_s64_sii + ; WAVE32: liveins: $sgpr0_sgpr1 + ; WAVE32: [[COPY:%[0-9]+]]:sreg_64 = COPY $sgpr0_sgpr1 + ; WAVE32: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0 + ; WAVE32: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 10 + ; WAVE32: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[S_MOV_B32_]], 63, implicit-def $scc + ; WAVE32: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[S_MOV_B32_1]], 16, implicit-def $scc + ; WAVE32: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE32: [[S_BFE_U64_:%[0-9]+]]:sreg_64 = S_BFE_U64 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE32: S_ENDPGM 0, implicit [[S_BFE_U64_]] + %0:sgpr(s64) = COPY $sgpr0_sgpr1 + %1:sgpr(s32) = G_CONSTANT i32 0 + %2:sgpr(s32) = G_CONSTANT i32 10 + %3:sgpr(s64) = G_UBFX %0, %1, %2 + S_ENDPGM 0, implicit %3 +... + +--- +name: ubfx_s32_sss +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $sgpr0, $sgpr1, $sgpr2 + ; WAVE64-LABEL: name: ubfx_s32_sss + ; WAVE64: liveins: $sgpr0, $sgpr1, $sgpr2 + ; WAVE64: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; WAVE64: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; WAVE64: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], 63, implicit-def $scc + ; WAVE64: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[COPY2]], 16, implicit-def $scc + ; WAVE64: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE64: [[S_BFE_U32_:%[0-9]+]]:sreg_32 = S_BFE_U32 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE64: S_ENDPGM 0, implicit [[S_BFE_U32_]] + ; WAVE32-LABEL: name: ubfx_s32_sss + ; WAVE32: liveins: $sgpr0, $sgpr1, $sgpr2 + ; WAVE32: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1 + ; WAVE32: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; WAVE32: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], 63, implicit-def $scc + ; WAVE32: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[COPY2]], 16, implicit-def $scc + ; WAVE32: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE32: [[S_BFE_U32_:%[0-9]+]]:sreg_32 = S_BFE_U32 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE32: S_ENDPGM 0, implicit [[S_BFE_U32_]] + %0:sgpr(s32) = COPY $sgpr0 + %1:sgpr(s32) = COPY $sgpr1 + %2:sgpr(s32) = COPY $sgpr2 + %3:sgpr(s32) = G_UBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... +--- +name: ubfx_s64_sss +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $sgpr0_sgpr1, $sgpr2, $sgpr3 + ; WAVE64-LABEL: name: ubfx_s64_sss + ; WAVE64: liveins: $sgpr0_sgpr1, $sgpr2, $sgpr3 + ; WAVE64: [[COPY:%[0-9]+]]:sreg_64 = COPY $sgpr0_sgpr1 + ; WAVE64: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; WAVE64: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; WAVE64: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], 63, implicit-def $scc + ; WAVE64: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[COPY2]], 16, implicit-def $scc + ; WAVE64: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE64: [[S_BFE_U64_:%[0-9]+]]:sreg_64 = S_BFE_U64 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE64: S_ENDPGM 0, implicit [[S_BFE_U64_]] + ; WAVE32-LABEL: name: ubfx_s64_sss + ; WAVE32: liveins: $sgpr0_sgpr1, $sgpr2, $sgpr3 + ; WAVE32: [[COPY:%[0-9]+]]:sreg_64 = COPY $sgpr0_sgpr1 + ; WAVE32: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr2 + ; WAVE32: [[COPY2:%[0-9]+]]:sreg_32 = COPY $sgpr3 + ; WAVE32: [[S_AND_B32_:%[0-9]+]]:sreg_32 = S_AND_B32 [[COPY1]], 63, implicit-def $scc + ; WAVE32: [[S_LSHL_B32_:%[0-9]+]]:sreg_32 = S_LSHL_B32 [[COPY2]], 16, implicit-def $scc + ; WAVE32: [[S_OR_B32_:%[0-9]+]]:sreg_32 = S_OR_B32 [[S_LSHL_B32_]], [[S_AND_B32_]], implicit-def $scc + ; WAVE32: [[S_BFE_U64_:%[0-9]+]]:sreg_64 = S_BFE_U64 [[COPY]], [[S_OR_B32_]], implicit-def $scc + ; WAVE32: S_ENDPGM 0, implicit [[S_BFE_U64_]] + %0:sgpr(s64) = COPY $sgpr0_sgpr1 + %1:sgpr(s32) = COPY $sgpr2 + %2:sgpr(s32) = COPY $sgpr3 + %3:sgpr(s64) = G_UBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... +--- +name: ubfx_s32_vii +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0 + ; WAVE64-LABEL: name: ubfx_s32_vii + ; WAVE64: liveins: $vgpr0 + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec + ; WAVE64: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec + ; WAVE64: [[V_BFE_U32_e64_:%[0-9]+]]:vgpr_32 = V_BFE_U32_e64 [[COPY]], [[V_MOV_B32_e32_]], [[V_MOV_B32_e32_1]], implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_BFE_U32_e64_]] + ; WAVE32-LABEL: name: ubfx_s32_vii + ; WAVE32: liveins: $vgpr0 + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec + ; WAVE32: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 10, implicit $exec + ; WAVE32: [[V_BFE_U32_e64_:%[0-9]+]]:vgpr_32 = V_BFE_U32_e64 [[COPY]], [[V_MOV_B32_e32_]], [[V_MOV_B32_e32_1]], implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_BFE_U32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = G_CONSTANT i32 2 + %2:vgpr(s32) = G_CONSTANT i32 10 + %3:vgpr(s32) = G_UBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... + +--- +name: ubfx_s32_vvv +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0, $vgpr1, $vgpr2 + ; WAVE64-LABEL: name: ubfx_s32_vvv + ; WAVE64: liveins: $vgpr0, $vgpr1, $vgpr2 + ; WAVE64: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE64: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE64: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; WAVE64: [[V_BFE_U32_e64_:%[0-9]+]]:vgpr_32 = V_BFE_U32_e64 [[COPY]], [[COPY1]], [[COPY2]], implicit $exec + ; WAVE64: S_ENDPGM 0, implicit [[V_BFE_U32_e64_]] + ; WAVE32-LABEL: name: ubfx_s32_vvv + ; WAVE32: liveins: $vgpr0, $vgpr1, $vgpr2 + ; WAVE32: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 + ; WAVE32: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 + ; WAVE32: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 + ; WAVE32: [[V_BFE_U32_e64_:%[0-9]+]]:vgpr_32 = V_BFE_U32_e64 [[COPY]], [[COPY1]], [[COPY2]], implicit $exec + ; WAVE32: S_ENDPGM 0, implicit [[V_BFE_U32_e64_]] + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s32) = COPY $vgpr1 + %2:vgpr(s32) = COPY $vgpr2 + %3:vgpr(s32) = G_UBFX %0, %1(s32), %2 + S_ENDPGM 0, implicit %3 +... Index: llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-sbfx.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-sbfx.mir @@ -0,0 +1,122 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=fiji -O0 -run-pass=legalizer -global-isel-abort=0 %s -o - | FileCheck --check-prefix=VI %s +# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 -O0 -run-pass=legalizer -global-isel-abort=0 %s -o - | FileCheck --check-prefix=GFX9 %s +# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx1010 -O0 -run-pass=legalizer -global-isel-abort=0 %s -o - | FileCheck --check-prefix=GFX10 %s +... +--- +name: test_sbfx_s32 +body: | + bb.0.entry: + liveins: $vgpr0, $vgpr1, $vgpr2 + + ; VI-LABEL: name: test_sbfx_s32 + ; VI: %copy:_(s32) = COPY $vgpr0 + ; VI: %offset:_(s32) = COPY $vgpr1 + ; VI: %width:_(s32) = COPY $vgpr2 + ; VI: %sbfx:_(s32) = G_SBFX %copy, %offset(s32), %width + ; VI: $vgpr0 = COPY %sbfx(s32) + ; GFX9-LABEL: name: test_sbfx_s32 + ; GFX9: %copy:_(s32) = COPY $vgpr0 + ; GFX9: %offset:_(s32) = COPY $vgpr1 + ; GFX9: %width:_(s32) = COPY $vgpr2 + ; GFX9: %sbfx:_(s32) = G_SBFX %copy, %offset(s32), %width + ; GFX9: $vgpr0 = COPY %sbfx(s32) + ; GFX10-LABEL: name: test_sbfx_s32 + ; GFX10: %copy:_(s32) = COPY $vgpr0 + ; GFX10: %offset:_(s32) = COPY $vgpr1 + ; GFX10: %width:_(s32) = COPY $vgpr2 + ; GFX10: %sbfx:_(s32) = G_SBFX %copy, %offset(s32), %width + ; GFX10: $vgpr0 = COPY %sbfx(s32) + %copy:_(s32) = COPY $vgpr0 + %offset:_(s32) = COPY $vgpr1 + %width:_(s32) = COPY $vgpr2 + %sbfx:_(s32) = G_SBFX %copy, %offset(s32), %width + $vgpr0 = COPY %sbfx(s32) +... + +--- +name: test_sbfx_s64 +body: | + bb.0.entry: + liveins: $vgpr0_vgpr1, $vgpr2, $vgpr3 + + ; VI-LABEL: name: test_sbfx_s64 + ; VI: %copy:_(s64) = COPY $vgpr0_vgpr1 + ; VI: %offset:_(s32) = COPY $vgpr2 + ; VI: %width:_(s32) = COPY $vgpr3 + ; VI: %sbfx:_(s64) = G_SBFX %copy, %offset(s32), %width + ; VI: $vgpr0_vgpr1 = COPY %sbfx(s64) + ; GFX9-LABEL: name: test_sbfx_s64 + ; GFX9: %copy:_(s64) = COPY $vgpr0_vgpr1 + ; GFX9: %offset:_(s32) = COPY $vgpr2 + ; GFX9: %width:_(s32) = COPY $vgpr3 + ; GFX9: %sbfx:_(s64) = G_SBFX %copy, %offset(s32), %width + ; GFX9: $vgpr0_vgpr1 = COPY %sbfx(s64) + ; GFX10-LABEL: name: test_sbfx_s64 + ; GFX10: %copy:_(s64) = COPY $vgpr0_vgpr1 + ; GFX10: %offset:_(s32) = COPY $vgpr2 + ; GFX10: %width:_(s32) = COPY $vgpr3 + ; GFX10: %sbfx:_(s64) = G_SBFX %copy, %offset(s32), %width + ; GFX10: $vgpr0_vgpr1 = COPY %sbfx(s64) + %copy:_(s64) = COPY $vgpr0_vgpr1 + %offset:_(s32) = COPY $vgpr2 + %width:_(s32) = COPY $vgpr3 + %sbfx:_(s64) = G_SBFX %copy, %offset(s32), %width + $vgpr0_vgpr1 = COPY %sbfx(s64) +... + +--- +name: test_sbfx_s8 +body: | + bb.0.entry: + liveins: $vgpr0, $vgpr1, $vgpr2 + + ; VI-LABEL: name: test_sbfx_s8 + ; VI: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0 + ; VI: [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr1 + ; VI: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2 + ; VI: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; VI: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32) + ; VI: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]] + ; VI: [[COPY4:%[0-9]+]]:_(s32) = COPY [[COPY2]](s32) + ; VI: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]] + ; VI: [[COPY5:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; VI: [[SBFX:%[0-9]+]]:_(s32) = G_SBFX [[COPY5]], [[AND]](s32), [[AND1]] + ; VI: [[COPY6:%[0-9]+]]:_(s32) = COPY [[SBFX]](s32) + ; VI: $vgpr0 = COPY [[COPY6]](s32) + ; GFX9-LABEL: name: test_sbfx_s8 + ; GFX9: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0 + ; GFX9: [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr1 + ; GFX9: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2 + ; GFX9: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; GFX9: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32) + ; GFX9: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]] + ; GFX9: [[COPY4:%[0-9]+]]:_(s32) = COPY [[COPY2]](s32) + ; GFX9: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]] + ; GFX9: [[COPY5:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; GFX9: [[SBFX:%[0-9]+]]:_(s32) = G_SBFX [[COPY5]], [[AND]](s32), [[AND1]] + ; GFX9: [[COPY6:%[0-9]+]]:_(s32) = COPY [[SBFX]](s32) + ; GFX9: $vgpr0 = COPY [[COPY6]](s32) + ; GFX10-LABEL: name: test_sbfx_s8 + ; GFX10: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0 + ; GFX10: [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr1 + ; GFX10: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2 + ; GFX10: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; GFX10: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32) + ; GFX10: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]] + ; GFX10: [[COPY4:%[0-9]+]]:_(s32) = COPY [[COPY2]](s32) + ; GFX10: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]] + ; GFX10: [[COPY5:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; GFX10: [[SBFX:%[0-9]+]]:_(s32) = G_SBFX [[COPY5]], [[AND]](s32), [[AND1]] + ; GFX10: [[COPY6:%[0-9]+]]:_(s32) = COPY [[SBFX]](s32) + ; GFX10: $vgpr0 = COPY [[COPY6]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s32) = COPY $vgpr2 + %copy:_(s8) = G_TRUNC %0 + %offset:_(s8) = G_TRUNC %1 + %width:_(s8) = G_TRUNC %2 + %sbfx:_(s8) = G_SBFX %copy, %offset, %width + %4:_(s32) = G_ANYEXT %sbfx + $vgpr0 = COPY %4 +... Index: llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-ubfx.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-ubfx.mir @@ -0,0 +1,122 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=fiji -O0 -run-pass=legalizer -global-isel-abort=0 %s -o - | FileCheck --check-prefix=VI %s +# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 -O0 -run-pass=legalizer -global-isel-abort=0 %s -o - | FileCheck --check-prefix=GFX9 %s +# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx1010 -O0 -run-pass=legalizer -global-isel-abort=0 %s -o - | FileCheck --check-prefix=GFX10 %s +... +--- +name: test_ubfx_s32 +body: | + bb.0.entry: + liveins: $vgpr0, $vgpr1, $vgpr2 + + ; VI-LABEL: name: test_ubfx_s32 + ; VI: %copy:_(s32) = COPY $vgpr0 + ; VI: %offset:_(s32) = COPY $vgpr1 + ; VI: %width:_(s32) = COPY $vgpr2 + ; VI: %ubfx:_(s32) = G_UBFX %copy, %offset(s32), %width + ; VI: $vgpr0 = COPY %ubfx(s32) + ; GFX9-LABEL: name: test_ubfx_s32 + ; GFX9: %copy:_(s32) = COPY $vgpr0 + ; GFX9: %offset:_(s32) = COPY $vgpr1 + ; GFX9: %width:_(s32) = COPY $vgpr2 + ; GFX9: %ubfx:_(s32) = G_UBFX %copy, %offset(s32), %width + ; GFX9: $vgpr0 = COPY %ubfx(s32) + ; GFX10-LABEL: name: test_ubfx_s32 + ; GFX10: %copy:_(s32) = COPY $vgpr0 + ; GFX10: %offset:_(s32) = COPY $vgpr1 + ; GFX10: %width:_(s32) = COPY $vgpr2 + ; GFX10: %ubfx:_(s32) = G_UBFX %copy, %offset(s32), %width + ; GFX10: $vgpr0 = COPY %ubfx(s32) + %copy:_(s32) = COPY $vgpr0 + %offset:_(s32) = COPY $vgpr1 + %width:_(s32) = COPY $vgpr2 + %ubfx:_(s32) = G_UBFX %copy, %offset(s32), %width + $vgpr0 = COPY %ubfx(s32) +... + +--- +name: test_ubfx_s64 +body: | + bb.0.entry: + liveins: $vgpr0_vgpr1, $vgpr2, $vgpr3 + + ; VI-LABEL: name: test_ubfx_s64 + ; VI: %copy:_(s64) = COPY $vgpr0_vgpr1 + ; VI: %offset:_(s32) = COPY $vgpr2 + ; VI: %width:_(s32) = COPY $vgpr3 + ; VI: %ubfx:_(s64) = G_UBFX %copy, %offset(s32), %width + ; VI: $vgpr0_vgpr1 = COPY %ubfx(s64) + ; GFX9-LABEL: name: test_ubfx_s64 + ; GFX9: %copy:_(s64) = COPY $vgpr0_vgpr1 + ; GFX9: %offset:_(s32) = COPY $vgpr2 + ; GFX9: %width:_(s32) = COPY $vgpr3 + ; GFX9: %ubfx:_(s64) = G_UBFX %copy, %offset(s32), %width + ; GFX9: $vgpr0_vgpr1 = COPY %ubfx(s64) + ; GFX10-LABEL: name: test_ubfx_s64 + ; GFX10: %copy:_(s64) = COPY $vgpr0_vgpr1 + ; GFX10: %offset:_(s32) = COPY $vgpr2 + ; GFX10: %width:_(s32) = COPY $vgpr3 + ; GFX10: %ubfx:_(s64) = G_UBFX %copy, %offset(s32), %width + ; GFX10: $vgpr0_vgpr1 = COPY %ubfx(s64) + %copy:_(s64) = COPY $vgpr0_vgpr1 + %offset:_(s32) = COPY $vgpr2 + %width:_(s32) = COPY $vgpr3 + %ubfx:_(s64) = G_UBFX %copy, %offset(s32), %width + $vgpr0_vgpr1 = COPY %ubfx(s64) +... + +--- +name: test_ubfx_s8 +body: | + bb.0.entry: + liveins: $vgpr0, $vgpr1, $vgpr2 + + ; VI-LABEL: name: test_ubfx_s8 + ; VI: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0 + ; VI: [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr1 + ; VI: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2 + ; VI: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; VI: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32) + ; VI: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]] + ; VI: [[COPY4:%[0-9]+]]:_(s32) = COPY [[COPY2]](s32) + ; VI: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]] + ; VI: [[COPY5:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; VI: [[UBFX:%[0-9]+]]:_(s32) = G_UBFX [[COPY5]], [[AND]](s32), [[AND1]] + ; VI: [[COPY6:%[0-9]+]]:_(s32) = COPY [[UBFX]](s32) + ; VI: $vgpr0 = COPY [[COPY6]](s32) + ; GFX9-LABEL: name: test_ubfx_s8 + ; GFX9: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0 + ; GFX9: [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr1 + ; GFX9: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2 + ; GFX9: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; GFX9: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32) + ; GFX9: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]] + ; GFX9: [[COPY4:%[0-9]+]]:_(s32) = COPY [[COPY2]](s32) + ; GFX9: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]] + ; GFX9: [[COPY5:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; GFX9: [[UBFX:%[0-9]+]]:_(s32) = G_UBFX [[COPY5]], [[AND]](s32), [[AND1]] + ; GFX9: [[COPY6:%[0-9]+]]:_(s32) = COPY [[UBFX]](s32) + ; GFX9: $vgpr0 = COPY [[COPY6]](s32) + ; GFX10-LABEL: name: test_ubfx_s8 + ; GFX10: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0 + ; GFX10: [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr1 + ; GFX10: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2 + ; GFX10: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; GFX10: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32) + ; GFX10: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]] + ; GFX10: [[COPY4:%[0-9]+]]:_(s32) = COPY [[COPY2]](s32) + ; GFX10: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C]] + ; GFX10: [[COPY5:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; GFX10: [[UBFX:%[0-9]+]]:_(s32) = G_UBFX [[COPY5]], [[AND]](s32), [[AND1]] + ; GFX10: [[COPY6:%[0-9]+]]:_(s32) = COPY [[UBFX]](s32) + ; GFX10: $vgpr0 = COPY [[COPY6]](s32) + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s32) = COPY $vgpr2 + %copy:_(s8) = G_TRUNC %0 + %offset:_(s8) = G_TRUNC %1 + %width:_(s8) = G_TRUNC %2 + %ubfx:_(s8) = G_UBFX %copy, %offset, %width + %4:_(s32) = G_ANYEXT %ubfx + $vgpr0 = COPY %4 +... Index: llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-sbfx.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-sbfx.mir @@ -0,0 +1,142 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=regbankselect -regbankselect-fast -verify-machineinstrs -o - %s | FileCheck %s +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=regbankselect -regbankselect-greedy -verify-machineinstrs -o - %s | FileCheck %s + +... +--- +name: test_sbfx_s32_vvv +legalized: true + +body: | + bb.0.entry: + liveins: $vgpr0, $vgpr1, $vgpr2 + + ; CHECK-LABEL: name: test_sbfx_s32_vvv + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr2 + ; CHECK: [[SBFX:%[0-9]+]]:vgpr(s32) = G_SBFX [[COPY]], [[COPY1]](s32), [[COPY2]] + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s32) = COPY $vgpr2 + %3:_(s32) = G_SBFX %0, %1(s32), %2 +... + +--- +name: test_sbfx_s32_vss +legalized: true + +body: | + bb.0.entry: + liveins: $vgpr0, $sgpr0, $sgpr1 + + ; CHECK-LABEL: name: test_sbfx_s32_vss + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY2:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[COPY3:%[0-9]+]]:vgpr(s32) = COPY [[COPY1]](s32) + ; CHECK: [[COPY4:%[0-9]+]]:vgpr(s32) = COPY [[COPY2]](s32) + ; CHECK: [[SBFX:%[0-9]+]]:vgpr(s32) = G_SBFX [[COPY]], [[COPY3]](s32), [[COPY4]] + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $sgpr0 + %2:_(s32) = COPY $sgpr1 + %3:_(s32) = G_SBFX %0, %1(s32), %2 +... + +--- +name: test_sbfx_s64_vvv +legalized: true + +body: | + bb.0.entry: + liveins: $vgpr0_vgpr1, $vgpr2, $vgpr3 + + ; CHECK-LABEL: name: test_sbfx_s64_vvv + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr2 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr3 + ; CHECK: [[SBFX:%[0-9]+]]:vgpr(s64) = G_SBFX [[COPY]], [[COPY1]](s32), [[COPY2]] + %0:_(s64) = COPY $vgpr0_vgpr1 + %1:_(s32) = COPY $vgpr2 + %2:_(s32) = COPY $vgpr3 + %3:_(s64) = G_SBFX %0, %1(s32), %2 +... + +--- +name: test_sbfx_s64_vss +legalized: true + +body: | + bb.0.entry: + liveins: $vgpr0_vgpr1, $sgpr0, $sgpr1 + + ; CHECK-LABEL: name: test_sbfx_s64_vss + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[SBFX:%[0-9]+]]:vgpr(s64) = G_SBFX [[COPY]], [[COPY1]](s32), [[COPY2]] + %0:_(s64) = COPY $vgpr0_vgpr1 + %1:_(s32) = COPY $vgpr0 + %2:_(s32) = COPY $vgpr1 + %3:_(s64) = G_SBFX %0, %1(s32), %2 +... + +... +--- +name: test_sbfx_s32_svv +legalized: true + +body: | + bb.0.entry: + liveins: $sgpr0, $vgpr0, $vgpr1 + + ; CHECK-LABEL: name: test_sbfx_s32_svv + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[COPY3:%[0-9]+]]:vgpr(s32) = COPY [[COPY]](s32) + ; CHECK: [[SBFX:%[0-9]+]]:vgpr(s32) = G_SBFX [[COPY3]], [[COPY1]](s32), [[COPY2]] + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $vgpr0 + %2:_(s32) = COPY $vgpr1 + %3:_(s32) = G_SBFX %0, %1(s32), %2 +... + +--- +name: test_sbfx_s64_sss +legalized: true + +body: | + bb.0.entry: + liveins: $sgpr0_sgpr1, $sgpr2, $sgpr3 + + ; CHECK-LABEL: name: test_sbfx_s64_sss + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr2 + ; CHECK: [[COPY2:%[0-9]+]]:sgpr(s32) = COPY $sgpr3 + ; CHECK: [[SBFX:%[0-9]+]]:sgpr(s64) = G_SBFX [[COPY]], [[COPY1]](s32), [[COPY2]] + %0:_(s64) = COPY $sgpr0_sgpr1 + %1:_(s32) = COPY $sgpr2 + %2:_(s32) = COPY $sgpr3 + %3:_(s64) = G_SBFX %0, %1(s32), %2 +... + +--- +name: test_sbfx_s64_svv +legalized: true + +body: | + bb.0.entry: + liveins: $sgpr0_sgpr1, $vgpr0, $vgpr1 + + ; CHECK-LABEL: name: test_sbfx_s64_svv + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[COPY3:%[0-9]+]]:vgpr(s64) = COPY [[COPY]](s64) + ; CHECK: [[SBFX:%[0-9]+]]:vgpr(s64) = G_SBFX [[COPY3]], [[COPY1]](s32), [[COPY2]] + %0:_(s64) = COPY $sgpr0_sgpr1 + %1:_(s32) = COPY $vgpr0 + %2:_(s32) = COPY $vgpr1 + %3:_(s64) = G_SBFX %0, %1(s32), %2 +... Index: llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-ubfx.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/GlobalISel/regbankselect-ubfx.mir @@ -0,0 +1,142 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=regbankselect -regbankselect-fast -verify-machineinstrs -o - %s | FileCheck %s +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=regbankselect -regbankselect-greedy -verify-machineinstrs -o - %s | FileCheck %s + +... +--- +name: test_ubfx_s32_vvv +legalized: true + +body: | + bb.0.entry: + liveins: $vgpr0, $vgpr1, $vgpr2 + + ; CHECK-LABEL: name: test_ubfx_s32_vvv + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr2 + ; CHECK: [[UBFX:%[0-9]+]]:vgpr(s32) = G_UBFX [[COPY]], [[COPY1]](s32), [[COPY2]] + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $vgpr1 + %2:_(s32) = COPY $vgpr2 + %3:_(s32) = G_UBFX %0, %1(s32), %2 +... + +--- +name: test_ubfx_s32_vss +legalized: true + +body: | + bb.0.entry: + liveins: $vgpr0, $sgpr0, $sgpr1 + + ; CHECK-LABEL: name: test_ubfx_s32_vss + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY2:%[0-9]+]]:sgpr(s32) = COPY $sgpr1 + ; CHECK: [[COPY3:%[0-9]+]]:vgpr(s32) = COPY [[COPY1]](s32) + ; CHECK: [[COPY4:%[0-9]+]]:vgpr(s32) = COPY [[COPY2]](s32) + ; CHECK: [[UBFX:%[0-9]+]]:vgpr(s32) = G_UBFX [[COPY]], [[COPY3]](s32), [[COPY4]] + %0:_(s32) = COPY $vgpr0 + %1:_(s32) = COPY $sgpr0 + %2:_(s32) = COPY $sgpr1 + %3:_(s32) = G_UBFX %0, %1(s32), %2 +... + +--- +name: test_ubfx_s64_vvv +legalized: true + +body: | + bb.0.entry: + liveins: $vgpr0_vgpr1, $vgpr2, $vgpr3 + + ; CHECK-LABEL: name: test_ubfx_s64_vvv + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr2 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr3 + ; CHECK: [[UBFX:%[0-9]+]]:vgpr(s64) = G_UBFX [[COPY]], [[COPY1]](s32), [[COPY2]] + %0:_(s64) = COPY $vgpr0_vgpr1 + %1:_(s32) = COPY $vgpr2 + %2:_(s32) = COPY $vgpr3 + %3:_(s64) = G_UBFX %0, %1(s32), %2 +... + +--- +name: test_ubfx_s64_vss +legalized: true + +body: | + bb.0.entry: + liveins: $vgpr0_vgpr1, $sgpr0, $sgpr1 + + ; CHECK-LABEL: name: test_ubfx_s64_vss + ; CHECK: [[COPY:%[0-9]+]]:vgpr(s64) = COPY $vgpr0_vgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[UBFX:%[0-9]+]]:vgpr(s64) = G_UBFX [[COPY]], [[COPY1]](s32), [[COPY2]] + %0:_(s64) = COPY $vgpr0_vgpr1 + %1:_(s32) = COPY $vgpr0 + %2:_(s32) = COPY $vgpr1 + %3:_(s64) = G_UBFX %0, %1(s32), %2 +... + +... +--- +name: test_ubfx_s32_svv +legalized: true + +body: | + bb.0.entry: + liveins: $sgpr0, $vgpr0, $vgpr1 + + ; CHECK-LABEL: name: test_ubfx_s32_svv + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s32) = COPY $sgpr0 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[COPY3:%[0-9]+]]:vgpr(s32) = COPY [[COPY]](s32) + ; CHECK: [[UBFX:%[0-9]+]]:vgpr(s32) = G_UBFX [[COPY3]], [[COPY1]](s32), [[COPY2]] + %0:_(s32) = COPY $sgpr0 + %1:_(s32) = COPY $vgpr0 + %2:_(s32) = COPY $vgpr1 + %3:_(s32) = G_UBFX %0, %1(s32), %2 +... + +--- +name: test_ubfx_s64_sss +legalized: true + +body: | + bb.0.entry: + liveins: $sgpr0_sgpr1, $sgpr2, $sgpr3 + + ; CHECK-LABEL: name: test_ubfx_s64_sss + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s32) = COPY $sgpr2 + ; CHECK: [[COPY2:%[0-9]+]]:sgpr(s32) = COPY $sgpr3 + ; CHECK: [[UBFX:%[0-9]+]]:sgpr(s64) = G_UBFX [[COPY]], [[COPY1]](s32), [[COPY2]] + %0:_(s64) = COPY $sgpr0_sgpr1 + %1:_(s32) = COPY $sgpr2 + %2:_(s32) = COPY $sgpr3 + %3:_(s64) = G_UBFX %0, %1(s32), %2 +... + +--- +name: test_ubfx_s64_svv +legalized: true + +body: | + bb.0.entry: + liveins: $sgpr0_sgpr1, $vgpr0, $vgpr1 + + ; CHECK-LABEL: name: test_ubfx_s64_svv + ; CHECK: [[COPY:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s32) = COPY $vgpr0 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s32) = COPY $vgpr1 + ; CHECK: [[COPY3:%[0-9]+]]:vgpr(s64) = COPY [[COPY]](s64) + ; CHECK: [[UBFX:%[0-9]+]]:vgpr(s64) = G_UBFX [[COPY3]], [[COPY1]](s32), [[COPY2]] + %0:_(s64) = COPY $sgpr0_sgpr1 + %1:_(s32) = COPY $vgpr0 + %2:_(s32) = COPY $vgpr1 + %3:_(s64) = G_UBFX %0, %1(s32), %2 +...