[llvm] 8ace121 - [IR] convert warn-stack-size from module flag to fn attr

Nick Desaulniers via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 21 15:16:54 PDT 2021


Author: Nick Desaulniers
Date: 2021-06-21T15:09:25-07:00
New Revision: 8ace12130526f450c822ca232d1f865b247d7434

URL: https://github.com/llvm/llvm-project/commit/8ace12130526f450c822ca232d1f865b247d7434
DIFF: https://github.com/llvm/llvm-project/commit/8ace12130526f450c822ca232d1f865b247d7434.diff

LOG: [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

Added: 
    clang/test/Frontend/fwarn-stack-size.c
    llvm/test/Verifier/invalid-warn-stack-size.ll

Modified: 
    clang/lib/CodeGen/CodeGenFunction.cpp
    clang/lib/CodeGen/CodeGenModule.cpp
    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

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


################################################################################
diff  --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 97288d01686e..0ca94657e815 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -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();

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 369c4b6ccef9..943ed5da6ede 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -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);
 

diff  --git a/clang/test/Frontend/fwarn-stack-size.c b/clang/test/Frontend/fwarn-stack-size.c
new file mode 100644
index 000000000000..7bffbbd5b0b3
--- /dev/null
+++ b/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"

diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 3f1492e67a3d..6c4163f2479f 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -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

diff  --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 024abe0623f6..81e29d9b86e8 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -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
   /// @{
 

diff  --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
index e09face17c79..e745f561a896 100644
--- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -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);

diff  --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 40d3401df052..9b955500b618 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -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());

diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index bfdfb7a61d49..9322919aae58 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -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);
@@ -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(

diff  --git a/llvm/test/CodeGen/ARM/warn-stack.ll b/llvm/test/CodeGen/ARM/warn-stack.ll
index 156bfbf66697..751590059d0d 100644
--- a/llvm/test/CodeGen/ARM/warn-stack.ll
+++ b/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 @@ 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}

diff  --git a/llvm/test/CodeGen/X86/warn-stack.ll b/llvm/test/CodeGen/X86/warn-stack.ll
index cf1cd14dc992..b0c51f22ebe0 100644
--- a/llvm/test/CodeGen/X86/warn-stack.ll
+++ b/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 @@ 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}

diff  --git a/llvm/test/Linker/warn-stack-frame.ll b/llvm/test/Linker/warn-stack-frame.ll
deleted file mode 100644
index 504eb8f01931..000000000000
--- a/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}

diff  --git a/llvm/test/Verifier/invalid-warn-stack-size.ll b/llvm/test/Verifier/invalid-warn-stack-size.ll
new file mode 100644
index 000000000000..56c2ebb3cfca
--- /dev/null
+++ b/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


        


More information about the llvm-commits mailing list