[llvm] [Verifier] Verify AMX tile-register index operands are in range (PR #204890)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 19 13:37:58 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: jofrn
<details>
<summary>Changes</summary>
AMX has 8 physical tile registers (TMM0-TMM7), so the tile-index operands
of the AMX intrinsics must be in [0, 8): operand 0 for the tile
load/store/zero intrinsics, operands 0-2 for the tdp* family.
---
Full diff: https://github.com/llvm/llvm-project/pull/204890.diff
2 Files Affected:
- (modified) llvm/lib/IR/Verifier.cpp (+24)
- (added) llvm/test/Verifier/x86-amx-tile-register-index.ll (+30)
``````````diff
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 48cfec0f55c41..2754fe49eef0a 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -99,6 +99,7 @@
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
+#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
#include "llvm/IR/Metadata.h"
@@ -7095,6 +7096,29 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
Call);
break;
}
+ case Intrinsic::x86_tilezero:
+ case Intrinsic::x86_tileloadd64:
+ case Intrinsic::x86_tileloaddt164:
+ case Intrinsic::x86_tilestored64: {
+ // AMX provides 8 physical tile registers, TMM0-TMM7; the leading immediate
+ // operand is a tile-register index and so must name one of them.
+ Check(cast<ConstantInt>(Call.getArgOperand(0))->getZExtValue() < 8,
+ "AMX tile register index must be in the range [0, 8)", Call);
+ break;
+ }
+ case Intrinsic::x86_tdpbssd:
+ case Intrinsic::x86_tdpbsud:
+ case Intrinsic::x86_tdpbusd:
+ case Intrinsic::x86_tdpbuud:
+ case Intrinsic::x86_tdpbf16ps:
+ case Intrinsic::x86_tdpfp16ps: {
+ // The destination and two source operands are each a tile-register index
+ // (TMM0-TMM7).
+ for (unsigned I : {0, 1, 2})
+ Check(cast<ConstantInt>(Call.getArgOperand(I))->getZExtValue() < 8,
+ "AMX tile register index must be in the range [0, 8)", Call);
+ break;
+ }
case Intrinsic::callbr_landingpad: {
const auto *CBR = dyn_cast<CallBrInst>(Call.getOperand(0));
Check(CBR, "intrinstic requires callbr operand", &Call);
diff --git a/llvm/test/Verifier/x86-amx-tile-register-index.ll b/llvm/test/Verifier/x86-amx-tile-register-index.ll
new file mode 100644
index 0000000000000..47b17e25ad589
--- /dev/null
+++ b/llvm/test/Verifier/x86-amx-tile-register-index.ll
@@ -0,0 +1,30 @@
+; RUN: not opt -passes=verify -S < %s 2>&1 | FileCheck %s
+
+; AMX exposes 8 physical tile registers (TMM0-TMM7), so a tile-register index
+; operand must be in the range [0, 8). This is a structural constraint on the
+; immediate operand and needs no subtarget information.
+
+declare void @llvm.x86.tilezero(i8 immarg)
+declare void @llvm.x86.tileloadd64(i8 immarg, ptr, i64)
+declare void @llvm.x86.tdpbssd(i8 immarg, i8 immarg, i8 immarg)
+
+define void @bad_tilezero() {
+; CHECK: AMX tile register index must be in the range [0, 8)
+ call void @llvm.x86.tilezero(i8 8)
+ ret void
+}
+
+; Only one of the three tile operands is out of range.
+define void @bad_tdpbssd() {
+; CHECK: AMX tile register index must be in the range [0, 8)
+ call void @llvm.x86.tdpbssd(i8 0, i8 1, i8 9)
+ ret void
+}
+
+; A valid tile index (0) with a large *constant* stride. The stride is operand 2,
+; not a tile-register index, so it must not be diagnosed.
+; CHECK-NOT: AMX tile register index
+define void @good_tileloadd64(ptr %p) {
+ call void @llvm.x86.tileloadd64(i8 0, ptr %p, i64 64)
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/204890
More information about the llvm-commits
mailing list