[llvm] [AMDGPU] Fix i64 amdgcn.ubfe/sbfe lowering crash (PR #217461)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 19 13:56:52 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Arseniy Obolenskiy (aobolensk)
<details>
<summary>Changes</summary>
- BFE_I32/BFE_U32 are 32-bit only
- wider widths now expand to shifts
---
Patch is 20.34 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/217461.diff
4 Files Affected:
- (modified) llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp (+2-2)
- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.cpp (+52-4)
- (modified) llvm/test/CodeGen/AMDGPU/llvm.amdgcn.sbfe.ll (+137)
- (modified) llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ubfe.ll (+327)
``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 3f93ca66dca17..3d4b3dac7520f 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -5676,8 +5676,8 @@ SDValue AMDGPUTargetLowering::PerformDAGCombine(SDNode *N,
return performFAbsCombine(N, DCI);
case AMDGPUISD::BFE_I32:
case AMDGPUISD::BFE_U32: {
- assert(!N->getValueType(0).isVector() &&
- "Vector handling of BFE not implemented");
+ assert(N->getValueType(0) == MVT::i32 &&
+ "BFE_I32/BFE_U32 is a 32-bit operation");
ConstantSDNode *Width = dyn_cast<ConstantSDNode>(N->getOperand(2));
if (!Width)
break;
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index f9943c6208656..c0b3e3d3cfe2e 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -8059,6 +8059,57 @@ static SDValue lowerBALLOTIntrinsic(const SITargetLowering &TLI, SDNode *N,
DAG.getConstant(0, SL, MVT::i32), DAG.getCondCode(ISD::SETNE));
}
+static SDValue lowerBFEIntrinsic(SDValue Op, SelectionDAG &DAG, bool Signed) {
+ SDLoc DL(Op);
+ EVT VT = Op.getValueType();
+ SDValue Src = Op.getOperand(1);
+ SDValue Offset = Op.getOperand(2);
+ SDValue Width = Op.getOperand(3);
+
+ if (VT == MVT::i32)
+ return DAG.getNode(Signed ? AMDGPUISD::BFE_I32 : AMDGPUISD::BFE_U32, DL, VT,
+ Src, Offset, Width);
+
+ assert(!VT.isVector() && "Vector handling of BFE not implemented");
+
+ auto *CWidth = dyn_cast<ConstantSDNode>(Width);
+ if (CWidth && CWidth->getZExtValue() == 0)
+ return DAG.getConstant(0, DL, VT);
+
+ // BFE_I32/BFE_U32 are 32-bit only; expand wider extracts into shifts. Mask
+ // a constant offset explicitly so the shift below doesn't fold to poison.
+ unsigned Size = VT.getSizeInBits();
+ unsigned ShrOpc = Signed ? ISD::SRA : ISD::SRL;
+ if (auto *COffset = dyn_cast<ConstantSDNode>(Offset))
+ Offset =
+ DAG.getConstant(COffset->getZExtValue() & (Size - 1), DL, MVT::i32);
+
+ SDValue Shift = DAG.getNode(ShrOpc, DL, VT, Src, Offset);
+
+ if (CWidth) {
+ uint64_t WidthVal = CWidth->getZExtValue();
+
+ // S_BFE_{I,U}64's width field is 7 bits; a full-width value needs no mask.
+ if (WidthVal >= Size)
+ return Shift;
+
+ EVT WidthVT = EVT::getIntegerVT(*DAG.getContext(), WidthVal);
+ if (Signed)
+ return DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, Shift,
+ DAG.getValueType(WidthVT));
+ return DAG.getZeroExtendInReg(Shift, DL, WidthVT);
+ }
+
+ // Select handles Width == 0: a shift amount of Size wraps to a shift by 0
+ // on hardware, so the shifts alone would wrongly return Src >> Offset.
+ SDValue ExtShift = DAG.getNode(ISD::SUB, DL, MVT::i32,
+ DAG.getConstant(Size, DL, MVT::i32), Width);
+ SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, Shift, ExtShift);
+ SDValue Ext = DAG.getNode(ShrOpc, DL, VT, Shl, ExtShift);
+ return DAG.getSelectCC(DL, Width, DAG.getConstant(0, DL, MVT::i32),
+ DAG.getConstant(0, DL, VT), Ext, ISD::SETEQ);
+}
+
static SDValue emitRemovedIntrinsicError(SelectionDAG &DAG, const SDLoc &DL,
EVT VT);
@@ -11459,11 +11510,8 @@ SDValue SITargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
return DAG.getNode(AMDGPUISD::FMUL_LEGACY, DL, VT, Op.getOperand(1),
Op.getOperand(2));
case Intrinsic::amdgcn_sbfe:
- return DAG.getNode(AMDGPUISD::BFE_I32, DL, VT, Op.getOperand(1),
- Op.getOperand(2), Op.getOperand(3));
case Intrinsic::amdgcn_ubfe:
- return DAG.getNode(AMDGPUISD::BFE_U32, DL, VT, Op.getOperand(1),
- Op.getOperand(2), Op.getOperand(3));
+ return lowerBFEIntrinsic(Op, DAG, IntrinsicID == Intrinsic::amdgcn_sbfe);
case Intrinsic::amdgcn_cvt_pkrtz:
case Intrinsic::amdgcn_cvt_pknorm_i16:
case Intrinsic::amdgcn_cvt_pknorm_u16:
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.sbfe.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.sbfe.ll
index f2274e3eef31e..412e8209e2d06 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.sbfe.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.sbfe.ll
@@ -590,6 +590,143 @@ define amdgpu_kernel void @bfe_i32_width_32(ptr addrspace(1) %out) #0 {
ret void
}
+; GCN-LABEL: {{^}}v_sbfe_i64_width_0:
+; GCN-DAG: v_mov_b32_e32 v0, 0
+; GCN-DAG: v_mov_b32_e32 v1, 0
+define i64 @v_sbfe_i64_width_0(i64 %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 0)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}v_sbfe_i64_width_31:
+; GCN: v_lshl{{(rev)?}}_b64 v[0:1], {{.*}}25
+; GCN-NEXT: v_ashrrev_i32_e32 v0, 1, v1
+; GCN-NEXT: v_ashrrev_i32_e32 v1, 31, v1
+define i64 @v_sbfe_i64_width_31(i64 %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 31)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}v_sbfe_i64_width_32:
+; GCN: v_lshr{{(rev)?}}_b64 v[2:3], {{.*}}8
+; GCN-NEXT: v_alignbit_b32 v0, v1, v0, 8
+; GCN-NEXT: v_ashrrev_i32_e32 v2, 31, v2
+; GCN-NEXT: v_mov_b32_e32 v1, v2
+define i64 @v_sbfe_i64_width_32(i64 %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 32)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}v_sbfe_i64_width_33:
+; GCN: v_lshl{{(rev)?}}_b64 v[0:1], {{.*}}23
+; GCN-NEXT: v_ashr{{(rev)?}}_i64 v[0:1], {{.*}}31
+define i64 @v_sbfe_i64_width_33(i64 %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 33)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}v_sbfe_i64_width_63:
+; GCN: v_ashr{{(rev)?}}_i64 v[0:1], {{.*}}8
+define i64 @v_sbfe_i64_width_63(i64 %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 63)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}v_sbfe_i64_width_64:
+; GCN: v_ashr{{(rev)?}}_i64 v[0:1], {{.*}}8
+define i64 @v_sbfe_i64_width_64(i64 %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 64)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}s_sbfe_i64_width_0:
+; GCN-DAG: v_mov_b32_e32 v0, 0
+; GCN-DAG: v_mov_b32_e32 v1, 0
+define i64 @s_sbfe_i64_width_0(i64 inreg %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 0)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}s_sbfe_i64_width_31:
+; GCN: s_lshl_b64 s[4:5], s[16:17], 25
+; GCN-NEXT: s_ashr_i32 s4, s5, 1
+; GCN-NEXT: s_ashr_i32 s5, s5, 31
+define i64 @s_sbfe_i64_width_31(i64 inreg %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 31)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}s_sbfe_i64_width_32:
+; GCN: s_lshr_b64 s[4:5], s[16:17], 8
+; GCN-NEXT: s_bfe_i64 s[6:7], s[4:5], 0x200000
+; GCN-NEXT: v_mov_b32_e32 v0, s4
+; GCN-NEXT: v_mov_b32_e32 v1, s7
+define i64 @s_sbfe_i64_width_32(i64 inreg %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 32)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}s_sbfe_i64_width_33:
+; GCN: s_lshl_b64 s[4:5], s[16:17], 23
+; GCN-NEXT: s_ashr_i64 s[4:5], s[4:5], 31
+define i64 @s_sbfe_i64_width_33(i64 inreg %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 33)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}s_sbfe_i64_width_63:
+; GCN: s_ashr_i64 s[4:5], s[16:17], 8
+define i64 @s_sbfe_i64_width_63(i64 inreg %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 63)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}s_sbfe_i64_width_64:
+; GCN: s_ashr_i64 s[4:5], s[16:17], 8
+define i64 @s_sbfe_i64_width_64(i64 inreg %src) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 64)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}v_sbfe_i64_arg_width:
+; GCN: v_ashr{{(rev)?}}_i64 v[0:1], {{.*}}8
+; GCN: v_sub_{{[iu]}}32_e32 v3, vcc, 64, v2
+; GCN: v_lshl{{(rev)?}}_b64 v[0:1],
+; GCN: v_cmp_eq_u32_e32 vcc, 0, v2
+; GCN: v_ashr{{(rev)?}}_i64 v[0:1],
+; GCN: v_cndmask_b32_e64 v0, v0, 0, vcc
+; GCN-NEXT: v_cndmask_b32_e64 v1, v1, 0, vcc
+define i64 @v_sbfe_i64_arg_width(i64 %src, i32 %width) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 %width)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}v_sbfe_i64_arg_offset_arg_width:
+; GCN: v_ashr{{(rev)?}}_i64 v[0:1], {{.*}}v2
+; GCN: v_sub_{{[iu]}}32_e32 v2, vcc, 64, v3
+; GCN: v_lshl{{(rev)?}}_b64 v[0:1],
+; GCN: v_cmp_eq_u32_e32 vcc, 0, v3
+; GCN: v_ashr{{(rev)?}}_i64 v[0:1],
+; GCN: v_cndmask_b32_e64 v0, v0, 0, vcc
+; GCN-NEXT: v_cndmask_b32_e64 v1, v1, 0, vcc
+define i64 @v_sbfe_i64_arg_offset_arg_width(i64 %src, i32 %offset, i32 %width) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 %offset, i32 %width)
+ ret i64 %bfe
+}
+
+; GCN-LABEL: {{^}}s_sbfe_i64_arg_width:
+; GCN-DAG: s_sub_i32 s6, 64, s18
+; GCN-DAG: s_ashr_i64 s[4:5], s[16:17], 8
+; GCN: s_lshl_b64 s[4:5], s[4:5], s6
+; GCN-NEXT: s_ashr_i64 s[4:5], s[4:5], s6
+; GCN-NEXT: s_cmp_eq_u32 s18, 0
+; GCN-NEXT: s_cselect_b32 s4, 0, s4
+; GCN-NEXT: s_cselect_b32 s5, 0, s5
+define i64 @s_sbfe_i64_arg_width(i64 inreg %src, i32 inreg %width) {
+ %bfe = call i64 @llvm.amdgcn.sbfe.i64(i64 %src, i32 8, i32 %width)
+ ret i64 %bfe
+}
+
declare i32 @llvm.amdgcn.sbfe.i32(i32, i32, i32) #1
attributes #0 = { nounwind }
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ubfe.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ubfe.ll
index 44acba7be3d14..7bf7006944ce4 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ubfe.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.ubfe.ll
@@ -1810,3 +1810,330 @@ define amdgpu_kernel void @bfe_u32_offset_0_width_24_ashr(ptr addrspace(1) %out,
store i32 %bfe, ptr addrspace(1) %out, align 4
ret void
}
+
+define i64 @v_ubfe_i64_width_0(i64 %src) {
+; SI-LABEL: v_ubfe_i64_width_0:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: v_mov_b32_e32 v0, 0
+; SI-NEXT: v_mov_b32_e32 v1, 0
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: v_ubfe_i64_width_0:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: v_mov_b32_e32 v0, 0
+; VI-NEXT: v_mov_b32_e32 v1, 0
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 0)
+ ret i64 %bfe
+}
+
+define i64 @v_ubfe_i64_width_31(i64 %src) {
+; SI-LABEL: v_ubfe_i64_width_31:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: v_alignbit_b32 v0, v1, v0, 8
+; SI-NEXT: v_and_b32_e32 v0, 0x7fffffff, v0
+; SI-NEXT: v_mov_b32_e32 v1, 0
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: v_ubfe_i64_width_31:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: v_alignbit_b32 v0, v1, v0, 8
+; VI-NEXT: v_and_b32_e32 v0, 0x7fffffff, v0
+; VI-NEXT: v_mov_b32_e32 v1, 0
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 31)
+ ret i64 %bfe
+}
+
+define i64 @v_ubfe_i64_width_32(i64 %src) {
+; SI-LABEL: v_ubfe_i64_width_32:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: v_alignbit_b32 v0, v1, v0, 8
+; SI-NEXT: v_mov_b32_e32 v1, 0
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: v_ubfe_i64_width_32:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: v_alignbit_b32 v0, v1, v0, 8
+; VI-NEXT: v_mov_b32_e32 v1, 0
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 32)
+ ret i64 %bfe
+}
+
+define i64 @v_ubfe_i64_width_33(i64 %src) {
+;
+; SI-LABEL: v_ubfe_i64_width_33:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: v_lshr_b64 v[0:1], v[0:1], 8
+; SI-NEXT: v_and_b32_e32 v1, 1, v1
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: v_ubfe_i64_width_33:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: v_lshrrev_b64 v[0:1], 8, v[0:1]
+; VI-NEXT: v_and_b32_e32 v1, 1, v1
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 33)
+ ret i64 %bfe
+}
+
+define i64 @v_ubfe_i64_width_63(i64 %src) {
+; SI-LABEL: v_ubfe_i64_width_63:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: v_alignbit_b32 v0, v1, v0, 8
+; SI-NEXT: v_lshrrev_b32_e32 v1, 8, v1
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: v_ubfe_i64_width_63:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: v_alignbit_b32 v0, v1, v0, 8
+; VI-NEXT: v_lshrrev_b32_e32 v1, 8, v1
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 63)
+ ret i64 %bfe
+}
+
+define i64 @v_ubfe_i64_width_64(i64 %src) {
+; SI-LABEL: v_ubfe_i64_width_64:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: v_alignbit_b32 v0, v1, v0, 8
+; SI-NEXT: v_lshrrev_b32_e32 v1, 8, v1
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: v_ubfe_i64_width_64:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: v_alignbit_b32 v0, v1, v0, 8
+; VI-NEXT: v_lshrrev_b32_e32 v1, 8, v1
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 64)
+ ret i64 %bfe
+}
+
+define i64 @s_ubfe_i64_width_0(i64 inreg %src) {
+; SI-LABEL: s_ubfe_i64_width_0:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: v_mov_b32_e32 v0, 0
+; SI-NEXT: v_mov_b32_e32 v1, 0
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: s_ubfe_i64_width_0:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: v_mov_b32_e32 v0, 0
+; VI-NEXT: v_mov_b32_e32 v1, 0
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 0)
+ ret i64 %bfe
+}
+
+define i64 @s_ubfe_i64_width_31(i64 inreg %src) {
+; SI-LABEL: s_ubfe_i64_width_31:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; SI-NEXT: s_bitset0_b32 s4, 31
+; SI-NEXT: v_mov_b32_e32 v0, s4
+; SI-NEXT: v_mov_b32_e32 v1, 0
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: s_ubfe_i64_width_31:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; VI-NEXT: s_bitset0_b32 s4, 31
+; VI-NEXT: v_mov_b32_e32 v0, s4
+; VI-NEXT: v_mov_b32_e32 v1, 0
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 31)
+ ret i64 %bfe
+}
+
+define i64 @s_ubfe_i64_width_32(i64 inreg %src) {
+; SI-LABEL: s_ubfe_i64_width_32:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; SI-NEXT: v_mov_b32_e32 v0, s4
+; SI-NEXT: v_mov_b32_e32 v1, 0
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: s_ubfe_i64_width_32:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; VI-NEXT: v_mov_b32_e32 v0, s4
+; VI-NEXT: v_mov_b32_e32 v1, 0
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 32)
+ ret i64 %bfe
+}
+
+define i64 @s_ubfe_i64_width_33(i64 inreg %src) {
+; SI-LABEL: s_ubfe_i64_width_33:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; SI-NEXT: s_and_b32 s5, s5, 1
+; SI-NEXT: v_mov_b32_e32 v0, s4
+; SI-NEXT: v_mov_b32_e32 v1, s5
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: s_ubfe_i64_width_33:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; VI-NEXT: s_and_b32 s5, s5, 1
+; VI-NEXT: v_mov_b32_e32 v0, s4
+; VI-NEXT: v_mov_b32_e32 v1, s5
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 33)
+ ret i64 %bfe
+}
+
+define i64 @s_ubfe_i64_width_63(i64 inreg %src) {
+; SI-LABEL: s_ubfe_i64_width_63:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; SI-NEXT: s_lshr_b32 s5, s17, 8
+; SI-NEXT: v_mov_b32_e32 v0, s4
+; SI-NEXT: v_mov_b32_e32 v1, s5
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: s_ubfe_i64_width_63:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; VI-NEXT: s_lshr_b32 s5, s17, 8
+; VI-NEXT: v_mov_b32_e32 v0, s4
+; VI-NEXT: v_mov_b32_e32 v1, s5
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 63)
+ ret i64 %bfe
+}
+
+define i64 @s_ubfe_i64_width_64(i64 inreg %src) {
+; SI-LABEL: s_ubfe_i64_width_64:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; SI-NEXT: s_lshr_b32 s5, s17, 8
+; SI-NEXT: v_mov_b32_e32 v0, s4
+; SI-NEXT: v_mov_b32_e32 v1, s5
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: s_ubfe_i64_width_64:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; VI-NEXT: s_lshr_b32 s5, s17, 8
+; VI-NEXT: v_mov_b32_e32 v0, s4
+; VI-NEXT: v_mov_b32_e32 v1, s5
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 64)
+ ret i64 %bfe
+}
+
+define i64 @v_ubfe_i64_arg_width(i64 %src, i32 %width) {
+;
+; SI-LABEL: v_ubfe_i64_arg_width:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: v_lshr_b64 v[0:1], v[0:1], 8
+; SI-NEXT: v_sub_i32_e32 v3, vcc, 64, v2
+; SI-NEXT: v_lshl_b64 v[0:1], v[0:1], v3
+; SI-NEXT: v_cmp_eq_u32_e32 vcc, 0, v2
+; SI-NEXT: v_lshr_b64 v[0:1], v[0:1], v3
+; SI-NEXT: v_cndmask_b32_e64 v0, v0, 0, vcc
+; SI-NEXT: v_cndmask_b32_e64 v1, v1, 0, vcc
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: v_ubfe_i64_arg_width:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: v_lshrrev_b64 v[0:1], 8, v[0:1]
+; VI-NEXT: v_sub_u32_e32 v3, vcc, 64, v2
+; VI-NEXT: v_lshlrev_b64 v[0:1], v3, v[0:1]
+; VI-NEXT: v_cmp_eq_u32_e32 vcc, 0, v2
+; VI-NEXT: v_lshrrev_b64 v[0:1], v3, v[0:1]
+; VI-NEXT: v_cndmask_b32_e64 v0, v0, 0, vcc
+; VI-NEXT: v_cndmask_b32_e64 v1, v1, 0, vcc
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 8, i32 %width)
+ ret i64 %bfe
+}
+
+define i64 @v_ubfe_i64_arg_offset_arg_width(i64 %src, i32 %offset, i32 %width) {
+;
+; SI-LABEL: v_ubfe_i64_arg_offset_arg_width:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: v_lshr_b64 v[0:1], v[0:1], v2
+; SI-NEXT: v_sub_i32_e32 v2, vcc, 64, v3
+; SI-NEXT: v_lshl_b64 v[0:1], v[0:1], v2
+; SI-NEXT: v_cmp_eq_u32_e32 vcc, 0, v3
+; SI-NEXT: v_lshr_b64 v[0:1], v[0:1], v2
+; SI-NEXT: v_cndmask_b32_e64 v0, v0, 0, vcc
+; SI-NEXT: v_cndmask_b32_e64 v1, v1, 0, vcc
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: v_ubfe_i64_arg_offset_arg_width:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: v_lshrrev_b64 v[0:1], v2, v[0:1]
+; VI-NEXT: v_sub_u32_e32 v2, vcc, 64, v3
+; VI-NEXT: v_lshlrev_b64 v[0:1], v2, v[0:1]
+; VI-NEXT: v_cmp_eq_u32_e32 vcc, 0, v3
+; VI-NEXT: v_lshrrev_b64 v[0:1], v2, v[0:1]
+; VI-NEXT: v_cndmask_b32_e64 v0, v0, 0, vcc
+; VI-NEXT: v_cndmask_b32_e64 v1, v1, 0, vcc
+; VI-NEXT: s_setpc_b64 s[30:31]
+ %bfe = call i64 @llvm.amdgcn.ubfe.i64(i64 %src, i32 %offset, i32 %width)
+ ret i64 %bfe
+}
+
+define i64 @s_ubfe_i64_arg_width(i64 inreg %src, i32 inreg %width) {
+; SI-LABEL: s_ubfe_i64_arg_width:
+; SI: ; %bb.0:
+; SI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; SI-NEXT: s_sub_i32 s6, 64, s18
+; SI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; SI-NEXT: s_lshl_b64 s[4:5], s[4:5], s6
+; SI-NEXT: s_lshr_b64 s[4:5], s[4:5], s6
+; SI-NEXT: s_cmp_eq_u32 s18, 0
+; SI-NEXT: s_cselect_b32 s4, 0, s4
+; SI-NEXT: s_cselect_b32 s5, 0, s5
+; SI-NEXT: v_mov_b32_e32 v0, s4
+; SI-NEXT: v_mov_b32_e32 v1, s5
+; SI-NEXT: s_setpc_b64 s[30:31]
+;
+; VI-LABEL: s_ubfe_i64_arg_width:
+; VI: ; %bb.0:
+; VI-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; VI-NEXT: s_sub_i32 s6, 64, s18
+; VI-NEXT: s_lshr_b64 s[4:5], s[16:17], 8
+; VI-NEXT: s_lshl_b64 s[4:5], s[4:5], s6
+;...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/217461
More information about the llvm-commits
mailing list