diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "SPIRVModuleAnalysis.h" +#include "MCTargetDesc/SPIRVBaseInfo.h" #include "SPIRV.h" #include "SPIRVSubtarget.h" #include "SPIRVTargetMachine.h" @@ -552,6 +553,10 @@ // TODO: verify if this needs some checks. addAvailableCaps({Capability::Float16, Capability::Float64}); + // Add cap for SPV_INTEL_optnone + // FIXME: this should be added only if the target has the extension + addAvailableCaps({Capability::OptNoneINTEL}); + // TODO: add OpenCL extensions. } } // namespace SPIRV diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp --- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp @@ -574,6 +574,28 @@ } } +// This function checks if the machine has optnone enabled and if so enables +// the SPIRV optnone extension and capability. +// FIXME: make this optional once we have a command line flag to explicitly +// enable extensions. +void runOptNoneAnalysis(MachineFunction &MF) { + // Possibly output Capability and Extension instructions if function is marked + // with optnone. + const Function &F = MF.getFunction(); + const SPIRVSubtarget &ST = MF.getSubtarget(); + MachineBasicBlock &EntryBB = MF.front(); + MachineIRBuilder MIRBuilder(EntryBB, EntryBB.begin()); + + if (F.hasOptNone() && ST.canUseExtension( + SPIRV::Extension::SPV_INTEL_optnone)) { + // Output OpCapability OptNoneINTEL. + MIRBuilder.buildInstr(SPIRV::OpExtension) + .addImm(SPIRV::Extension::SPV_INTEL_optnone); + MIRBuilder.buildInstr(SPIRV::OpCapability) + .addImm(SPIRV::Capability::OptNoneINTEL); + } +} + bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) { // Initialize the type registry. const SPIRVSubtarget &ST = MF.getSubtarget(); @@ -586,6 +608,7 @@ generateAssignInstrs(MF, GR, MIB); processSwitches(MF, GR, MIB); processInstrsWithTypeFolding(MF, GR, MIB); + runOptNoneAnalysis(MF); return true; } diff --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp --- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp @@ -96,8 +96,11 @@ if (!isOpenCLEnv()) return; // A default extension for testing. + // FIXME: This should be changed when we can select extensions through a + // command line flag. AvailableExtensions.insert( SPIRV::Extension::SPV_KHR_no_integer_wrap_decoration); + AvailableExtensions.insert(SPIRV::Extension::SPV_INTEL_optnone); } // TODO: use command line args for this rather than just defaults. diff --git a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td --- a/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td +++ b/llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td @@ -243,6 +243,7 @@ defm SPV_INTEL_unstructured_loop_controls : ExtensionOperand<55>; defm SPV_EXT_demote_to_helper_invocation : ExtensionOperand<56>; defm SPV_INTEL_fpga_reg : ExtensionOperand<57>; +defm SPV_INTEL_optnone : ExtensionOperand<58>; //===----------------------------------------------------------------------===// // Multiclass used to define Capabilities enum values and at the same time @@ -396,6 +397,7 @@ defm FragmentDensityEXT : CapabilityOperand<5291, 0, 0, [], [Shader]>; defm PhysicalStorageBufferAddressesEXT : CapabilityOperand<5347, 0, 0, [], [Shader]>; defm CooperativeMatrixNV : CapabilityOperand<5357, 0, 0, [], [Shader]>; +defm OptNoneINTEL : CapabilityOperand<6094, 0, 0, [SPV_INTEL_optnone], []>; //===----------------------------------------------------------------------===// // Multiclass used to define SourceLanguage enum values and at the same time diff --git a/llvm/test/CodeGen/SPIRV/optnone.ll b/llvm/test/CodeGen/SPIRV/optnone.ll --- a/llvm/test/CodeGen/SPIRV/optnone.ll +++ b/llvm/test/CodeGen/SPIRV/optnone.ll @@ -1,14 +1,17 @@ ;; Check that optnone is correctly ignored when extension is not enabled ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV -;; Per SPIR-V spec: -;; FunctionControlDontInlineMask = 0x2 (2) -; CHECK-SPIRV: %[[#]] = OpFunction %[[#]] DontInline - ; Function Attrs: nounwind optnone noinline define spir_func void @_Z3foov() #0 { entry: ret void } +; CHECK-SPIRV: OpCapability OptNoneINTEL +; CHECK-SPIRV: OpExtension "SPV_INTEL_optnone" + +;; Per SPIR-V spec: +;; FunctionControlDontInlineMask = 0x2 (2) +; CHECK-SPIRV: %[[#]] = OpFunction %[[#]] DontInline attributes #0 = { nounwind optnone noinline } +