forked from OSchip/llvm-project
[InstCombine] canonicalize fneg with llvm.sin
This is a follow-up to rL339604 which did the same transform for a sin libcall. The handling of intrinsics vs. libcalls is unfortunately scattered, so I'm just adding this next to the existing transform for llvm.cos for now. This should resolve PR38458: https://bugs.llvm.org/show_bug.cgi?id=38458 If the call was already negated, the negates will cancel each other out. llvm-svn: 340952
This commit is contained in:
parent
f5403d83e7
commit
0f29e953b7
|
@ -2124,16 +2124,25 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
|||
}
|
||||
case Intrinsic::cos:
|
||||
case Intrinsic::amdgcn_cos: {
|
||||
Value *SrcSrc;
|
||||
Value *X;
|
||||
Value *Src = II->getArgOperand(0);
|
||||
if (match(Src, m_FNeg(m_Value(SrcSrc))) ||
|
||||
match(Src, m_FAbs(m_Value(SrcSrc)))) {
|
||||
if (match(Src, m_FNeg(m_Value(X))) || match(Src, m_FAbs(m_Value(X)))) {
|
||||
// cos(-x) -> cos(x)
|
||||
// cos(fabs(x)) -> cos(x)
|
||||
II->setArgOperand(0, SrcSrc);
|
||||
II->setArgOperand(0, X);
|
||||
return II;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Intrinsic::sin: {
|
||||
Value *X;
|
||||
if (match(II->getArgOperand(0), m_OneUse(m_FNeg(m_Value(X))))) {
|
||||
// sin(-x) --> -sin(x)
|
||||
Value *NewSin = Builder.CreateIntrinsic(Intrinsic::sin, { X }, II);
|
||||
Instruction *FNeg = BinaryOperator::CreateFNeg(NewSin);
|
||||
FNeg->copyFastMathFlags(II);
|
||||
return FNeg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Intrinsic::ppc_altivec_lvx:
|
||||
|
|
|
@ -92,14 +92,14 @@ define <2 x float> @fabs_fneg_v2f32(<2 x float> %x) {
|
|||
ret <2 x float> %cos
|
||||
}
|
||||
|
||||
; TODO: Negate is canonicalized after sin.
|
||||
; Negate is canonicalized after sin.
|
||||
|
||||
declare <2 x float> @llvm.sin.v2f32(<2 x float>)
|
||||
|
||||
define <2 x float> @fneg_sin(<2 x float> %x){
|
||||
; CHECK-LABEL: @fneg_sin(
|
||||
; CHECK-NEXT: [[NEGX:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
|
||||
; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.sin.v2f32(<2 x float> [[NEGX]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.sin.v2f32(<2 x float> [[X:%.*]])
|
||||
; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[TMP1]]
|
||||
; CHECK-NEXT: ret <2 x float> [[R]]
|
||||
;
|
||||
%negx = fsub <2 x float> <float -0.0, float -0.0>, %x
|
||||
|
@ -107,12 +107,12 @@ define <2 x float> @fneg_sin(<2 x float> %x){
|
|||
ret <2 x float> %r
|
||||
}
|
||||
|
||||
; TODO: FMF are not required, but they should propagate.
|
||||
; FMF are not required, but they should propagate.
|
||||
|
||||
define <2 x float> @fneg_sin_fmf(<2 x float> %x){
|
||||
; CHECK-LABEL: @fneg_sin_fmf(
|
||||
; CHECK-NEXT: [[NEGX:%.*]] = fsub fast <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
|
||||
; CHECK-NEXT: [[R:%.*]] = call nnan arcp afn <2 x float> @llvm.sin.v2f32(<2 x float> [[NEGX]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call nnan arcp afn <2 x float> @llvm.sin.v2f32(<2 x float> [[X:%.*]])
|
||||
; CHECK-NEXT: [[R:%.*]] = fsub nnan arcp afn <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[TMP1]]
|
||||
; CHECK-NEXT: ret <2 x float> [[R]]
|
||||
;
|
||||
%negx = fsub fast <2 x float> <float -0.0, float -0.0>, %x
|
||||
|
|
Loading…
Reference in New Issue