From a50a33576704605efc41ea53d36c76692eddd1c6 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Mon, 13 Apr 2015 18:43:38 +0000 Subject: [PATCH] [inliner] Don't inline a function if it doesn't have exactly the same target-cpu and target-features attribute strings as the caller. Differential Revision: http://reviews.llvm.org/D8984 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234773 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/IPA/InlineCost.cpp | 10 +++--- test/Transforms/Inline/attributes.ll | 50 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/lib/Analysis/IPA/InlineCost.cpp b/lib/Analysis/IPA/InlineCost.cpp index eeb3b87382e..aa015647926 100644 --- a/lib/Analysis/IPA/InlineCost.cpp +++ b/lib/Analysis/IPA/InlineCost.cpp @@ -1286,16 +1286,18 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, int Threshold) { /// \brief Test that two functions either have or have not the given attribute /// at the same time. -static bool attributeMatches(Function *F1, Function *F2, - Attribute::AttrKind Attr) { - return F1->hasFnAttribute(Attr) == F2->hasFnAttribute(Attr); +template +static bool attributeMatches(Function *F1, Function *F2, AttrKind Attr) { + return F1->getFnAttribute(Attr) == F2->getFnAttribute(Attr); } /// \brief Test that there are no attribute conflicts between Caller and Callee /// that prevent inlining. static bool functionsHaveCompatibleAttributes(Function *Caller, Function *Callee) { - return attributeMatches(Caller, Callee, Attribute::SanitizeAddress) && + return attributeMatches(Caller, Callee, "target-cpu") && + attributeMatches(Caller, Callee, "target-features") && + attributeMatches(Caller, Callee, Attribute::SanitizeAddress) && attributeMatches(Caller, Callee, Attribute::SanitizeMemory) && attributeMatches(Caller, Callee, Attribute::SanitizeThread); } diff --git a/test/Transforms/Inline/attributes.ll b/test/Transforms/Inline/attributes.ll index 53fb13f2baf..a97e6a60de7 100644 --- a/test/Transforms/Inline/attributes.ll +++ b/test/Transforms/Inline/attributes.ll @@ -110,3 +110,53 @@ define i32 @test_sanitize_thread(i32 %arg) sanitize_thread { ; CHECK-NEXT: @noattr_callee ; CHECK-NEXT: ret i32 } + +; Check that a function doesn't get inlined if target-cpu strings don't match +; exactly. +define i32 @test_target_cpu_callee0(i32 %i) "target-cpu"="corei7" { + ret i32 %i +} + +define i32 @test_target_cpu0(i32 %i) "target-cpu"="corei7" { + %1 = call i32 @test_target_cpu_callee0(i32 %i) + ret i32 %1 +; CHECK-LABEL: @test_target_cpu0( +; CHECK-NOT: @test_target_cpu_callee0 +} + +define i32 @test_target_cpu_callee1(i32 %i) "target-cpu"="x86-64" { + ret i32 %i +} + +define i32 @test_target_cpu1(i32 %i) "target-cpu"="corei7" { + %1 = call i32 @test_target_cpu_callee1(i32 %i) + ret i32 %1 +; CHECK-LABEL: @test_target_cpu1( +; CHECK-NEXT: @test_target_cpu_callee1 +; CHECK-NEXT: ret i32 +} + +; Check that a function doesn't get inlined if target-features strings don't +; match exactly. +define i32 @test_target_features_callee0(i32 %i) "target-features"="+sse4.2" { + ret i32 %i +} + +define i32 @test_target_features0(i32 %i) "target-features"="+sse4.2" { + %1 = call i32 @test_target_features_callee0(i32 %i) + ret i32 %1 +; CHECK-LABEL: @test_target_features0( +; CHECK-NOT: @test_target_features_callee0 +} + +define i32 @test_target_features_callee1(i32 %i) "target-features"="+avx2" { + ret i32 %i +} + +define i32 @test_target_features1(i32 %i) "target-features"="+sse4.2" { + %1 = call i32 @test_target_features_callee1(i32 %i) + ret i32 %1 +; CHECK-LABEL: @test_target_features1( +; CHECK-NEXT: @test_target_features_callee1 +; CHECK-NEXT: ret i32 +} -- 2.34.1