Skip to content

Commit

Permalink
[IR] convert warn-stack-size from module flag to fn attr
Browse files Browse the repository at this point in the history
Otherwise, this causes issues when building with LTO for object files
that use different values.

Link: ClangBuiltLinux/linux#1395

Reviewed By: dblaikie, MaskRay

Differential Revision: https://reviews.llvm.org/D104342
  • Loading branch information
nickdesaulniers committed Jun 21, 2021
1 parent 759e797 commit 8ace121
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 64 deletions.
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
Fn->addFnAttr("packed-stack");
}

if (CGM.getCodeGenOpts().WarnStackSize != UINT_MAX)
Fn->addFnAttr("warn-stack-size",
std::to_string(CGM.getCodeGenOpts().WarnStackSize));

if (RetTy->isVoidType()) {
// Void type; nothing to return.
ReturnValue = Address::invalid();
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,8 +787,6 @@ void CodeGenModule::Release() {
getCodeGenOpts().StackProtectorGuardOffset);
if (getCodeGenOpts().StackAlignment)
getModule().setOverrideStackAlignment(getCodeGenOpts().StackAlignment);
if (getCodeGenOpts().WarnStackSize != UINT_MAX)
getModule().setWarnStackSize(getCodeGenOpts().WarnStackSize);

getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames);

Expand Down
4 changes: 4 additions & 0 deletions clang/test/Frontend/fwarn-stack-size.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// RUN: %clang_cc1 -fwarn-stack-size=42 -emit-llvm -o - %s | FileCheck %s
void foo(void) {}
// CHECK: define {{.*}} @foo() [[ATTR:#[0-9]+]] {
// CHECK: attributes [[ATTR]] = {{.*}} "warn-stack-size"="42"
5 changes: 5 additions & 0 deletions llvm/docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2048,6 +2048,11 @@ example:
function does not satisfy this contract, the behavior is undefined. This
attribute does not apply transitively to callees, but does apply to call
sites within the function. Note that `willreturn` implies `mustprogress`.
``"warn-stack-size"="<threshold>"``
This attribute sets a threshold to emit diagnostics once the frame size is
known should the frame size exceed the specified value. It takes one
required integer value, which should be a non-negative integer, and less
than `UINT_MAX`.
``vscale_range(<min>[, <max>])``
This attribute indicates the minimum and maximum vscale value for the given
function. A value of 0 means unbounded. If the optional max value is omitted
Expand Down
4 changes: 0 additions & 4 deletions llvm/include/llvm/IR/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -913,10 +913,6 @@ class Module {
unsigned getOverrideStackAlignment() const;
void setOverrideStackAlignment(unsigned Align);

/// Get/set the stack frame size threshold to warn on.
unsigned getWarnStackSize() const;
void setWarnStackSize(unsigned Threshold);

/// @name Utility functions for querying and setting the build SDK version
/// @{

Expand Down
11 changes: 10 additions & 1 deletion llvm/lib/CodeGen/PrologEpilogInserter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,16 @@ bool PEI::runOnMachineFunction(MachineFunction &MF) {
MachineFrameInfo &MFI = MF.getFrameInfo();
uint64_t StackSize = MFI.getStackSize();

unsigned Threshold = MF.getFunction().getParent()->getWarnStackSize();
unsigned Threshold = UINT_MAX;
if (MF.getFunction().hasFnAttribute("warn-stack-size")) {
bool Failed = MF.getFunction()
.getFnAttribute("warn-stack-size")
.getValueAsString()
.getAsInteger(10, Threshold);
// Verifier should have caught this.
assert(!Failed && "Invalid warn-stack-size fn attr value");
(void)Failed;
}
if (StackSize > Threshold) {
DiagnosticInfoStackSize DiagStackSize(F, StackSize);
F.getContext().diagnose(DiagStackSize);
Expand Down
11 changes: 0 additions & 11 deletions llvm/lib/IR/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -732,17 +732,6 @@ void Module::setOverrideStackAlignment(unsigned Align) {
addModuleFlag(ModFlagBehavior::Error, "override-stack-alignment", Align);
}

unsigned Module::getWarnStackSize() const {
Metadata *MD = getModuleFlag("warn-stack-size");
if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
return CI->getZExtValue();
return UINT_MAX;
}

void Module::setWarnStackSize(unsigned Threshold) {
addModuleFlag(ModFlagBehavior::Error, "warn-stack-size", Threshold);
}

void Module::setSDKVersion(const VersionTuple &V) {
SmallVector<unsigned, 3> Entries;
Entries.push_back(V.getMajor());
Expand Down
36 changes: 16 additions & 20 deletions llvm/lib/IR/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,8 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
void verifyAttributeTypes(AttributeSet Attrs, bool IsFunction,
const Value *V);
void verifyParameterAttrs(AttributeSet Attrs, Type *Ty, const Value *V);
void checkUnsignedBaseTenFuncAttr(AttributeList Attrs, StringRef Attr,
const Value *V);
void verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
const Value *V, bool IsIntrinsic);
void verifyFunctionMetadata(ArrayRef<std::pair<unsigned, MDNode *>> MDs);
Expand Down Expand Up @@ -1899,6 +1901,17 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
}
}

void Verifier::checkUnsignedBaseTenFuncAttr(AttributeList Attrs, StringRef Attr,
const Value *V) {
if (Attrs.hasFnAttribute(Attr)) {
StringRef S = Attrs.getAttribute(AttributeList::FunctionIndex, Attr)
.getValueAsString();
unsigned N;
if (S.getAsInteger(10, N))
CheckFailed("\"" + Attr + "\" takes an unsigned integer: " + S, V);
}
}

// Check parameter attributes against a function type.
// The value V is printed in error messages.
void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
Expand Down Expand Up @@ -2098,26 +2111,9 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V);
}

if (Attrs.hasFnAttribute("patchable-function-prefix")) {
StringRef S = Attrs
.getAttribute(AttributeList::FunctionIndex,
"patchable-function-prefix")
.getValueAsString();
unsigned N;
if (S.getAsInteger(10, N))
CheckFailed(
"\"patchable-function-prefix\" takes an unsigned integer: " + S, V);
}
if (Attrs.hasFnAttribute("patchable-function-entry")) {
StringRef S = Attrs
.getAttribute(AttributeList::FunctionIndex,
"patchable-function-entry")
.getValueAsString();
unsigned N;
if (S.getAsInteger(10, N))
CheckFailed(
"\"patchable-function-entry\" takes an unsigned integer: " + S, V);
}
checkUnsignedBaseTenFuncAttr(Attrs, "patchable-function-prefix", V);
checkUnsignedBaseTenFuncAttr(Attrs, "patchable-function-entry", V);
checkUnsignedBaseTenFuncAttr(Attrs, "warn-stack-size", V);
}

void Verifier::verifyFunctionMetadata(
Expand Down
7 changes: 2 additions & 5 deletions llvm/test/CodeGen/ARM/warn-stack.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
; <rdar://13987214>

; CHECK-NOT: nowarn
define void @nowarn() nounwind ssp "frame-pointer"="all" {
define void @nowarn() nounwind ssp "frame-pointer"="all" "warn-stack-size"="80" {
entry:
%buffer = alloca [12 x i8], align 1
%arraydecay = getelementptr inbounds [12 x i8], [12 x i8]* %buffer, i64 0, i64 0
Expand All @@ -13,7 +13,7 @@ entry:
}

; CHECK: warning: stack size limit exceeded (92) in warn
define void @warn() nounwind ssp "frame-pointer"="all" {
define void @warn() nounwind ssp "frame-pointer"="all" "warn-stack-size"="80" {
entry:
%buffer = alloca [80 x i8], align 1
%arraydecay = getelementptr inbounds [80 x i8], [80 x i8]* %buffer, i64 0, i64 0
Expand All @@ -22,6 +22,3 @@ entry:
}

declare void @doit(i8*)

!llvm.module.flags = !{!0}
!0 = !{i32 1, !"warn-stack-size", i32 80}
7 changes: 2 additions & 5 deletions llvm/test/CodeGen/X86/warn-stack.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
; <rdar://13987214>

; CHECK-NOT: nowarn
define void @nowarn() nounwind ssp {
define void @nowarn() nounwind ssp "warn-stack-size"="80" {
entry:
%buffer = alloca [12 x i8], align 1
%arraydecay = getelementptr inbounds [12 x i8], [12 x i8]* %buffer, i64 0, i64 0
Expand All @@ -13,7 +13,7 @@ entry:
}

; CHECK: warning: stack size limit exceeded (88) in warn
define void @warn() nounwind ssp {
define void @warn() nounwind ssp "warn-stack-size"="80" {
entry:
%buffer = alloca [80 x i8], align 1
%arraydecay = getelementptr inbounds [80 x i8], [80 x i8]* %buffer, i64 0, i64 0
Expand All @@ -22,6 +22,3 @@ entry:
}

declare void @doit(i8*)

!llvm.module.flags = !{!0}
!0 = !{i32 1, !"warn-stack-size", i32 80}
16 changes: 0 additions & 16 deletions llvm/test/Linker/warn-stack-frame.ll

This file was deleted.

10 changes: 10 additions & 0 deletions llvm/test/Verifier/invalid-warn-stack-size.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
; RUN: not opt -passes=verify %s -disable-output 2>&1 | FileCheck %s
define void @foo() "warn-stack-size"="42" { ret void }
define void @bar() "warn-stack-size"="-1" { ret void }
define void @baz() "warn-stack-size"="999999999999999999999" { ret void }
define void @qux() "warn-stack-size"="a lot lol" { ret void }

; CHECK-NOT: "warn-stack-size" takes an unsigned integer: 42
; CHECK: "warn-stack-size" takes an unsigned integer: -1
; CHECK: "warn-stack-size" takes an unsigned integer: 999999999999999999999
; CHECK: "warn-stack-size" takes an unsigned integer: a lot lol

0 comments on commit 8ace121

Please sign in to comment.