1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00

[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: https://github.com/ClangBuiltLinux/linux/issues/1395

Reviewed By: dblaikie, MaskRay

Differential Revision: https://reviews.llvm.org/D104342
This commit is contained in:
Nick Desaulniers 2021-06-21 15:09:23 -07:00
parent 2d9e36a4c2
commit 2aca733d9e
9 changed files with 45 additions and 62 deletions

View File

@ -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

View File

@ -913,10 +913,6 @@ public:
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
/// @{

View File

@ -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);

View File

@ -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());

View File

@ -543,6 +543,8 @@ private:
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);
@ -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,
@ -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(

View File

@ -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 @@ 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
@ -22,6 +22,3 @@ entry:
}
declare void @doit(i8*)
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"warn-stack-size", i32 80}

View File

@ -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 @@ 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
@ -22,6 +22,3 @@ entry:
}
declare void @doit(i8*)
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"warn-stack-size", i32 80}

View File

@ -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}

View File

@ -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