forked from OSchip/llvm-project
[SimplifyLibCalls] add reflection fold for -sin(-x) (PR38458)
This is a very partial fix for the reported problem. I suspect we do not get this fold in most motivating cases because most of the time, the libcall would have been replaced by an intrinsic, and that optimization is handled elsewhere...but maybe it should be handled here? llvm-svn: 339604
This commit is contained in:
parent
f138fda5ed
commit
e45a83d447
|
@ -131,7 +131,6 @@ private:
|
||||||
|
|
||||||
// Math Library Optimizations
|
// Math Library Optimizations
|
||||||
Value *optimizeCAbs(CallInst *CI, IRBuilder<> &B);
|
Value *optimizeCAbs(CallInst *CI, IRBuilder<> &B);
|
||||||
Value *optimizeCos(CallInst *CI, IRBuilder<> &B);
|
|
||||||
Value *optimizePow(CallInst *CI, IRBuilder<> &B);
|
Value *optimizePow(CallInst *CI, IRBuilder<> &B);
|
||||||
Value *replacePowWithSqrt(CallInst *Pow, IRBuilder<> &B);
|
Value *replacePowWithSqrt(CallInst *Pow, IRBuilder<> &B);
|
||||||
Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
|
Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
|
||||||
|
|
|
@ -1122,18 +1122,30 @@ Value *LibCallSimplifier::optimizeCAbs(CallInst *CI, IRBuilder<> &B) {
|
||||||
return B.CreateCall(FSqrt, B.CreateFAdd(RealReal, ImagImag), "cabs");
|
return B.CreateCall(FSqrt, B.CreateFAdd(RealReal, ImagImag), "cabs");
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *LibCallSimplifier::optimizeCos(CallInst *CI, IRBuilder<> &B) {
|
static Value *optimizeTrigReflections(CallInst *Call, LibFunc Func,
|
||||||
Function *Callee = CI->getCalledFunction();
|
IRBuilder<> &B) {
|
||||||
StringRef Name = Callee->getName();
|
// FIXME: This drops FMF.
|
||||||
if (UnsafeFPShrink && Name == "cos" && hasFloatVersion(Name))
|
// TODO: Add tan() and other calls.
|
||||||
if (Value *V = optimizeUnaryDoubleFP(CI, B, true))
|
// TODO: Can this be shared to also handle LLVM intrinsics?
|
||||||
return V;
|
|
||||||
|
|
||||||
// cos(-X) -> cos(X)
|
|
||||||
Value *X;
|
Value *X;
|
||||||
if (match(CI->getArgOperand(0), m_FNeg(m_Value(X))))
|
switch (Func) {
|
||||||
return B.CreateCall(Callee, X, "cos");
|
case LibFunc_sin:
|
||||||
|
case LibFunc_sinf:
|
||||||
|
case LibFunc_sinl:
|
||||||
|
// sin(-X) --> -sin(X)
|
||||||
|
if (match(Call->getArgOperand(0), m_OneUse(m_FNeg(m_Value(X)))))
|
||||||
|
return B.CreateFNeg(B.CreateCall(Call->getCalledFunction(), X, "sin"));
|
||||||
|
break;
|
||||||
|
case LibFunc_cos:
|
||||||
|
case LibFunc_cosf:
|
||||||
|
case LibFunc_cosl:
|
||||||
|
// cos(-X) --> cos(X)
|
||||||
|
if (match(Call->getArgOperand(0), m_FNeg(m_Value(X))))
|
||||||
|
return B.CreateCall(Call->getCalledFunction(), X, "cos");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2327,11 +2339,10 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
|
||||||
if (CI->isStrictFP())
|
if (CI->isStrictFP())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
if (Value *V = optimizeTrigReflections(CI, Func, Builder))
|
||||||
|
return V;
|
||||||
|
|
||||||
switch (Func) {
|
switch (Func) {
|
||||||
case LibFunc_cosf:
|
|
||||||
case LibFunc_cos:
|
|
||||||
case LibFunc_cosl:
|
|
||||||
return optimizeCos(CI, Builder);
|
|
||||||
case LibFunc_sinpif:
|
case LibFunc_sinpif:
|
||||||
case LibFunc_sinpi:
|
case LibFunc_sinpi:
|
||||||
case LibFunc_cospif:
|
case LibFunc_cospif:
|
||||||
|
@ -2386,6 +2397,7 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
|
||||||
case LibFunc_exp:
|
case LibFunc_exp:
|
||||||
case LibFunc_exp10:
|
case LibFunc_exp10:
|
||||||
case LibFunc_expm1:
|
case LibFunc_expm1:
|
||||||
|
case LibFunc_cos:
|
||||||
case LibFunc_sin:
|
case LibFunc_sin:
|
||||||
case LibFunc_sinh:
|
case LibFunc_sinh:
|
||||||
case LibFunc_tanh:
|
case LibFunc_tanh:
|
||||||
|
|
|
@ -52,9 +52,9 @@ define float @cosf_negated_arg_FMF(float %x) {
|
||||||
|
|
||||||
define double @sin_negated_arg(double %x) {
|
define double @sin_negated_arg(double %x) {
|
||||||
; ANY-LABEL: @sin_negated_arg(
|
; ANY-LABEL: @sin_negated_arg(
|
||||||
; ANY-NEXT: [[NEG:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
|
; ANY-NEXT: [[SIN:%.*]] = call double @sin(double [[X:%.*]])
|
||||||
; ANY-NEXT: [[R:%.*]] = call double @sin(double [[NEG]])
|
; ANY-NEXT: [[TMP1:%.*]] = fsub double -0.000000e+00, [[SIN]]
|
||||||
; ANY-NEXT: ret double [[R]]
|
; ANY-NEXT: ret double [[TMP1]]
|
||||||
;
|
;
|
||||||
%neg = fsub double -0.0, %x
|
%neg = fsub double -0.0, %x
|
||||||
%r = call double @sin(double %neg)
|
%r = call double @sin(double %neg)
|
||||||
|
@ -63,9 +63,9 @@ define double @sin_negated_arg(double %x) {
|
||||||
|
|
||||||
define float @sinf_negated_arg(float %x) {
|
define float @sinf_negated_arg(float %x) {
|
||||||
; ANY-LABEL: @sinf_negated_arg(
|
; ANY-LABEL: @sinf_negated_arg(
|
||||||
; ANY-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
|
; ANY-NEXT: [[SIN:%.*]] = call float @sinf(float [[X:%.*]])
|
||||||
; ANY-NEXT: [[R:%.*]] = call float @sinf(float [[NEG]])
|
; ANY-NEXT: [[TMP1:%.*]] = fsub float -0.000000e+00, [[SIN]]
|
||||||
; ANY-NEXT: ret float [[R]]
|
; ANY-NEXT: ret float [[TMP1]]
|
||||||
;
|
;
|
||||||
%neg = fsub float -0.0, %x
|
%neg = fsub float -0.0, %x
|
||||||
%r = call float @sinf(float %neg)
|
%r = call float @sinf(float %neg)
|
||||||
|
@ -92,10 +92,8 @@ define double @sin_negated_arg_extra_use(double %x) {
|
||||||
|
|
||||||
define double @neg_sin_negated_arg(double %x) {
|
define double @neg_sin_negated_arg(double %x) {
|
||||||
; ANY-LABEL: @neg_sin_negated_arg(
|
; ANY-LABEL: @neg_sin_negated_arg(
|
||||||
; ANY-NEXT: [[NEG:%.*]] = fsub double -0.000000e+00, [[X:%.*]]
|
; ANY-NEXT: [[SIN:%.*]] = call double @sin(double [[X:%.*]])
|
||||||
; ANY-NEXT: [[R:%.*]] = call double @sin(double [[NEG]])
|
; ANY-NEXT: ret double [[SIN]]
|
||||||
; ANY-NEXT: [[RN:%.*]] = fsub double -0.000000e+00, [[R]]
|
|
||||||
; ANY-NEXT: ret double [[RN]]
|
|
||||||
;
|
;
|
||||||
%neg = fsub double -0.0, %x
|
%neg = fsub double -0.0, %x
|
||||||
%r = call double @sin(double %neg)
|
%r = call double @sin(double %neg)
|
||||||
|
|
Loading…
Reference in New Issue