[LibCallSimplifier] use instruction-level fast-math-flags to transform log calls

Also, add tests to verify that we're checking 'fast' on both calls of each transform pair,
tighten the CHECK lines, and give the tests more meaningful names.

This is a continuation of:
http://reviews.llvm.org/rL255555
http://reviews.llvm.org/rL256871
http://reviews.llvm.org/rL256964
http://reviews.llvm.org/rL257400
http://reviews.llvm.org/rL257404

llvm-svn: 257414
This commit is contained in:
Sanjay Patel 2016-01-11 23:31:48 +00:00
parent 7bf779859a
commit e896ede7f1
2 changed files with 47 additions and 25 deletions

View File

@ -1354,11 +1354,13 @@ Value *LibCallSimplifier::optimizeLog(CallInst *CI, IRBuilder<> &B) {
!FT->getParamType(0)->isFloatingPointTy())
return Ret;
if (!canUseUnsafeFPMath(CI->getParent()->getParent()))
if (!CI->hasUnsafeAlgebra())
return Ret;
Value *Op1 = CI->getArgOperand(0);
auto *OpC = dyn_cast<CallInst>(Op1);
if (!OpC)
// The earlier call must also be unsafe in order to do these transforms.
if (!OpC || !OpC->hasUnsafeAlgebra())
return Ret;
// log(pow(x,y)) -> y*log(x)

View File

@ -1,41 +1,61 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
define double @mylog(double %x, double %y) #0 {
entry:
%pow = call double @llvm.pow.f64(double %x, double %y)
%call = call double @log(double %pow) #0
define double @log_pow(double %x, double %y) {
%pow = call fast double @llvm.pow.f64(double %x, double %y)
%call = call fast double @log(double %pow)
ret double %call
}
; CHECK-LABEL: define double @mylog(
; CHECK: %log = call fast double @log(double %x) #0
; CHECK: %mul = fmul fast double %log, %y
; CHECK: ret double %mul
; CHECK: }
; CHECK-LABEL: define double @log_pow(
; CHECK-NEXT: %log = call fast double @log(double %x)
; CHECK-NEXT: %mul = fmul fast double %log, %y
; CHECK-NEXT: ret double %mul
define double @test2(double ()* %fptr, double %p1) #0 {
define double @log_pow_not_fast(double %x, double %y) {
%pow = call double @llvm.pow.f64(double %x, double %y)
%call = call fast double @log(double %pow)
ret double %call
}
; CHECK-LABEL: define double @log_pow_not_fast(
; CHECK-NEXT: %pow = call double @llvm.pow.f64(double %x, double %y)
; CHECK-NEXT: %call = call fast double @log(double %pow)
; CHECK-NEXT: ret double %call
define double @function_pointer(double ()* %fptr, double %p1) {
%call1 = call double %fptr()
%pow = call double @log(double %call1)
ret double %pow
}
; CHECK-LABEL: @test2
; CHECK: log
; CHECK-LABEL: @function_pointer
; CHECK-NEXT: %call1 = call double %fptr()
; CHECK-NEXT: %pow = call double @log(double %call1)
; CHECK-NEXT: ret double %pow
define double @test3(double %x) #0 {
%call2 = call double @exp2(double %x) #0
%call3 = call double @log(double %call2) #0
define double @log_exp2(double %x) {
%call2 = call fast double @exp2(double %x)
%call3 = call fast double @log(double %call2)
ret double %call3
}
; CHECK-LABEL: @test3
; CHECK: %call2 = call double @exp2(double %x) #0
; CHECK: %logmul = fmul fast double %x, 0x3FE62E42FEFA39EF
; CHECK: ret double %logmul
; CHECK: }
; CHECK-LABEL: @log_exp2
; CHECK-NEXT: %call2 = call fast double @exp2(double %x)
; CHECK-NEXT: %logmul = fmul fast double %x, 0x3FE62E42FEFA39EF
; CHECK-NEXT: ret double %logmul
declare double @log(double) #0
declare double @exp2(double) #0
define double @log_exp2_not_fast(double %x) {
%call2 = call double @exp2(double %x)
%call3 = call fast double @log(double %call2)
ret double %call3
}
; CHECK-LABEL: @log_exp2_not_fast
; CHECK-NEXT: %call2 = call double @exp2(double %x)
; CHECK-NEXT: %call3 = call fast double @log(double %call2)
; CHECK-NEXT: ret double %call3
declare double @log(double)
declare double @exp2(double)
declare double @llvm.pow.f64(double, double)
attributes #0 = { "unsafe-fp-math"="true" }