[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