diff --git a/llvm/include/llvm/SYCLLowerIR/LowerESIMD.h b/llvm/include/llvm/SYCLLowerIR/LowerESIMD.h index e265dcbe366c3..c2400d5a096b9 100644 --- a/llvm/include/llvm/SYCLLowerIR/LowerESIMD.h +++ b/llvm/include/llvm/SYCLLowerIR/LowerESIMD.h @@ -28,12 +28,15 @@ namespace llvm { class SYCLLowerESIMDPass : public PassInfoMixin { public: PreservedAnalyses run(Module &M, ModuleAnalysisManager &); + SYCLLowerESIMDPass(); + SYCLLowerESIMDPass(bool OptLevelO0); private: size_t runOnFunction(Function &F, SmallPtrSet &); + const bool OptLevelO0; }; -ModulePass *createSYCLLowerESIMDPass(); +ModulePass *createSYCLLowerESIMDPass(bool OptLevelO0 = false); void initializeSYCLLowerESIMDLegacyPassPass(PassRegistry &); class ESIMDLowerLoadStorePass : public PassInfoMixin { diff --git a/llvm/lib/SYCLLowerIR/LowerESIMD.cpp b/llvm/lib/SYCLLowerIR/LowerESIMD.cpp index 3a8b6e4c1dcfc..6e8bb25b5a7ac 100644 --- a/llvm/lib/SYCLLowerIR/LowerESIMD.cpp +++ b/llvm/lib/SYCLLowerIR/LowerESIMD.cpp @@ -29,6 +29,7 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" #include @@ -42,6 +43,13 @@ namespace id = itanium_demangle; #define SLM_BTI 254 +// This option is only for testing. TODO: remove this option +// with the refactoring of LowerESIMD pass (ModulePass -> FunctionPass) +static cl::opt LowerEsimdOptLevelO0( + "lower-esimd-opt-level-O0", llvm::cl::Optional, llvm::cl::Hidden, + llvm::cl::desc("Force no optimizations for LowerESIMD pass"), + llvm::cl::init(false)); + namespace { SmallPtrSet collectGenXVolatileTypes(Module &); void generateKernelMetadata(Module &); @@ -49,7 +57,10 @@ void generateKernelMetadata(Module &); class SYCLLowerESIMDLegacyPass : public ModulePass { public: static char ID; // Pass identification, replacement for typeid - SYCLLowerESIMDLegacyPass() : ModulePass(ID) { + SYCLLowerESIMDLegacyPass() : ModulePass(ID), Impl(/*OptLevelO0*/ false) { + initializeSYCLLowerESIMDLegacyPassPass(*PassRegistry::getPassRegistry()); + } + SYCLLowerESIMDLegacyPass(bool OptLevelO0) : ModulePass(ID), Impl(OptLevelO0) { initializeSYCLLowerESIMDLegacyPassPass(*PassRegistry::getPassRegistry()); } @@ -70,10 +81,14 @@ INITIALIZE_PASS(SYCLLowerESIMDLegacyPass, "LowerESIMD", "Lower constructs specific to Close To Metal", false, false) // Public interface to the SYCLLowerESIMDPass. -ModulePass *llvm::createSYCLLowerESIMDPass() { - return new SYCLLowerESIMDLegacyPass(); +ModulePass *llvm::createSYCLLowerESIMDPass(bool OptLevelO0) { + return new SYCLLowerESIMDLegacyPass(OptLevelO0); } +SYCLLowerESIMDPass::SYCLLowerESIMDPass() : OptLevelO0(LowerEsimdOptLevelO0) {} +SYCLLowerESIMDPass::SYCLLowerESIMDPass(bool OptLevelO0) + : OptLevelO0(LowerEsimdOptLevelO0 ? true : OptLevelO0) {} + namespace { // The regexp for ESIMD intrinsics: // /^_Z(\d+)__esimd_\w+/ @@ -1262,7 +1277,7 @@ size_t SYCLLowerESIMDPass::runOnFunction(Function &F, // functions to be inlined into the kernel itself. To overcome this // limitation, mark every function called from ESIMD kernel with // 'alwaysinline' attribute. - if ((F.getCallingConv() != CallingConv::SPIR_KERNEL) && + if (!OptLevelO0 && (F.getCallingConv() != CallingConv::SPIR_KERNEL) && !F.hasFnAttribute(Attribute::AlwaysInline)) F.addFnAttr(Attribute::AlwaysInline); diff --git a/llvm/test/SYCLLowerIR/esimd_lower_inline_hint.ll b/llvm/test/SYCLLowerIR/esimd_lower_inline_hint.ll index 836d3010fd549..52c4124066bb2 100644 --- a/llvm/test/SYCLLowerIR/esimd_lower_inline_hint.ll +++ b/llvm/test/SYCLLowerIR/esimd_lower_inline_hint.ll @@ -1,4 +1,5 @@ -; RUN: opt -LowerESIMD -S < %s | FileCheck %s +; RUN: opt -LowerESIMD -S < %s | FileCheck -check-prefixes=CHECK,CHECK-ATTR %s +; RUN: opt -LowerESIMD -lower-esimd-opt-level-O0 -S < %s | FileCheck -check-prefixes=CHECK,CHECK-NO-ATTR %s ; This test checks that LowerESIMD pass sets the 'alwaysinline' ; attribute for all non-kernel functions. @@ -20,20 +21,25 @@ define spir_kernel void @EsimdKernel2() { } define spir_func void @foo() { -; CHECK: @foo() #[[ATTR:[0-9]+]] +; CHECK-ATTR: @foo() #[[ATTR:[0-9]+]] { +; CHECK-NO-ATTR @foo() { ret void } define spir_func void @bar() { -; CHECK: @bar() #[[ATTR]] -; CHECK-NEXT: call void @foobar +; CHECK-ATTR: @bar() #[[ATTR]] { +; CHECK-ATTR-NEXT: call void @foobar +; CHECK-NO-ATTR: @bar() { +; CHECK-NO-ATTR-NEXT: call void @foobar call void @foobar() ret void } define spir_func void @foobar() { -; CHECK: @foobar() #[[ATTR]] +; CHECK-ATTR: @foobar() #[[ATTR]] { +; CHECK-NO-ATTR: @foobar() { ret void } -; CHECK: attributes #[[ATTR]] = { alwaysinline } +; CHECK-ATTR: attributes #[[ATTR]] = { alwaysinline } +; CHECK-NO-ATTR-NOT: attributes {{.*}} alwaysinline diff --git a/llvm/tools/sycl-post-link/sycl-post-link.cpp b/llvm/tools/sycl-post-link/sycl-post-link.cpp index 9bb3a4739ef11..5afea33f135bc 100644 --- a/llvm/tools/sycl-post-link/sycl-post-link.cpp +++ b/llvm/tools/sycl-post-link/sycl-post-link.cpp @@ -491,7 +491,7 @@ static string_vector saveResultSymbolsLists(string_vector &ResSymbolsLists, // TODO: support options like -debug-pass, -print-[before|after], and others static void LowerEsimdConstructs(Module &M) { legacy::PassManager MPM; - MPM.add(createSYCLLowerESIMDPass()); + MPM.add(createSYCLLowerESIMDPass(OptLevelO0)); if (!OptLevelO0) { // Force-inline all functions marked 'alwaysinline' by the LowerESIMD pass. MPM.add(createAlwaysInlinerLegacyPass()); diff --git a/sycl/test/esimd/vadd.cpp b/sycl/test/esimd/vadd.cpp index 68208337d2eb2..db9429e2b4a11 100644 --- a/sycl/test/esimd/vadd.cpp +++ b/sycl/test/esimd/vadd.cpp @@ -2,6 +2,10 @@ // RUN: %clangxx -I %sycl_include %s -o %t.out -lsycl // RUN: %RUN_ON_HOST %t.out +// Check that the code compiles with -O0 and -g +// RUN: %clangxx -I %sycl_include %s -o %t.out -fsycl -fsycl-explicit-simd -O0 +// RUN: %clangxx -I %sycl_include %s -o %t.out -fsycl -fsycl-explicit-simd -O0 -g + #include #include #include