From 4f403e88f260cd1df3633fbcbe8fa8d1c8e0a745 Mon Sep 17 00:00:00 2001 From: Vyacheslav Levytskyy Date: Tue, 3 Sep 2024 19:02:46 +0200 Subject: [PATCH] [SPIR-V] Ensure that OpExtInst instructions generated by NonSemantic_Shader_DebugInfo_100 are not mixed up with other OpExtInst instructions (#107007) This PR is to ensure that OpExtInst instructions generated by NonSemantic_Shader_DebugInfo_100 are not mixed up with other OpExtInst instructions. Original implementation (https://github.com/llvm/llvm-project/pull/97558) has introduced an issue by moving OpExtInst instruction with the 3rd operand equal to DebugSource (value 35) or DebugCompilationUnit (value 1) even if OpExtInst is not generated by NonSemantic_Shader_DebugInfo_100 implementation code. The reproducer is attached as a new test case. The code of the test case reproduces the issue, because "lgamma" has the same code (35) inside OpenCL_std as DebugSource inside NonSemantic_Shader_DebugInfo_100. --- llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 5 ++- .../debug-info/no-misplaced-opextinst.ll | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/SPIRV/debug-info/no-misplaced-opextinst.ll diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp index a2fcfc636e3684..df42b6de193bda 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp @@ -428,7 +428,10 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) { const unsigned OpCode = MI.getOpcode(); if (OpCode == SPIRV::OpString) { collectOtherInstr(MI, MAI, SPIRV::MB_DebugStrings, IS); - } else if (OpCode == SPIRV::OpExtInst) { + } else if (OpCode == SPIRV::OpExtInst && MI.getOperand(2).isImm() && + MI.getOperand(2).getImm() == + SPIRV::InstructionSet:: + NonSemantic_Shader_DebugInfo_100) { MachineOperand Ins = MI.getOperand(3); namespace NS = SPIRV::NonSemanticExtInst; static constexpr int64_t GlobalNonSemanticDITy[] = { diff --git a/llvm/test/CodeGen/SPIRV/debug-info/no-misplaced-opextinst.ll b/llvm/test/CodeGen/SPIRV/debug-info/no-misplaced-opextinst.ll new file mode 100644 index 00000000000000..b3d202505d1226 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/debug-info/no-misplaced-opextinst.ll @@ -0,0 +1,36 @@ +; This test is to ensure that OpExtInst generated by NonSemantic_Shader_DebugInfo_100 +; are not mixed up with other OpExtInst instructions. +; The code of the test is a reproducer, because "lgamma" has the same code (35) +; inside OpenCL_std as DebugSource inside NonSemantic_Shader_DebugInfo_100. + +; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s +; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %} + +; CHECK: %[[#Ocl:]] = OpExtInstImport "OpenCL.std" +; CHECK: OpName %[[#Fun:]] "__devicelib_lgammaf" +; CHECK: %[[#Fun]] = OpFunction %[[#]] None %[[#]] +; CHECK: OpFunctionParameter +; CHECK: %[[#]] = OpExtInst %[[#]] %[[#Ocl]] lgamma %[[#]] + +define weak_odr dso_local spir_kernel void @foo() { +entry: + %r = tail call spir_func noundef float @lgammaf(float noundef 0x7FF8000000000000) + ret void +} + +define weak dso_local spir_func float @lgammaf(float noundef %x) { +entry: + %call = tail call spir_func float @__devicelib_lgammaf(float noundef %x) + ret float %call +} + +define weak dso_local spir_func float @__devicelib_lgammaf(float noundef %x) { +entry: + %call = tail call spir_func noundef float @_Z18__spirv_ocl_lgammaf(float noundef %x) + ret float %call +} + +declare dso_local spir_func noundef float @_Z18__spirv_ocl_lgammaf(float noundef)