[llvm] 37b8e76 - [AlwaysInliner] Do not inline on attribute mismatches

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 06:15:40 PDT 2026


Author: Aiden Grossman
Date: 2026-07-14T06:15:35-07:00
New Revision: 37b8e765ce4837a7577e6f762bcdffe4b232759c

URL: https://github.com/llvm/llvm-project/commit/37b8e765ce4837a7577e6f762bcdffe4b232759c
DIFF: https://github.com/llvm/llvm-project/commit/37b8e765ce4837a7577e6f762bcdffe4b232759c.diff

LOG: [AlwaysInliner] Do not inline on attribute mismatches

7bdca287b102ee935e982613dba2264cbc7a32ad made it so that the inliner
will not inline functions with mismatched target attributes regardless
of the presence of alwaysinline. However, always-inline never actually
called into this function so would still do the illegal thing. I believe
the motivation for not putting it here originally/recently was that
clang does some rudimentary target feature checks, but we should not be
crashing on valid IR, and we do generate IR that caused crashes in ISel
due to this (e.g., ICP in ThinLTO backend actions).

Reviewers: nikic, aeubanks

Pull Request: https://github.com/llvm/llvm-project/pull/209345

Added: 
    llvm/test/Transforms/Inline/X86/always-inline-incompatible-target-features.ll

Modified: 
    llvm/lib/Transforms/IPO/AlwaysInliner.cpp
    llvm/test/Transforms/Inline/always-inline-phase-ordering.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
index 080cb8ddb33fd..1bdefb25b8dfb 100644
--- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
+++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp
@@ -21,6 +21,7 @@
 #include "llvm/Analysis/ProfileSummaryInfo.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Transforms/Utils/Cloning.h"
@@ -52,6 +53,22 @@ bool AlwaysInlineImpl(
     DebugLoc DLoc = CB.getDebugLoc();
     BasicBlock *Block = CB.getParent();
 
+    TargetTransformInfo &CalleeTTI = GetTTI(Callee);
+    std::optional<InlineResult> CanInlineWithAttributes =
+        getAttributeBasedInliningDecision(CB, &Callee, CalleeTTI, GetTLI);
+    if (!CanInlineWithAttributes || !CanInlineWithAttributes->isSuccess()) {
+      ORE.emit([&]() {
+        return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
+               << "'" << ore::NV("Callee", &Callee) << ", is not inlined into"
+               << ore::NV("Caller", Caller) << "': "
+               << ore::NV("Reason",
+                          CanInlineWithAttributes.has_value()
+                              ? CanInlineWithAttributes->getFailureReason()
+                              : "due to incompatible function attributes");
+      });
+      return false;
+    }
+
     InlineFunctionInfo IFI(GetAssumptionCache, &PSI);
     InlineResult Res = InlineFunction(
         CB, IFI, /*MergeAttributes=*/true, &GetAAR(Callee), InsertLifetime,

diff  --git a/llvm/test/Transforms/Inline/X86/always-inline-incompatible-target-features.ll b/llvm/test/Transforms/Inline/X86/always-inline-incompatible-target-features.ll
new file mode 100644
index 0000000000000..e4524c69f0206
--- /dev/null
+++ b/llvm/test/Transforms/Inline/X86/always-inline-incompatible-target-features.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=always-inline -S < %s | FileCheck %s
+
+; Check that always-inline does not inline functions with incompatible target
+; features.
+
+target triple = "x86_64-grtev4-linux-gnu"
+
+define i64 @clck(i64 %a) {
+; CHECK-LABEL: define i64 @clck(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @dkwaysa(i64 [[A]])
+; CHECK-NEXT:    ret i64 [[TMP1]]
+;
+  %1 = call i64 @dkwaysa(i64 %a)
+  ret i64 %1
+}
+
+define i64 @dkwaysa(i64 %a) #0 {
+; CHECK-LABEL: define i64 @dkwaysa(
+; CHECK-SAME: i64 [[A:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i64 @llvm.x86.bmi.bzhi.64(i64 1, i64 [[A]])
+; CHECK-NEXT:    ret i64 [[TMP1]]
+;
+  %2 = tail call i64 @llvm.x86.bmi.bzhi.64(i64 1, i64 %a)
+  ret i64 %2
+}
+
+attributes #0 = { alwaysinline "target-features"="+bmi2" }

diff  --git a/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll b/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll
index 1cfdaddd34a65..7beaa5767bd3a 100644
--- a/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll
+++ b/llvm/test/Transforms/Inline/always-inline-phase-ordering.ll
@@ -118,7 +118,7 @@ bb:
 }
 
 attributes #0 = { optsize "frame-pointer"="non-leaf" }
-attributes #1 = { optsize "target-cpu"="apple-m1" }
+attributes #1 = { optsize }
 attributes #2 = { optsize alwaysinline }
 
 !llvm.module.flags = !{!0, !1, !30, !31, !32, !36, !37}


        


More information about the llvm-commits mailing list