Index: lib/Target/AArch64/AArch64FrameLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64FrameLowering.cpp +++ lib/Target/AArch64/AArch64FrameLowering.cpp @@ -531,9 +531,10 @@ return; // REDZONE: If the stack size is less than 128 bytes, we don't need // to actually allocate. - if (canUseRedZone(MF)) + if (canUseRedZone(MF)) { + AFI->setUsesRedZone(true); ++NumRedZoneFunctions; - else { + } else { emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP, -NumBytes, TII, MachineInstr::FrameSetup); Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5006,13 +5006,15 @@ bool AArch64InstrInfo::isFunctionSafeToOutlineFrom( MachineFunction &MF, bool OutlineFromLinkOnceODRs) const { - const Function &F = MF.getFunction(); - // If F uses a redzone, then don't outline from it because it might mess up + // If MF uses a redzone, then don't outline from it because it might mess up // the stack. - if (!F.hasFnAttribute(Attribute::NoRedZone)) + AArch64FunctionInfo *AFI = MF.getInfo(); + if (!AFI || AFI->usesRedZone()) return false; + const Function &F = MF.getFunction(); + // Can F be deduplicated by the linker? If it can, don't outline from it. if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage()) return false; Index: lib/Target/AArch64/AArch64MachineFunctionInfo.h =================================================================== --- lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -90,6 +90,9 @@ /// other stack allocations. bool CalleeSaveStackHasFreeSpace = false; + /// True when the function uses a red zone. + bool UsesRedZone = false; + public: AArch64FunctionInfo() = default; @@ -132,6 +135,9 @@ return NumLocalDynamicTLSAccesses; } + bool usesRedZone() const { return UsesRedZone; } + void setUsesRedZone(bool s) { UsesRedZone = s; } + int getVarArgsStackIndex() const { return VarArgsStackIndex; } void setVarArgsStackIndex(int Index) { VarArgsStackIndex = Index; } Index: test/CodeGen/AArch64/machine-outliner-noredzone.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/machine-outliner-noredzone.ll @@ -0,0 +1,44 @@ +; RUN: llc -enable-machine-outliner %s -o - | FileCheck %s +; CHECK: OUTLINED_FUNCTION +; RUN: llc -enable-machine-outliner -aarch64-redzone %s -o - | FileCheck %s -check-prefix=REDZONE +; REDZONE-NOT: OUTLINED_FUNCTION + +target triple = "arm64----" + +define void @foo() #0 { + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + store i32 0, i32* %2, align 4 + store i32 0, i32* %3, align 4 + store i32 0, i32* %4, align 4 + %5 = load i32, i32* %1, align 4 + %6 = add nsw i32 %5, 1 + store i32 %6, i32* %1, align 4 + %7 = load i32, i32* %3, align 4 + %8 = add nsw i32 %7, 1 + store i32 %8, i32* %3, align 4 + %9 = load i32, i32* %4, align 4 + %10 = add nsw i32 %9, 1 + store i32 %10, i32* %4, align 4 + %11 = load i32, i32* %2, align 4 + %12 = add nsw i32 %11, 1 + store i32 %12, i32* %2, align 4 + %13 = load i32, i32* %1, align 4 + %14 = add nsw i32 %13, 1 + store i32 %14, i32* %1, align 4 + %15 = load i32, i32* %3, align 4 + %16 = add nsw i32 %15, 1 + store i32 %16, i32* %3, align 4 + %17 = load i32, i32* %4, align 4 + %18 = add nsw i32 %17, 1 + store i32 %18, i32* %4, align 4 + %19 = load i32, i32* %2, align 4 + %20 = add nsw i32 %19, -1 + store i32 %20, i32* %2, align 4 + ret void +} + +attributes #0 = { noinline nounwind optnone }