diff --git a/clang/test/CodeGenSYCL/simplifycfg.cpp b/clang/test/CodeGenSYCL/simplifycfg.cpp new file mode 100644 index 0000000000000..ffa208119d3ed --- /dev/null +++ b/clang/test/CodeGenSYCL/simplifycfg.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown -flegacy-pass-manager -mllvm -sycl-opt %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown -fno-legacy-pass-manager -mllvm -sycl-opt %s -emit-llvm -o - | FileCheck %s +// +// This test checks that foo (which is @_Z3foov) is called twice after O3 optimizations. +// +// Usually clang with SimplifyCFG pass optimizes constructs like: +// if (i % 2 == 0) +// func(); +// else +// func(); +// +// into one simple func() invocation. +// This behaviour might be wrong in cases when func's behaviour depends on +// a place where it is written. +// There is a relevant discussion about introducing +// a reliable tool for such cases: https://reviews.llvm.org/D85603 + +// CHECK: tail call spir_func void @_Z3foov() +// CHECK: tail call spir_func void @_Z3foov() + +SYCL_EXTERNAL void foo(); + +SYCL_EXTERNAL void bar(int i) { + if (i % 2 == 0) { + foo(); + } else { + foo(); + } +} diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index 9fe7d590eb6f5..ccc601d94a7b6 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -598,8 +598,12 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level, for (auto &C : ScalarOptimizerLateEPCallbacks) C(FPM, Level); - FPM.addPass(SimplifyCFGPass( - SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true))); + if (SYCLOptimizationMode) + FPM.addPass(SimplifyCFGPass()); + else + FPM.addPass(SimplifyCFGPass( + SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true))); + FPM.addPass(InstCombinePass()); invokePeepholeEPCallbacks(FPM, Level); diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index e4431520151ef..e4d08feae9ed6 100644 --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -541,8 +541,12 @@ void PassManagerBuilder::addFunctionSimplificationPasses( MPM.add(createLoopRerollPass()); // Merge & remove BBs and sink & hoist common instructions. - MPM.add(createCFGSimplificationPass( - SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true))); + if (SYCLOptimizationMode) + MPM.add(createCFGSimplificationPass()); + else + MPM.add(createCFGSimplificationPass( + SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true))); + // Clean up after everything. MPM.add(createInstructionCombiningPass()); addExtensionsToPM(EP_Peephole, MPM);