[llvm] r347862 - [GlobalISel] Fix insertion of stack-protector epilogue
Petr Pavlu via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 29 05:22:53 PST 2018
Author: petr.pavlu
Date: Thu Nov 29 05:22:53 2018
New Revision: 347862
URL: http://llvm.org/viewvc/llvm-project?rev=347862&view=rev
Log:
[GlobalISel] Fix insertion of stack-protector epilogue
* Tell the StackProtector pass to generate the epilogue instrumentation
when GlobalISel is enabled because GISel currently does not implement
the same deferred epilogue insertion as SelectionDAG.
* Update StackProtector::InsertStackProtectors() to find a stack guard
slot by searching for the llvm.stackprotector intrinsic when the
prologue was not created by StackProtector itself but the pass still
needs to generate the epilogue instrumentation. This fixes a problem
when the pass would abort because the stack guard AllocInst pointer
was null when generating the epilogue -- test
CodeGen/AArch64/GlobalISel/arm64-irtranslator-stackprotect.ll.
Differential Revision: https://reviews.llvm.org/D54518
Added:
llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-stackprotect-check.ll
Modified:
llvm/trunk/lib/CodeGen/StackProtector.cpp
Modified: llvm/trunk/lib/CodeGen/StackProtector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackProtector.cpp?rev=347862&r1=347861&r2=347862&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/StackProtector.cpp (original)
+++ llvm/trunk/lib/CodeGen/StackProtector.cpp Thu Nov 29 05:22:53 2018
@@ -199,6 +199,18 @@ bool StackProtector::HasAddressTaken(con
return false;
}
+/// Search for the first call to the llvm.stackprotector intrinsic and return it
+/// if present.
+static const CallInst *findStackProtectorIntrinsic(Function &F) {
+ for (const BasicBlock &BB : F)
+ for (const Instruction &I : BB)
+ if (const CallInst *CI = dyn_cast<CallInst>(&I))
+ if (CI->getCalledFunction() ==
+ Intrinsic::getDeclaration(F.getParent(), Intrinsic::stackprotector))
+ return CI;
+ return nullptr;
+}
+
/// Check whether or not this function needs a stack protector based
/// upon the stack protector level.
///
@@ -215,13 +227,7 @@ bool StackProtector::HasAddressTaken(con
bool StackProtector::RequiresStackProtector() {
bool Strong = false;
bool NeedsProtector = false;
- for (const BasicBlock &BB : *F)
- for (const Instruction &I : BB)
- if (const CallInst *CI = dyn_cast<CallInst>(&I))
- if (CI->getCalledFunction() ==
- Intrinsic::getDeclaration(F->getParent(),
- Intrinsic::stackprotector))
- HasPrologue = true;
+ HasPrologue = findStackProtectorIntrinsic(*F);
if (F->hasFnAttribute(Attribute::SafeStack))
return false;
@@ -379,7 +385,8 @@ bool StackProtector::InsertStackProtecto
// protection in SDAG.
bool SupportsSelectionDAGSP =
TLI->useStackGuardXorFP() ||
- (EnableSelectionDAGSP && !TM->Options.EnableFastISel);
+ (EnableSelectionDAGSP && !TM->Options.EnableFastISel &&
+ !TM->Options.EnableGlobalISel);
AllocaInst *AI = nullptr; // Place on stack that stores the stack guard.
for (Function::iterator I = F->begin(), E = F->end(); I != E;) {
@@ -399,6 +406,14 @@ bool StackProtector::InsertStackProtecto
if (SupportsSelectionDAGSP)
break;
+ // Find the stack guard slot if the prologue was not created by this pass
+ // itself via a previous call to CreatePrologue().
+ if (!AI) {
+ const CallInst *SPCall = findStackProtectorIntrinsic(*F);
+ assert(SPCall && "Call to llvm.stackprotector is missing");
+ AI = cast<AllocaInst>(SPCall->getArgOperand(1));
+ }
+
// Set HasIRCheck to true, so that SelectionDAG will not generate its own
// version. SelectionDAG called 'shouldEmitSDCheck' to check whether
// instrumentation has already been generated.
Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-stackprotect-check.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-stackprotect-check.ll?rev=347862&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-stackprotect-check.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/irtranslator-stackprotect-check.ll Thu Nov 29 05:22:53 2018
@@ -0,0 +1,50 @@
+; RUN: llc -O0 -stop-before=irtranslator -global-isel %s -o - | FileCheck %s
+; RUN: llc -O0 -stop-after=irtranslator -verify-machineinstrs -global-isel %s -o - | FileCheck --check-prefixes CHECK,CHECK-MIR %s
+
+; Check that when using GlobalISel, the StackProtector pass currently inserts
+; both prologue and epilogue instrumentation because GlobalISel does not have
+; the same epilogue insertion/optimization as SelectionDAG.
+
+target triple = "armv8-arm-none-eabi"
+
+define void @foo() ssp {
+; CHECK-LABEL: entry:
+; CHECK-NEXT: %StackGuardSlot = alloca i8*
+; CHECK-NEXT: %0 = call i8* @llvm.stackguard()
+; CHECK-NEXT: call void @llvm.stackprotector(i8* %0, i8** %StackGuardSlot)
+; CHECK-NEXT: %buf = alloca [8 x i8], align 1
+; CHECK-NEXT: %1 = call i8* @llvm.stackguard()
+; CHECK-NEXT: %2 = load volatile i8*, i8** %StackGuardSlot
+; CHECK-NEXT: %3 = icmp eq i8* %1, %2
+; CHECK-NEXT: br i1 %3, label %SP_return, label %CallStackCheckFailBlk, !prof !0
+;
+; CHECK: SP_return:
+; CHECK-NEXT: ret void
+;
+; CHECK: CallStackCheckFailBlk:
+; CHECK-NEXT: call void @__stack_chk_fail()
+; CHECK-NEXT: unreachable
+
+; CHECK-MIR: bb.1.entry:
+; CHECK-MIR: %0:_(p0) = G_FRAME_INDEX %stack.0.StackGuardSlot
+; CHECK-MIR-NEXT: %1:gpr(p0) = LOAD_STACK_GUARD :: (dereferenceable invariant load 4 from @__stack_chk_guard)
+; CHECK-MIR-NEXT: %2:gpr(p0) = LOAD_STACK_GUARD :: (dereferenceable invariant load 4 from @__stack_chk_guard)
+; CHECK-MIR-NEXT: G_STORE %2(p0), %0(p0) :: (volatile store 4 into %stack.0.StackGuardSlot, align 8)
+; CHECK-MIR-NEXT: %3:_(p0) = G_FRAME_INDEX %stack.1.buf
+; CHECK-MIR-NEXT: %4:gpr(p0) = LOAD_STACK_GUARD :: (dereferenceable invariant load 4 from @__stack_chk_guard)
+; CHECK-MIR-NEXT: %5:_(p0) = G_LOAD %0(p0) :: (volatile load 4 from %ir.StackGuardSlot)
+; CHECK-MIR-NEXT: %6:_(s1) = G_ICMP intpred(eq), %4(p0), %5
+; CHECK-MIR-NEXT: G_BRCOND %6(s1), %bb.2
+; CHECK-MIR-NEXT: G_BR %bb.3
+;
+; CHECK-MIR: bb.2.SP_return:
+; CHECK-MIR-NEXT: BX_RET 14, $noreg
+;
+; CHECK-MIR: bb.3.CallStackCheckFailBlk:
+; CHECK-MIR-NEXT: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
+; CHECK-MIR-NEXT: BL @__stack_chk_fail, csr_aapcs, implicit-def $lr, implicit $sp
+; CHECK-MIR-NEXT: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp
+entry:
+ %buf = alloca [8 x i8], align 1
+ ret void
+}
More information about the llvm-commits
mailing list