diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp --- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp +++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp @@ -54,12 +54,25 @@ if (CB->getCalledFunction() == &F) Calls.insert(CB); - for (CallBase *CB : Calls) - // FIXME: We really shouldn't be able to fail to inline at this point! - // We should do something to log or check the inline failures here. - Changed |= - InlineFunction(*CB, IFI, /*CalleeAAR=*/nullptr, InsertLifetime) - .isSuccess(); + for (CallBase *CB : Calls) { + Function *Caller = CB->getCaller(); + OptimizationRemarkEmitter ORE(Caller); + auto OIC = shouldInline( + *CB, + [&](CallBase &CB) { + return InlineCost::getAlways("always inline attribute"); + }, + ORE); + assert(OIC); + emitInlinedInto(ORE, CB->getDebugLoc(), CB->getParent(), F, *Caller, + *OIC, false, DEBUG_TYPE); + + InlineResult Res = + InlineFunction(*CB, IFI, /*CalleeAAR=*/nullptr, InsertLifetime); + assert(Res.isSuccess() && "unexpected failure to inline"); + (void)Res; + Changed = true; + } // Remember to try and delete this function afterward. This both avoids // re-walking the rest of the module and avoids dealing with any iterator diff --git a/llvm/test/Transforms/Inline/optimization-remarks.ll b/llvm/test/Transforms/Inline/optimization-remarks.ll --- a/llvm/test/Transforms/Inline/optimization-remarks.ll +++ b/llvm/test/Transforms/Inline/optimization-remarks.ll @@ -1,28 +1,35 @@ ; RUN: opt < %s -inline -pass-remarks=inline -pass-remarks-missed=inline \ ; RUN: -pass-remarks-analysis=inline -S 2>&1 | \ -; RUN: FileCheck -check-prefix=CHECK -check-prefix=NO_HOTNESS %s +; RUN: FileCheck -check-prefixes=CHECK,NO_HOTNESS,ALWAYS %s ; RUN: opt < %s -inline -pass-remarks=inline -pass-remarks-missed=inline \ ; RUN: -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 | \ -; RUN: FileCheck -check-prefix=CHECK -check-prefix=HOTNESS %s +; RUN: FileCheck -check-prefixes=CHECK,HOTNESS,ALWAYS %s + +; RUN: opt < %s -passes=always-inline -pass-remarks=inline -pass-remarks-missed=inline \ +; RUN: -pass-remarks-analysis=inline -S 2>&1 | \ +; RUN: FileCheck -check-prefixes=ALWAYS %s +; RUN: opt < %s -passes=always-inline -pass-remarks=inline -pass-remarks-missed=inline \ +; RUN: -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 | \ +; RUN: FileCheck -check-prefixes=ALWAYS %s ; RUN: opt < %s -passes=inline -pass-remarks=inline -pass-remarks-missed=inline \ ; RUN: -pass-remarks-analysis=inline -S 2>&1 | \ -; RUN: FileCheck -check-prefix=CHECK -check-prefix=NO_HOTNESS %s +; RUN: FileCheck -check-prefixes=CHECK,NO_HOTNESS,ALWAYS %s ; RUN: opt < %s -passes=inline -pass-remarks=inline -pass-remarks-missed=inline \ ; RUN: -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 | \ -; RUN: FileCheck -check-prefix=CHECK -check-prefix=HOTNESS %s +; RUN: FileCheck -check-prefixes=CHECK,HOTNESS,ALWAYS %s ; RUN: opt < %s -passes=inliner-wrapper -pass-remarks=inline -pass-remarks-missed=inline \ ; RUN: -pass-remarks-analysis=inline -S 2>&1 | \ -; RUN: FileCheck -check-prefix=CHECK -check-prefix=NO_HOTNESS %s +; RUN: FileCheck -check-prefixes=CHECK,NO_HOTNESS,ALWAYS %s ; RUN: opt < %s -passes=inliner-wrapper -pass-remarks=inline -pass-remarks-missed=inline \ ; RUN: -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 | \ -; RUN: FileCheck -check-prefix=CHECK -check-prefix=HOTNESS %s +; RUN: FileCheck -check-prefixes=CHECK,HOTNESS,ALWAYS %s -; HOTNESS: fox will not be inlined into bar because its definition is unavailable +; HOTNESS-DAG: fox will not be inlined into bar because its definition is unavailable ; NO_HOTNESS-NOT: fox will not be inlined into bar because its definition is unavailable -; CHECK: foo inlined into bar with (cost=always): always inline attribute -; CHECK: foz not inlined into bar because it should never be inlined (cost=never): noinline function attribute +; ALWAYS-DAG: foo inlined into bar with (cost=always): always inline attribute +; CHECK-DAG: foz not inlined into bar because it should never be inlined (cost=never): noinline function attribute ; Function Attrs: alwaysinline nounwind uwtable define i32 @foo(i32 %x, i32 %y) #0 !prof !1 {