Skip to content

Commit 3746294

Browse files
authored
[Transforms] Add more cos combinations to SimplifyLibCalls and InstCombine (#79699)
Add cos(fabs(x)) -> cos(x) and cos(copysign(x, y)) -> cos(x).
1 parent 9805c05 commit 3746294

File tree

3 files changed

+88
-7
lines changed

3 files changed

+88
-7
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,11 +2488,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
24882488
}
24892489
case Intrinsic::cos:
24902490
case Intrinsic::amdgcn_cos: {
2491-
Value *X;
2491+
Value *X, *Sign;
24922492
Value *Src = II->getArgOperand(0);
2493-
if (match(Src, m_FNeg(m_Value(X))) || match(Src, m_FAbs(m_Value(X)))) {
2494-
// cos(-x) -> cos(x)
2495-
// cos(fabs(x)) -> cos(x)
2493+
if (match(Src, m_FNeg(m_Value(X))) || match(Src, m_FAbs(m_Value(X))) ||
2494+
match(Src, m_CopySign(m_Value(X), m_Value(Sign)))) {
2495+
// cos(-x) --> cos(x)
2496+
// cos(fabs(x)) --> cos(x)
2497+
// cos(copysign(x, y)) --> cos(x)
24962498
return replaceOperand(*II, 0, X);
24972499
}
24982500
break;

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,12 +1933,18 @@ static Value *optimizeTrigReflections(CallInst *Call, LibFunc Func,
19331933
break;
19341934
case LibFunc_cos:
19351935
case LibFunc_cosf:
1936-
case LibFunc_cosl:
1937-
// cos(-X) --> cos(X)
1938-
if (match(Call->getArgOperand(0), m_FNeg(m_Value(X))))
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))))
19391944
return copyFlags(*Call,
19401945
B.CreateCall(Call->getCalledFunction(), X, "cos"));
19411946
break;
1947+
}
19421948
default:
19431949
break;
19441950
}

llvm/test/Transforms/InstCombine/cos-1.ll

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ declare float @llvm.sin.f32(float)
1717
declare double @tan(double)
1818
declare fp128 @tanl(fp128)
1919

20+
declare double @fabs(double)
21+
declare double @llvm.fabs.f64(double)
22+
declare float @fabsf(float)
23+
declare float @llvm.fabs.f32(float)
24+
25+
declare double @llvm.copysign(double, double)
26+
declare float @llvm.copysign.f32(float, float)
27+
2028
; cos(-x) -> cos(x);
2129

2230
define double @cos_negated_arg(double %x) {
@@ -100,6 +108,71 @@ define float @cosf_unary_negated_arg_FMF(float %x) {
100108
ret float %r
101109
}
102110

111+
; cos(fabs(x)) -> cos(x)
112+
113+
define double @cos_unary_fabs_arg(double %x) {
114+
; ANY-LABEL: @cos_unary_fabs_arg(
115+
; ANY-NEXT: [[COS:%.*]] = call double @cos(double [[X:%.*]])
116+
; ANY-NEXT: ret double [[COS]]
117+
;
118+
%fabs = tail call double @llvm.fabs.f64(double %x)
119+
%r = call double @cos(double %fabs)
120+
ret double %r
121+
}
122+
123+
define float @cosf_unary_fabs_arg(float %x) {
124+
; ANY-LABEL: @cosf_unary_fabs_arg(
125+
; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]])
126+
; ANY-NEXT: ret float [[COS]]
127+
;
128+
%fabs = tail call float @llvm.fabs.f32(float %x)
129+
%r = call float @cosf(float %fabs)
130+
ret float %r
131+
}
132+
133+
define float @cosf_unary_fabs_arg_FMF(float %x) {
134+
; ANY-LABEL: @cosf_unary_fabs_arg_FMF(
135+
; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
136+
; ANY-NEXT: ret float [[COS]]
137+
;
138+
%fabs = tail call float @llvm.fabs.f32(float %x)
139+
%r = call nnan reassoc float @cosf(float %fabs)
140+
ret float %r
141+
}
142+
143+
; cos(copysign(x, y)) -> cos(x)
144+
145+
define double @cos_copysign_arg(double %x, double %y) {
146+
; ANY-LABEL: @cos_copysign_arg(
147+
; ANY-NEXT: [[COS:%.*]] = call double @cos(double [[X:%.*]])
148+
; ANY-NEXT: ret double [[COS]]
149+
;
150+
%copysign = tail call double @llvm.copysign(double %x, double %y)
151+
%r = call double @cos(double %copysign)
152+
ret double %r
153+
}
154+
155+
156+
define float @cosf_unary_copysign_arg(float %x) {
157+
; ANY-LABEL: @cosf_unary_copysign_arg(
158+
; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]])
159+
; ANY-NEXT: ret float [[COS]]
160+
;
161+
%copysign = tail call float @llvm.copysign.f32(float %x, float 1.0)
162+
%r = call float @cosf(float %copysign)
163+
ret float %r
164+
}
165+
166+
define float @cosf_copysign_arg_FMF(float %x, float %y) {
167+
; ANY-LABEL: @cosf_copysign_arg_FMF(
168+
; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
169+
; ANY-NEXT: ret float [[COS]]
170+
;
171+
%copysign = tail call float @llvm.copysign.f32(float %x, float %y)
172+
%r = call nnan reassoc float @cosf(float %copysign)
173+
ret float %r
174+
}
175+
103176
; sin(-x) -> -sin(x);
104177

105178
define double @sin_negated_arg(double %x) {

0 commit comments

Comments
 (0)