-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[StackProtector] Introduce stack-protect-refinement pass to remove unnecessary protections. #150390
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-lto @llvm/pr-subscribers-llvm-globalisel Author: None (Mermen) ChangesThis pass uses StackSafetyGlobalAnalysis to reduce number of functions that require stack protector. All llvm lit tests passed. In llvm-test-suite it reduces number of instrumented functions by 13% (8883 -> 7723) under Patch is 24.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/150390.diff 31 Files Affected:
diff --git a/clang/test/Driver/memtag-stack_lto.c b/clang/test/Driver/memtag-stack_lto.c
index 324bdec070873..fc014c027fcf8 100644
--- a/clang/test/Driver/memtag-stack_lto.c
+++ b/clang/test/Driver/memtag-stack_lto.c
@@ -33,7 +33,7 @@
// RUN: rm -f %t*
// -O0: both are unsafe.
-// RUN: %clang -O0 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o - 2>&1 | FileCheck %s
+// RUN: %clang -O0 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o - 2>&1 | FileCheck %s -check-prefixes=CHECK-O0
// No LTO: just one is safe.
// RUN: %clang -O1 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefixes=SSI,XUNSAFE,YSAFE
@@ -87,6 +87,7 @@ int fn() {
return x + y;
}
-// CHECK-NOT: allocas uses:
+// CHECK-O0-NOT: allocas uses:
+// CHECK: allocas uses:
#endif
diff --git a/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h b/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h
new file mode 100644
index 0000000000000..d0097669d3067
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h
@@ -0,0 +1,33 @@
+//===- StackProtectAttributor.h - Stack Protect Attributoor ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
+#define LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
+
+#include "llvm/Analysis/StackSafetyAnalysis.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class BasicBlock;
+class Function;
+class Instruction;
+
+class StackProtectAttributorPass
+ : public PassInfoMixin<StackProtectAttributorPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+
+private:
+ void processFunction(Function &F) const;
+
+ const StackSafetyGlobalInfo *SSI;
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f810368a84940..1eebf607ef366 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -324,6 +324,7 @@
#include "llvm/Transforms/Scalar/Reassociate.h"
#include "llvm/Transforms/Scalar/Reg2Mem.h"
#include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
#include "llvm/Transforms/Scalar/SCCP.h"
#include "llvm/Transforms/Scalar/SROA.h"
#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 98821bb1408a7..20e297bfa3dc5 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -127,6 +127,7 @@
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
#include "llvm/Transforms/Scalar/SpeculativeExecution.h"
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
#include "llvm/Transforms/Scalar/TailRecursionElimination.h"
#include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
#include "llvm/Transforms/Utils/AddDiscriminators.h"
@@ -1278,6 +1279,9 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
else
MPM.addPass(buildInlinerPipeline(Level, Phase));
+ if (Level != OptimizationLevel::O0)
+ MPM.addPass(StackProtectAttributorPass());
+
// Remove any dead arguments exposed by cleanups, constant folding globals,
// and argument promotion.
MPM.addPass(DeadArgumentEliminationPass());
@@ -1944,6 +1948,8 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
// is fixed.
MPM.addPass(WholeProgramDevirtPass(ExportSummary, nullptr));
+ MPM.addPass(StackProtectAttributorPass());
+
// Stop here at -O1.
if (Level == OptimizationLevel::O1) {
// The LowerTypeTestsPass needs to run to lower type metadata and the
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index bb7ccdb2bc187..d1a22c9ece01e 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -59,6 +59,7 @@ MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass())
MODULE_PASS("check-debugify", NewPMCheckDebugifyPass())
MODULE_PASS("constmerge", ConstantMergePass())
MODULE_PASS("coro-cleanup", CoroCleanupPass())
+MODULE_PASS("stack-protect-attributor", StackProtectAttributorPass())
MODULE_PASS("coro-early", CoroEarlyPass())
MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass())
MODULE_PASS("ctx-instr-gen",
diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt
index 84a5b02043d01..b161ab6810a8c 100644
--- a/llvm/lib/Transforms/Scalar/CMakeLists.txt
+++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt
@@ -64,6 +64,7 @@ add_llvm_component_library(LLVMScalarOpts
PlaceSafepoints.cpp
Reassociate.cpp
Reg2Mem.cpp
+ StackProtectAttributor.cpp
RewriteStatepointsForGC.cpp
SCCP.cpp
SROA.cpp
diff --git a/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp b/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp
new file mode 100644
index 0000000000000..8695cb32c4e5d
--- /dev/null
+++ b/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp
@@ -0,0 +1,60 @@
+//===- StackProtectAttributor.cpp - Stack Protect Attributoor -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "stack-protect-attributor"
+
+STATISTIC(
+ NumFuncsWithAllocaInst,
+ "Number of functions with an instruction to allocate memory on the stack");
+STATISTIC(NumFuncsWithRemovedStackProtectAttr,
+ "Number of functions with alloca and removed stack protect attr");
+
+static cl::opt<bool>
+ UseStackSafety("ctpa-optimize-ssp", cl::init(true), cl::Hidden,
+ cl::desc("Use Stack Safety analysis results"));
+
+void StackProtectAttributorPass::processFunction(Function &F) const {
+
+ bool hasAlloca = false;
+
+ for (auto &I : instructions(&F))
+ if (auto *AI = dyn_cast<AllocaInst>(&I)) {
+ hasAlloca = true;
+ NumFuncsWithAllocaInst++;
+ if (!SSI->isSafe(*AI))
+ return;
+ }
+
+ if (hasAlloca)
+ NumFuncsWithRemovedStackProtectAttr++;
+
+ F.removeFnAttr(Attribute::StackProtect);
+ F.removeFnAttr(Attribute::StackProtectStrong);
+}
+
+PreservedAnalyses StackProtectAttributorPass::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+ if (!UseStackSafety)
+ return PreservedAnalyses::all();
+
+ SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
+ for (Function &F : M)
+ if (F.hasFnAttribute(Attribute::StackProtect) ||
+ F.hasFnAttribute(Attribute::StackProtectStrong))
+ processFunction(F);
+
+ return PreservedAnalyses::all();
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll b/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
index 683cdfd9eeac8..5faa0a6fc8d59 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple aarch64-unknown-unknown -global-isel \
+; RUN: llc -ctpa-optimize-ssp=false -mtriple aarch64-unknown-unknown -global-isel \
; RUN: -no-stack-coloring=false -pass-remarks-missed=gisel* < %s \
; RUN: 2>&1 | FileCheck %s
diff --git a/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll b/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
index 4dc71bc90dcdc..32268bf29331c 100644
--- a/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
+++ b/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -o - -verify-machineinstrs | FileCheck %s
+; RUN: llc %s -o - -ctpa-optimize-ssp=false -verify-machineinstrs | FileCheck %s
target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
target triple = "thumbv7s-apple-ios8.0.0"
diff --git a/llvm/test/CodeGen/ARM/ssp-data-layout.ll b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
index c5f13a66c11ca..ceffe076b985f 100644
--- a/llvm/test/CodeGen/ARM/ssp-data-layout.ll
+++ b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -frame-pointer=all -mcpu=cortex-a8 -mtriple arm-linux-gnu -target-abi=apcs -o - | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -frame-pointer=all -mcpu=cortex-a8 -mtriple arm-linux-gnu -target-abi=apcs -o - | FileCheck %s
; This test is fairly fragile. The goal is to ensure that "large" stack
; objects are allocated closest to the stack protector (i.e., farthest away
; from the Stack Pointer.) In standard SSP mode this means that large (>=
diff --git a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
index 822f6a4c4616e..ead9bc9b64245 100644
--- a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
+++ b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=i386-apple-darwin -O0 -regalloc=fast | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=i386-apple-darwin -O0 -regalloc=fast | FileCheck %s
; rdar://6787136
%struct.X = type { i8, [32 x i8] }
diff --git a/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll b/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
index 99a50295727c4..8062704971a5f 100644
--- a/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
+++ b/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
; rdar://7396984
@str = private unnamed_addr constant [28 x i8] c"xxxxxxxxxxxxxxxxxxxxxxxxxxx\00", align 1
diff --git a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
index ecaa105dedcfe..112001dcf450f 100644
--- a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
+++ b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-- -mcpu=core2 | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=x86_64-- -mcpu=core2 | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
diff --git a/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll b/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
index abd1d4e7d350c..fc50bc9072395 100644
--- a/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
+++ b/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
@@ -1,4 +1,4 @@
-; RUN: llc -no-stack-coloring=false < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -no-stack-coloring=false < %s | FileCheck %s
; This test crashed in PEI because the stack protector was dead.
; This was due to it being colored, which was in turn due to incorrect
diff --git a/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll b/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
index a4e5ae66b1fd8..04c75e0915c92 100644
--- a/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
+++ b/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
@@ -1,4 +1,4 @@
-; RUN: llc -o - %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -o - %s | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx"
diff --git a/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll b/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
index 72d75456ce4ce..6ea291c876be5 100644
--- a/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
+++ b/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
@@ -1,4 +1,4 @@
-; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
; Ensure that the outliner doesn't outline from any functions that use a redzone.
declare ptr @llvm.stacksave() #1
diff --git a/llvm/test/CodeGen/X86/ssp-data-layout.ll b/llvm/test/CodeGen/X86/ssp-data-layout.ll
index bda2598384db8..16075f0149cc1 100644
--- a/llvm/test/CodeGen/X86/ssp-data-layout.ll
+++ b/llvm/test/CodeGen/X86/ssp-data-layout.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -stack-symbol-ordering=0 -frame-pointer=all -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -stack-symbol-ordering=0 -frame-pointer=all -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
; This test is fairly fragile. The goal is to ensure that "large" stack
; objects are allocated closest to the stack protector (i.e., farthest away
; from the Stack Pointer.) In standard SSP mode this means that large (>=
diff --git a/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll b/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
index d18353a89126c..d136c70ff44bb 100644
--- a/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
+++ b/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=x86_64 -O0 < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -mtriple=x86_64 -O0 < %s | FileCheck %s
; Check that we don't crash on this input.
; CHECK-LABEL: @foo
diff --git a/llvm/test/CodeGen/X86/stack-protector-remarks.ll b/llvm/test/CodeGen/X86/stack-protector-remarks.ll
index cbd986a64eac6..cb08058e50fb6 100644
--- a/llvm/test/CodeGen/X86/stack-protector-remarks.ll
+++ b/llvm/test/CodeGen/X86/stack-protector-remarks.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -mtriple=x86_64-unknown-unknown -pass-remarks=stack-protector -o /dev/null 2>&1 | FileCheck %s
+; RUN: llc %s -ctpa-optimize-ssp=false -mtriple=x86_64-unknown-unknown -pass-remarks=stack-protector -o /dev/null 2>&1 | FileCheck %s
; CHECK-NOT: nossp
; CHECK: function attribute_ssp
; CHECK-SAME: a function attribute or command-line switch
diff --git a/llvm/test/CodeGen/X86/stackguard-internal.ll b/llvm/test/CodeGen/X86/stackguard-internal.ll
index 328e04b9a718c..15177b4d3d866 100644
--- a/llvm/test/CodeGen/X86/stackguard-internal.ll
+++ b/llvm/test/CodeGen/X86/stackguard-internal.ll
@@ -1,5 +1,5 @@
; Check that the backend doesn't crash.
-; RUN: llc -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s
@__stack_chk_guard = internal global [8 x i64] zeroinitializer, align 16
diff --git a/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll b/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
index 53202f19f7602..6aa986a9ebd7a 100644
--- a/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
+++ b/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -o - -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
+; RUN: llc %s -o - -ctpa-optimize-ssp=false -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
; In the sequence below, the sdiv is converted to a function call to __divsi3,
; which is then tail call optimised. The dbg.value is suddenly stuck between
diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll
index c554fdbf4c799..bb8e00c5b260b 100644
--- a/llvm/test/Other/new-pm-defaults.ll
+++ b/llvm/test/Other/new-pm-defaults.ll
@@ -235,6 +235,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
; CHECK-O-NEXT: Running pass: GlobalOptPass
diff --git a/llvm/test/Other/new-pm-lto-defaults.ll b/llvm/test/Other/new-pm-lto-defaults.ll
index 3aea0f2061f3e..f8b4eabcbcdbc 100644
--- a/llvm/test/Other/new-pm-lto-defaults.ll
+++ b/llvm/test/Other/new-pm-lto-defaults.ll
@@ -67,6 +67,8 @@
; CHECK-O1-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-O-NEXT: Running pass: GlobalSplitPass
; CHECK-O-NEXT: Running pass: WholeProgramDevirtPass
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O23SZ-NEXT: Running pass: CoroEarlyPass
; CHECK-O1-NEXT: Running pass: LowerTypeTestsPass
; CHECK-O23SZ-NEXT: Running pass: GlobalOptPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
index 62bb02d9b3c40..fd1faf4bd9067 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
@@ -158,6 +158,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
index 0da7a9f73bdce..f25fce6fe497f 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
@@ -142,6 +142,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
index 38b7890682783..4422e9b7bb9e4 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
@@ -151,6 +151,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
index 5aacd26def2be..ba3d7e2fb58ad 100644
--- a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
@@ -188,6 +188,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: Shou...
[truncated]
|
@llvm/pr-subscribers-backend-x86 Author: None (Mermen) ChangesThis pass uses StackSafetyGlobalAnalysis to reduce number of functions that require stack protector. All llvm lit tests passed. In llvm-test-suite it reduces number of instrumented functions by 13% (8883 -> 7723) under Patch is 24.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/150390.diff 31 Files Affected:
diff --git a/clang/test/Driver/memtag-stack_lto.c b/clang/test/Driver/memtag-stack_lto.c
index 324bdec070873..fc014c027fcf8 100644
--- a/clang/test/Driver/memtag-stack_lto.c
+++ b/clang/test/Driver/memtag-stack_lto.c
@@ -33,7 +33,7 @@
// RUN: rm -f %t*
// -O0: both are unsafe.
-// RUN: %clang -O0 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o - 2>&1 | FileCheck %s
+// RUN: %clang -O0 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o - 2>&1 | FileCheck %s -check-prefixes=CHECK-O0
// No LTO: just one is safe.
// RUN: %clang -O1 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefixes=SSI,XUNSAFE,YSAFE
@@ -87,6 +87,7 @@ int fn() {
return x + y;
}
-// CHECK-NOT: allocas uses:
+// CHECK-O0-NOT: allocas uses:
+// CHECK: allocas uses:
#endif
diff --git a/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h b/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h
new file mode 100644
index 0000000000000..d0097669d3067
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h
@@ -0,0 +1,33 @@
+//===- StackProtectAttributor.h - Stack Protect Attributoor ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
+#define LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
+
+#include "llvm/Analysis/StackSafetyAnalysis.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class BasicBlock;
+class Function;
+class Instruction;
+
+class StackProtectAttributorPass
+ : public PassInfoMixin<StackProtectAttributorPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+
+private:
+ void processFunction(Function &F) const;
+
+ const StackSafetyGlobalInfo *SSI;
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f810368a84940..1eebf607ef366 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -324,6 +324,7 @@
#include "llvm/Transforms/Scalar/Reassociate.h"
#include "llvm/Transforms/Scalar/Reg2Mem.h"
#include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
#include "llvm/Transforms/Scalar/SCCP.h"
#include "llvm/Transforms/Scalar/SROA.h"
#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 98821bb1408a7..20e297bfa3dc5 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -127,6 +127,7 @@
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
#include "llvm/Transforms/Scalar/SpeculativeExecution.h"
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
#include "llvm/Transforms/Scalar/TailRecursionElimination.h"
#include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
#include "llvm/Transforms/Utils/AddDiscriminators.h"
@@ -1278,6 +1279,9 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
else
MPM.addPass(buildInlinerPipeline(Level, Phase));
+ if (Level != OptimizationLevel::O0)
+ MPM.addPass(StackProtectAttributorPass());
+
// Remove any dead arguments exposed by cleanups, constant folding globals,
// and argument promotion.
MPM.addPass(DeadArgumentEliminationPass());
@@ -1944,6 +1948,8 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
// is fixed.
MPM.addPass(WholeProgramDevirtPass(ExportSummary, nullptr));
+ MPM.addPass(StackProtectAttributorPass());
+
// Stop here at -O1.
if (Level == OptimizationLevel::O1) {
// The LowerTypeTestsPass needs to run to lower type metadata and the
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index bb7ccdb2bc187..d1a22c9ece01e 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -59,6 +59,7 @@ MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass())
MODULE_PASS("check-debugify", NewPMCheckDebugifyPass())
MODULE_PASS("constmerge", ConstantMergePass())
MODULE_PASS("coro-cleanup", CoroCleanupPass())
+MODULE_PASS("stack-protect-attributor", StackProtectAttributorPass())
MODULE_PASS("coro-early", CoroEarlyPass())
MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass())
MODULE_PASS("ctx-instr-gen",
diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt
index 84a5b02043d01..b161ab6810a8c 100644
--- a/llvm/lib/Transforms/Scalar/CMakeLists.txt
+++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt
@@ -64,6 +64,7 @@ add_llvm_component_library(LLVMScalarOpts
PlaceSafepoints.cpp
Reassociate.cpp
Reg2Mem.cpp
+ StackProtectAttributor.cpp
RewriteStatepointsForGC.cpp
SCCP.cpp
SROA.cpp
diff --git a/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp b/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp
new file mode 100644
index 0000000000000..8695cb32c4e5d
--- /dev/null
+++ b/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp
@@ -0,0 +1,60 @@
+//===- StackProtectAttributor.cpp - Stack Protect Attributoor -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "stack-protect-attributor"
+
+STATISTIC(
+ NumFuncsWithAllocaInst,
+ "Number of functions with an instruction to allocate memory on the stack");
+STATISTIC(NumFuncsWithRemovedStackProtectAttr,
+ "Number of functions with alloca and removed stack protect attr");
+
+static cl::opt<bool>
+ UseStackSafety("ctpa-optimize-ssp", cl::init(true), cl::Hidden,
+ cl::desc("Use Stack Safety analysis results"));
+
+void StackProtectAttributorPass::processFunction(Function &F) const {
+
+ bool hasAlloca = false;
+
+ for (auto &I : instructions(&F))
+ if (auto *AI = dyn_cast<AllocaInst>(&I)) {
+ hasAlloca = true;
+ NumFuncsWithAllocaInst++;
+ if (!SSI->isSafe(*AI))
+ return;
+ }
+
+ if (hasAlloca)
+ NumFuncsWithRemovedStackProtectAttr++;
+
+ F.removeFnAttr(Attribute::StackProtect);
+ F.removeFnAttr(Attribute::StackProtectStrong);
+}
+
+PreservedAnalyses StackProtectAttributorPass::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+ if (!UseStackSafety)
+ return PreservedAnalyses::all();
+
+ SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
+ for (Function &F : M)
+ if (F.hasFnAttribute(Attribute::StackProtect) ||
+ F.hasFnAttribute(Attribute::StackProtectStrong))
+ processFunction(F);
+
+ return PreservedAnalyses::all();
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll b/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
index 683cdfd9eeac8..5faa0a6fc8d59 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple aarch64-unknown-unknown -global-isel \
+; RUN: llc -ctpa-optimize-ssp=false -mtriple aarch64-unknown-unknown -global-isel \
; RUN: -no-stack-coloring=false -pass-remarks-missed=gisel* < %s \
; RUN: 2>&1 | FileCheck %s
diff --git a/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll b/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
index 4dc71bc90dcdc..32268bf29331c 100644
--- a/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
+++ b/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -o - -verify-machineinstrs | FileCheck %s
+; RUN: llc %s -o - -ctpa-optimize-ssp=false -verify-machineinstrs | FileCheck %s
target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
target triple = "thumbv7s-apple-ios8.0.0"
diff --git a/llvm/test/CodeGen/ARM/ssp-data-layout.ll b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
index c5f13a66c11ca..ceffe076b985f 100644
--- a/llvm/test/CodeGen/ARM/ssp-data-layout.ll
+++ b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -frame-pointer=all -mcpu=cortex-a8 -mtriple arm-linux-gnu -target-abi=apcs -o - | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -frame-pointer=all -mcpu=cortex-a8 -mtriple arm-linux-gnu -target-abi=apcs -o - | FileCheck %s
; This test is fairly fragile. The goal is to ensure that "large" stack
; objects are allocated closest to the stack protector (i.e., farthest away
; from the Stack Pointer.) In standard SSP mode this means that large (>=
diff --git a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
index 822f6a4c4616e..ead9bc9b64245 100644
--- a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
+++ b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=i386-apple-darwin -O0 -regalloc=fast | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=i386-apple-darwin -O0 -regalloc=fast | FileCheck %s
; rdar://6787136
%struct.X = type { i8, [32 x i8] }
diff --git a/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll b/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
index 99a50295727c4..8062704971a5f 100644
--- a/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
+++ b/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
; rdar://7396984
@str = private unnamed_addr constant [28 x i8] c"xxxxxxxxxxxxxxxxxxxxxxxxxxx\00", align 1
diff --git a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
index ecaa105dedcfe..112001dcf450f 100644
--- a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
+++ b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-- -mcpu=core2 | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=x86_64-- -mcpu=core2 | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
diff --git a/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll b/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
index abd1d4e7d350c..fc50bc9072395 100644
--- a/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
+++ b/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
@@ -1,4 +1,4 @@
-; RUN: llc -no-stack-coloring=false < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -no-stack-coloring=false < %s | FileCheck %s
; This test crashed in PEI because the stack protector was dead.
; This was due to it being colored, which was in turn due to incorrect
diff --git a/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll b/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
index a4e5ae66b1fd8..04c75e0915c92 100644
--- a/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
+++ b/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
@@ -1,4 +1,4 @@
-; RUN: llc -o - %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -o - %s | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx"
diff --git a/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll b/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
index 72d75456ce4ce..6ea291c876be5 100644
--- a/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
+++ b/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
@@ -1,4 +1,4 @@
-; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
; Ensure that the outliner doesn't outline from any functions that use a redzone.
declare ptr @llvm.stacksave() #1
diff --git a/llvm/test/CodeGen/X86/ssp-data-layout.ll b/llvm/test/CodeGen/X86/ssp-data-layout.ll
index bda2598384db8..16075f0149cc1 100644
--- a/llvm/test/CodeGen/X86/ssp-data-layout.ll
+++ b/llvm/test/CodeGen/X86/ssp-data-layout.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -stack-symbol-ordering=0 -frame-pointer=all -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -stack-symbol-ordering=0 -frame-pointer=all -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
; This test is fairly fragile. The goal is to ensure that "large" stack
; objects are allocated closest to the stack protector (i.e., farthest away
; from the Stack Pointer.) In standard SSP mode this means that large (>=
diff --git a/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll b/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
index d18353a89126c..d136c70ff44bb 100644
--- a/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
+++ b/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=x86_64 -O0 < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -mtriple=x86_64 -O0 < %s | FileCheck %s
; Check that we don't crash on this input.
; CHECK-LABEL: @foo
diff --git a/llvm/test/CodeGen/X86/stack-protector-remarks.ll b/llvm/test/CodeGen/X86/stack-protector-remarks.ll
index cbd986a64eac6..cb08058e50fb6 100644
--- a/llvm/test/CodeGen/X86/stack-protector-remarks.ll
+++ b/llvm/test/CodeGen/X86/stack-protector-remarks.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -mtriple=x86_64-unknown-unknown -pass-remarks=stack-protector -o /dev/null 2>&1 | FileCheck %s
+; RUN: llc %s -ctpa-optimize-ssp=false -mtriple=x86_64-unknown-unknown -pass-remarks=stack-protector -o /dev/null 2>&1 | FileCheck %s
; CHECK-NOT: nossp
; CHECK: function attribute_ssp
; CHECK-SAME: a function attribute or command-line switch
diff --git a/llvm/test/CodeGen/X86/stackguard-internal.ll b/llvm/test/CodeGen/X86/stackguard-internal.ll
index 328e04b9a718c..15177b4d3d866 100644
--- a/llvm/test/CodeGen/X86/stackguard-internal.ll
+++ b/llvm/test/CodeGen/X86/stackguard-internal.ll
@@ -1,5 +1,5 @@
; Check that the backend doesn't crash.
-; RUN: llc -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s
@__stack_chk_guard = internal global [8 x i64] zeroinitializer, align 16
diff --git a/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll b/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
index 53202f19f7602..6aa986a9ebd7a 100644
--- a/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
+++ b/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -o - -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
+; RUN: llc %s -o - -ctpa-optimize-ssp=false -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
; In the sequence below, the sdiv is converted to a function call to __divsi3,
; which is then tail call optimised. The dbg.value is suddenly stuck between
diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll
index c554fdbf4c799..bb8e00c5b260b 100644
--- a/llvm/test/Other/new-pm-defaults.ll
+++ b/llvm/test/Other/new-pm-defaults.ll
@@ -235,6 +235,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
; CHECK-O-NEXT: Running pass: GlobalOptPass
diff --git a/llvm/test/Other/new-pm-lto-defaults.ll b/llvm/test/Other/new-pm-lto-defaults.ll
index 3aea0f2061f3e..f8b4eabcbcdbc 100644
--- a/llvm/test/Other/new-pm-lto-defaults.ll
+++ b/llvm/test/Other/new-pm-lto-defaults.ll
@@ -67,6 +67,8 @@
; CHECK-O1-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-O-NEXT: Running pass: GlobalSplitPass
; CHECK-O-NEXT: Running pass: WholeProgramDevirtPass
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O23SZ-NEXT: Running pass: CoroEarlyPass
; CHECK-O1-NEXT: Running pass: LowerTypeTestsPass
; CHECK-O23SZ-NEXT: Running pass: GlobalOptPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
index 62bb02d9b3c40..fd1faf4bd9067 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
@@ -158,6 +158,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
index 0da7a9f73bdce..f25fce6fe497f 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
@@ -142,6 +142,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
index 38b7890682783..4422e9b7bb9e4 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
@@ -151,6 +151,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
index 5aacd26def2be..ba3d7e2fb58ad 100644
--- a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
@@ -188,6 +188,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: Shou...
[truncated]
|
@llvm/pr-subscribers-debuginfo Author: None (Mermen) ChangesThis pass uses StackSafetyGlobalAnalysis to reduce number of functions that require stack protector. All llvm lit tests passed. In llvm-test-suite it reduces number of instrumented functions by 13% (8883 -> 7723) under Patch is 24.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/150390.diff 31 Files Affected:
diff --git a/clang/test/Driver/memtag-stack_lto.c b/clang/test/Driver/memtag-stack_lto.c
index 324bdec070873..fc014c027fcf8 100644
--- a/clang/test/Driver/memtag-stack_lto.c
+++ b/clang/test/Driver/memtag-stack_lto.c
@@ -33,7 +33,7 @@
// RUN: rm -f %t*
// -O0: both are unsafe.
-// RUN: %clang -O0 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o - 2>&1 | FileCheck %s
+// RUN: %clang -O0 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o - 2>&1 | FileCheck %s -check-prefixes=CHECK-O0
// No LTO: just one is safe.
// RUN: %clang -O1 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefixes=SSI,XUNSAFE,YSAFE
@@ -87,6 +87,7 @@ int fn() {
return x + y;
}
-// CHECK-NOT: allocas uses:
+// CHECK-O0-NOT: allocas uses:
+// CHECK: allocas uses:
#endif
diff --git a/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h b/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h
new file mode 100644
index 0000000000000..d0097669d3067
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h
@@ -0,0 +1,33 @@
+//===- StackProtectAttributor.h - Stack Protect Attributoor ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
+#define LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
+
+#include "llvm/Analysis/StackSafetyAnalysis.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class BasicBlock;
+class Function;
+class Instruction;
+
+class StackProtectAttributorPass
+ : public PassInfoMixin<StackProtectAttributorPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+
+private:
+ void processFunction(Function &F) const;
+
+ const StackSafetyGlobalInfo *SSI;
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f810368a84940..1eebf607ef366 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -324,6 +324,7 @@
#include "llvm/Transforms/Scalar/Reassociate.h"
#include "llvm/Transforms/Scalar/Reg2Mem.h"
#include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
#include "llvm/Transforms/Scalar/SCCP.h"
#include "llvm/Transforms/Scalar/SROA.h"
#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 98821bb1408a7..20e297bfa3dc5 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -127,6 +127,7 @@
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
#include "llvm/Transforms/Scalar/SpeculativeExecution.h"
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
#include "llvm/Transforms/Scalar/TailRecursionElimination.h"
#include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
#include "llvm/Transforms/Utils/AddDiscriminators.h"
@@ -1278,6 +1279,9 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
else
MPM.addPass(buildInlinerPipeline(Level, Phase));
+ if (Level != OptimizationLevel::O0)
+ MPM.addPass(StackProtectAttributorPass());
+
// Remove any dead arguments exposed by cleanups, constant folding globals,
// and argument promotion.
MPM.addPass(DeadArgumentEliminationPass());
@@ -1944,6 +1948,8 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
// is fixed.
MPM.addPass(WholeProgramDevirtPass(ExportSummary, nullptr));
+ MPM.addPass(StackProtectAttributorPass());
+
// Stop here at -O1.
if (Level == OptimizationLevel::O1) {
// The LowerTypeTestsPass needs to run to lower type metadata and the
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index bb7ccdb2bc187..d1a22c9ece01e 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -59,6 +59,7 @@ MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass())
MODULE_PASS("check-debugify", NewPMCheckDebugifyPass())
MODULE_PASS("constmerge", ConstantMergePass())
MODULE_PASS("coro-cleanup", CoroCleanupPass())
+MODULE_PASS("stack-protect-attributor", StackProtectAttributorPass())
MODULE_PASS("coro-early", CoroEarlyPass())
MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass())
MODULE_PASS("ctx-instr-gen",
diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt
index 84a5b02043d01..b161ab6810a8c 100644
--- a/llvm/lib/Transforms/Scalar/CMakeLists.txt
+++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt
@@ -64,6 +64,7 @@ add_llvm_component_library(LLVMScalarOpts
PlaceSafepoints.cpp
Reassociate.cpp
Reg2Mem.cpp
+ StackProtectAttributor.cpp
RewriteStatepointsForGC.cpp
SCCP.cpp
SROA.cpp
diff --git a/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp b/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp
new file mode 100644
index 0000000000000..8695cb32c4e5d
--- /dev/null
+++ b/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp
@@ -0,0 +1,60 @@
+//===- StackProtectAttributor.cpp - Stack Protect Attributoor -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "stack-protect-attributor"
+
+STATISTIC(
+ NumFuncsWithAllocaInst,
+ "Number of functions with an instruction to allocate memory on the stack");
+STATISTIC(NumFuncsWithRemovedStackProtectAttr,
+ "Number of functions with alloca and removed stack protect attr");
+
+static cl::opt<bool>
+ UseStackSafety("ctpa-optimize-ssp", cl::init(true), cl::Hidden,
+ cl::desc("Use Stack Safety analysis results"));
+
+void StackProtectAttributorPass::processFunction(Function &F) const {
+
+ bool hasAlloca = false;
+
+ for (auto &I : instructions(&F))
+ if (auto *AI = dyn_cast<AllocaInst>(&I)) {
+ hasAlloca = true;
+ NumFuncsWithAllocaInst++;
+ if (!SSI->isSafe(*AI))
+ return;
+ }
+
+ if (hasAlloca)
+ NumFuncsWithRemovedStackProtectAttr++;
+
+ F.removeFnAttr(Attribute::StackProtect);
+ F.removeFnAttr(Attribute::StackProtectStrong);
+}
+
+PreservedAnalyses StackProtectAttributorPass::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+ if (!UseStackSafety)
+ return PreservedAnalyses::all();
+
+ SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
+ for (Function &F : M)
+ if (F.hasFnAttribute(Attribute::StackProtect) ||
+ F.hasFnAttribute(Attribute::StackProtectStrong))
+ processFunction(F);
+
+ return PreservedAnalyses::all();
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll b/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
index 683cdfd9eeac8..5faa0a6fc8d59 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple aarch64-unknown-unknown -global-isel \
+; RUN: llc -ctpa-optimize-ssp=false -mtriple aarch64-unknown-unknown -global-isel \
; RUN: -no-stack-coloring=false -pass-remarks-missed=gisel* < %s \
; RUN: 2>&1 | FileCheck %s
diff --git a/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll b/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
index 4dc71bc90dcdc..32268bf29331c 100644
--- a/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
+++ b/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -o - -verify-machineinstrs | FileCheck %s
+; RUN: llc %s -o - -ctpa-optimize-ssp=false -verify-machineinstrs | FileCheck %s
target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
target triple = "thumbv7s-apple-ios8.0.0"
diff --git a/llvm/test/CodeGen/ARM/ssp-data-layout.ll b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
index c5f13a66c11ca..ceffe076b985f 100644
--- a/llvm/test/CodeGen/ARM/ssp-data-layout.ll
+++ b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -frame-pointer=all -mcpu=cortex-a8 -mtriple arm-linux-gnu -target-abi=apcs -o - | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -frame-pointer=all -mcpu=cortex-a8 -mtriple arm-linux-gnu -target-abi=apcs -o - | FileCheck %s
; This test is fairly fragile. The goal is to ensure that "large" stack
; objects are allocated closest to the stack protector (i.e., farthest away
; from the Stack Pointer.) In standard SSP mode this means that large (>=
diff --git a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
index 822f6a4c4616e..ead9bc9b64245 100644
--- a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
+++ b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=i386-apple-darwin -O0 -regalloc=fast | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=i386-apple-darwin -O0 -regalloc=fast | FileCheck %s
; rdar://6787136
%struct.X = type { i8, [32 x i8] }
diff --git a/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll b/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
index 99a50295727c4..8062704971a5f 100644
--- a/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
+++ b/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
; rdar://7396984
@str = private unnamed_addr constant [28 x i8] c"xxxxxxxxxxxxxxxxxxxxxxxxxxx\00", align 1
diff --git a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
index ecaa105dedcfe..112001dcf450f 100644
--- a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
+++ b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-- -mcpu=core2 | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=x86_64-- -mcpu=core2 | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
diff --git a/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll b/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
index abd1d4e7d350c..fc50bc9072395 100644
--- a/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
+++ b/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
@@ -1,4 +1,4 @@
-; RUN: llc -no-stack-coloring=false < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -no-stack-coloring=false < %s | FileCheck %s
; This test crashed in PEI because the stack protector was dead.
; This was due to it being colored, which was in turn due to incorrect
diff --git a/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll b/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
index a4e5ae66b1fd8..04c75e0915c92 100644
--- a/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
+++ b/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
@@ -1,4 +1,4 @@
-; RUN: llc -o - %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -o - %s | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx"
diff --git a/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll b/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
index 72d75456ce4ce..6ea291c876be5 100644
--- a/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
+++ b/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
@@ -1,4 +1,4 @@
-; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
; Ensure that the outliner doesn't outline from any functions that use a redzone.
declare ptr @llvm.stacksave() #1
diff --git a/llvm/test/CodeGen/X86/ssp-data-layout.ll b/llvm/test/CodeGen/X86/ssp-data-layout.ll
index bda2598384db8..16075f0149cc1 100644
--- a/llvm/test/CodeGen/X86/ssp-data-layout.ll
+++ b/llvm/test/CodeGen/X86/ssp-data-layout.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -stack-symbol-ordering=0 -frame-pointer=all -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -stack-symbol-ordering=0 -frame-pointer=all -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
; This test is fairly fragile. The goal is to ensure that "large" stack
; objects are allocated closest to the stack protector (i.e., farthest away
; from the Stack Pointer.) In standard SSP mode this means that large (>=
diff --git a/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll b/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
index d18353a89126c..d136c70ff44bb 100644
--- a/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
+++ b/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=x86_64 -O0 < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -mtriple=x86_64 -O0 < %s | FileCheck %s
; Check that we don't crash on this input.
; CHECK-LABEL: @foo
diff --git a/llvm/test/CodeGen/X86/stack-protector-remarks.ll b/llvm/test/CodeGen/X86/stack-protector-remarks.ll
index cbd986a64eac6..cb08058e50fb6 100644
--- a/llvm/test/CodeGen/X86/stack-protector-remarks.ll
+++ b/llvm/test/CodeGen/X86/stack-protector-remarks.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -mtriple=x86_64-unknown-unknown -pass-remarks=stack-protector -o /dev/null 2>&1 | FileCheck %s
+; RUN: llc %s -ctpa-optimize-ssp=false -mtriple=x86_64-unknown-unknown -pass-remarks=stack-protector -o /dev/null 2>&1 | FileCheck %s
; CHECK-NOT: nossp
; CHECK: function attribute_ssp
; CHECK-SAME: a function attribute or command-line switch
diff --git a/llvm/test/CodeGen/X86/stackguard-internal.ll b/llvm/test/CodeGen/X86/stackguard-internal.ll
index 328e04b9a718c..15177b4d3d866 100644
--- a/llvm/test/CodeGen/X86/stackguard-internal.ll
+++ b/llvm/test/CodeGen/X86/stackguard-internal.ll
@@ -1,5 +1,5 @@
; Check that the backend doesn't crash.
-; RUN: llc -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s
@__stack_chk_guard = internal global [8 x i64] zeroinitializer, align 16
diff --git a/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll b/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
index 53202f19f7602..6aa986a9ebd7a 100644
--- a/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
+++ b/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -o - -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
+; RUN: llc %s -o - -ctpa-optimize-ssp=false -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
; In the sequence below, the sdiv is converted to a function call to __divsi3,
; which is then tail call optimised. The dbg.value is suddenly stuck between
diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll
index c554fdbf4c799..bb8e00c5b260b 100644
--- a/llvm/test/Other/new-pm-defaults.ll
+++ b/llvm/test/Other/new-pm-defaults.ll
@@ -235,6 +235,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
; CHECK-O-NEXT: Running pass: GlobalOptPass
diff --git a/llvm/test/Other/new-pm-lto-defaults.ll b/llvm/test/Other/new-pm-lto-defaults.ll
index 3aea0f2061f3e..f8b4eabcbcdbc 100644
--- a/llvm/test/Other/new-pm-lto-defaults.ll
+++ b/llvm/test/Other/new-pm-lto-defaults.ll
@@ -67,6 +67,8 @@
; CHECK-O1-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-O-NEXT: Running pass: GlobalSplitPass
; CHECK-O-NEXT: Running pass: WholeProgramDevirtPass
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O23SZ-NEXT: Running pass: CoroEarlyPass
; CHECK-O1-NEXT: Running pass: LowerTypeTestsPass
; CHECK-O23SZ-NEXT: Running pass: GlobalOptPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
index 62bb02d9b3c40..fd1faf4bd9067 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
@@ -158,6 +158,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
index 0da7a9f73bdce..f25fce6fe497f 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
@@ -142,6 +142,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
index 38b7890682783..4422e9b7bb9e4 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
@@ -151,6 +151,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
index 5aacd26def2be..ba3d7e2fb58ad 100644
--- a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
@@ -188,6 +188,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: Shou...
[truncated]
|
@llvm/pr-subscribers-llvm-transforms Author: None (Mermen) ChangesThis pass uses StackSafetyGlobalAnalysis to reduce number of functions that require stack protector. All llvm lit tests passed. In llvm-test-suite it reduces number of instrumented functions by 13% (8883 -> 7723) under Patch is 24.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/150390.diff 31 Files Affected:
diff --git a/clang/test/Driver/memtag-stack_lto.c b/clang/test/Driver/memtag-stack_lto.c
index 324bdec070873..fc014c027fcf8 100644
--- a/clang/test/Driver/memtag-stack_lto.c
+++ b/clang/test/Driver/memtag-stack_lto.c
@@ -33,7 +33,7 @@
// RUN: rm -f %t*
// -O0: both are unsafe.
-// RUN: %clang -O0 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o - 2>&1 | FileCheck %s
+// RUN: %clang -O0 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o - 2>&1 | FileCheck %s -check-prefixes=CHECK-O0
// No LTO: just one is safe.
// RUN: %clang -O1 --target=aarch64-unknown-linux -march=armv8+memtag -fsanitize=memtag-stack -mllvm -stack-safety-print %s -S -o /dev/null 2>&1 | FileCheck %s -check-prefixes=SSI,XUNSAFE,YSAFE
@@ -87,6 +87,7 @@ int fn() {
return x + y;
}
-// CHECK-NOT: allocas uses:
+// CHECK-O0-NOT: allocas uses:
+// CHECK: allocas uses:
#endif
diff --git a/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h b/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h
new file mode 100644
index 0000000000000..d0097669d3067
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Scalar/StackProtectAttributor.h
@@ -0,0 +1,33 @@
+//===- StackProtectAttributor.h - Stack Protect Attributoor ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
+#define LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
+
+#include "llvm/Analysis/StackSafetyAnalysis.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class BasicBlock;
+class Function;
+class Instruction;
+
+class StackProtectAttributorPass
+ : public PassInfoMixin<StackProtectAttributorPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+
+private:
+ void processFunction(Function &F) const;
+
+ const StackSafetyGlobalInfo *SSI;
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_ATTRIBUTTOR_H
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f810368a84940..1eebf607ef366 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -324,6 +324,7 @@
#include "llvm/Transforms/Scalar/Reassociate.h"
#include "llvm/Transforms/Scalar/Reg2Mem.h"
#include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h"
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
#include "llvm/Transforms/Scalar/SCCP.h"
#include "llvm/Transforms/Scalar/SROA.h"
#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 98821bb1408a7..20e297bfa3dc5 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -127,6 +127,7 @@
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
#include "llvm/Transforms/Scalar/SpeculativeExecution.h"
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
#include "llvm/Transforms/Scalar/TailRecursionElimination.h"
#include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
#include "llvm/Transforms/Utils/AddDiscriminators.h"
@@ -1278,6 +1279,9 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
else
MPM.addPass(buildInlinerPipeline(Level, Phase));
+ if (Level != OptimizationLevel::O0)
+ MPM.addPass(StackProtectAttributorPass());
+
// Remove any dead arguments exposed by cleanups, constant folding globals,
// and argument promotion.
MPM.addPass(DeadArgumentEliminationPass());
@@ -1944,6 +1948,8 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
// is fixed.
MPM.addPass(WholeProgramDevirtPass(ExportSummary, nullptr));
+ MPM.addPass(StackProtectAttributorPass());
+
// Stop here at -O1.
if (Level == OptimizationLevel::O1) {
// The LowerTypeTestsPass needs to run to lower type metadata and the
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index bb7ccdb2bc187..d1a22c9ece01e 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -59,6 +59,7 @@ MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass())
MODULE_PASS("check-debugify", NewPMCheckDebugifyPass())
MODULE_PASS("constmerge", ConstantMergePass())
MODULE_PASS("coro-cleanup", CoroCleanupPass())
+MODULE_PASS("stack-protect-attributor", StackProtectAttributorPass())
MODULE_PASS("coro-early", CoroEarlyPass())
MODULE_PASS("cross-dso-cfi", CrossDSOCFIPass())
MODULE_PASS("ctx-instr-gen",
diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt
index 84a5b02043d01..b161ab6810a8c 100644
--- a/llvm/lib/Transforms/Scalar/CMakeLists.txt
+++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt
@@ -64,6 +64,7 @@ add_llvm_component_library(LLVMScalarOpts
PlaceSafepoints.cpp
Reassociate.cpp
Reg2Mem.cpp
+ StackProtectAttributor.cpp
RewriteStatepointsForGC.cpp
SCCP.cpp
SROA.cpp
diff --git a/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp b/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp
new file mode 100644
index 0000000000000..8695cb32c4e5d
--- /dev/null
+++ b/llvm/lib/Transforms/Scalar/StackProtectAttributor.cpp
@@ -0,0 +1,60 @@
+//===- StackProtectAttributor.cpp - Stack Protect Attributoor -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Scalar/StackProtectAttributor.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "stack-protect-attributor"
+
+STATISTIC(
+ NumFuncsWithAllocaInst,
+ "Number of functions with an instruction to allocate memory on the stack");
+STATISTIC(NumFuncsWithRemovedStackProtectAttr,
+ "Number of functions with alloca and removed stack protect attr");
+
+static cl::opt<bool>
+ UseStackSafety("ctpa-optimize-ssp", cl::init(true), cl::Hidden,
+ cl::desc("Use Stack Safety analysis results"));
+
+void StackProtectAttributorPass::processFunction(Function &F) const {
+
+ bool hasAlloca = false;
+
+ for (auto &I : instructions(&F))
+ if (auto *AI = dyn_cast<AllocaInst>(&I)) {
+ hasAlloca = true;
+ NumFuncsWithAllocaInst++;
+ if (!SSI->isSafe(*AI))
+ return;
+ }
+
+ if (hasAlloca)
+ NumFuncsWithRemovedStackProtectAttr++;
+
+ F.removeFnAttr(Attribute::StackProtect);
+ F.removeFnAttr(Attribute::StackProtectStrong);
+}
+
+PreservedAnalyses StackProtectAttributorPass::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+ if (!UseStackSafety)
+ return PreservedAnalyses::all();
+
+ SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
+ for (Function &F : M)
+ if (F.hasFnAttribute(Attribute::StackProtect) ||
+ F.hasFnAttribute(Attribute::StackProtectStrong))
+ processFunction(F);
+
+ return PreservedAnalyses::all();
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll b/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
index 683cdfd9eeac8..5faa0a6fc8d59 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/dynamic-alloca-lifetime.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple aarch64-unknown-unknown -global-isel \
+; RUN: llc -ctpa-optimize-ssp=false -mtriple aarch64-unknown-unknown -global-isel \
; RUN: -no-stack-coloring=false -pass-remarks-missed=gisel* < %s \
; RUN: 2>&1 | FileCheck %s
diff --git a/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll b/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
index 4dc71bc90dcdc..32268bf29331c 100644
--- a/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
+++ b/llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -o - -verify-machineinstrs | FileCheck %s
+; RUN: llc %s -o - -ctpa-optimize-ssp=false -verify-machineinstrs | FileCheck %s
target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
target triple = "thumbv7s-apple-ios8.0.0"
diff --git a/llvm/test/CodeGen/ARM/ssp-data-layout.ll b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
index c5f13a66c11ca..ceffe076b985f 100644
--- a/llvm/test/CodeGen/ARM/ssp-data-layout.ll
+++ b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -frame-pointer=all -mcpu=cortex-a8 -mtriple arm-linux-gnu -target-abi=apcs -o - | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -frame-pointer=all -mcpu=cortex-a8 -mtriple arm-linux-gnu -target-abi=apcs -o - | FileCheck %s
; This test is fairly fragile. The goal is to ensure that "large" stack
; objects are allocated closest to the stack protector (i.e., farthest away
; from the Stack Pointer.) In standard SSP mode this means that large (>=
diff --git a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
index 822f6a4c4616e..ead9bc9b64245 100644
--- a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
+++ b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=i386-apple-darwin -O0 -regalloc=fast | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=i386-apple-darwin -O0 -regalloc=fast | FileCheck %s
; rdar://6787136
%struct.X = type { i8, [32 x i8] }
diff --git a/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll b/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
index 99a50295727c4..8062704971a5f 100644
--- a/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
+++ b/llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
; rdar://7396984
@str = private unnamed_addr constant [28 x i8] c"xxxxxxxxxxxxxxxxxxxxxxxxxxx\00", align 1
diff --git a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
index ecaa105dedcfe..112001dcf450f 100644
--- a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
+++ b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-- -mcpu=core2 | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -mtriple=x86_64-- -mcpu=core2 | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind
diff --git a/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll b/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
index abd1d4e7d350c..fc50bc9072395 100644
--- a/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
+++ b/llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
@@ -1,4 +1,4 @@
-; RUN: llc -no-stack-coloring=false < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -no-stack-coloring=false < %s | FileCheck %s
; This test crashed in PEI because the stack protector was dead.
; This was due to it being colored, which was in turn due to incorrect
diff --git a/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll b/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
index a4e5ae66b1fd8..04c75e0915c92 100644
--- a/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
+++ b/llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
@@ -1,4 +1,4 @@
-; RUN: llc -o - %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -o - %s | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx"
diff --git a/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll b/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
index 72d75456ce4ce..6ea291c876be5 100644
--- a/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
+++ b/llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
@@ -1,4 +1,4 @@
-; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
; Ensure that the outliner doesn't outline from any functions that use a redzone.
declare ptr @llvm.stacksave() #1
diff --git a/llvm/test/CodeGen/X86/ssp-data-layout.ll b/llvm/test/CodeGen/X86/ssp-data-layout.ll
index bda2598384db8..16075f0149cc1 100644
--- a/llvm/test/CodeGen/X86/ssp-data-layout.ll
+++ b/llvm/test/CodeGen/X86/ssp-data-layout.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -stack-symbol-ordering=0 -frame-pointer=all -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
+; RUN: llc < %s -ctpa-optimize-ssp=false -stack-symbol-ordering=0 -frame-pointer=all -mtriple=x86_64-pc-linux-gnu -mcpu=corei7 -o - | FileCheck %s
; This test is fairly fragile. The goal is to ensure that "large" stack
; objects are allocated closest to the stack protector (i.e., farthest away
; from the Stack Pointer.) In standard SSP mode this means that large (>=
diff --git a/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll b/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
index d18353a89126c..d136c70ff44bb 100644
--- a/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
+++ b/llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=x86_64 -O0 < %s | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -mtriple=x86_64 -O0 < %s | FileCheck %s
; Check that we don't crash on this input.
; CHECK-LABEL: @foo
diff --git a/llvm/test/CodeGen/X86/stack-protector-remarks.ll b/llvm/test/CodeGen/X86/stack-protector-remarks.ll
index cbd986a64eac6..cb08058e50fb6 100644
--- a/llvm/test/CodeGen/X86/stack-protector-remarks.ll
+++ b/llvm/test/CodeGen/X86/stack-protector-remarks.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -mtriple=x86_64-unknown-unknown -pass-remarks=stack-protector -o /dev/null 2>&1 | FileCheck %s
+; RUN: llc %s -ctpa-optimize-ssp=false -mtriple=x86_64-unknown-unknown -pass-remarks=stack-protector -o /dev/null 2>&1 | FileCheck %s
; CHECK-NOT: nossp
; CHECK: function attribute_ssp
; CHECK-SAME: a function attribute or command-line switch
diff --git a/llvm/test/CodeGen/X86/stackguard-internal.ll b/llvm/test/CodeGen/X86/stackguard-internal.ll
index 328e04b9a718c..15177b4d3d866 100644
--- a/llvm/test/CodeGen/X86/stackguard-internal.ll
+++ b/llvm/test/CodeGen/X86/stackguard-internal.ll
@@ -1,5 +1,5 @@
; Check that the backend doesn't crash.
-; RUN: llc -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s
+; RUN: llc -ctpa-optimize-ssp=false -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s
@__stack_chk_guard = internal global [8 x i64] zeroinitializer, align 16
diff --git a/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll b/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
index 53202f19f7602..6aa986a9ebd7a 100644
--- a/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
+++ b/llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -o - -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
+; RUN: llc %s -o - -ctpa-optimize-ssp=false -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
; In the sequence below, the sdiv is converted to a function call to __divsi3,
; which is then tail call optimised. The dbg.value is suddenly stuck between
diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll
index c554fdbf4c799..bb8e00c5b260b 100644
--- a/llvm/test/Other/new-pm-defaults.ll
+++ b/llvm/test/Other/new-pm-defaults.ll
@@ -235,6 +235,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
; CHECK-O-NEXT: Running pass: GlobalOptPass
diff --git a/llvm/test/Other/new-pm-lto-defaults.ll b/llvm/test/Other/new-pm-lto-defaults.ll
index 3aea0f2061f3e..f8b4eabcbcdbc 100644
--- a/llvm/test/Other/new-pm-lto-defaults.ll
+++ b/llvm/test/Other/new-pm-lto-defaults.ll
@@ -67,6 +67,8 @@
; CHECK-O1-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-O-NEXT: Running pass: GlobalSplitPass
; CHECK-O-NEXT: Running pass: WholeProgramDevirtPass
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O23SZ-NEXT: Running pass: CoroEarlyPass
; CHECK-O1-NEXT: Running pass: LowerTypeTestsPass
; CHECK-O23SZ-NEXT: Running pass: GlobalOptPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
index 62bb02d9b3c40..fd1faf4bd9067 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
@@ -158,6 +158,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
index 0da7a9f73bdce..f25fce6fe497f 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
@@ -142,6 +142,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
index 38b7890682783..4422e9b7bb9e4 100644
--- a/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
@@ -151,6 +151,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
+; CHECK-O-NEXT: Running pass: StackProtectAttributorPass
+; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
diff --git a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
index 5aacd26def2be..ba3d7e2fb58ad 100644
--- a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
+++ b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
@@ -188,6 +188,8 @@
; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis
; CHECK-O-NEXT: Invalidating analysis: Shou...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a separate pass that removes attributes from the function if all allocas are safe, rather than integrated with the actual stack protection, so that the decision can be made per alloca?
@vitalybuka @eugenis FYI |
StackSafetyAnalysis is a module pass so using it in StackProtectorPass (which is a function pass) changes pipeline significantly (introducing spurious changes in tests and performance jitter). |
627fe89
to
ce503cf
Compare
llvm/lib/Passes/PassBuilder.cpp
Outdated
@@ -324,6 +324,7 @@ | |||
#include "llvm/Transforms/Scalar/Reassociate.h" | |||
#include "llvm/Transforms/Scalar/Reg2Mem.h" | |||
#include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h" | |||
#include "llvm/Transforms/Scalar/StackProtectAttributor.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sorted correctly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"StackProtectAttributor" sounds like it is adding stack-protection attributes, but it is actually removing them. Please find a better name; "StackProtectRefinement" maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not use attributor and should not have attributor in the name
ce503cf
to
2242daa
Compare
2242daa
to
f1c7f73
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly stylistic suggestions.
llvm/lib/Passes/PassRegistry.def
Outdated
@@ -59,6 +59,7 @@ MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass()) | |||
MODULE_PASS("check-debugify", NewPMCheckDebugifyPass()) | |||
MODULE_PASS("constmerge", ConstantMergePass()) | |||
MODULE_PASS("coro-cleanup", CoroCleanupPass()) | |||
MODULE_PASS("stack-protect-refinement", StackProtectRefinementPass()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list is sorted, pls put in correct position
|
||
bool hasAlloca = false; | ||
|
||
for (auto &I : instructions(&F)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pls put braces around this for-loop body. It is technically one statement but contains nested statements with their own braces.
@@ -0,0 +1,64 @@ | |||
// RUN: clang -O2 -fstack-protector-strong -emit-llvm -S %s -o - | FileCheck %s | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pls remove excess blank lines, you need only one
} | ||
|
||
//. | ||
// CHECK-NOT: attributes #[[ATTR1]] = {{.* sspstrong}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// CHECK-NOT: attributes #[[ATTR1]] = {{.* sspstrong}} | |
// CHECK: attributes #[[ATTR1]] = | |
// CHECK-NOT: sspstrong |
Not a big deal but slightly more robust IMO to have positive checks for each attribute number
// CHECK: attributes #[[ATTR2]] = {{.* sspstrong}} | ||
// CHECK: attributes #[[ATTR3]] = {{.* sspstrong}} | ||
// CHECK: attributes #[[ATTR4]] = {{.* sspstrong}} | ||
// CHECK-NOT: attributes #[[ATTR5]] = {{.* sspstrong}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// CHECK-NOT: attributes #[[ATTR5]] = {{.* sspstrong}} | |
// CHECK: attributes #[[ATTR5]] = | |
// CHECK-NOT: sspstrong |
#ifndef LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_REFINEMENT_H | ||
#define LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_REFINEMENT_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#ifndef LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_REFINEMENT_H | |
#define LLVM_TRANSFORMS_SCALAR_STACK_PROTECT_REFINEMENT_H | |
#ifndef LLVM_TRANSFORMS_SCALAR_STACKPROTECTREFINEMENT_H | |
#define LLVM_TRANSFORMS_SCALAR_STACKPROTECTREFINEMENT_H |
Underscores replace punctuation rather than separating words
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Remove ssp attributes from functions where we can prove it is safe. | |
Any data on compile-time cost? I imagine it won't be huge but worth it to look at one decent-sized example. |
…necessary protections. This pass uses StackSafetyGlobalAnalysis to reduce number of functions that require stack protector.
f1c7f73
to
7a7ced9
Compare
for (auto &I : instructions(&F)) { | ||
if (auto *AI = dyn_cast<AllocaInst>(&I)) { | ||
hasAlloca = true; | ||
if (!SSI->isSafe(*AI)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is all the pass is doing, should this just be done directly in the SSP lowering pass?
Stripping the attribute seems potentially dangerous. Suppose a later pass chooses to introduce a new unsafe alloca, which will now no longer be appropriately processed during lowering
This pass uses StackSafetyGlobalAnalysis to reduce number of functions that require stack protector.
All llvm lit tests passed.
In llvm-test-suite it reduces number of instrumented functions by 13% (8883 -> 7723) under
-O2 -fstack-protector-strong
.Thanks to @yugr for the original idea.