Index: include/llvm/CodeGen/CommandFlags.h =================================================================== --- include/llvm/CodeGen/CommandFlags.h +++ include/llvm/CodeGen/CommandFlags.h @@ -256,6 +256,7 @@ Options.JTType = JTableType; Options.ThreadModel = TMModel; + Options.NoRedZone = DisableRedZone; return Options; } Index: include/llvm/Target/TargetOptions.h =================================================================== --- include/llvm/Target/TargetOptions.h +++ include/llvm/Target/TargetOptions.h @@ -70,8 +70,8 @@ EnableFastISel(false), PositionIndependentExecutable(false), UseInitArray(false), DisableIntegratedAS(false), CompressDebugSections(false), FunctionSections(false), - DataSections(false), TrapUnreachable(false), TrapFuncName(""), - FloatABIType(FloatABI::Default), + DataSections(false), TrapUnreachable(false), NoRedZone(false), + TrapFuncName(""), FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard), JTType(JumpTable::Single), ThreadModel(ThreadModel::POSIX) {} @@ -192,6 +192,16 @@ /// Emit target-specific trap instruction for 'unreachable' IR instructions. unsigned TrapUnreachable : 1; + /// NoRedZone - This flag is enabled when the -disable-red-zone flag is + /// specified on the command line. When this flag is off (the default), + /// leaf functions may use unallocated stack space. This optimization + /// eliminates stack adjustment instructions. For example, in + /// x86_64 targets, red zone use results in insructions with negative + /// stack offsets, as in -8(%rsp). Red Zone optimization is unsafe + /// where hardware preemption such as interrupt handling may overwrite + /// unallocated stack space. + unsigned NoRedZone : 1; + /// getTrapFunctionName - If this returns a non-empty string, this means /// isel should lower Intrinsic::trap to a call to the specified function /// name instead of an ISD::TRAP node. @@ -258,6 +268,7 @@ ARE_EQUAL(PositionIndependentExecutable) && ARE_EQUAL(UseInitArray) && ARE_EQUAL(TrapUnreachable) && + ARE_EQUAL(NoRedZone) && ARE_EQUAL(TrapFuncName) && ARE_EQUAL(FloatABIType) && ARE_EQUAL(AllowFPOpFusion) && Index: lib/Target/X86/X86FrameLowering.cpp =================================================================== --- lib/Target/X86/X86FrameLowering.cpp +++ lib/Target/X86/X86FrameLowering.cpp @@ -517,6 +517,7 @@ !MFI->adjustsStack() && // No calls. !IsWin64 && // Win64 has no Red Zone !usesTheStack(MF) && // Don't push and pop. + !MF.getTarget().Options.NoRedZone && // command line !MF.shouldSplitStack()) { // Regular stack uint64_t MinSize = X86FI->getCalleeSavedFrameSize(); if (HasFP) MinSize += SlotSize; Index: test/CodeGen/X86/red-zone.ll =================================================================== --- test/CodeGen/X86/red-zone.ll +++ test/CodeGen/X86/red-zone.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux | FileCheck %s +; RUN: llc < %s -mcpu=generic -disable-red-zone -mtriple=x86_64-linux | FileCheck %s --check-prefix=CMDLINE ; First without noredzone. ; CHECK-LABEL: f0: @@ -11,7 +12,7 @@ ret x86_fp80 %0 } -; Then with noredzone. +; Then with noredzone function attribute. ; CHECK-LABEL: f1: ; CHECK: subq $4, %rsp ; CHECK: (%rsp) @@ -23,3 +24,11 @@ %0 = fpext float %f to x86_fp80 ; [#uses=1] ret x86_fp80 %0 } + +; Then with -disable-red-zone on command line +; CMDLINE-LABEL: f0: +; CMDLINE: subq $4, %rsp +; CMDLINE: (%rsp) +; CMDLINE: (%rsp) +; CMDLINE: addq $4, %rsp +; CMDLINE: ret