Skip to content

[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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions llvm/include/llvm/Transforms/Scalar/StackProtectRefinement.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===- StackProtectRefinement.h - Stack Protect Refinement ----------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Remove ssp attributes from functions where we can prove it is safe.
//
//===----------------------------------------------------------------------===//

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Remove ssp attributes from functions where we can prove it is safe.

#ifndef LLVM_TRANSFORMS_SCALAR_STACKPROTECTREFINEMENT_H
#define LLVM_TRANSFORMS_SCALAR_STACKPROTECTREFINEMENT_H

#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/IR/PassManager.h"

namespace llvm {

class BasicBlock;
class Function;
class Instruction;

class StackProtectRefinementPass
: public PassInfoMixin<StackProtectRefinementPass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);

private:
void processFunction(Function &F) const;

const StackSafetyGlobalInfo *SSI;
};
} // end namespace llvm

#endif // LLVM_TRANSFORMS_SCALAR_STACKPROTECTREFINEMENT_H
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
#include "llvm/Transforms/Scalar/Sink.h"
#include "llvm/Transforms/Scalar/SpeculativeExecution.h"
#include "llvm/Transforms/Scalar/StackProtectRefinement.h"
#include "llvm/Transforms/Scalar/StraightLineStrengthReduce.h"
#include "llvm/Transforms/Scalar/StructurizeCFG.h"
#include "llvm/Transforms/Scalar/TailRecursionElimination.h"
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Passes/PassBuilderPipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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/StackProtectRefinement.h"
#include "llvm/Transforms/Scalar/TailRecursionElimination.h"
#include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
#include "llvm/Transforms/Utils/AddDiscriminators.h"
Expand Down Expand Up @@ -1278,6 +1279,9 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
else
MPM.addPass(buildInlinerPipeline(Level, Phase));

if (Level != OptimizationLevel::O0)
MPM.addPass(StackProtectRefinementPass());

// Remove any dead arguments exposed by cleanups, constant folding globals,
// and argument promotion.
MPM.addPass(DeadArgumentEliminationPass());
Expand Down Expand Up @@ -1944,6 +1948,8 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
// is fixed.
MPM.addPass(WholeProgramDevirtPass(ExportSummary, nullptr));

MPM.addPass(StackProtectRefinementPass());

// Stop here at -O1.
if (Level == OptimizationLevel::O1) {
// The LowerTypeTestsPass needs to run to lower type metadata and the
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ MODULE_PASS("scc-oz-module-inliner",
buildInlinerPipeline(OptimizationLevel::Oz,
ThinOrFullLTOPhase::None))
MODULE_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass())
MODULE_PASS("stack-protect-refinement", StackProtectRefinementPass())
MODULE_PASS("strip", StripSymbolsPass())
MODULE_PASS("strip-dead-debug-info", StripDeadDebugInfoPass())
MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass())
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/Scalar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ add_llvm_component_library(LLVMScalarOpts
SimplifyCFGPass.cpp
Sink.cpp
SpeculativeExecution.cpp
StackProtectRefinement.cpp
StraightLineStrengthReduce.cpp
StructurizeCFG.cpp
TailRecursionElimination.cpp
Expand Down
64 changes: 64 additions & 0 deletions llvm/lib/Transforms/Scalar/StackProtectRefinement.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//===- StackProtectRefinement.cpp - Stack Protect Refinement --------------===//
//
// 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/StackProtectRefinement.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-refinement"

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("optimize-ssp", cl::init(true), cl::Hidden,
cl::desc("Use Stack Safety analysis results"));

void StackProtectRefinementPass::processFunction(Function &F) const {

bool hasAlloca = false;

for (auto &I : instructions(&F)) {
if (auto *AI = dyn_cast<AllocaInst>(&I)) {
hasAlloca = true;
if (!SSI->isSafe(*AI)) {
Copy link
Contributor

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

NumFuncsWithAllocaInst++;
return;
}
}
}

if (hasAlloca) {
NumFuncsWithAllocaInst++;
NumFuncsWithRemovedStackProtectAttr++;
}

F.removeFnAttr(Attribute::StackProtect);
F.removeFnAttr(Attribute::StackProtectStrong);
}

PreservedAnalyses StackProtectRefinementPass::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();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc -mtriple aarch64-unknown-unknown -global-isel \
; RUN: llc -optimize-ssp=false -mtriple aarch64-unknown-unknown -global-isel \
; RUN: -no-stack-coloring=false -pass-remarks-missed=gisel* < %s \
; RUN: 2>&1 | FileCheck %s

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/ARM/ifcvt-regmask-noreturn.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc %s -o - -verify-machineinstrs | FileCheck %s
; RUN: llc %s -o - -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"
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/ARM/ssp-data-layout.ll
Original file line number Diff line number Diff line change
@@ -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 -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 (>=
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll
Original file line number Diff line number Diff line change
@@ -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 -optimize-ssp=false -mtriple=i386-apple-darwin -O0 -regalloc=fast | FileCheck %s
; rdar://6787136

%struct.X = type { i8, [32 x i8] }
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/2009-11-16-UnfoldMemOpBug.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck %s
; RUN: llc < %s -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
Original file line number Diff line number Diff line change
@@ -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 -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/dynamic-alloca-lifetime.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc -no-stack-coloring=false < %s | FileCheck %s
; RUN: llc -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/fast-isel-stackcheck.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc -o - %s | FileCheck %s
; RUN: llc -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"

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/X86/machine-outliner-noredzone.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s
; RUN: llc -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
Expand Down Expand Up @@ -67,4 +67,4 @@ define void @shibe(i32) #0 {
}

attributes #0 = { noinline nounwind optnone ssp uwtable "frame-pointer"="all" }
attributes #1 = { nounwind }
attributes #1 = { nounwind }
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/ssp-data-layout.ll
Original file line number Diff line number Diff line change
@@ -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 -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 (>=
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/stack-guard-memloc-vararg.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc -mtriple=x86_64 -O0 < %s | FileCheck %s
; RUN: llc -optimize-ssp=false -mtriple=x86_64 -O0 < %s | FileCheck %s

; Check that we don't crash on this input.
; CHECK-LABEL: @foo
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/stack-protector-remarks.ll
Original file line number Diff line number Diff line change
@@ -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 -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
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/stackguard-internal.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; Check that the backend doesn't crash.
; RUN: llc -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s
; RUN: llc -optimize-ssp=false -mtriple=x86_64-pc-freebsd %s -o - | FileCheck %s

@__stack_chk_guard = internal global [8 x i64] zeroinitializer, align 16

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/DebugInfo/ARM/instr-ref-tcreturn.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc %s -o - -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
; RUN: llc %s -o - -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
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Other/new-pm-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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: StackProtectRefinementPass
; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
; CHECK-O-NEXT: Running pass: GlobalOptPass
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Other/new-pm-lto-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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: StackProtectRefinementPass
; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O23SZ-NEXT: Running pass: CoroEarlyPass
; CHECK-O1-NEXT: Running pass: LowerTypeTestsPass
; CHECK-O23SZ-NEXT: Running pass: GlobalOptPass
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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: StackProtectRefinementPass
; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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: StackProtectRefinementPass
; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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: StackProtectRefinementPass
; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
; CHECK-O-NEXT: Running pass: CoroCleanupPass
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,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: StackProtectRefinementPass
; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: GlobalOptPass
; CHECK-O-NEXT: Running pass: GlobalDCEPass
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,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: StackProtectRefinementPass
; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: GlobalOptPass
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis on bar
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,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: StackProtectRefinementPass
; CHECK-O-NEXT: Running analysis: StackSafetyGlobalAnalysis
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O-NEXT: Running pass: GlobalOptPass
; CHECK-O-NEXT: Running pass: GlobalDCEPass
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/ThinLTO/X86/nossp.ll
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; RUN: split-file %s %t
; RUN: opt -module-summary %t/a.ll -o %ta.bc
; RUN: opt -module-summary %t/b.ll -o %tb.bc
; RUN: llvm-lto2 run %ta.bc %tb.bc -o %tc.bc -save-temps \
; RUN: opt -optimize-ssp=false -module-summary %t/a.ll -o %ta.bc
; RUN: opt -optimize-ssp=false -module-summary %t/b.ll -o %tb.bc
; RUN: llvm-lto2 run -optimize-ssp=false %ta.bc %tb.bc -o %tc.bc -save-temps \
; RUN: -r=%ta.bc,nossp_caller,px \
; RUN: -r=%ta.bc,ssp_caller,px \
; RUN: -r=%ta.bc,nossp_caller2,px \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// RUN: clang -O2 -fstack-protector-strong -emit-llvm -S %s -o - | FileCheck %s

__attribute__((noinline))
int foo1(int *p) {
return p[10];
}
int bar1() {
// CHECK-LABEL: define {{[^@]+}}@bar1
// CHECK-SAME: () local_unnamed_addr #[[ATTR1:[0-9]+]] {
int x[128];
return foo1(x);
}

__attribute__((noinline))
int foo2(int *p) {
return p[1000];
}
int bar2() {
// CHECK-LABEL: define {{[^@]+}}@bar2
// CHECK-SAME: () local_unnamed_addr #[[ATTR2:[0-9]+]] {
int x[128];
return foo2(x);
}

int k;
__attribute__((noinline))
int foo3(int *p) {
return p[k];
}
int bar3() {
// CHECK-LABEL: define {{[^@]+}}@bar3
// CHECK-SAME: () local_unnamed_addr #[[ATTR3:[0-9]+]] {
int x[128];
return foo3(x);
}

__attribute__((noinline))
int foo4(int *p);
int bar4() {
// CHECK-LABEL: define {{[^@]+}}@bar4
// CHECK-SAME: () local_unnamed_addr #[[ATTR4:[0-9]+]] {
int x[128];
return foo4(x);
}

int bar5() {
// CHECK-LABEL: define {{[^@]+}}@bar5
// CHECK-SAME: () local_unnamed_addr #[[ATTR5:[0-9]+]] {
int x[128];
int i;
for (i = 0; i < 128; ++i)
x[i] = i;
return foo1(x);
}

//.
// CHECK: attributes #[[ATTR1]] =
// CHECK-NOT: sspstrong
// CHECK: attributes #[[ATTR2]] = {{.* sspstrong}}
// CHECK: attributes #[[ATTR3]] = {{.* sspstrong}}
// CHECK: attributes #[[ATTR4]] = {{.* sspstrong}}
// CHECK: attributes #[[ATTR5]] =
// CHECK-NOT: sspstrong
//.