1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefix=CHECK-FLOAT-IN-VEC
3 ; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,CHECK-DOUBLE-ALIGN4
4 ; RUN: opt -passes=instcombine -S < %s -mtriple=arm64-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,CHECK-DOUBLE-ALIGN8
5 ; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK-NO-SINCOS,CHECK-NO-SINCOS-DOUBLE-ALIGN8
6 ; RUN: opt -passes=instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=CHECK-NO-SINCOS,CHECK-NO-SINCOS-DOUBLE-ALIGN4
7 ; RUN: opt -passes=instcombine -S < %s -mtriple=x86_64-none-linux-gnu | FileCheck %s --check-prefixes=CHECK-NO-SINCOS,CHECK-NO-SINCOS-DOUBLE-ALIGN8
8 ; REQUIRES: arm-registered-target, x86-registered-target
10 attributes #0 = { readnone nounwind }
12 declare float @__sinpif(float %x) #0
13 declare float @__cospif(float %x) #0
15 declare double @__sinpi(double %x) #0
16 declare double @__cospi(double %x) #0
18 @var32 = global float 0.0
19 @var64 = global double 0.0
21 define float @test_instbased_f32() {
22 ; CHECK-FLOAT-IN-VEC-LABEL: @test_instbased_f32(
23 ; CHECK-FLOAT-IN-VEC-NEXT: [[VAL:%.*]] = load float, ptr @var32, align 4
24 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINCOSPI:%.*]] = call <2 x float> @__sincospif_stret(float [[VAL]])
25 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINPI:%.*]] = extractelement <2 x float> [[SINCOSPI]], i64 0
26 ; CHECK-FLOAT-IN-VEC-NEXT: [[COSPI:%.*]] = extractelement <2 x float> [[SINCOSPI]], i64 1
27 ; CHECK-FLOAT-IN-VEC-NEXT: [[COS:%.*]] = call float @__cospif(float [[VAL]]) #[[ATTR0:[0-9]+]]
28 ; CHECK-FLOAT-IN-VEC-NEXT: [[RES:%.*]] = fadd float [[SINPI]], [[COSPI]]
29 ; CHECK-FLOAT-IN-VEC-NEXT: ret float [[RES]]
31 ; CHECK-LABEL: @test_instbased_f32(
32 ; CHECK-NEXT: [[VAL:%.*]] = load float, ptr @var32, align 4
33 ; CHECK-NEXT: [[SINCOSPI:%.*]] = call { float, float } @__sincospif_stret(float [[VAL]])
34 ; CHECK-NEXT: [[SINPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 0
35 ; CHECK-NEXT: [[COSPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 1
36 ; CHECK-NEXT: [[COS:%.*]] = call float @__cospif(float [[VAL]]) #[[ATTR0:[0-9]+]]
37 ; CHECK-NEXT: [[RES:%.*]] = fadd float [[SINPI]], [[COSPI]]
38 ; CHECK-NEXT: ret float [[RES]]
40 ; CHECK-NO-SINCOS-LABEL: @test_instbased_f32(
41 ; CHECK-NO-SINCOS-NEXT: [[VAL:%.*]] = load float, ptr @var32, align 4
42 ; CHECK-NO-SINCOS-NEXT: [[SIN:%.*]] = call float @__sinpif(float [[VAL]]) #[[ATTR0:[0-9]+]]
43 ; CHECK-NO-SINCOS-NEXT: [[COS:%.*]] = call float @__cospif(float [[VAL]]) #[[ATTR0]]
44 ; CHECK-NO-SINCOS-NEXT: [[RES:%.*]] = fadd float [[SIN]], [[COS]]
45 ; CHECK-NO-SINCOS-NEXT: ret float [[RES]]
47 %val = load float, ptr @var32
48 %sin = call float @__sinpif(float %val) #0
49 %cos = call float @__cospif(float %val) #0
50 %res = fadd float %sin, %cos
54 define float @test_instbased_f32_other_user(ptr %ptr) {
55 ; CHECK-FLOAT-IN-VEC-LABEL: @test_instbased_f32_other_user(
56 ; CHECK-FLOAT-IN-VEC-NEXT: [[VAL:%.*]] = load float, ptr @var32, align 4
57 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINCOSPI:%.*]] = call <2 x float> @__sincospif_stret(float [[VAL]])
58 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINPI:%.*]] = extractelement <2 x float> [[SINCOSPI]], i64 0
59 ; CHECK-FLOAT-IN-VEC-NEXT: [[COSPI:%.*]] = extractelement <2 x float> [[SINCOSPI]], i64 1
60 ; CHECK-FLOAT-IN-VEC-NEXT: store float [[VAL]], ptr [[PTR:%.*]], align 4
61 ; CHECK-FLOAT-IN-VEC-NEXT: [[COS:%.*]] = call float @__cospif(float [[VAL]]) #[[ATTR0]]
62 ; CHECK-FLOAT-IN-VEC-NEXT: [[RES:%.*]] = fadd float [[SINPI]], [[COSPI]]
63 ; CHECK-FLOAT-IN-VEC-NEXT: ret float [[RES]]
65 ; CHECK-LABEL: @test_instbased_f32_other_user(
66 ; CHECK-NEXT: [[VAL:%.*]] = load float, ptr @var32, align 4
67 ; CHECK-NEXT: [[SINCOSPI:%.*]] = call { float, float } @__sincospif_stret(float [[VAL]])
68 ; CHECK-NEXT: [[SINPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 0
69 ; CHECK-NEXT: [[COSPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 1
70 ; CHECK-NEXT: store float [[VAL]], ptr [[PTR:%.*]], align 4
71 ; CHECK-NEXT: [[COS:%.*]] = call float @__cospif(float [[VAL]]) #[[ATTR0]]
72 ; CHECK-NEXT: [[RES:%.*]] = fadd float [[SINPI]], [[COSPI]]
73 ; CHECK-NEXT: ret float [[RES]]
75 ; CHECK-NO-SINCOS-LABEL: @test_instbased_f32_other_user(
76 ; CHECK-NO-SINCOS-NEXT: [[VAL:%.*]] = load float, ptr @var32, align 4
77 ; CHECK-NO-SINCOS-NEXT: store float [[VAL]], ptr [[PTR:%.*]], align 4
78 ; CHECK-NO-SINCOS-NEXT: [[SIN:%.*]] = call float @__sinpif(float [[VAL]]) #[[ATTR0]]
79 ; CHECK-NO-SINCOS-NEXT: [[COS:%.*]] = call float @__cospif(float [[VAL]]) #[[ATTR0]]
80 ; CHECK-NO-SINCOS-NEXT: [[RES:%.*]] = fadd float [[SIN]], [[COS]]
81 ; CHECK-NO-SINCOS-NEXT: ret float [[RES]]
83 %val = load float, ptr @var32
84 store float %val, ptr %ptr
85 %sin = call float @__sinpif(float %val) #0
86 %cos = call float @__cospif(float %val) #0
87 %res = fadd float %sin, %cos
91 define float @test_constant_f32() {
92 ; CHECK-FLOAT-IN-VEC-LABEL: @test_constant_f32(
93 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINCOSPI:%.*]] = call <2 x float> @__sincospif_stret(float 1.000000e+00)
94 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINPI:%.*]] = extractelement <2 x float> [[SINCOSPI]], i64 0
95 ; CHECK-FLOAT-IN-VEC-NEXT: [[COSPI:%.*]] = extractelement <2 x float> [[SINCOSPI]], i64 1
96 ; CHECK-FLOAT-IN-VEC-NEXT: [[COS:%.*]] = call float @__cospif(float 1.000000e+00) #[[ATTR0]]
97 ; CHECK-FLOAT-IN-VEC-NEXT: [[RES:%.*]] = fadd float [[SINPI]], [[COSPI]]
98 ; CHECK-FLOAT-IN-VEC-NEXT: ret float [[RES]]
100 ; CHECK-LABEL: @test_constant_f32(
101 ; CHECK-NEXT: [[SINCOSPI:%.*]] = call { float, float } @__sincospif_stret(float 1.000000e+00)
102 ; CHECK-NEXT: [[SINPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 0
103 ; CHECK-NEXT: [[COSPI:%.*]] = extractvalue { float, float } [[SINCOSPI]], 1
104 ; CHECK-NEXT: [[COS:%.*]] = call float @__cospif(float 1.000000e+00) #[[ATTR0]]
105 ; CHECK-NEXT: [[RES:%.*]] = fadd float [[SINPI]], [[COSPI]]
106 ; CHECK-NEXT: ret float [[RES]]
108 ; CHECK-NO-SINCOS-LABEL: @test_constant_f32(
109 ; CHECK-NO-SINCOS-NEXT: [[SIN:%.*]] = call float @__sinpif(float 1.000000e+00) #[[ATTR0]]
110 ; CHECK-NO-SINCOS-NEXT: [[COS:%.*]] = call float @__cospif(float 1.000000e+00) #[[ATTR0]]
111 ; CHECK-NO-SINCOS-NEXT: [[RES:%.*]] = fadd float [[SIN]], [[COS]]
112 ; CHECK-NO-SINCOS-NEXT: ret float [[RES]]
114 %sin = call float @__sinpif(float 1.0) #0
115 %cos = call float @__cospif(float 1.0) #0
116 %res = fadd float %sin, %cos
122 define double @test_instbased_f64() {
123 ; CHECK-FLOAT-IN-VEC-LABEL: @test_instbased_f64(
124 ; CHECK-FLOAT-IN-VEC-NEXT: [[VAL:%.*]] = load double, ptr @var64, align 8
125 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINCOSPI:%.*]] = call { double, double } @__sincospi_stret(double [[VAL]])
126 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 0
127 ; CHECK-FLOAT-IN-VEC-NEXT: [[COSPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 1
128 ; CHECK-FLOAT-IN-VEC-NEXT: [[COS:%.*]] = call double @__cospi(double [[VAL]]) #[[ATTR0]]
129 ; CHECK-FLOAT-IN-VEC-NEXT: [[RES:%.*]] = fadd double [[SINPI]], [[COSPI]]
130 ; CHECK-FLOAT-IN-VEC-NEXT: ret double [[RES]]
132 ; CHECK-DOUBLE-ALIGN4-LABEL: @test_instbased_f64(
133 ; CHECK-DOUBLE-ALIGN4-NEXT: [[VAL:%.*]] = load double, ptr @var64, align 4
134 ; CHECK-DOUBLE-ALIGN4-NEXT: [[SINCOSPI:%.*]] = call { double, double } @__sincospi_stret(double [[VAL]])
135 ; CHECK-DOUBLE-ALIGN4-NEXT: [[SINPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 0
136 ; CHECK-DOUBLE-ALIGN4-NEXT: [[COSPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 1
137 ; CHECK-DOUBLE-ALIGN4-NEXT: [[COS:%.*]] = call double @__cospi(double [[VAL]]) #[[ATTR0]]
138 ; CHECK-DOUBLE-ALIGN4-NEXT: [[RES:%.*]] = fadd double [[SINPI]], [[COSPI]]
139 ; CHECK-DOUBLE-ALIGN4-NEXT: ret double [[RES]]
141 ; CHECK-DOUBLE-ALIGN8-LABEL: @test_instbased_f64(
142 ; CHECK-DOUBLE-ALIGN8-NEXT: [[VAL:%.*]] = load double, ptr @var64, align 8
143 ; CHECK-DOUBLE-ALIGN8-NEXT: [[SINCOSPI:%.*]] = call { double, double } @__sincospi_stret(double [[VAL]])
144 ; CHECK-DOUBLE-ALIGN8-NEXT: [[SINPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 0
145 ; CHECK-DOUBLE-ALIGN8-NEXT: [[COSPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 1
146 ; CHECK-DOUBLE-ALIGN8-NEXT: [[COS:%.*]] = call double @__cospi(double [[VAL]]) #[[ATTR0]]
147 ; CHECK-DOUBLE-ALIGN8-NEXT: [[RES:%.*]] = fadd double [[SINPI]], [[COSPI]]
148 ; CHECK-DOUBLE-ALIGN8-NEXT: ret double [[RES]]
150 ; CHECK-NO-SINCOS-DOUBLE-ALIGN8-LABEL: @test_instbased_f64(
151 ; CHECK-NO-SINCOS-DOUBLE-ALIGN8-NEXT: [[VAL:%.*]] = load double, ptr @var64, align 8
152 ; CHECK-NO-SINCOS-DOUBLE-ALIGN8-NEXT: [[SIN:%.*]] = call double @__sinpi(double [[VAL]]) #[[ATTR0]]
153 ; CHECK-NO-SINCOS-DOUBLE-ALIGN8-NEXT: [[COS:%.*]] = call double @__cospi(double [[VAL]]) #[[ATTR0]]
154 ; CHECK-NO-SINCOS-DOUBLE-ALIGN8-NEXT: [[RES:%.*]] = fadd double [[SIN]], [[COS]]
155 ; CHECK-NO-SINCOS-DOUBLE-ALIGN8-NEXT: ret double [[RES]]
157 ; CHECK-NO-SINCOS-DOUBLE-ALIGN4-LABEL: @test_instbased_f64(
158 ; CHECK-NO-SINCOS-DOUBLE-ALIGN4-NEXT: [[VAL:%.*]] = load double, ptr @var64, align 4
159 ; CHECK-NO-SINCOS-DOUBLE-ALIGN4-NEXT: [[SIN:%.*]] = call double @__sinpi(double [[VAL]]) #[[ATTR0]]
160 ; CHECK-NO-SINCOS-DOUBLE-ALIGN4-NEXT: [[COS:%.*]] = call double @__cospi(double [[VAL]]) #[[ATTR0]]
161 ; CHECK-NO-SINCOS-DOUBLE-ALIGN4-NEXT: [[RES:%.*]] = fadd double [[SIN]], [[COS]]
162 ; CHECK-NO-SINCOS-DOUBLE-ALIGN4-NEXT: ret double [[RES]]
164 %val = load double, ptr @var64
165 %sin = call double @__sinpi(double %val) #0
166 %cos = call double @__cospi(double %val) #0
167 %res = fadd double %sin, %cos
173 define double @test_constant_f64() {
174 ; CHECK-FLOAT-IN-VEC-LABEL: @test_constant_f64(
175 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINCOSPI:%.*]] = call { double, double } @__sincospi_stret(double 1.000000e+00)
176 ; CHECK-FLOAT-IN-VEC-NEXT: [[SINPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 0
177 ; CHECK-FLOAT-IN-VEC-NEXT: [[COSPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 1
178 ; CHECK-FLOAT-IN-VEC-NEXT: [[COS:%.*]] = call double @__cospi(double 1.000000e+00) #[[ATTR0]]
179 ; CHECK-FLOAT-IN-VEC-NEXT: [[RES:%.*]] = fadd double [[SINPI]], [[COSPI]]
180 ; CHECK-FLOAT-IN-VEC-NEXT: ret double [[RES]]
182 ; CHECK-LABEL: @test_constant_f64(
183 ; CHECK-NEXT: [[SINCOSPI:%.*]] = call { double, double } @__sincospi_stret(double 1.000000e+00)
184 ; CHECK-NEXT: [[SINPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 0
185 ; CHECK-NEXT: [[COSPI:%.*]] = extractvalue { double, double } [[SINCOSPI]], 1
186 ; CHECK-NEXT: [[COS:%.*]] = call double @__cospi(double 1.000000e+00) #[[ATTR0]]
187 ; CHECK-NEXT: [[RES:%.*]] = fadd double [[SINPI]], [[COSPI]]
188 ; CHECK-NEXT: ret double [[RES]]
190 ; CHECK-NO-SINCOS-LABEL: @test_constant_f64(
191 ; CHECK-NO-SINCOS-NEXT: [[SIN:%.*]] = call double @__sinpi(double 1.000000e+00) #[[ATTR0]]
192 ; CHECK-NO-SINCOS-NEXT: [[COS:%.*]] = call double @__cospi(double 1.000000e+00) #[[ATTR0]]
193 ; CHECK-NO-SINCOS-NEXT: [[RES:%.*]] = fadd double [[SIN]], [[COS]]
194 ; CHECK-NO-SINCOS-NEXT: ret double [[RES]]
196 %sin = call double @__sinpi(double 1.0) #0
197 %cos = call double @__cospi(double 1.0) #0
198 %res = fadd double %sin, %cos
204 define double @test_fptr(ptr %fptr, double %p1) {
205 ; CHECK-FLOAT-IN-VEC-LABEL: @test_fptr(
206 ; CHECK-FLOAT-IN-VEC-NEXT: [[SIN:%.*]] = call double @__sinpi(double [[P1:%.*]]) #[[ATTR0]]
207 ; CHECK-FLOAT-IN-VEC-NEXT: [[COS:%.*]] = call double [[FPTR:%.*]](double [[P1]])
208 ; CHECK-FLOAT-IN-VEC-NEXT: [[RES:%.*]] = fadd double [[SIN]], [[COS]]
209 ; CHECK-FLOAT-IN-VEC-NEXT: ret double [[RES]]
211 ; CHECK-LABEL: @test_fptr(
212 ; CHECK-NEXT: [[SIN:%.*]] = call double @__sinpi(double [[P1:%.*]]) #[[ATTR0]]
213 ; CHECK-NEXT: [[COS:%.*]] = call double [[FPTR:%.*]](double [[P1]])
214 ; CHECK-NEXT: [[RES:%.*]] = fadd double [[SIN]], [[COS]]
215 ; CHECK-NEXT: ret double [[RES]]
217 ; CHECK-NO-SINCOS-LABEL: @test_fptr(
218 ; CHECK-NO-SINCOS-NEXT: [[SIN:%.*]] = call double @__sinpi(double [[P1:%.*]]) #[[ATTR0]]
219 ; CHECK-NO-SINCOS-NEXT: [[COS:%.*]] = call double [[FPTR:%.*]](double [[P1]])
220 ; CHECK-NO-SINCOS-NEXT: [[RES:%.*]] = fadd double [[SIN]], [[COS]]
221 ; CHECK-NO-SINCOS-NEXT: ret double [[RES]]
223 %sin = call double @__sinpi(double %p1) #0
224 %cos = call double %fptr(double %p1)
225 %res = fadd double %sin, %cos
229 define i1 @test_cospif_used_in_branch_cond() {
230 ; CHECK-FLOAT-IN-VEC-LABEL: @test_cospif_used_in_branch_cond(
231 ; CHECK-FLOAT-IN-VEC-NEXT: entry:
232 ; CHECK-FLOAT-IN-VEC-NEXT: [[RES:%.*]] = call float @__cospif(float noundef 0.000000e+00)
233 ; CHECK-FLOAT-IN-VEC-NEXT: [[CMP:%.*]] = fcmp uno float [[RES]], 0.000000e+00
234 ; CHECK-FLOAT-IN-VEC-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
235 ; CHECK-FLOAT-IN-VEC: then:
236 ; CHECK-FLOAT-IN-VEC-NEXT: ret i1 false
237 ; CHECK-FLOAT-IN-VEC: else:
238 ; CHECK-FLOAT-IN-VEC-NEXT: ret i1 true
240 ; CHECK-LABEL: @test_cospif_used_in_branch_cond(
242 ; CHECK-NEXT: [[RES:%.*]] = call float @__cospif(float noundef 0.000000e+00)
243 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno float [[RES]], 0.000000e+00
244 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
246 ; CHECK-NEXT: ret i1 false
248 ; CHECK-NEXT: ret i1 true
250 ; CHECK-NO-SINCOS-LABEL: @test_cospif_used_in_branch_cond(
251 ; CHECK-NO-SINCOS-NEXT: entry:
252 ; CHECK-NO-SINCOS-NEXT: [[RES:%.*]] = call float @__cospif(float noundef 0.000000e+00)
253 ; CHECK-NO-SINCOS-NEXT: [[CMP:%.*]] = fcmp uno float [[RES]], 0.000000e+00
254 ; CHECK-NO-SINCOS-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
255 ; CHECK-NO-SINCOS: then:
256 ; CHECK-NO-SINCOS-NEXT: ret i1 false
257 ; CHECK-NO-SINCOS: else:
258 ; CHECK-NO-SINCOS-NEXT: ret i1 true
261 %res = call float @__cospif(float noundef 0.000000e+00) #3
262 %cmp = fcmp uno float %res, 0.000000e+00
263 br i1 %cmp, label %then, label %else