Skip to content

Commit 4715cb8

Browse files
committed
Check contract flag instead of reassoc
Removed folding from foldFMulReassoc() that assumed hasAllowReassoc() Moved folding back into visitFMul()
1 parent e39ab3f commit 4715cb8

File tree

2 files changed

+73
-72
lines changed

2 files changed

+73
-72
lines changed

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -947,17 +947,6 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
947947
return BinaryOperator::CreateFMulFMF(XX, Y, &I);
948948
}
949949

950-
// tan(X) * cos(X) -> sin(X)
951-
if (match(&I,
952-
m_c_FMul(m_OneUse(m_Intrinsic<Intrinsic::tan>(m_Value(X))),
953-
m_OneUse(m_Intrinsic<Intrinsic::cos>(m_Deferred(X)))))) {
954-
auto *Sin = Builder.CreateUnaryIntrinsic(Intrinsic::sin, X, &I);
955-
if (auto *Metadata = I.getMetadata(LLVMContext::MD_fpmath)) {
956-
Sin->setMetadata(LLVMContext::MD_fpmath, Metadata);
957-
}
958-
return replaceInstUsesWith(I, Sin);
959-
}
960-
961950
return nullptr;
962951
}
963952

@@ -1084,6 +1073,18 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
10841073
return Result;
10851074
}
10861075

1076+
// tan(X) * cos(X) -> sin(X)
1077+
if (I.hasAllowContract() &&
1078+
match(&I,
1079+
m_c_FMul(m_OneUse(m_Intrinsic<Intrinsic::tan>(m_Value(X))),
1080+
m_OneUse(m_Intrinsic<Intrinsic::cos>(m_Deferred(X)))))) {
1081+
auto *Sin = Builder.CreateUnaryIntrinsic(Intrinsic::sin, X, &I);
1082+
if (auto *Metadata = I.getMetadata(LLVMContext::MD_fpmath)) {
1083+
Sin->setMetadata(LLVMContext::MD_fpmath, Metadata);
1084+
}
1085+
return replaceInstUsesWith(I, Sin);
1086+
}
1087+
10871088
return nullptr;
10881089
}
10891090

llvm/test/Transforms/InstCombine/fmul-tan-cos.ll

Lines changed: 61 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,160 +15,160 @@ define double @fmul_tan_cos(double %a) {
1515
ret double %res
1616
}
1717

18-
define double @fmul_strict_tan_strict_cos_reassoc(double %a) {
19-
; CHECK-LABEL: define double @fmul_strict_tan_strict_cos_reassoc(
18+
define double @fmul_strict_tan_strict_cos_contract(double %a) {
19+
; CHECK-LABEL: define double @fmul_strict_tan_strict_cos_contract(
2020
; CHECK-SAME: double [[A:%.*]]) {
2121
; CHECK-NEXT: [[TAN:%.*]] = call double @llvm.tan.f64(double [[A]])
22-
; CHECK-NEXT: [[COS:%.*]] = call reassoc double @llvm.cos.f64(double [[A]])
22+
; CHECK-NEXT: [[COS:%.*]] = call contract double @llvm.cos.f64(double [[A]])
2323
; CHECK-NEXT: [[RES:%.*]] = fmul double [[TAN]], [[COS]]
2424
; CHECK-NEXT: ret double [[RES]]
2525
;
2626
%tan = call double @llvm.tan.f64(double %a)
27-
%cos = call reassoc double @llvm.cos.f64(double %a)
27+
%cos = call contract double @llvm.cos.f64(double %a)
2828
%res = fmul double %tan, %cos
2929
ret double %res
3030
}
3131

32-
define double @fmul_reassoc_tan_strict_cos_strict(double %a) {
33-
; CHECK-LABEL: define double @fmul_reassoc_tan_strict_cos_strict(
32+
define double @fmul_contract_tan_strict_cos_strict(double %a) {
33+
; CHECK-LABEL: define double @fmul_contract_tan_strict_cos_strict(
3434
; CHECK-SAME: double [[A:%.*]]) {
35-
; CHECK-NEXT: [[RES:%.*]] = call reassoc double @llvm.sin.f64(double [[A]])
35+
; CHECK-NEXT: [[RES:%.*]] = call contract double @llvm.sin.f64(double [[A]])
3636
; CHECK-NEXT: ret double [[RES]]
3737
;
3838
%tan = call double @llvm.tan.f64(double %a)
3939
%cos = call double @llvm.cos.f64(double %a)
40-
%res = fmul reassoc double %tan, %cos
40+
%res = fmul contract double %tan, %cos
4141
ret double %res
4242
}
4343

44-
define double @fmul_reassoc_tan_reassoc_cos_strict(double %a) {
45-
; CHECK-LABEL: define double @fmul_reassoc_tan_reassoc_cos_strict(
44+
define double @fmul_contract_tan_contract_cos_strict(double %a) {
45+
; CHECK-LABEL: define double @fmul_contract_tan_contract_cos_strict(
4646
; CHECK-SAME: double [[A:%.*]]) {
47-
; CHECK-NEXT: [[RES:%.*]] = call reassoc double @llvm.sin.f64(double [[A]])
47+
; CHECK-NEXT: [[RES:%.*]] = call contract double @llvm.sin.f64(double [[A]])
4848
; CHECK-NEXT: ret double [[RES]]
4949
;
50-
%tan = call reassoc double @llvm.tan.f64(double %a)
50+
%tan = call contract double @llvm.tan.f64(double %a)
5151
%cos = call double @llvm.cos.f64(double %a)
52-
%res = fmul reassoc double %tan, %cos
52+
%res = fmul contract double %tan, %cos
5353
ret double %res
5454
}
5555

56-
define double @fmul_tan_cos_reassoc_multiple_uses(double %a) {
57-
; CHECK-LABEL: define double @fmul_tan_cos_reassoc_multiple_uses(
56+
define double @fmul_tan_cos_contract_multiple_uses(double %a) {
57+
; CHECK-LABEL: define double @fmul_tan_cos_contract_multiple_uses(
5858
; CHECK-SAME: double [[A:%.*]]) {
59-
; CHECK-NEXT: [[TAN:%.*]] = call reassoc double @llvm.tan.f64(double [[A]])
60-
; CHECK-NEXT: [[COS:%.*]] = call reassoc double @llvm.cos.f64(double [[A]])
61-
; CHECK-NEXT: [[RES:%.*]] = fmul reassoc double [[TAN]], [[COS]]
59+
; CHECK-NEXT: [[TAN:%.*]] = call contract double @llvm.tan.f64(double [[A]])
60+
; CHECK-NEXT: [[COS:%.*]] = call contract double @llvm.cos.f64(double [[A]])
61+
; CHECK-NEXT: [[RES:%.*]] = fmul contract double [[TAN]], [[COS]]
6262
; CHECK-NEXT: call void @use(double [[COS]])
6363
; CHECK-NEXT: ret double [[RES]]
6464
;
65-
%tan = call reassoc double @llvm.tan.f64(double %a)
66-
%cos = call reassoc double @llvm.cos.f64(double %a)
67-
%res = fmul reassoc double %tan, %cos
65+
%tan = call contract double @llvm.tan.f64(double %a)
66+
%cos = call contract double @llvm.cos.f64(double %a)
67+
%res = fmul contract double %tan, %cos
6868
call void @use(double %cos)
6969
ret double %res
7070
}
7171

72-
define double @fmul_tan_cos_reassoc(double %a) {
73-
; CHECK-LABEL: define double @fmul_tan_cos_reassoc(
72+
define double @fmul_tan_cos_contract(double %a) {
73+
; CHECK-LABEL: define double @fmul_tan_cos_contract(
7474
; CHECK-SAME: double [[A:%.*]]) {
75-
; CHECK-NEXT: [[RES:%.*]] = call reassoc double @llvm.sin.f64(double [[A]])
75+
; CHECK-NEXT: [[RES:%.*]] = call contract double @llvm.sin.f64(double [[A]])
7676
; CHECK-NEXT: ret double [[RES]]
7777
;
78-
%tan = call reassoc double @llvm.tan.f64(double %a)
79-
%cos = call reassoc double @llvm.cos.f64(double %a)
80-
%res = fmul reassoc double %tan, %cos
78+
%tan = call contract double @llvm.tan.f64(double %a)
79+
%cos = call contract double @llvm.cos.f64(double %a)
80+
%res = fmul contract double %tan, %cos
8181
ret double %res
8282
}
8383

84-
define float @fmul_tanf_cosf_reassoc(float %a) {
85-
; CHECK-LABEL: define float @fmul_tanf_cosf_reassoc(
84+
define float @fmul_tanf_cosf_contract(float %a) {
85+
; CHECK-LABEL: define float @fmul_tanf_cosf_contract(
8686
; CHECK-SAME: float [[A:%.*]]) {
87-
; CHECK-NEXT: [[RES:%.*]] = call reassoc float @llvm.sin.f32(float [[A]])
87+
; CHECK-NEXT: [[RES:%.*]] = call contract float @llvm.sin.f32(float [[A]])
8888
; CHECK-NEXT: ret float [[RES]]
8989
;
90-
%tan = call reassoc float @llvm.tan.f32(float %a)
91-
%cos = call reassoc float @llvm.cos.f32(float %a)
92-
%res = fmul reassoc float %tan, %cos
90+
%tan = call contract float @llvm.tan.f32(float %a)
91+
%cos = call contract float @llvm.cos.f32(float %a)
92+
%res = fmul contract float %tan, %cos
9393
ret float %res
9494
}
9595

96-
define fp128 @fmul_tanfp128_cosfp128_reassoc(fp128 %a) {
97-
; CHECK-LABEL: define fp128 @fmul_tanfp128_cosfp128_reassoc(
96+
define fp128 @fmul_tanfp128_cosfp128_contract(fp128 %a) {
97+
; CHECK-LABEL: define fp128 @fmul_tanfp128_cosfp128_contract(
9898
; CHECK-SAME: fp128 [[A:%.*]]) {
99-
; CHECK-NEXT: [[RES:%.*]] = call reassoc fp128 @llvm.sin.f128(fp128 [[A]])
99+
; CHECK-NEXT: [[RES:%.*]] = call contract fp128 @llvm.sin.f128(fp128 [[A]])
100100
; CHECK-NEXT: ret fp128 [[RES]]
101101
;
102-
%tan = call reassoc fp128 @llvm.tan.fp128(fp128 %a)
103-
%cos = call reassoc fp128 @llvm.cos.fp128(fp128 %a)
104-
%res = fmul reassoc fp128 %tan, %cos
102+
%tan = call contract fp128 @llvm.tan.fp128(fp128 %a)
103+
%cos = call contract fp128 @llvm.cos.fp128(fp128 %a)
104+
%res = fmul contract fp128 %tan, %cos
105105
ret fp128 %res
106106
}
107107

108108
; commutativity
109109
define double @commutativity_cos_tan(double %a) {
110110
; CHECK-LABEL: define double @commutativity_cos_tan(
111111
; CHECK-SAME: double [[A:%.*]]) {
112-
; CHECK-NEXT: [[RES:%.*]] = call reassoc double @llvm.sin.f64(double [[A]])
112+
; CHECK-NEXT: [[RES:%.*]] = call contract double @llvm.sin.f64(double [[A]])
113113
; CHECK-NEXT: ret double [[RES]]
114114
;
115-
%cos = call reassoc double @llvm.cos.f64(double %a)
116-
%tan = call reassoc double @llvm.tan.f64(double %a)
117-
%res = fmul reassoc double %cos, %tan
115+
%cos = call contract double @llvm.cos.f64(double %a)
116+
%tan = call contract double @llvm.tan.f64(double %a)
117+
%res = fmul contract double %cos, %tan
118118
ret double %res
119119
}
120120

121121
; negative test with mismatched value
122122
define double @tan_cos_value_mismatch(double %a, double %b) {
123123
; CHECK-LABEL: define double @tan_cos_value_mismatch(
124124
; CHECK-SAME: double [[A:%.*]], double [[B:%.*]]) {
125-
; CHECK-NEXT: [[TAN:%.*]] = call reassoc double @llvm.tan.f64(double [[A]])
126-
; CHECK-NEXT: [[COS:%.*]] = call reassoc double @llvm.cos.f64(double [[B]])
127-
; CHECK-NEXT: [[RES:%.*]] = fmul reassoc double [[TAN]], [[COS]]
125+
; CHECK-NEXT: [[TAN:%.*]] = call contract double @llvm.tan.f64(double [[A]])
126+
; CHECK-NEXT: [[COS:%.*]] = call contract double @llvm.cos.f64(double [[B]])
127+
; CHECK-NEXT: [[RES:%.*]] = fmul contract double [[TAN]], [[COS]]
128128
; CHECK-NEXT: ret double [[RES]]
129129
;
130-
%tan = call reassoc double @llvm.tan.f64(double %a)
131-
%cos = call reassoc double @llvm.cos.f64(double %b)
132-
%res = fmul reassoc double %tan, %cos
130+
%tan = call contract double @llvm.tan.f64(double %a)
131+
%cos = call contract double @llvm.cos.f64(double %b)
132+
%res = fmul contract double %tan, %cos
133133
ret double %res
134134
}
135135

136136
; Vector
137137
define <2 x double> @fmul_tan_cos_vector(<2 x double> %a) {
138138
; CHECK-LABEL: define <2 x double> @fmul_tan_cos_vector(
139139
; CHECK-SAME: <2 x double> [[A:%.*]]) {
140-
; CHECK-NEXT: [[RES:%.*]] = call reassoc <2 x double> @llvm.sin.v2f64(<2 x double> [[A]])
140+
; CHECK-NEXT: [[RES:%.*]] = call contract <2 x double> @llvm.sin.v2f64(<2 x double> [[A]])
141141
; CHECK-NEXT: ret <2 x double> [[RES]]
142142
;
143-
%tan = call reassoc <2 x double> @llvm.tan.v2f64(<2 x double> %a)
144-
%cos = call reassoc <2 x double> @llvm.cos.v2f64(<2 x double> %a)
145-
%res = fmul reassoc <2 x double> %tan, %cos
143+
%tan = call contract <2 x double> @llvm.tan.v2f64(<2 x double> %a)
144+
%cos = call contract <2 x double> @llvm.cos.v2f64(<2 x double> %a)
145+
%res = fmul contract <2 x double> %tan, %cos
146146
ret <2 x double> %res
147147
}
148148

149149
; Flag preservation
150150
define double @fmul_tan_cos_nnan_preservation(double %a) {
151151
; CHECK-LABEL: define double @fmul_tan_cos_nnan_preservation(
152152
; CHECK-SAME: double [[A:%.*]]) {
153-
; CHECK-NEXT: [[RES:%.*]] = call reassoc nnan double @llvm.sin.f64(double [[A]])
153+
; CHECK-NEXT: [[RES:%.*]] = call nnan contract double @llvm.sin.f64(double [[A]])
154154
; CHECK-NEXT: ret double [[RES]]
155155
;
156-
%tan = call reassoc double @llvm.tan.f64(double %a)
157-
%cos = call reassoc double @llvm.cos.f64(double %a)
158-
%res = fmul reassoc nnan double %tan, %cos
156+
%tan = call contract double @llvm.tan.f64(double %a)
157+
%cos = call contract double @llvm.cos.f64(double %a)
158+
%res = fmul contract nnan double %tan, %cos
159159
ret double %res
160160
}
161161

162162
; !fpmath metadata preservation
163163
define double @fmul_tan_cos_fpmath_metadata_preservation(double %a) {
164164
; CHECK-LABEL: define double @fmul_tan_cos_fpmath_metadata_preservation(
165165
; CHECK-SAME: double [[A:%.*]]) {
166-
; CHECK-NEXT: [[RES:%.*]] = call reassoc double @llvm.sin.f64(double [[A]]), !fpmath [[META0:![0-9]+]]
166+
; CHECK-NEXT: [[RES:%.*]] = call contract double @llvm.sin.f64(double [[A]]), !fpmath [[META0:![0-9]+]]
167167
; CHECK-NEXT: ret double [[RES]]
168168
;
169-
%tan = call reassoc double @llvm.tan.f64(double %a)
170-
%cos = call reassoc double @llvm.cos.f64(double %a)
171-
%res = fmul reassoc double %tan, %cos, !fpmath !0
169+
%tan = call contract double @llvm.tan.f64(double %a)
170+
%cos = call contract double @llvm.cos.f64(double %a)
171+
%res = fmul contract double %tan, %cos, !fpmath !0
172172
ret double %res
173173
}
174174

0 commit comments

Comments
 (0)