@@ -1908,49 +1908,6 @@ Value *LibCallSimplifier::optimizeCAbs(CallInst *CI, IRBuilderBase &B) {
19081908 *CI, B.CreateCall (FSqrt, B.CreateFAdd (RealReal, ImagImag), " cabs" ));
19091909}
19101910
1911- static Value *optimizeTrigReflections (CallInst *Call, LibFunc Func,
1912- IRBuilderBase &B) {
1913- if (!isa<FPMathOperator>(Call))
1914- return nullptr ;
1915-
1916- IRBuilderBase::FastMathFlagGuard Guard (B);
1917- B.setFastMathFlags (Call->getFastMathFlags ());
1918-
1919- // TODO: Can this be shared to also handle LLVM intrinsics?
1920- Value *X;
1921- switch (Func) {
1922- case LibFunc_sin:
1923- case LibFunc_sinf:
1924- case LibFunc_sinl:
1925- case LibFunc_tan:
1926- case LibFunc_tanf:
1927- case LibFunc_tanl:
1928- // sin(-X) --> -sin(X)
1929- // tan(-X) --> -tan(X)
1930- if (match (Call->getArgOperand (0 ), m_OneUse (m_FNeg (m_Value (X)))))
1931- return B.CreateFNeg (
1932- copyFlags (*Call, B.CreateCall (Call->getCalledFunction (), X)));
1933- break ;
1934- case LibFunc_cos:
1935- case LibFunc_cosf:
1936- case LibFunc_cosl: {
1937- // cos(-x) --> cos(x)
1938- // cos(fabs(x)) --> cos(x)
1939- // cos(copysign(x, y)) --> cos(x)
1940- Value *Sign;
1941- Value *Src = Call->getArgOperand (0 );
1942- if (match (Src, m_FNeg (m_Value (X))) || match (Src, m_FAbs (m_Value (X))) ||
1943- match (Src, m_CopySign (m_Value (X), m_Value (Sign))))
1944- return copyFlags (*Call,
1945- B.CreateCall (Call->getCalledFunction (), X, " cos" ));
1946- break ;
1947- }
1948- default :
1949- break ;
1950- }
1951- return nullptr ;
1952- }
1953-
19541911// Return a properly extended integer (DstWidth bits wide) if the operation is
19551912// an itofp.
19561913static Value *getIntToFPVal (Value *I2F, IRBuilderBase &B, unsigned DstWidth) {
@@ -2797,6 +2754,63 @@ static bool insertSinCosCall(IRBuilderBase &B, Function *OrigCallee, Value *Arg,
27972754 return true ;
27982755}
27992756
2757+ static Value *optimizeSymmetricCall (CallInst *CI, bool IsEven,
2758+ IRBuilderBase &B) {
2759+ Value *X;
2760+ Value *Src = CI->getArgOperand (0 );
2761+
2762+ if (match (Src, m_OneUse (m_FNeg (m_Value (X))))) {
2763+ IRBuilderBase::FastMathFlagGuard Guard (B);
2764+ B.setFastMathFlags (CI->getFastMathFlags ());
2765+
2766+ auto *CallInst = copyFlags (*CI, B.CreateCall (CI->getCalledFunction (), {X}));
2767+ if (IsEven) {
2768+ // Even function: f(-x) = f(x)
2769+ return CallInst;
2770+ }
2771+ // Odd function: f(-x) = -f(x)
2772+ return B.CreateFNeg (CallInst);
2773+ }
2774+
2775+ // Even function: f(abs(x)) = f(x), f(copysign(x, y)) = f(x)
2776+ if (IsEven && (match (Src, m_FAbs (m_Value (X))) ||
2777+ match (Src, m_CopySign (m_Value (X), m_Value ())))) {
2778+ IRBuilderBase::FastMathFlagGuard Guard (B);
2779+ B.setFastMathFlags (CI->getFastMathFlags ());
2780+
2781+ auto *CallInst = copyFlags (*CI, B.CreateCall (CI->getCalledFunction (), {X}));
2782+ return CallInst;
2783+ }
2784+
2785+ return nullptr ;
2786+ }
2787+
2788+ Value *LibCallSimplifier::optimizeSymmetric (CallInst *CI, LibFunc Func,
2789+ IRBuilderBase &B) {
2790+ switch (Func) {
2791+ case LibFunc_cos:
2792+ case LibFunc_cosf:
2793+ case LibFunc_cosl:
2794+ return optimizeSymmetricCall (CI, /* IsEven*/ true , B);
2795+
2796+ case LibFunc_sin:
2797+ case LibFunc_sinf:
2798+ case LibFunc_sinl:
2799+
2800+ case LibFunc_tan:
2801+ case LibFunc_tanf:
2802+ case LibFunc_tanl:
2803+
2804+ case LibFunc_erf:
2805+ case LibFunc_erff:
2806+ case LibFunc_erfl:
2807+ return optimizeSymmetricCall (CI, /* IsEven*/ false , B);
2808+
2809+ default :
2810+ return nullptr ;
2811+ }
2812+ }
2813+
28002814Value *LibCallSimplifier::optimizeSinCosPi (CallInst *CI, bool IsSin, IRBuilderBase &B) {
28012815 // Make sure the prototype is as expected, otherwise the rest of the
28022816 // function is probably invalid and likely to abort.
@@ -3678,7 +3692,7 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
36783692 if (CI->isStrictFP ())
36793693 return nullptr ;
36803694
3681- if (Value *V = optimizeTrigReflections (CI, Func, Builder))
3695+ if (Value *V = optimizeSymmetric (CI, Func, Builder))
36823696 return V;
36833697
36843698 switch (Func) {
0 commit comments