nickdesaulniers updated this revision to Diff 352841.
nickdesaulniers marked an inline comment as done.
nickdesaulniers added a comment.
- verifier checks, inliner test, use base 10 radix
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D104342/new/
https://reviews.llvm.org/D104342
Files:
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/test/Frontend/fwarn-stack-size.c
llvm/docs/LangRef.rst
llvm/include/llvm/IR/Module.h
llvm/lib/CodeGen/PrologEpilogInserter.cpp
llvm/lib/IR/Module.cpp
llvm/lib/IR/Verifier.cpp
llvm/test/CodeGen/ARM/warn-stack.ll
llvm/test/CodeGen/X86/warn-stack.ll
llvm/test/Linker/warn-stack-frame.ll
llvm/test/Transforms/Inline/warn-stack-size.ll
llvm/test/Verifier/invalid-warn-stack-size.ll
Index: llvm/test/Verifier/invalid-warn-stack-size.ll
===================================================================
--- /dev/null
+++ llvm/test/Verifier/invalid-warn-stack-size.ll
@@ -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
Index: llvm/test/Transforms/Inline/warn-stack-size.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/Inline/warn-stack-size.ll
@@ -0,0 +1,24 @@
+; RUN: opt -passes=inline -S %s | FileCheck %s
+
+; The caller should NOT inherit the callee's "warn-stack-size" value.
+define void @foo() "warn-stack-size"="42" { ret void }
+; CHECK: @foo(
+; CHECK-NEXT: ret void
+;
+define void @bar() "warn-stack-size"="7" {
+; CHECK: @bar() [[ATTR0:#[0-9]+]] {
+; CHECK-NEXT: ret void
+;
+ call void @foo()
+ ret void
+}
+define void @baz() "warn-stack-size"="99" {
+; CHECK: @baz() [[ATTR1:#[0-9]+]] {
+; CHECK-NEXT: ret void
+;
+ call void @bar()
+ ret void
+}
+
+; CHECK: attributes [[ATTR0]] = {{.*}} "warn-stack-size"="7"
+; CHECK: attributes [[ATTR1]] = {{.*}} "warn-stack-size"="99"
Index: llvm/test/Linker/warn-stack-frame.ll
===================================================================
--- llvm/test/Linker/warn-stack-frame.ll
+++ /dev/null
@@ -1,16 +0,0 @@
-; RUN: split-file %s %t
-; RUN: llvm-link %t/main.ll %t/match.ll
-; RUN: not llvm-link %t/main.ll %t/mismatch.ll 2>&1 | \
-; RUN: FileCheck --check-prefix=CHECK-MISMATCH %s
-
-; CHECK-MISMATCH: error: linking module flags 'warn-stack-size': IDs have conflicting values
-
-;--- main.ll
-!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"warn-stack-size", i32 80}
-;--- match.ll
-!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"warn-stack-size", i32 80}
-;--- mismatch.ll
-!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"warn-stack-size", i32 81}
Index: llvm/test/CodeGen/X86/warn-stack.ll
===================================================================
--- llvm/test/CodeGen/X86/warn-stack.ll
+++ llvm/test/CodeGen/X86/warn-stack.ll
@@ -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
@@ -13,7 +13,7 @@
}
; 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
@@ -22,6 +22,3 @@
}
declare void @doit(i8*)
-
-!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"warn-stack-size", i32 80}
Index: llvm/test/CodeGen/ARM/warn-stack.ll
===================================================================
--- llvm/test/CodeGen/ARM/warn-stack.ll
+++ llvm/test/CodeGen/ARM/warn-stack.ll
@@ -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
@@ -13,7 +13,7 @@
}
; 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
@@ -22,6 +22,3 @@
}
declare void @doit(i8*)
-
-!llvm.module.flags = !{!0}
-!0 = !{i32 1, !"warn-stack-size", i32 80}
Index: llvm/lib/IR/Verifier.cpp
===================================================================
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -543,6 +543,8 @@
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);
@@ -1888,6 +1890,17 @@
}
}
+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,
@@ -2087,26 +2100,9 @@
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(
Index: llvm/lib/IR/Module.cpp
===================================================================
--- llvm/lib/IR/Module.cpp
+++ llvm/lib/IR/Module.cpp
@@ -732,17 +732,6 @@
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());
Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp
===================================================================
--- llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -274,7 +274,16 @@
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);
Index: llvm/include/llvm/IR/Module.h
===================================================================
--- llvm/include/llvm/IR/Module.h
+++ llvm/include/llvm/IR/Module.h
@@ -913,10 +913,6 @@
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
/// @{
Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -2048,6 +2048,11 @@
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 for once the frame size
+ is known should the frame size exceed the specified value. It takes one
+ required integer value, which should be greater than or equal to 0, 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
Index: clang/test/Frontend/fwarn-stack-size.c
===================================================================
--- /dev/null
+++ clang/test/Frontend/fwarn-stack-size.c
@@ -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"
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -787,8 +787,6 @@
getCodeGenOpts().StackProtectorGuardOffset);
if (getCodeGenOpts().StackAlignment)
getModule().setOverrideStackAlignment(getCodeGenOpts().StackAlignment);
- if (getCodeGenOpts().WarnStackSize != UINT_MAX)
- getModule().setWarnStackSize(getCodeGenOpts().WarnStackSize);
getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames);
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1050,6 +1050,10 @@
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();
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits