Index: llvm/lib/CodeGen/LocalStackSlotAllocation.cpp =================================================================== --- llvm/lib/CodeGen/LocalStackSlotAllocation.cpp +++ llvm/lib/CodeGen/LocalStackSlotAllocation.cpp @@ -199,19 +199,26 @@ // Make sure that the stack protector comes before the local variables on the // stack. SmallSet ProtectedObjs; - if (MFI.getStackProtectorIndex() >= 0) { + if (MFI.hasStackProtectorIndex()) { + int StackProtectorFI = MFI.getStackProtectorIndex(); + // We need to make sure we didn't pre-allocate the stack protector when + // doing this. + // If we already have a stack protector, this will re-assign it to a slot + // that is **not** covering the protected objects. + assert(!MFI.isObjectPreAllocated(StackProtectorFI) && + "Stack protector pre-allocated in LocalStackSlotAllocation"); + StackObjSet LargeArrayObjs; StackObjSet SmallArrayObjs; StackObjSet AddrOfObjs; - AdjustStackOffset(MFI, MFI.getStackProtectorIndex(), Offset, - StackGrowsDown, MaxAlign); + AdjustStackOffset(MFI, StackProtectorFI, Offset, StackGrowsDown, MaxAlign); // Assign large stack objects first. for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { if (MFI.isDeadObjectIndex(i)) continue; - if (MFI.getStackProtectorIndex() == (int)i) + if (StackProtectorFI == (int)i) continue; switch (MFI.getObjectSSPLayout(i)) { Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp =================================================================== --- llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -927,18 +927,23 @@ // Make sure that the stack protector comes before the local variables on the // stack. SmallSet ProtectedObjs; - if (MFI.getStackProtectorIndex() >= 0) { + // If we have a stack protector index, we need to make sure that + // LocalStackSlotPass didn't already allocate a slot for it. If it did, we + // need to use that one. + if (MFI.hasStackProtectorIndex() && + !(MFI.getUseLocalStackAllocationBlock() && + MFI.isObjectPreAllocated(MFI.getStackProtectorIndex()))) { + int StackProtectorFI = MFI.getStackProtectorIndex(); StackObjSet LargeArrayObjs; StackObjSet SmallArrayObjs; StackObjSet AddrOfObjs; - AdjustStackOffset(MFI, MFI.getStackProtectorIndex(), StackGrowsDown, - Offset, MaxAlign, Skew); + AdjustStackOffset(MFI, StackProtectorFI, StackGrowsDown, Offset, MaxAlign, + Skew); // Assign large stack objects first. for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { - if (MFI.isObjectPreAllocated(i) && - MFI.getUseLocalStackAllocationBlock()) + if (MFI.isObjectPreAllocated(i) && MFI.getUseLocalStackAllocationBlock()) continue; if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) continue; @@ -946,8 +951,7 @@ continue; if (MFI.isDeadObjectIndex(i)) continue; - if (MFI.getStackProtectorIndex() == (int)i || - EHRegNodeFrameIndex == (int)i) + if (StackProtectorFI == (int)i || EHRegNodeFrameIndex == (int)i) continue; if (MFI.getStackID(i) != TargetStackID::Default) // Only allocate objects on the default stack. Index: test/CodeGen/AArch64/stack-guard-reassign.mir =================================================================== --- /dev/null +++ test/CodeGen/AArch64/stack-guard-reassign.mir @@ -0,0 +1,34 @@ +# RUN: llc -mtriple=arm64-apple-ios -start-before=localstackalloc -stop-after=prologepilog -o - %s | FileCheck %s + +--- | + @__stack_chk_guard = external global i8* + define i32 @main(i32, i8**) { + %StackGuardSlot = alloca i8* + unreachable + } +... +--- +name: main +tracksRegLiveness: true +frameInfo: +# CHECK: stackSize: 544 + stackProtector: '%stack.0.StackGuardSlot' +stack: + - { id: 0, name: StackGuardSlot, size: 8, alignment: 8, stack-id: 0 } +# Verify that the offset assigned to the stack protector is at the top of the +# frame, covering the locals. +# CHECK: - { id: 0, name: StackGuardSlot, type: default, offset: -24, size: 8, +# CHECK-NEXT: alignment: 8, stack-id: 0, callee-saved-register: '', callee-saved-restored: true, +# CHECK-NEXT: local-offset: -8, debug-info-variable: '', debug-info-expression: '', +# CHECK-NEXT: debug-info-location: '' } + - { id: 1, size: 512, alignment: 1, stack-id: 0 } + - { id: 2, size: 4, alignment: 4, stack-id: 0 } +body: | + bb.0: + %25:gpr64common = LOAD_STACK_GUARD :: (dereferenceable invariant load 8 from @__stack_chk_guard) + STRXui killed %25, %stack.0.StackGuardSlot, 0 :: (volatile store 8 into %stack.0.StackGuardSlot) + %28:gpr64 = LDRXui %stack.0.StackGuardSlot, 0 :: (volatile load 8 from %stack.0.StackGuardSlot) + %29:gpr64common = LOAD_STACK_GUARD :: (dereferenceable invariant load 8 from @__stack_chk_guard) + RET_ReallyLR implicit undef $w0, implicit killed %28, implicit killed %29 + +...