[llvm] 3948379 - prevent undefined behaviour of SPIR-V Backend non-asserts builds when dealing with token type (#78437)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 30 09:11:01 PST 2024


Author: Vyacheslav Levytskyy
Date: 2024-01-30T18:10:57+01:00
New Revision: 39483797b8981528eafaf6dad557ccfb2312e1ef

URL: https://github.com/llvm/llvm-project/commit/39483797b8981528eafaf6dad557ccfb2312e1ef
DIFF: https://github.com/llvm/llvm-project/commit/39483797b8981528eafaf6dad557ccfb2312e1ef.diff

LOG: prevent undefined behaviour of SPIR-V Backend non-asserts builds when dealing with token type (#78437)

The goal of this PR is to fix the issue when use of token type in LLVM
intrinsic causes undefined behavior of SPIR-V Backend code generator
when assertions are disabled:
https://github.com/llvm/llvm-project/issues/78434

Among possible fix options, discussed in the
https://github.com/llvm/llvm-project/issues/78434 issue description, the
option to generate a meaningful error before execution arrives at the
`llvm_unreachable` call looks like a better solution for now, because
SPIR-V doesn't support token type anyway without additional extensions.

The PR is to generate a user-friendly error message and exit without
generating a stack dump when such a usage of token type was detected
that would lead to undefined behavior of SPIR-V Backend code generator.

Added: 
    llvm/test/CodeGen/SPIRV/token/token-type-preallocated-setup-arg.ll
    llvm/test/CodeGen/SPIRV/token/token-type-requires-extension.ll

Modified: 
    llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 4169f7c6233c9..26a5d7a30f19d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -149,6 +149,13 @@ static bool requireAssignType(Instruction *I) {
   return true;
 }
 
+static inline void reportFatalOnTokenType(const Instruction *I) {
+  if (I->getType()->isTokenTy())
+    report_fatal_error("A token is encountered but SPIR-V without extensions "
+                       "does not support token type",
+                       false);
+}
+
 void SPIRVEmitIntrinsics::replaceMemInstrUses(Instruction *Old,
                                               Instruction *New) {
   while (!Old->user_empty()) {
@@ -544,6 +551,7 @@ void SPIRVEmitIntrinsics::processGlobalValue(GlobalVariable &GV) {
 }
 
 void SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I) {
+  reportFatalOnTokenType(I);
   if (I->getType()->isVoidTy() || !requireAssignPtrType(I))
     return;
 
@@ -566,6 +574,7 @@ void SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I) {
 }
 
 void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I) {
+  reportFatalOnTokenType(I);
   Type *Ty = I->getType();
   if (!Ty->isVoidTy() && requireAssignType(I) && !requireAssignPtrType(I)) {
     setInsertPointSkippingPhis(*IRB, I->getNextNode());
@@ -625,6 +634,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I) {
     }
   }
   if (I->hasName()) {
+    reportFatalOnTokenType(I);
     setInsertPointSkippingPhis(*IRB, I->getNextNode());
     std::vector<Value *> Args = {I};
     addStringImm(I->getName(), *IRB, Args);

diff  --git a/llvm/test/CodeGen/SPIRV/token/token-type-preallocated-setup-arg.ll b/llvm/test/CodeGen/SPIRV/token/token-type-preallocated-setup-arg.ll
new file mode 100644
index 0000000000000..42e59c726b6fd
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/token/token-type-preallocated-setup-arg.ll
@@ -0,0 +1,17 @@
+; Example of token usage is from https://llvm.org/docs/LangRef.html (Preallocated Operand Bundles)
+
+; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s
+
+; CHECK: A token is encountered but SPIR-V without extensions does not support token type
+
+%foo = type { i64, i32 }
+
+define dso_local spir_func void @test() {
+entry:
+  %tok = call token @llvm.call.preallocated.setup(i32 1)
+  %a = call ptr @llvm.call.preallocated.arg(token %tok, i32 0) preallocated(%foo)
+  ret void
+}
+
+declare token @llvm.call.preallocated.setup(i32 %num_args)
+declare ptr @llvm.call.preallocated.arg(token %setup_token, i32 %arg_index)

diff  --git a/llvm/test/CodeGen/SPIRV/token/token-type-requires-extension.ll b/llvm/test/CodeGen/SPIRV/token/token-type-requires-extension.ll
new file mode 100644
index 0000000000000..ee545a77e5d68
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/token/token-type-requires-extension.ll
@@ -0,0 +1,11 @@
+; RUN: not llc -O0 -mtriple=spirv64-unknown-unknown %s -o - 2>&1 | FileCheck %s
+
+; CHECK: A token is encountered but SPIR-V without extensions does not support token type
+
+declare token @llvm.myfun()
+
+define dso_local spir_func void @func() {
+entry:
+  %tok = call token @llvm.myfun()
+  ret void
+}


        


More information about the llvm-commits mailing list