From c0130961e5637b2e97c9e5a41fbaf63ec044530c Mon Sep 17 00:00:00 2001 From: Zahira Ammarguellat Date: Tue, 26 May 2020 09:39:11 -0700 Subject: [PATCH] Ignore llvm.trap instrinsic Clang, due to some ABI constraints needs to generate llvm.trap intrinsics. According to the LangRef documentation a trap instruction is lowered to a target's trap instruction or to an abort() function if the target doesn't have a trap instruction. SPIRV has neither a trap nor an abort instruction and no current opcode has the semantics of an abort/trap. Currently the IR to SPIRV translator is crashing when it finds an llvm.trap intrinsic. The solution will require some thoughts on the SPIRV side to decide how to implement an abort instruction. This patch changes the translator so it doesn't crash. This will be revised when a decision is taken. NOTE: clang could eventually not generate an llvm.trap instruction in the current case (non-base destructor of an abstract class needs to be emmitted) but keep in mind that clang might generate an llvm.trap intrinsic some other ways and we might stumble into this issue again. An alternative to this, could be to add an LLVM pass that will get rid of the llvm.trap intrisincs in the code before the SPIRV translator. But having the translator solve this issue is a preferred solution. --- lib/SPIRV/SPIRVWriter.cpp | 3 +++ test/trap.ll | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 test/trap.ll diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 73a96b2fb8..90b7a20237 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -1915,6 +1915,9 @@ SPIRVValue *LLVMToSPIRV::transIntrinsicInst(IntrinsicInst *II, case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::dbg_label: + case Intrinsic::trap: + // llvm.trap intrinsic is not implemented. But for now don't crash. This + // change is pending the trap/abort intrisinc implementation. return nullptr; default: if (SPIRVAllowUnknownIntrinsics) diff --git a/test/trap.ll b/test/trap.ll new file mode 100644 index 0000000000..7366d32985 --- /dev/null +++ b/test/trap.ll @@ -0,0 +1,40 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc -spirv-text -o %t +; RUN: FileCheck < %t %s +; RUN: llvm-spirv %t.bc -o %t.spv +; RUN: spirv-val %t.spv +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024" +target triple = "spir-unknown-unknown" + +; Function Attrs: nounwind +; CHECK: Capability Addresses +; CHECK: "foo" + +; Function Attrs: cold noreturn nounwind +declare void @llvm.trap() #8 + +define spir_kernel void @foo(i32 addrspace(1)* %a) #0 !kernel_arg_addr_space !1 !kernel_arg_access_qual !2 !kernel_arg_type !3 !kernel_arg_base_type !4 !kernel_arg_type_qual !5 { +entry: + %a.addr = alloca i32 addrspace(1)*, align 4 + store i32 addrspace(1)* %a, i32 addrspace(1)** %a.addr, align 4 + call void @llvm.trap() #12 + ret void +} + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #12 = { noreturn nounwind } + +!opencl.enable.FP_CONTRACT = !{} +!opencl.spir.version = !{!6} +!opencl.ocl.version = !{!6} +!opencl.used.extensions = !{!7} +!opencl.used.optional.core.features = !{!7} +!opencl.compiler.options = !{!7} + +!1 = !{i32 1} +!2 = !{!"none"} +!3 = !{!"int*"} +!4 = !{!"int*"} +!5 = !{!""} +!6 = !{i32 1, i32 2} +!7 = !{}