diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2016-01-13 06:02:45 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2016-01-13 06:02:45 +0000 |
commit | b45b1ea86f8f93b206af878194239a243dff3e21 (patch) | |
tree | 7d98044019db961ef7c35c82bf69d7f48804a029 | |
parent | e9a1c31ebf8d33ac378bb37fe3d3bc0b2051b173 (diff) | |
download | bcm5719-llvm-b45b1ea86f8f93b206af878194239a243dff3e21.tar.gz bcm5719-llvm-b45b1ea86f8f93b206af878194239a243dff3e21.zip |
[Inliner] Merge the attributes of the caller and callee functions
This patch turns off the fast-math optimization attribute on the caller
if the callee's fast-math attribute is not turned on.
For example,
- before inlining
caller: "less-precise-fpmad"="true"
callee: "less-precise-fpmad"="false"
- after inlining
caller: "less-precise-fpmad"="false"
Alternatively, it's possible to block inlining if the caller's and
callee's attributes don't match. If this approach is preferable to the
one in this patch, we can discuss post-commit.
rdar://problem/19836465
Differential Revision: http://reviews.llvm.org/D7802
llvm-svn: 257575
-rw-r--r-- | llvm/include/llvm/IR/Attributes.td | 5 | ||||
-rw-r--r-- | llvm/test/Transforms/Inline/attributes.ll | 84 |
2 files changed, 89 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index 797cd55427b..30249bbd8fa 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -189,4 +189,9 @@ class MergeRule<string F> { string MergeFunc = F; } +def : MergeRule<"setAND<LessPreciseFPMADAttr>">; +def : MergeRule<"setAND<NoInfsFPMathAttr>">; +def : MergeRule<"setAND<NoNansFPMathAttr>">; +def : MergeRule<"setAND<UnsafeFPMathAttr>">; +def : MergeRule<"setOR<NoImplicitFloatAttr>">; def : MergeRule<"adjustCallerSSPLevel">; diff --git a/llvm/test/Transforms/Inline/attributes.ll b/llvm/test/Transforms/Inline/attributes.ll index a97e6a60de7..0458fa23f79 100644 --- a/llvm/test/Transforms/Inline/attributes.ll +++ b/llvm/test/Transforms/Inline/attributes.ll @@ -160,3 +160,87 @@ define i32 @test_target_features1(i32 %i) "target-features"="+sse4.2" { ; CHECK-NEXT: @test_target_features_callee1 ; CHECK-NEXT: ret i32 } + +define i32 @less-precise-fpmad_callee0(i32 %i) "less-precise-fpmad"="false" { + ret i32 %i +; CHECK: @less-precise-fpmad_callee0(i32 %i) [[FPMAD_FALSE:#[0-9]+]] { +; CHECK-NEXT: ret i32 +} + +define i32 @less-precise-fpmad_callee1(i32 %i) "less-precise-fpmad"="true" { + ret i32 %i +; CHECK: @less-precise-fpmad_callee1(i32 %i) [[FPMAD_TRUE:#[0-9]+]] { +; CHECK-NEXT: ret i32 +} + +define i32 @test_less-precise-fpmad0(i32 %i) "less-precise-fpmad"="false" { + %1 = call i32 @less-precise-fpmad_callee0(i32 %i) + ret i32 %1 +; CHECK: @test_less-precise-fpmad0(i32 %i) [[FPMAD_FALSE]] { +; CHECK-NEXT: ret i32 +} + +define i32 @test_less-precise-fpmad1(i32 %i) "less-precise-fpmad"="false" { + %1 = call i32 @less-precise-fpmad_callee1(i32 %i) + ret i32 %1 +; CHECK: @test_less-precise-fpmad1(i32 %i) [[FPMAD_FALSE]] { +; CHECK-NEXT: ret i32 +} + +define i32 @test_less-precise-fpmad2(i32 %i) "less-precise-fpmad"="true" { + %1 = call i32 @less-precise-fpmad_callee0(i32 %i) + ret i32 %1 +; CHECK: @test_less-precise-fpmad2(i32 %i) [[FPMAD_FALSE]] { +; CHECK-NEXT: ret i32 +} + +define i32 @test_less-precise-fpmad3(i32 %i) "less-precise-fpmad"="true" { + %1 = call i32 @less-precise-fpmad_callee1(i32 %i) + ret i32 %1 +; CHECK: @test_less-precise-fpmad3(i32 %i) [[FPMAD_TRUE]] { +; CHECK-NEXT: ret i32 +} + +define i32 @no-implicit-float_callee0(i32 %i) { + ret i32 %i +; CHECK: @no-implicit-float_callee0(i32 %i) { +; CHECK-NEXT: ret i32 +} + +define i32 @no-implicit-float_callee1(i32 %i) noimplicitfloat { + ret i32 %i +; CHECK: @no-implicit-float_callee1(i32 %i) [[NOIMPLICITFLOAT:#[0-9]+]] { +; CHECK-NEXT: ret i32 +} + +define i32 @test_no-implicit-float0(i32 %i) { + %1 = call i32 @no-implicit-float_callee0(i32 %i) + ret i32 %1 +; CHECK: @test_no-implicit-float0(i32 %i) { +; CHECK-NEXT: ret i32 +} + +define i32 @test_no-implicit-float1(i32 %i) { + %1 = call i32 @no-implicit-float_callee1(i32 %i) + ret i32 %1 +; CHECK: @test_no-implicit-float1(i32 %i) [[NOIMPLICITFLOAT]] { +; CHECK-NEXT: ret i32 +} + +define i32 @test_no-implicit-float2(i32 %i) noimplicitfloat { + %1 = call i32 @no-implicit-float_callee0(i32 %i) + ret i32 %1 +; CHECK: @test_no-implicit-float2(i32 %i) [[NOIMPLICITFLOAT]] { +; CHECK-NEXT: ret i32 +} + +define i32 @test_no-implicit-float3(i32 %i) noimplicitfloat { + %1 = call i32 @no-implicit-float_callee1(i32 %i) + ret i32 %1 +; CHECK: @test_no-implicit-float3(i32 %i) [[NOIMPLICITFLOAT]] { +; CHECK-NEXT: ret i32 +} + +; CHECK: attributes [[FPMAD_FALSE]] = { "less-precise-fpmad"="false" } +; CHECK: attributes [[FPMAD_TRUE]] = { "less-precise-fpmad"="true" } +; CHECK: attributes [[NOIMPLICITFLOAT]] = { noimplicitfloat } |