Skip to content

Commit 8ace121

Browse files
[IR] convert warn-stack-size from module flag to fn attr
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
1 parent 759e797 commit 8ace121

File tree

12 files changed

+53
-64
lines changed

12 files changed

+53
-64
lines changed

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
10531053
Fn->addFnAttr("packed-stack");
10541054
}
10551055

1056+
if (CGM.getCodeGenOpts().WarnStackSize != UINT_MAX)
1057+
Fn->addFnAttr("warn-stack-size",
1058+
std::to_string(CGM.getCodeGenOpts().WarnStackSize));
1059+
10561060
if (RetTy->isVoidType()) {
10571061
// Void type; nothing to return.
10581062
ReturnValue = Address::invalid();

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -787,8 +787,6 @@ void CodeGenModule::Release() {
787787
getCodeGenOpts().StackProtectorGuardOffset);
788788
if (getCodeGenOpts().StackAlignment)
789789
getModule().setOverrideStackAlignment(getCodeGenOpts().StackAlignment);
790-
if (getCodeGenOpts().WarnStackSize != UINT_MAX)
791-
getModule().setWarnStackSize(getCodeGenOpts().WarnStackSize);
792790

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: %clang_cc1 -fwarn-stack-size=42 -emit-llvm -o - %s | FileCheck %s
2+
void foo(void) {}
3+
// CHECK: define {{.*}} @foo() [[ATTR:#[0-9]+]] {
4+
// CHECK: attributes [[ATTR]] = {{.*}} "warn-stack-size"="42"

llvm/docs/LangRef.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,6 +2048,11 @@ example:
20482048
function does not satisfy this contract, the behavior is undefined. This
20492049
attribute does not apply transitively to callees, but does apply to call
20502050
sites within the function. Note that `willreturn` implies `mustprogress`.
2051+
``"warn-stack-size"="<threshold>"``
2052+
This attribute sets a threshold to emit diagnostics once the frame size is
2053+
known should the frame size exceed the specified value. It takes one
2054+
required integer value, which should be a non-negative integer, and less
2055+
than `UINT_MAX`.
20512056
``vscale_range(<min>[, <max>])``
20522057
This attribute indicates the minimum and maximum vscale value for the given
20532058
function. A value of 0 means unbounded. If the optional max value is omitted

llvm/include/llvm/IR/Module.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -913,10 +913,6 @@ class Module {
913913
unsigned getOverrideStackAlignment() const;
914914
void setOverrideStackAlignment(unsigned Align);
915915

916-
/// Get/set the stack frame size threshold to warn on.
917-
unsigned getWarnStackSize() const;
918-
void setWarnStackSize(unsigned Threshold);
919-
920916
/// @name Utility functions for querying and setting the build SDK version
921917
/// @{
922918

llvm/lib/CodeGen/PrologEpilogInserter.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,16 @@ bool PEI::runOnMachineFunction(MachineFunction &MF) {
274274
MachineFrameInfo &MFI = MF.getFrameInfo();
275275
uint64_t StackSize = MFI.getStackSize();
276276

277-
unsigned Threshold = MF.getFunction().getParent()->getWarnStackSize();
277+
unsigned Threshold = UINT_MAX;
278+
if (MF.getFunction().hasFnAttribute("warn-stack-size")) {
279+
bool Failed = MF.getFunction()
280+
.getFnAttribute("warn-stack-size")
281+
.getValueAsString()
282+
.getAsInteger(10, Threshold);
283+
// Verifier should have caught this.
284+
assert(!Failed && "Invalid warn-stack-size fn attr value");
285+
(void)Failed;
286+
}
278287
if (StackSize > Threshold) {
279288
DiagnosticInfoStackSize DiagStackSize(F, StackSize);
280289
F.getContext().diagnose(DiagStackSize);

llvm/lib/IR/Module.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -732,17 +732,6 @@ void Module::setOverrideStackAlignment(unsigned Align) {
732732
addModuleFlag(ModFlagBehavior::Error, "override-stack-alignment", Align);
733733
}
734734

735-
unsigned Module::getWarnStackSize() const {
736-
Metadata *MD = getModuleFlag("warn-stack-size");
737-
if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
738-
return CI->getZExtValue();
739-
return UINT_MAX;
740-
}
741-
742-
void Module::setWarnStackSize(unsigned Threshold) {
743-
addModuleFlag(ModFlagBehavior::Error, "warn-stack-size", Threshold);
744-
}
745-
746735
void Module::setSDKVersion(const VersionTuple &V) {
747736
SmallVector<unsigned, 3> Entries;
748737
Entries.push_back(V.getMajor());

llvm/lib/IR/Verifier.cpp

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,8 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
543543
void verifyAttributeTypes(AttributeSet Attrs, bool IsFunction,
544544
const Value *V);
545545
void verifyParameterAttrs(AttributeSet Attrs, Type *Ty, const Value *V);
546+
void checkUnsignedBaseTenFuncAttr(AttributeList Attrs, StringRef Attr,
547+
const Value *V);
546548
void verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
547549
const Value *V, bool IsIntrinsic);
548550
void verifyFunctionMetadata(ArrayRef<std::pair<unsigned, MDNode *>> MDs);
@@ -1899,6 +1901,17 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
18991901
}
19001902
}
19011903

1904+
void Verifier::checkUnsignedBaseTenFuncAttr(AttributeList Attrs, StringRef Attr,
1905+
const Value *V) {
1906+
if (Attrs.hasFnAttribute(Attr)) {
1907+
StringRef S = Attrs.getAttribute(AttributeList::FunctionIndex, Attr)
1908+
.getValueAsString();
1909+
unsigned N;
1910+
if (S.getAsInteger(10, N))
1911+
CheckFailed("\"" + Attr + "\" takes an unsigned integer: " + S, V);
1912+
}
1913+
}
1914+
19021915
// Check parameter attributes against a function type.
19031916
// The value V is printed in error messages.
19041917
void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
@@ -2098,26 +2111,9 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
20982111
CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V);
20992112
}
21002113

2101-
if (Attrs.hasFnAttribute("patchable-function-prefix")) {
2102-
StringRef S = Attrs
2103-
.getAttribute(AttributeList::FunctionIndex,
2104-
"patchable-function-prefix")
2105-
.getValueAsString();
2106-
unsigned N;
2107-
if (S.getAsInteger(10, N))
2108-
CheckFailed(
2109-
"\"patchable-function-prefix\" takes an unsigned integer: " + S, V);
2110-
}
2111-
if (Attrs.hasFnAttribute("patchable-function-entry")) {
2112-
StringRef S = Attrs
2113-
.getAttribute(AttributeList::FunctionIndex,
2114-
"patchable-function-entry")
2115-
.getValueAsString();
2116-
unsigned N;
2117-
if (S.getAsInteger(10, N))
2118-
CheckFailed(
2119-
"\"patchable-function-entry\" takes an unsigned integer: " + S, V);
2120-
}
2114+
checkUnsignedBaseTenFuncAttr(Attrs, "patchable-function-prefix", V);
2115+
checkUnsignedBaseTenFuncAttr(Attrs, "patchable-function-entry", V);
2116+
checkUnsignedBaseTenFuncAttr(Attrs, "warn-stack-size", V);
21212117
}
21222118

21232119
void Verifier::verifyFunctionMetadata(

llvm/test/CodeGen/ARM/warn-stack.ll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
; <rdar://13987214>
55

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

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

2424
declare void @doit(i8*)
25-
26-
!llvm.module.flags = !{!0}
27-
!0 = !{i32 1, !"warn-stack-size", i32 80}

llvm/test/CodeGen/X86/warn-stack.ll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
; <rdar://13987214>
55

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

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

2424
declare void @doit(i8*)
25-
26-
!llvm.module.flags = !{!0}
27-
!0 = !{i32 1, !"warn-stack-size", i32 80}

llvm/test/Linker/warn-stack-frame.ll

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; RUN: not opt -passes=verify %s -disable-output 2>&1 | FileCheck %s
2+
define void @foo() "warn-stack-size"="42" { ret void }
3+
define void @bar() "warn-stack-size"="-1" { ret void }
4+
define void @baz() "warn-stack-size"="999999999999999999999" { ret void }
5+
define void @qux() "warn-stack-size"="a lot lol" { ret void }
6+
7+
; CHECK-NOT: "warn-stack-size" takes an unsigned integer: 42
8+
; CHECK: "warn-stack-size" takes an unsigned integer: -1
9+
; CHECK: "warn-stack-size" takes an unsigned integer: 999999999999999999999
10+
; CHECK: "warn-stack-size" takes an unsigned integer: a lot lol

0 commit comments

Comments
 (0)