[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
This commit is contained in:
Akira Hatanaka 2015-04-13 18:43:38 +00:00
parent 75f1ab4b1b
commit a50a335767
2 changed files with 56 additions and 4 deletions

View File

@ -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<typename AttrKind>
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);
}

View File

@ -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
}