Summary:
We shouldn't do this transformation if the function is marked nobuitlin.
We were only checking that the return type is floating point, we really should be checking the argument types and argument count as well. This can be accomplished by using the other version of getLibFunc that takes the Function and not just the name.
We should also be checking TLI::has since sqrtf is a macro on Windows.
Fixes PR32559.
Reviewers: hfinkel, spatel, davide, efriedma
Reviewed By: davide, efriedma
Subscribers: efriedma, llvm-commits, eraman
Differential Revision: https://reviews.llvm.org/D39381
llvm-svn: 316819
if (Call->onlyReadsMemory())
return false;
- // The call must have the expected result type.
- if (!Call->getType()->isFloatingPointTy())
- return false;
-
// Do the following transformation:
//
// (before)
if (!Call || !(CalledFunc = Call->getCalledFunction()))
continue;
+ if (Call->isNoBuiltin())
+ continue;
+
// Skip if function either has local linkage or is not a known library
// function.
LibFunc LF;
- if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() ||
- !TLI->getLibFunc(CalledFunc->getName(), LF))
+ if (CalledFunc->hasLocalLinkage() ||
+ !TLI->getLibFunc(*CalledFunc, LF) || !TLI->has(LF))
continue;
switch (LF) {
target triple = "x86_64-unknown-linux-gnu"
declare i32 @sqrt()
+declare float @sqrtf()
; CHECK-LABEL: @foo
define i32 @foo() {
%r = call i32 @sqrt()
ret i32 %r
}
+
+; CHECK-LABEL: @bar
+define float @bar() {
+ ; CHECK: call{{.*}}@sqrtf
+ ; CHECK-NOT: call{{.*}}@sqrtf
+ %r = call float @sqrtf()
+ ret float %r
+}
--- /dev/null
+; RUN: opt -S -partially-inline-libcalls -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: opt -S -passes=partially-inline-libcalls -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+
+define float @f(float %val) {
+; CHECK-LABEL: @f
+; CHECK: call{{.*}}@sqrtf
+; CHECK-NOT: call{{.*}}@sqrtf
+ %res = tail call float @sqrtf(float %val) nobuiltin
+ ret float %res
+}
+
+declare float @sqrtf(float)