188 lines
6.7 KiB
Diff
188 lines
6.7 KiB
Diff
|
|
From fdbf1bd9f1bdec32384eda47f419d895d11a1c50 Mon Sep 17 00:00:00 2001
|
||
|
|
From: XingYuShuai <1150775134@qq.com>
|
||
|
|
Date: Wed, 15 May 2024 14:42:27 +0800
|
||
|
|
Subject: [PATCH] [LICM] Solve runtime error caused by the signal function.
|
||
|
|
|
||
|
|
Using the option enable-signal to control whether to solve the
|
||
|
|
runtime error caused by the signal function when lto is turned on.
|
||
|
|
---
|
||
|
|
llvm/cmake/modules/HandleLLVMOptions.cmake | 8 ++++
|
||
|
|
llvm/lib/Transforms/Scalar/LICM.cpp | 47 +++++++++++++++++++
|
||
|
|
.../Transforms/LICM/signal-before-loop-2.ll | 25 ++++++++++
|
||
|
|
.../Transforms/LICM/signal-before-loop.ll | 25 ++++++++++
|
||
|
|
llvm/test/lit.site.cfg.py.in | 1 +
|
||
|
|
5 files changed, 106 insertions(+)
|
||
|
|
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/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
|
||
|
|
index b8e9dbe29d88..8be5d4ba52c2 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_BUILD_FOR_COMMON "" ON)
|
||
|
|
+if(LLVM_BUILD_FOR_COMMON)
|
||
|
|
+ set(LLVM_BUILD_FOR_COMMON 1)
|
||
|
|
+ add_definitions( -DBUILD_FOR_COMMON )
|
||
|
|
+else()
|
||
|
|
+ set(LLVM_BUILD_FOR_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..2feec759f240 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 BUILD_FOR_COMMON
|
||
|
|
+#include "llvm/Analysis/CFG.h"
|
||
|
|
+#endif // BUILD_FOR_COMMON
|
||
|
|
#include "llvm/Analysis/GuardUtils.h"
|
||
|
|
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
|
||
|
|
#include "llvm/Analysis/Loads.h"
|
||
|
|
@@ -122,6 +125,13 @@ static cl::opt<bool>
|
||
|
|
SingleThread("licm-force-thread-model-single", cl::Hidden, cl::init(false),
|
||
|
|
cl::desc("Force thread model single in LICM pass"));
|
||
|
|
|
||
|
|
+#ifdef BUILD_FOR_COMMON
|
||
|
|
+static cl::opt<bool> DisableMovStoreInsOutsideOfLoopInSigFun(
|
||
|
|
+ "disable-move-store-ins-outside-of-loop",
|
||
|
|
+ cl::Hidden, cl::init(true), cl::desc("Disable move store instruction"
|
||
|
|
+ "outside of loop in signal function."));
|
||
|
|
+#endif // BUILD_FOR_COMMON
|
||
|
|
+
|
||
|
|
static cl::opt<uint32_t> MaxNumUsesTraversed(
|
||
|
|
"licm-max-num-uses-traversed", cl::Hidden, cl::init(8),
|
||
|
|
cl::desc("Max num uses visited for identifying load "
|
||
|
|
@@ -2075,8 +2085,45 @@ bool llvm::promoteLoopAccessesToScalars(
|
||
|
|
for (Use &U : ASIV->uses()) {
|
||
|
|
// Ignore instructions that are outside the loop.
|
||
|
|
Instruction *UI = dyn_cast<Instruction>(U.getUser());
|
||
|
|
+ #if defined(BUILD_FOR_COMMON)
|
||
|
|
+ if (DisableMovStoreInsOutsideOfLoopInSigFun) {
|
||
|
|
+ if (!UI)
|
||
|
|
+ continue;
|
||
|
|
+
|
||
|
|
+ // In the following scenario, there will be a loop index store
|
||
|
|
+ // instruction 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<LoadInst>(UI)) {
|
||
|
|
+ Function *NotCurLoopFun = UI->getParent()->getParent();
|
||
|
|
+ for (Use &UseFun : NotCurLoopFun->uses()) {
|
||
|
|
+ CallInst *Call = dyn_cast<CallInst>(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;
|
||
|
|
+ }
|
||
|
|
+#else
|
||
|
|
if (!UI || !CurLoop->contains(UI))
|
||
|
|
continue;
|
||
|
|
+#endif // BUILD_FOR_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..da878c6c691b
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/llvm/test/Transforms/LICM/signal-before-loop-2.ll
|
||
|
|
@@ -0,0 +1,25 @@
|
||
|
|
+; REQUIRES: enable_build_for_common
|
||
|
|
+; RUN:opt -disable-move-store-ins-outside-of-loop=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..cfae4e87db56
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/llvm/test/Transforms/LICM/signal-before-loop.ll
|
||
|
|
@@ -0,0 +1,25 @@
|
||
|
|
+; REQUIRES: enable_build_for_common
|
||
|
|
+; RUN:opt -disable-move-store-ins-outside-of-loop=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..20c1ecca1d43 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_build_for_common = @LLVM_BUILD_FOR_COMMON@
|
||
|
|
|
||
|
|
import lit.llvm
|
||
|
|
lit.llvm.initialize(lit_config, config)
|
||
|
|
--
|
||
|
|
2.38.1.windows.1
|
||
|
|
|