From 7dc8f0f31024f52222909cdc2978eb52ac8baa25 Mon Sep 17 00:00:00 2001 From: xingyushuai Date: Thu, 25 Apr 2024 10:34:41 +0800 Subject: [PATCH] Using the option enable-signal to control whether to solve the runtime error caused by the signal function when lto is turned on. --- build.sh | 3 +- llvm/cmake/modules/HandleLLVMOptions.cmake | 8 ++++ llvm/lib/Transforms/Scalar/LICM.cpp | 41 +++++++++++++++++++ .../Transforms/LICM/signal-before-loop-2.ll | 25 +++++++++++ .../Transforms/LICM/signal-before-loop.ll | 25 +++++++++++ llvm/test/lit.site.cfg.py.in | 1 + 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/LICM/signal-before-loop-2.ll create mode 100644 llvm/test/Transforms/LICM/signal-before-loop.ll diff --git a/build.sh b/build.sh index 4e13df09d78f..c029a43aa231 100755 --- a/build.sh +++ b/build.sh @@ -142,7 +142,8 @@ CMAKE_OPTIONS="-DCMAKE_INSTALL_PREFIX=$install_prefix \ -DCMAKE_BUILD_TYPE=$buildtype \ -DCMAKE_C_COMPILER=$C_COMPILER_PATH \ -DCMAKE_CXX_COMPILER=$CXX_COMPILER_PATH \ - -DLLVM_TARGETS_TO_BUILD=$backends " + -DLLVM_TARGETS_TO_BUILD=$backends \ + -DLLVM_PUB_COMMON=ON " gold=$(type -p ld.gold) if [ -z "$gold" -o ! -x "$gold" ]; then diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index b8e9dbe29d88..a0d66fbf446e 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -120,6 +120,14 @@ else() set(LLVM_ENABLE_AUTOTUNER 0) endif() +option(LLVM_PUB_COMMON "" OFF) +if(LLVM_PUB_COMMON) + set(LLVM_PUB_COMMON 1) + add_definitions( -DPUB_COMMON ) +else() + set(LLVM_PUB_COMMON 0) +endif() + if(LLVM_ENABLE_EXPENSIVE_CHECKS) add_compile_definitions(EXPENSIVE_CHECKS) diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index f8fab03f151d..ba59c61ba4cc 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -44,6 +44,9 @@ #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CaptureTracking.h" +#ifdef PUB_COMMON +#include "llvm/Analysis/CFG.h" +#endif // PUB_COMMON #include "llvm/Analysis/GuardUtils.h" #include "llvm/Analysis/LazyBlockFrequencyInfo.h" #include "llvm/Analysis/Loads.h" @@ -122,6 +125,11 @@ static cl::opt SingleThread("licm-force-thread-model-single", cl::Hidden, cl::init(false), cl::desc("Force thread model single in LICM pass")); +#ifdef PUB_COMMON +static cl::opt EnableSignalBeforeLoop("enable-signal", cl::Hidden, + cl::init(false), cl::desc("Enable signal function before loop")); +#endif // PUB_COMMON + static cl::opt MaxNumUsesTraversed( "licm-max-num-uses-traversed", cl::Hidden, cl::init(8), cl::desc("Max num uses visited for identifying load " @@ -2075,8 +2083,41 @@ bool llvm::promoteLoopAccessesToScalars( for (Use &U : ASIV->uses()) { // Ignore instructions that are outside the loop. Instruction *UI = dyn_cast(U.getUser()); + #if defined(PUB_COMMON) + if (EnableSignalBeforeLoop) { + if (!UI) + continue; + + // that is moved outside the loop and when the termination loop is + // triggered by the signal function, the store instruction is not + // executed.However, the function registered by the signal will read the + // data sored in the store instruction, so the data read is incorrect. + // Solution: Prevent the store instruction form going outside the loop. + // NOTE: The sys_signal function takes the same arguments and performs + // the same task as signal. They all belong to glic. + if(StoreSafety == StoreSafe && !CurLoop->contains(UI)) { + if(LoadInst *NotCurLoopLoad = dyn_cast(UI)) { + Function *NotCurLoopFun = UI->getParent()->getParent(); + for (Use &UseFun : NotCurLoopFun->uses()) { + CallInst *Call = dyn_cast(UseFun.getUser()); + if (Call && Call->getCalledFunction() && + (Call->getCalledFunction()->getName() == "__sysv_signal" || + Call->getCalledFunction()->getName() == "signal") && + isPotentiallyReachable(Call->getParent(), + CurLoop->getLoopPreheader(),NULL,DT, + LI)) + return false; + } + } + } + + if (!CurLoop->contains(UI)) + continue; + } +#else if (!UI || !CurLoop->contains(UI)) continue; +#endif // PUB_COMMON // If there is an non-load/store instruction in the loop, we can't promote // it. diff --git a/llvm/test/Transforms/LICM/signal-before-loop-2.ll b/llvm/test/Transforms/LICM/signal-before-loop-2.ll new file mode 100644 index 000000000000..1c38dbd6e72e --- /dev/null +++ b/llvm/test/Transforms/LICM/signal-before-loop-2.ll @@ -0,0 +1,25 @@ +; REQUIRES: enable_pub_common +; RUN:opt -enable-signal=true -S < %s | FileCheck %s + +@Run_Index = external global i64 + +declare ptr @signal(ptr) + +define void @report() { +entry: + %0 = load i64, ptr @Run_Index, align 8 + unreachable +} + +define i32 @main() { +if.end: + %call.i4 = call ptr @signal(ptr @report) + br label %for.cond + +; CHECK-LABEL: for.cond +; CHECK: store +for.cond: + %0 = load i64, ptr @Run_Index, align 8 + store i64 %0, ptr @Run_Index, align 8 + br label %for.cond +} diff --git a/llvm/test/Transforms/LICM/signal-before-loop.ll b/llvm/test/Transforms/LICM/signal-before-loop.ll new file mode 100644 index 000000000000..95a494c6ec57 --- /dev/null +++ b/llvm/test/Transforms/LICM/signal-before-loop.ll @@ -0,0 +1,25 @@ +; REQUIRES: enable_pub_common +; RUN:opt -enable-signal=true -S < %s | FileCheck %s + +@Run_Index = external global i64 + +declare ptr @__sysv_signal(ptr) + +define void @report() { +entry: + %0 = load i64, ptr @Run_Index, align 8 + unreachable +} + +define i32 @main() { +if.end: + %call.i4 = call ptr @__sysv_signal(ptr @report) + br label %for.cond + +; CHECK-LABEL: for.cond +; CHECK: store +for.cond: + %0 = load i64, ptr @Run_Index, align 8 + store i64 %0, ptr @Run_Index, align 8 + br label %for.cond +} diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in index 0e9396e3b014..426d99240313 100644 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -63,6 +63,7 @@ config.dxil_tests = @LLVM_INCLUDE_DXIL_TESTS@ config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@ config.use_classic_flang = @LLVM_ENABLE_CLASSIC_FLANG@ config.enable_enable_autotuner = @LLVM_ENABLE_AUTOTUNER@ +config.enable_pub_common = @LLVM_PUB_COMMON@ import lit.llvm lit.llvm.initialize(lit_config, config) -- Gitee