[llvm] 8aee282 - [IR] remove assert since always_inline can appear on CallBase

Nick Desaulniers via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 28 13:59:22 PDT 2021


Author: Nick Desaulniers
Date: 2021-06-28T13:53:57-07:00
New Revision: 8aee282f57f42773570fc5d29f03a03361ff7fb4

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

LOG: [IR] remove assert since always_inline can appear on CallBase

I added an assertion in D91816 (documenting behavior added in D93422)
that callers and callees with mismatched fn attr's related to stack
protectors should not occur unless the callee was attributed
always_inline.

This falls apart when a call, invoke, or callbr (any instruction
inheriting from CallBase) itself has an always_inline attribute. Clang
will emit such attributes on Instructions when __attribute__((flatten))
is used to recursively force inlining from a caller.

Since these assertions only had the caller and callee Functions, and not
the call site (CallBase derived classes), we would have to search the
caller for such instructions to reconstruct the call site information.
But at that point, inlining has already occurred; the call site has
already been removed from the caller.

Remove the assertions, add a unit test for always_inline call sites, and
update the LangRef.

Another curiosity is that the always_inline Attribute on Instructions is
only expanded by the inline pass, not the always_inline pass.

Thanks to @pcc on this report when building Android's RunTime (ART)
interpreter.

Reviewed By: pcc, MaskRay

Differential Revision: https://reviews.llvm.org/D104944

Added: 
    

Modified: 
    llvm/docs/LangRef.rst
    llvm/lib/IR/Attributes.cpp
    llvm/test/Transforms/Inline/inline_nossp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 083ece600448f..243e9ea8bf7e8 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1922,7 +1922,8 @@ example:
     A function with the ``ssp`` attribute but without the ``alwaysinline``
     attribute cannot be inlined into a function without a
     ``ssp/sspreq/sspstrong`` attribute. If inlined, the caller will get the
-    ``ssp`` attribute.
+    ``ssp`` attribute. ``call``, ``invoke``, and ``callbr`` instructions with
+    the ``alwaysinline`` attribute force inlining.
 ``sspstrong``
     This attribute indicates that the function should emit a stack smashing
     protector. This attribute causes a strong heuristic to be used when
@@ -1950,7 +1951,9 @@ example:
     A function with the ``sspstrong`` attribute but without the
     ``alwaysinline`` attribute cannot be inlined into a function without a
     ``ssp/sspstrong/sspreq`` attribute. If inlined, the caller will get the
-    ``sspstrong`` attribute unless the ``sspreq`` attribute exists.
+    ``sspstrong`` attribute unless the ``sspreq`` attribute exists.  ``call``,
+    ``invoke``, and ``callbr`` instructions with the ``alwaysinline`` attribute
+    force inlining.
 ``sspreq``
     This attribute indicates that the function should *always* emit a stack
     smashing protector. This overrides the ``ssp`` and ``sspstrong`` function
@@ -1970,7 +1973,8 @@ example:
     A function with the ``sspreq`` attribute but without the ``alwaysinline``
     attribute cannot be inlined into a function without a
     ``ssp/sspstrong/sspreq`` attribute. If inlined, the caller will get the
-    ``sspreq`` attribute.
+    ``sspreq`` attribute.  ``call``, ``invoke``, and ``callbr`` instructions
+    with the ``alwaysinline`` attribute force inlining.
 
 ``strictfp``
     This attribute indicates that the function was called from a scope that

diff  --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index daf0f178e4c47..27b5835c85583 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -2159,16 +2159,6 @@ static void setOR(Function &Caller, const Function &Callee) {
 /// If the inlined function had a higher stack protection level than the
 /// calling function, then bump up the caller's stack protection level.
 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
-#ifndef NDEBUG
-  if (!Callee.hasFnAttribute(Attribute::AlwaysInline)) {
-    assert(!(!Callee.hasStackProtectorFnAttr() &&
-             Caller.hasStackProtectorFnAttr()) &&
-           "stack protected caller but callee requested no stack protector");
-    assert(!(!Caller.hasStackProtectorFnAttr() &&
-             Callee.hasStackProtectorFnAttr()) &&
-           "stack protected callee but caller requested no stack protector");
-  }
-#endif
   // If upgrading the SSP attribute, clear out the old SSP Attributes first.
   // Having multiple SSP attributes doesn't actually hurt, but it adds useless
   // clutter to the IR.

diff  --git a/llvm/test/Transforms/Inline/inline_nossp.ll b/llvm/test/Transforms/Inline/inline_nossp.ll
index 586735ec81992..2a4c8c65f8929 100644
--- a/llvm/test/Transforms/Inline/inline_nossp.ll
+++ b/llvm/test/Transforms/Inline/inline_nossp.ll
@@ -35,3 +35,18 @@ define i32 @ssp_caller() sspstrong {
   %2 = call i32 @nossp_alwaysinline()
   ret i32 %2
 }
+
+; The alwaysinline attribute can also appear on the CallBase (ie. the call
+; site), ie. when __attribute__((flatten)) is used on the caller. Treat this
+; the same as if the caller had the fn attr alwaysinline and permit inline
+; substitution, despite the mismatch between caller and callee on ssp attrs.
+;
+; Curiously, the always_inline attribute on a CallInst is only expanded by the
+; inline pass, but not always_inline pass!
+define i32 @nossp_alwaysinline_caller() {
+; CHECK-INLINE-LABEL: @nossp_alwaysinline_caller(
+; CHECK-INLINE-NEXT:    ret i32 42
+;
+  %1 = call i32 @ssp() alwaysinline
+  ret i32 %1
+}


        


More information about the llvm-commits mailing list