[llvm] 869be01 - [AMDGPU] Diagnose unsupported permlane16/mov.dpp8/tanh intrinsics (#200585)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 3 04:17:22 PDT 2026
Author: Arseniy Obolenskiy
Date: 2026-06-03T13:17:16+02:00
New Revision: 869be014cf9a02f26ad938cc40fa83dfb62e90f9
URL: https://github.com/llvm/llvm-project/commit/869be014cf9a02f26ad938cc40fa83dfb62e90f9
DIFF: https://github.com/llvm/llvm-project/commit/869be014cf9a02f26ad938cc40fa83dfb62e90f9.diff
LOG: [AMDGPU] Diagnose unsupported permlane16/mov.dpp8/tanh intrinsics (#200585)
Added:
Modified:
llvm/lib/Target/AMDGPU/AMDGPU.td
llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
llvm/lib/Target/AMDGPU/GCNSubtarget.h
llvm/lib/Target/AMDGPU/SIISelLowering.cpp
llvm/lib/Target/AMDGPU/VOP3Instructions.td
llvm/test/CodeGen/AMDGPU/llvm.amdgcn.mov.dpp8.ll
llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane.ll
llvm/test/CodeGen/AMDGPU/llvm.amdgcn.tanh.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td
index 73321dabf4af2..dbd3ca23dbdd3 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -430,6 +430,10 @@ defm GFX940Insts : AMDGPUSubtargetFeature<"gfx940-insts",
/*GenPredicate=*/0
>;
+defm Permlane16Insts : AMDGPUSubtargetFeature<"permlane16-insts",
+ "Has v_permlane16_b32/v_permlanex16_b32 instructions"
+>;
+
defm Permlane16Swap : AMDGPUSubtargetFeature<"permlane16-swap",
"Has v_permlane16_swap_b32 instructions"
>;
@@ -1494,6 +1498,7 @@ def FeatureGFX10 : GCNSubtargetFeatureGeneration<"GFX10",
FeatureAddNoCarryInsts, FeatureFmaMixInsts, FeatureGFX8Insts,
FeatureNoSdstCMPX, FeatureVscnt,
FeatureVOP3Literal, FeatureDPP8, FeatureExtendedImageInsts,
+ FeaturePermlane16Insts,
FeatureNoDataDepHazard, FeaturePkFmacF16Inst,
FeatureA16, FeatureSMemTimeInst, FeatureFastDenormalF32, FeatureG16,
FeatureUnalignedBufferAccess, FeatureUnalignedScratchAccess,
@@ -1523,6 +1528,7 @@ def FeatureGFX11 : GCNSubtargetFeatureGeneration<"GFX11",
FeatureAddNoCarryInsts, FeatureFmaMixInsts,
FeatureNoSdstCMPX, FeatureVscnt,
FeatureVOP3Literal, FeatureDPP8, FeatureExtendedImageInsts,
+ FeaturePermlane16Insts,
FeatureNoDataDepHazard, FeaturePkFmacF16Inst,
FeatureA16, FeatureFastDenormalF32, FeatureG16,
FeatureUnalignedBufferAccess, FeatureUnalignedScratchAccess,
@@ -1550,6 +1556,7 @@ def FeatureGFX12 : GCNSubtargetFeatureGeneration<"GFX12",
FeatureAddNoCarryInsts, FeatureFmaMixInsts,
FeatureNoSdstCMPX, FeatureVscnt,
FeatureVOP3Literal, FeatureDPP8,
+ FeaturePermlane16Insts,
FeatureNoDataDepHazard, FeaturePkFmacF16Inst,
FeatureA16, FeatureFastDenormalF32, FeatureG16,
FeatureUnalignedBufferAccess, FeatureUnalignedScratchAccess,
@@ -1576,6 +1583,7 @@ def FeatureGFX13 : GCNSubtargetFeatureGeneration<"GFX13",
FeatureAddNoCarryInsts, FeatureFmaMixInsts,
FeatureNoSdstCMPX, FeatureVscnt,
FeatureVOP3Literal, FeatureDPP8,
+ FeaturePermlane16Insts,
FeatureNoDataDepHazard, FeaturePkFmacF16Inst,
FeatureA16, FeatureFastDenormalF32, FeatureG16,
FeatureUnalignedBufferAccess, FeatureUnalignedScratchAccess, FeatureImageInsts,
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
index a4029fb79b49a..cf4c2bbc78359 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
@@ -402,7 +402,7 @@ Value *AMDGPUAtomicOptimizerImpl::buildReduction(IRBuilder<> &B,
}
// Reduce within each pair of rows (i.e. 32 lanes).
- assert(ST.hasPermLaneX16());
+ assert(ST.hasPermlane16Insts());
Value *Permlanex16Call =
B.CreateIntrinsic(AtomicTy, Intrinsic::amdgcn_permlanex16,
{PoisonValue::get(AtomicTy), V, B.getInt32(0),
@@ -463,7 +463,7 @@ Value *AMDGPUAtomicOptimizerImpl::buildScan(IRBuilder<> &B,
// Combine lane 15 into lanes 16..31 (and, for wave 64, lane 47 into lanes
// 48..63).
- assert(ST.hasPermLaneX16());
+ assert(ST.hasPermlane16Insts());
Value *PermX =
B.CreateIntrinsic(AtomicTy, Intrinsic::amdgcn_permlanex16,
{PoisonValue::get(AtomicTy), V, B.getInt32(-1),
@@ -738,7 +738,7 @@ void AMDGPUAtomicOptimizerImpl::optimizeAtomic(Instruction &I,
// that they can correctly contribute to the final result.
NewV =
B.CreateIntrinsic(Intrinsic::amdgcn_set_inactive, Ty, {V, Identity});
- if (!NeedResult && ST.hasPermLaneX16()) {
+ if (!NeedResult && ST.hasPermlane16Insts()) {
// On GFX10 the permlanex16 instruction helps us build a reduction
// without too many readlanes and writelanes, which are generally bad
// for performance.
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
index b288f30d8c291..2370c379e75f5 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -987,7 +987,7 @@ static Value *matchShuffleToHWIntrinsic(IRBuilderBase &B, Value *Src,
return createMovDpp8(B, Src, *Sel);
}
- if (ST.hasPermLaneX16()) {
+ if (ST.hasPermlane16Insts()) {
if (isFullRowPattern(Ids)) {
uint64_t Sel = computePermlane16Masks(Ids);
return createPermlane16(B, Src, Lo_32(Sel), Hi_32(Sel));
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
index ba5e5f4e38902..da46e3e9685a2 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
@@ -1298,6 +1298,25 @@ bool AMDGPUInstructionSelector::selectG_INTRINSIC(MachineInstr &I) const {
return false;
}
return selectImpl(I, *CoverageInfo);
+ case Intrinsic::amdgcn_permlane16:
+ case Intrinsic::amdgcn_permlanex16:
+ if (!STI.hasPermlane16Insts()) {
+ diagnoseUnsupportedIntrinsic(I);
+ return false;
+ }
+ return selectImpl(I, *CoverageInfo);
+ case Intrinsic::amdgcn_mov_dpp8:
+ if (!STI.hasDPP8()) {
+ diagnoseUnsupportedIntrinsic(I);
+ return false;
+ }
+ return selectImpl(I, *CoverageInfo);
+ case Intrinsic::amdgcn_tanh:
+ if (!STI.hasTanhInsts()) {
+ diagnoseUnsupportedIntrinsic(I);
+ return false;
+ }
+ return selectImpl(I, *CoverageInfo);
default:
return selectImpl(I, *CoverageInfo);
}
diff --git a/llvm/lib/Target/AMDGPU/GCNSubtarget.h b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
index b817a79f4c226..082c5c33d6067 100644
--- a/llvm/lib/Target/AMDGPU/GCNSubtarget.h
+++ b/llvm/lib/Target/AMDGPU/GCNSubtarget.h
@@ -510,9 +510,6 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
return HasGFX90AInsts || HasGFX1250Insts;
}
- /// \returns true if the subtarget has the v_permlanex16_b32 instruction.
- bool hasPermLaneX16() const { return getGeneration() >= GFX10; }
-
/// \returns true if the subtarget has the v_permlane64_b32 instruction.
bool hasPermLane64() const { return getGeneration() >= GFX11; }
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 50bde737912af..bb8942afe0832 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -7876,6 +7876,9 @@ static SDValue lowerBALLOTIntrinsic(const SITargetLowering &TLI, SDNode *N,
DAG.getConstant(0, SL, MVT::i32), DAG.getCondCode(ISD::SETNE));
}
+static SDValue emitRemovedIntrinsicError(SelectionDAG &DAG, const SDLoc &DL,
+ EVT VT);
+
static SDValue lowerLaneOp(const SITargetLowering &TLI, SDNode *N,
SelectionDAG &DAG) {
EVT VT = N->getValueType(0);
@@ -7892,6 +7895,11 @@ static SDValue lowerLaneOp(const SITargetLowering &TLI, SDNode *N,
SDLoc SL(N);
MVT IntVT = MVT::getIntegerVT(ValSize);
const GCNSubtarget *ST = TLI.getSubtarget();
+
+ if ((IsPermLane16 && !ST->hasPermlane16Insts()) ||
+ (IID == Intrinsic::amdgcn_mov_dpp8 && !ST->hasDPP8()))
+ return emitRemovedIntrinsicError(DAG, SL, VT);
+
unsigned SplitSize = 32;
if (IID == Intrinsic::amdgcn_update_dpp && (ValSize % 64 == 0) &&
ST->hasDPALU_DPP() &&
@@ -10781,6 +10789,10 @@ SDValue SITargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
if (!Subtarget->hasDot8Insts())
return emitRemovedIntrinsicError(DAG, DL, VT);
return SDValue();
+ case Intrinsic::amdgcn_tanh:
+ if (!Subtarget->hasTanhInsts())
+ return emitRemovedIntrinsicError(DAG, DL, VT);
+ return SDValue();
case Intrinsic::amdgcn_rsq_clamp: {
if (Subtarget->getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS)
return DAG.getNode(AMDGPUISD::RSQ_CLAMP, DL, VT, Op.getOperand(1));
diff --git a/llvm/lib/Target/AMDGPU/VOP3Instructions.td b/llvm/lib/Target/AMDGPU/VOP3Instructions.td
index 150da320e9c2c..f2a2f2b3a2499 100644
--- a/llvm/lib/Target/AMDGPU/VOP3Instructions.td
+++ b/llvm/lib/Target/AMDGPU/VOP3Instructions.td
@@ -1561,15 +1561,17 @@ let SubtargetPredicate = isGFX10Plus in {
} // End isCommutable = 1, isReMaterializable = 1
def : ThreeOp_i32_Pats<xor, xor, V_XOR3_B32_e64>;
- let Constraints = "$vdst = $vdst_in", isConvergent = 1 in {
- defm V_PERMLANE16_B32 : VOP3Inst<"v_permlane16_b32", VOP3_PERMLANE_Profile>;
- defm V_PERMLANEX16_B32 : VOP3Inst<"v_permlanex16_b32", VOP3_PERMLANE_Profile>;
- } // End $vdst = $vdst_in, isConvergent = 1
-
- foreach vt = Reg32Types.types in {
- def : PermlanePat<int_amdgcn_permlane16, V_PERMLANE16_B32_e64, vt>;
- def : PermlanePat<int_amdgcn_permlanex16, V_PERMLANEX16_B32_e64, vt>;
- }
+ let SubtargetPredicate = HasPermlane16Insts in {
+ let Constraints = "$vdst = $vdst_in", isConvergent = 1 in {
+ defm V_PERMLANE16_B32 : VOP3Inst<"v_permlane16_b32", VOP3_PERMLANE_Profile>;
+ defm V_PERMLANEX16_B32 : VOP3Inst<"v_permlanex16_b32", VOP3_PERMLANE_Profile>;
+ } // End $vdst = $vdst_in, isConvergent = 1
+
+ foreach vt = Reg32Types.types in {
+ def : PermlanePat<int_amdgcn_permlane16, V_PERMLANE16_B32_e64, vt>;
+ def : PermlanePat<int_amdgcn_permlanex16, V_PERMLANEX16_B32_e64, vt>;
+ }
+ } // End SubtargetPredicate = HasPermlane16Insts
let isCommutable = 1 in {
defm V_ADD_NC_U16 : VOP3Inst_t16 <"v_add_nc_u16", VOP_I16_I16_I16, add>;
} // End isCommutable = 1
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.mov.dpp8.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.mov.dpp8.ll
index e7d8683137dd5..cf8c681df6d5a 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.mov.dpp8.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.mov.dpp8.ll
@@ -5,6 +5,11 @@
; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1200 -amdgpu-enable-vopd=0 < %s | FileCheck -check-prefix=GFX10PLUS %s
; RUN: llc -global-isel=1 -global-isel-abort=2 -mtriple=amdgcn -mcpu=gfx1200 -amdgpu-enable-vopd=0 < %s | FileCheck -check-prefix=GFX10PLUS %s
+; RUN: not llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx900 -filetype=null < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -global-isel=1 -global-isel-abort=0 -mtriple=amdgcn -mcpu=gfx900 -filetype=null < %s 2>&1 | FileCheck -check-prefix=ERR %s
+
+; ERR: error: <unknown>:0:0: in function dpp8_test void (ptr addrspace(1), i32): intrinsic not supported on subtarget
+
; GFX10PLUS-LABEL: {{^}}dpp8_test:
; GFX10PLUS: v_mov_b32_e32 [[SRC:v[0-9]+]], s{{[0-9]+}}
; GFX10PLUS: v_mov_b32_dpp [[SRC]], [[SRC]] dpp8:[1,0,0,0,0,0,0,0]{{$}}
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane.ll
index ed3d57d9fbda0..384875ebaf60f 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane.ll
@@ -8,6 +8,11 @@
; RUN: llc -global-isel=0 -amdgpu-load-store-vectorizer=0 -mtriple=amdgcn -mcpu=gfx1310 < %s | FileCheck -check-prefixes=GFX13,GFX13-SDAG %s
; RUN: llc -global-isel=1 -new-reg-bank-select -global-isel-abort=2 -amdgpu-load-store-vectorizer=0 -mtriple=amdgcn -mcpu=gfx1310 < %s | FileCheck -check-prefixes=GFX13,GFX13-GISEL %s
+; RUN: not llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx900 -filetype=null < %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -global-isel=1 -global-isel-abort=0 -mtriple=amdgcn -mcpu=gfx900 -filetype=null < %s 2>&1 | FileCheck -check-prefix=ERR %s
+
+; ERR: error: <unknown>:0:0: in function v_permlane16_b32_vss_i32 void (ptr addrspace(1), i32, i32, i32): intrinsic not supported on subtarget
+
declare i32 @llvm.amdgcn.permlane16(i32, i32, i32, i32, i1, i1)
declare i32 @llvm.amdgcn.permlanex16(i32, i32, i32, i32, i1, i1)
declare i32 @llvm.amdgcn.workitem.id.x()
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.tanh.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.tanh.ll
index 77b3fff56bdec..9d6c5ea82c8ea 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.tanh.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.tanh.ll
@@ -8,6 +8,11 @@
; xUN: llc -global-isel=1 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1310 -mattr=+real-true16 %s -o - | FileCheck -check-prefixes=GFX13,GFX13-GISEL-REAL16 %s
; xUN: llc -global-isel=1 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1310 -mattr=-real-true16 %s -o - | FileCheck -check-prefixes=GFX13,GFX13-GISEL-FAKE16 %s
+; RUN: not llc -global-isel=0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
+; RUN: not llc -global-isel=1 -global-isel-abort=0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx950 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s
+
+; ERR: error: <unknown>:0:0: in function tanh_f32 void (ptr addrspace(1), float): intrinsic not supported on subtarget
+
; FIXME: GlobalISel does not work with bf16
declare float @llvm.amdgcn.tanh.f32(float) #0
More information about the llvm-commits
mailing list