[llvm] r347862 - [GlobalISel] Fix insertion of stack-protector epilogue

Daniel Sanders via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 30 10:27:58 PST 2018


Hi Petr,

This test is failing when the ARM backend isn't compiled and looking at the triple (armv8...) it appears to be an ARM test rather than an AArch64 test. Could you move it to test/CodeGen/ARM/GlobalISel/irtranslator-stackprotect-check.ll?

> On Nov 29, 2018, at 05:22, Petr Pavlu via llvm-commits <llvm-commits at lists.llvm.org> wrote:
> 
> 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
> +}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list