diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -297,6 +297,7 @@ def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; def : CompatRule<"isEqual">; +def : CompatRule<"isEqual">; class MergeRule { // The name of the function called to merge the attributes of the caller and diff --git a/llvm/test/Transforms/Inline/inline_noprofile.ll b/llvm/test/Transforms/Inline/inline_noprofile.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/inline_noprofile.ll @@ -0,0 +1,41 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes=inline %s -S -pass-remarks-missed=inline 2>&1 | FileCheck %s + +; Test that we don't inline when caller and callee don't have matching +; noprofile fn attrs. + +; CHECK: foo not inlined into bar because it should never be inlined (cost=never): conflicting attributes +; CHECK: bar not inlined into baz because it should never be inlined (cost=never): conflicting attributes + +define i32 @foo() { +; CHECK-LABEL: @foo( +; CHECK-NEXT: ret i32 42 +; + ret i32 42 +} + +define i32 @bar() noprofile { +; CHECK-LABEL: @bar( +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @foo() +; CHECK-NEXT: ret i32 [[TMP1]] +; + %1 = call i32 @foo() + ret i32 %1 +} + +define i32 @baz() { +; CHECK-LABEL: @baz( +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @bar() +; CHECK-NEXT: ret i32 [[TMP1]] +; + %1 = call i32 @bar() + ret i32 %1 +} + +define i32 @quux() { +; CHECK-LABEL: @quux( +; CHECK-NEXT: ret i32 42 +; + %1 = call i32 @foo() + ret i32 %1 +}