[Alignment][NFC] Use Align with TargetLowering::setMinFunctionAlignment
[llvm-core.git] / test / CodeGen / X86 / fp128-i128.ll
blobf18b3e46e7a8149c2a8e17a231a5362793ca32fc
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -O2 -verify-machineinstrs -mtriple=x86_64-linux-android -mattr=+mmx -enable-legalize-types-checking | FileCheck %s --check-prefixes=CHECK,SSE
3 ; RUN: llc < %s -O2 -verify-machineinstrs -mtriple=x86_64-linux-gnu     -mattr=+mmx -enable-legalize-types-checking | FileCheck %s --check-prefixes=CHECK,SSE
4 ; RUN: llc < %s -O2 -verify-machineinstrs -mtriple=x86_64-linux-android -mattr=+mmx,avx2 -enable-legalize-types-checking | FileCheck %s --check-prefixes=CHECK,AVX
5 ; RUN: llc < %s -O2 -verify-machineinstrs -mtriple=x86_64-linux-gnu     -mattr=+mmx,avx2 -enable-legalize-types-checking | FileCheck %s --check-prefixes=CHECK,AVX
6 ; RUN: llc < %s -O2 -verify-machineinstrs -mtriple=x86_64-linux-android -mattr=+mmx,avx512vl -enable-legalize-types-checking | FileCheck %s --check-prefixes=CHECK,AVX
7 ; RUN: llc < %s -O2 -verify-machineinstrs -mtriple=x86_64-linux-gnu     -mattr=+mmx,avx512vl -enable-legalize-types-checking | FileCheck %s --check-prefixes=CHECK,AVX
9 ; These tests were generated from simplified libm C code.
10 ; When compiled for the x86_64-linux-android target,
11 ; long double is mapped to f128 type that should be passed
12 ; in SSE registers. When the f128 type calling convention
13 ; problem was fixed, old llvm code failed to handle f128 values
14 ; in several f128/i128 type operations. These unit tests hopefully
15 ; will catch regression in any future change in this area.
16 ; To modified or enhance these test cases, please consult libm
17 ; code pattern and compile with -target x86_64-linux-android
18 ; to generate IL. The __float128 keyword if not accepted by
19 ; clang, just define it to "long double".
22 ; typedef long double __float128;
23 ; union IEEEl2bits {
24 ;   __float128 e;
25 ;   struct {
26 ;     unsigned long manl :64;
27 ;     unsigned long manh :48;
28 ;     unsigned int exp :15;
29 ;     unsigned int sign :1;
30 ;   } bits;
31 ;   struct {
32 ;     unsigned long manl :64;
33 ;     unsigned long manh :48;
34 ;     unsigned int expsign :16;
35 ;   } xbits;
36 ; };
38 ; C code:
39 ; void foo(__float128 x);
40 ; void TestUnionLD1(__float128 s, unsigned long n) {
41 ;      union IEEEl2bits u;
42 ;      __float128 w;
43 ;      u.e = s;
44 ;      u.bits.manh = n;
45 ;      w = u.e;
46 ;      foo(w);
47 ; }
48 define void @TestUnionLD1(fp128 %s, i64 %n) #0 {
49 ; SSE-LABEL: TestUnionLD1:
50 ; SSE:       # %bb.0: # %entry
51 ; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
52 ; SSE-NEXT:    movzwl -{{[0-9]+}}(%rsp), %eax
53 ; SSE-NEXT:    shlq $48, %rax
54 ; SSE-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx
55 ; SSE-NEXT:    movabsq $281474976710655, %rdx # imm = 0xFFFFFFFFFFFF
56 ; SSE-NEXT:    andq %rdi, %rdx
57 ; SSE-NEXT:    orq %rax, %rdx
58 ; SSE-NEXT:    movq %rcx, -{{[0-9]+}}(%rsp)
59 ; SSE-NEXT:    movq %rdx, -{{[0-9]+}}(%rsp)
60 ; SSE-NEXT:    movaps -{{[0-9]+}}(%rsp), %xmm0
61 ; SSE-NEXT:    jmp foo # TAILCALL
63 ; AVX-LABEL: TestUnionLD1:
64 ; AVX:       # %bb.0: # %entry
65 ; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
66 ; AVX-NEXT:    movzwl -{{[0-9]+}}(%rsp), %eax
67 ; AVX-NEXT:    shlq $48, %rax
68 ; AVX-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx
69 ; AVX-NEXT:    movabsq $281474976710655, %rdx # imm = 0xFFFFFFFFFFFF
70 ; AVX-NEXT:    andq %rdi, %rdx
71 ; AVX-NEXT:    orq %rax, %rdx
72 ; AVX-NEXT:    movq %rcx, -{{[0-9]+}}(%rsp)
73 ; AVX-NEXT:    movq %rdx, -{{[0-9]+}}(%rsp)
74 ; AVX-NEXT:    vmovaps -{{[0-9]+}}(%rsp), %xmm0
75 ; AVX-NEXT:    jmp foo # TAILCALL
76 entry:
77   %0 = bitcast fp128 %s to i128
78   %1 = zext i64 %n to i128
79   %bf.value = shl nuw i128 %1, 64
80   %bf.shl = and i128 %bf.value, 5192296858534809181786422619668480
81   %bf.clear = and i128 %0, -5192296858534809181786422619668481
82   %bf.set = or i128 %bf.shl, %bf.clear
83   %2 = bitcast i128 %bf.set to fp128
84   tail call void @foo(fp128 %2) #2
85   ret void
88 ; C code:
89 ; __float128 TestUnionLD2(__float128 s) {
90 ;      union IEEEl2bits u;
91 ;      __float128 w;
92 ;      u.e = s;
93 ;      u.bits.manl = 0;
94 ;      w = u.e;
95 ;      return w;
96 ; }
97 define fp128 @TestUnionLD2(fp128 %s) #0 {
98 ; SSE-LABEL: TestUnionLD2:
99 ; SSE:       # %bb.0: # %entry
100 ; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
101 ; SSE-NEXT:    movq -{{[0-9]+}}(%rsp), %rax
102 ; SSE-NEXT:    movq %rax, -{{[0-9]+}}(%rsp)
103 ; SSE-NEXT:    movq $0, -{{[0-9]+}}(%rsp)
104 ; SSE-NEXT:    movaps -{{[0-9]+}}(%rsp), %xmm0
105 ; SSE-NEXT:    retq
107 ; AVX-LABEL: TestUnionLD2:
108 ; AVX:       # %bb.0: # %entry
109 ; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
110 ; AVX-NEXT:    movq -{{[0-9]+}}(%rsp), %rax
111 ; AVX-NEXT:    movq %rax, -{{[0-9]+}}(%rsp)
112 ; AVX-NEXT:    movq $0, -{{[0-9]+}}(%rsp)
113 ; AVX-NEXT:    vmovaps -{{[0-9]+}}(%rsp), %xmm0
114 ; AVX-NEXT:    retq
115 entry:
116   %0 = bitcast fp128 %s to i128
117   %bf.clear = and i128 %0, -18446744073709551616
118   %1 = bitcast i128 %bf.clear to fp128
119   ret fp128 %1
122 ; C code:
123 ; __float128 TestI128_1(__float128 x)
124 ; {
125 ;  union IEEEl2bits z;
126 ;  z.e = x;
127 ;  z.bits.sign = 0;
128 ;  return (z.e < 0.1L) ? 1.0L : 2.0L;
129 ; }
130 define fp128 @TestI128_1(fp128 %x) #0 {
131 ; SSE-LABEL: TestI128_1:
132 ; SSE:       # %bb.0: # %entry
133 ; SSE-NEXT:    subq $40, %rsp
134 ; SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
135 ; SSE-NEXT:    movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF
136 ; SSE-NEXT:    andq {{[0-9]+}}(%rsp), %rax
137 ; SSE-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
138 ; SSE-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
139 ; SSE-NEXT:    movq %rcx, (%rsp)
140 ; SSE-NEXT:    movaps (%rsp), %xmm0
141 ; SSE-NEXT:    movaps {{.*}}(%rip), %xmm1
142 ; SSE-NEXT:    callq __lttf2
143 ; SSE-NEXT:    xorl %ecx, %ecx
144 ; SSE-NEXT:    testl %eax, %eax
145 ; SSE-NEXT:    sets %cl
146 ; SSE-NEXT:    shlq $4, %rcx
147 ; SSE-NEXT:    movaps {{\.LCPI.*}}(%rcx), %xmm0
148 ; SSE-NEXT:    addq $40, %rsp
149 ; SSE-NEXT:    retq
151 ; AVX-LABEL: TestI128_1:
152 ; AVX:       # %bb.0: # %entry
153 ; AVX-NEXT:    subq $40, %rsp
154 ; AVX-NEXT:    vmovaps %xmm0, {{[0-9]+}}(%rsp)
155 ; AVX-NEXT:    movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF
156 ; AVX-NEXT:    andq {{[0-9]+}}(%rsp), %rax
157 ; AVX-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
158 ; AVX-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
159 ; AVX-NEXT:    movq %rcx, (%rsp)
160 ; AVX-NEXT:    vmovaps (%rsp), %xmm0
161 ; AVX-NEXT:    vmovaps {{.*}}(%rip), %xmm1
162 ; AVX-NEXT:    callq __lttf2
163 ; AVX-NEXT:    xorl %ecx, %ecx
164 ; AVX-NEXT:    testl %eax, %eax
165 ; AVX-NEXT:    sets %cl
166 ; AVX-NEXT:    shlq $4, %rcx
167 ; AVX-NEXT:    vmovaps {{\.LCPI.*}}(%rcx), %xmm0
168 ; AVX-NEXT:    addq $40, %rsp
169 ; AVX-NEXT:    retq
170 entry:
171   %0 = bitcast fp128 %x to i128
172   %bf.clear = and i128 %0, 170141183460469231731687303715884105727
173   %1 = bitcast i128 %bf.clear to fp128
174   %cmp = fcmp olt fp128 %1, 0xL999999999999999A3FFB999999999999
175   %cond = select i1 %cmp, fp128 0xL00000000000000003FFF000000000000, fp128 0xL00000000000000004000000000000000
176   ret fp128 %cond
179 ; C code:
180 ; __float128 TestI128_2(__float128 x, __float128 y)
181 ; {
182 ;  unsigned short hx;
183 ;  union IEEEl2bits ge_u;
184 ;  ge_u.e = x;
185 ;  hx = ge_u.xbits.expsign;
186 ;  return (hx & 0x8000) == 0 ? x : y;
187 ; }
188 define fp128 @TestI128_2(fp128 %x, fp128 %y) #0 {
189 ; SSE-LABEL: TestI128_2:
190 ; SSE:       # %bb.0: # %entry
191 ; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
192 ; SSE-NEXT:    cmpq $0, -{{[0-9]+}}(%rsp)
193 ; SSE-NEXT:    jns .LBB3_2
194 ; SSE-NEXT:  # %bb.1: # %entry
195 ; SSE-NEXT:    movaps %xmm1, %xmm0
196 ; SSE-NEXT:  .LBB3_2: # %entry
197 ; SSE-NEXT:    retq
199 ; AVX-LABEL: TestI128_2:
200 ; AVX:       # %bb.0: # %entry
201 ; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
202 ; AVX-NEXT:    cmpq $0, -{{[0-9]+}}(%rsp)
203 ; AVX-NEXT:    jns .LBB3_2
204 ; AVX-NEXT:  # %bb.1: # %entry
205 ; AVX-NEXT:    vmovaps %xmm1, %xmm0
206 ; AVX-NEXT:  .LBB3_2: # %entry
207 ; AVX-NEXT:    retq
208 entry:
209   %0 = bitcast fp128 %x to i128
210   %cmp = icmp sgt i128 %0, -1
211   %cond = select i1 %cmp, fp128 %x, fp128 %y
212   ret fp128 %cond
215 ; C code:
216 ; __float128 TestI128_3(__float128 x, int *ex)
217 ; {
218 ;  union IEEEl2bits u;
219 ;  u.e = x;
220 ;  if (u.bits.exp == 0) {
221 ;    u.e *= 0x1.0p514;
222 ;    u.bits.exp = 0x3ffe;
223 ;  }
224 ;  return (u.e);
225 ; }
226 define fp128 @TestI128_3(fp128 %x, i32* nocapture readnone %ex) #0 {
227 ; SSE-LABEL: TestI128_3:
228 ; SSE:       # %bb.0: # %entry
229 ; SSE-NEXT:    subq $56, %rsp
230 ; SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
231 ; SSE-NEXT:    movq {{[0-9]+}}(%rsp), %rax
232 ; SSE-NEXT:    movabsq $9223090561878065152, %rcx # imm = 0x7FFF000000000000
233 ; SSE-NEXT:    testq %rcx, %rax
234 ; SSE-NEXT:    je .LBB4_2
235 ; SSE-NEXT:  # %bb.1:
236 ; SSE-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
237 ; SSE-NEXT:    jmp .LBB4_3
238 ; SSE-NEXT:  .LBB4_2: # %if.then
239 ; SSE-NEXT:    movaps {{.*}}(%rip), %xmm1
240 ; SSE-NEXT:    callq __multf3
241 ; SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
242 ; SSE-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
243 ; SSE-NEXT:    movabsq $-9223090561878065153, %rdx # imm = 0x8000FFFFFFFFFFFF
244 ; SSE-NEXT:    andq {{[0-9]+}}(%rsp), %rdx
245 ; SSE-NEXT:    movabsq $4611123068473966592, %rax # imm = 0x3FFE000000000000
246 ; SSE-NEXT:    orq %rdx, %rax
247 ; SSE-NEXT:  .LBB4_3: # %if.end
248 ; SSE-NEXT:    movq %rcx, (%rsp)
249 ; SSE-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
250 ; SSE-NEXT:    movaps (%rsp), %xmm0
251 ; SSE-NEXT:    addq $56, %rsp
252 ; SSE-NEXT:    retq
254 ; AVX-LABEL: TestI128_3:
255 ; AVX:       # %bb.0: # %entry
256 ; AVX-NEXT:    subq $56, %rsp
257 ; AVX-NEXT:    vmovaps %xmm0, {{[0-9]+}}(%rsp)
258 ; AVX-NEXT:    movq {{[0-9]+}}(%rsp), %rax
259 ; AVX-NEXT:    movabsq $9223090561878065152, %rcx # imm = 0x7FFF000000000000
260 ; AVX-NEXT:    testq %rcx, %rax
261 ; AVX-NEXT:    je .LBB4_2
262 ; AVX-NEXT:  # %bb.1:
263 ; AVX-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
264 ; AVX-NEXT:    jmp .LBB4_3
265 ; AVX-NEXT:  .LBB4_2: # %if.then
266 ; AVX-NEXT:    vmovaps {{.*}}(%rip), %xmm1
267 ; AVX-NEXT:    callq __multf3
268 ; AVX-NEXT:    vmovaps %xmm0, {{[0-9]+}}(%rsp)
269 ; AVX-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
270 ; AVX-NEXT:    movabsq $-9223090561878065153, %rdx # imm = 0x8000FFFFFFFFFFFF
271 ; AVX-NEXT:    andq {{[0-9]+}}(%rsp), %rdx
272 ; AVX-NEXT:    movabsq $4611123068473966592, %rax # imm = 0x3FFE000000000000
273 ; AVX-NEXT:    orq %rdx, %rax
274 ; AVX-NEXT:  .LBB4_3: # %if.end
275 ; AVX-NEXT:    movq %rcx, (%rsp)
276 ; AVX-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
277 ; AVX-NEXT:    vmovaps (%rsp), %xmm0
278 ; AVX-NEXT:    addq $56, %rsp
279 ; AVX-NEXT:    retq
280 entry:
281   %0 = bitcast fp128 %x to i128
282   %bf.cast = and i128 %0, 170135991163610696904058773219554885632
283   %cmp = icmp eq i128 %bf.cast, 0
284   br i1 %cmp, label %if.then, label %if.end
286 if.then:                                          ; preds = %entry
287   %mul = fmul fp128 %x, 0xL00000000000000004201000000000000
288   %1 = bitcast fp128 %mul to i128
289   %bf.clear4 = and i128 %1, -170135991163610696904058773219554885633
290   %bf.set = or i128 %bf.clear4, 85060207136517546210586590865283612672
291   br label %if.end
293 if.end:                                           ; preds = %if.then, %entry
294   %u.sroa.0.0 = phi i128 [ %bf.set, %if.then ], [ %0, %entry ]
295   %2 = bitcast i128 %u.sroa.0.0 to fp128
296   ret fp128 %2
299 ; C code:
300 ; __float128 TestI128_4(__float128 x)
301 ; {
302 ;  union IEEEl2bits u;
303 ;  __float128 df;
304 ;  u.e = x;
305 ;  u.xbits.manl = 0;
306 ;  df = u.e;
307 ;  return x + df;
308 ; }
309 define fp128 @TestI128_4(fp128 %x) #0 {
310 ; SSE-LABEL: TestI128_4:
311 ; SSE:       # %bb.0: # %entry
312 ; SSE-NEXT:    subq $40, %rsp
313 ; SSE-NEXT:    movaps %xmm0, %xmm1
314 ; SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
315 ; SSE-NEXT:    movq {{[0-9]+}}(%rsp), %rax
316 ; SSE-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
317 ; SSE-NEXT:    movq $0, (%rsp)
318 ; SSE-NEXT:    movaps (%rsp), %xmm0
319 ; SSE-NEXT:    callq __addtf3
320 ; SSE-NEXT:    addq $40, %rsp
321 ; SSE-NEXT:    retq
323 ; AVX-LABEL: TestI128_4:
324 ; AVX:       # %bb.0: # %entry
325 ; AVX-NEXT:    subq $40, %rsp
326 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
327 ; AVX-NEXT:    vmovaps %xmm0, {{[0-9]+}}(%rsp)
328 ; AVX-NEXT:    movq {{[0-9]+}}(%rsp), %rax
329 ; AVX-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
330 ; AVX-NEXT:    movq $0, (%rsp)
331 ; AVX-NEXT:    vmovaps (%rsp), %xmm0
332 ; AVX-NEXT:    callq __addtf3
333 ; AVX-NEXT:    addq $40, %rsp
334 ; AVX-NEXT:    retq
335 entry:
336   %0 = bitcast fp128 %x to i128
337   %bf.clear = and i128 %0, -18446744073709551616
338   %1 = bitcast i128 %bf.clear to fp128
339   %add = fadd fp128 %1, %x
340   ret fp128 %add
343 @v128 = common global i128 0, align 16
344 @v128_2 = common global i128 0, align 16
346 ; C code:
347 ; unsigned __int128 v128, v128_2;
348 ; void TestShift128_2() {
349 ;   v128 = ((v128 << 96) | v128_2);
350 ; }
351 define void @TestShift128_2() #2 {
352 ; CHECK-LABEL: TestShift128_2:
353 ; CHECK:       # %bb.0: # %entry
354 ; CHECK-NEXT:    movq {{.*}}(%rip), %rax
355 ; CHECK-NEXT:    shlq $32, %rax
356 ; CHECK-NEXT:    movq {{.*}}(%rip), %rcx
357 ; CHECK-NEXT:    orq v128_2+{{.*}}(%rip), %rax
358 ; CHECK-NEXT:    movq %rcx, {{.*}}(%rip)
359 ; CHECK-NEXT:    movq %rax, v128+{{.*}}(%rip)
360 ; CHECK-NEXT:    retq
361 entry:
362   %0 = load i128, i128* @v128, align 16
363   %shl = shl i128 %0, 96
364   %1 = load i128, i128* @v128_2, align 16
365   %or = or i128 %shl, %1
366   store i128 %or, i128* @v128, align 16
367   ret void
370 define fp128 @acosl(fp128 %x) #0 {
371 ; SSE-LABEL: acosl:
372 ; SSE:       # %bb.0: # %entry
373 ; SSE-NEXT:    subq $40, %rsp
374 ; SSE-NEXT:    movaps %xmm0, %xmm1
375 ; SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
376 ; SSE-NEXT:    movq {{[0-9]+}}(%rsp), %rax
377 ; SSE-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
378 ; SSE-NEXT:    movq $0, (%rsp)
379 ; SSE-NEXT:    movaps (%rsp), %xmm0
380 ; SSE-NEXT:    callq __addtf3
381 ; SSE-NEXT:    addq $40, %rsp
382 ; SSE-NEXT:    retq
384 ; AVX-LABEL: acosl:
385 ; AVX:       # %bb.0: # %entry
386 ; AVX-NEXT:    subq $40, %rsp
387 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
388 ; AVX-NEXT:    vmovaps %xmm0, {{[0-9]+}}(%rsp)
389 ; AVX-NEXT:    movq {{[0-9]+}}(%rsp), %rax
390 ; AVX-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
391 ; AVX-NEXT:    movq $0, (%rsp)
392 ; AVX-NEXT:    vmovaps (%rsp), %xmm0
393 ; AVX-NEXT:    callq __addtf3
394 ; AVX-NEXT:    addq $40, %rsp
395 ; AVX-NEXT:    retq
396 entry:
397   %0 = bitcast fp128 %x to i128
398   %bf.clear = and i128 %0, -18446744073709551616
399   %1 = bitcast i128 %bf.clear to fp128
400   %add = fadd fp128 %1, %x
401   ret fp128 %add
404 ; Compare i128 values and check i128 constants.
405 define fp128 @TestComp(fp128 %x, fp128 %y) #0 {
406 ; SSE-LABEL: TestComp:
407 ; SSE:       # %bb.0: # %entry
408 ; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
409 ; SSE-NEXT:    cmpq $0, -{{[0-9]+}}(%rsp)
410 ; SSE-NEXT:    jns .LBB8_2
411 ; SSE-NEXT:  # %bb.1: # %entry
412 ; SSE-NEXT:    movaps %xmm1, %xmm0
413 ; SSE-NEXT:  .LBB8_2: # %entry
414 ; SSE-NEXT:    retq
416 ; AVX-LABEL: TestComp:
417 ; AVX:       # %bb.0: # %entry
418 ; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
419 ; AVX-NEXT:    cmpq $0, -{{[0-9]+}}(%rsp)
420 ; AVX-NEXT:    jns .LBB8_2
421 ; AVX-NEXT:  # %bb.1: # %entry
422 ; AVX-NEXT:    vmovaps %xmm1, %xmm0
423 ; AVX-NEXT:  .LBB8_2: # %entry
424 ; AVX-NEXT:    retq
425 entry:
426   %0 = bitcast fp128 %x to i128
427   %cmp = icmp sgt i128 %0, -1
428   %cond = select i1 %cmp, fp128 %x, fp128 %y
429   ret fp128 %cond
432 declare void @foo(fp128) #1
434 ; Test logical operations on fp128 values.
435 define fp128 @TestFABS_LD(fp128 %x) #0 {
436 ; SSE-LABEL: TestFABS_LD:
437 ; SSE:       # %bb.0: # %entry
438 ; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
439 ; SSE-NEXT:    retq
441 ; AVX-LABEL: TestFABS_LD:
442 ; AVX:       # %bb.0: # %entry
443 ; AVX-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
444 ; AVX-NEXT:    retq
445 entry:
446   %call = tail call fp128 @fabsl(fp128 %x) #2
447   ret fp128 %call
450 declare fp128 @fabsl(fp128) #1
452 declare fp128 @copysignl(fp128, fp128) #1
454 ; Test more complicated logical operations generated from copysignl.
455 define void @TestCopySign({ fp128, fp128 }* noalias nocapture sret %agg.result, { fp128, fp128 }* byval nocapture readonly align 16 %z) #0 {
456 ; SSE-LABEL: TestCopySign:
457 ; SSE:       # %bb.0: # %entry
458 ; SSE-NEXT:    pushq %rbp
459 ; SSE-NEXT:    pushq %rbx
460 ; SSE-NEXT:    subq $40, %rsp
461 ; SSE-NEXT:    movq %rdi, %rbx
462 ; SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
463 ; SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm1
464 ; SSE-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
465 ; SSE-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
466 ; SSE-NEXT:    callq __gttf2
467 ; SSE-NEXT:    movl %eax, %ebp
468 ; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
469 ; SSE-NEXT:    movaps %xmm0, %xmm1
470 ; SSE-NEXT:    callq __subtf3
471 ; SSE-NEXT:    testl %ebp, %ebp
472 ; SSE-NEXT:    jle .LBB10_1
473 ; SSE-NEXT:  # %bb.2: # %if.then
474 ; SSE-NEXT:    movaps %xmm0, %xmm1
475 ; SSE-NEXT:    andps {{.*}}(%rip), %xmm1
476 ; SSE-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
477 ; SSE-NEXT:    jmp .LBB10_3
478 ; SSE-NEXT:  .LBB10_1:
479 ; SSE-NEXT:    movaps (%rsp), %xmm1 # 16-byte Reload
480 ; SSE-NEXT:  .LBB10_3: # %cleanup
481 ; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 16-byte Reload
482 ; SSE-NEXT:    andps {{.*}}(%rip), %xmm2
483 ; SSE-NEXT:    andps {{.*}}(%rip), %xmm0
484 ; SSE-NEXT:    orps %xmm2, %xmm0
485 ; SSE-NEXT:    movaps %xmm1, (%rbx)
486 ; SSE-NEXT:    movaps %xmm0, 16(%rbx)
487 ; SSE-NEXT:    movq %rbx, %rax
488 ; SSE-NEXT:    addq $40, %rsp
489 ; SSE-NEXT:    popq %rbx
490 ; SSE-NEXT:    popq %rbp
491 ; SSE-NEXT:    retq
493 ; AVX-LABEL: TestCopySign:
494 ; AVX:       # %bb.0: # %entry
495 ; AVX-NEXT:    pushq %rbp
496 ; AVX-NEXT:    pushq %rbx
497 ; AVX-NEXT:    subq $40, %rsp
498 ; AVX-NEXT:    movq %rdi, %rbx
499 ; AVX-NEXT:    vmovaps {{[0-9]+}}(%rsp), %xmm0
500 ; AVX-NEXT:    vmovaps {{[0-9]+}}(%rsp), %xmm1
501 ; AVX-NEXT:    vmovaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
502 ; AVX-NEXT:    vmovaps %xmm0, (%rsp) # 16-byte Spill
503 ; AVX-NEXT:    callq __gttf2
504 ; AVX-NEXT:    movl %eax, %ebp
505 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
506 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
507 ; AVX-NEXT:    callq __subtf3
508 ; AVX-NEXT:    testl %ebp, %ebp
509 ; AVX-NEXT:    jle .LBB10_1
510 ; AVX-NEXT:  # %bb.2: # %if.then
511 ; AVX-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm1
512 ; AVX-NEXT:    vmovaps (%rsp), %xmm0 # 16-byte Reload
513 ; AVX-NEXT:    vmovaps %xmm1, %xmm2
514 ; AVX-NEXT:    jmp .LBB10_3
515 ; AVX-NEXT:  .LBB10_1:
516 ; AVX-NEXT:    vmovaps (%rsp), %xmm2 # 16-byte Reload
517 ; AVX-NEXT:  .LBB10_3: # %cleanup
518 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
519 ; AVX-NEXT:    vandps {{.*}}(%rip), %xmm1, %xmm1
520 ; AVX-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
521 ; AVX-NEXT:    vorps %xmm1, %xmm0, %xmm0
522 ; AVX-NEXT:    vmovaps %xmm2, (%rbx)
523 ; AVX-NEXT:    vmovaps %xmm0, 16(%rbx)
524 ; AVX-NEXT:    movq %rbx, %rax
525 ; AVX-NEXT:    addq $40, %rsp
526 ; AVX-NEXT:    popq %rbx
527 ; AVX-NEXT:    popq %rbp
528 ; AVX-NEXT:    retq
529 entry:
530   %z.realp = getelementptr inbounds { fp128, fp128 }, { fp128, fp128 }* %z, i64 0, i32 0
531   %z.real = load fp128, fp128* %z.realp, align 16
532   %z.imagp = getelementptr inbounds { fp128, fp128 }, { fp128, fp128 }* %z, i64 0, i32 1
533   %z.imag4 = load fp128, fp128* %z.imagp, align 16
534   %cmp = fcmp ogt fp128 %z.real, %z.imag4
535   %sub = fsub fp128 %z.imag4, %z.imag4
536   br i1 %cmp, label %if.then, label %cleanup
538 if.then:                                          ; preds = %entry
539   %call = tail call fp128 @fabsl(fp128 %sub) #2
540   br label %cleanup
542 cleanup:                                          ; preds = %entry, %if.then
543   %z.real.sink = phi fp128 [ %z.real, %if.then ], [ %sub, %entry ]
544   %call.sink = phi fp128 [ %call, %if.then ], [ %z.real, %entry ]
545   %call5 = tail call fp128 @copysignl(fp128 %z.real.sink, fp128 %z.imag4) #2
546   %0 = getelementptr inbounds { fp128, fp128 }, { fp128, fp128 }* %agg.result, i64 0, i32 0
547   %1 = getelementptr inbounds { fp128, fp128 }, { fp128, fp128 }* %agg.result, i64 0, i32 1
548   store fp128 %call.sink, fp128* %0, align 16
549   store fp128 %call5, fp128* %1, align 16
550   ret void
554 attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+ssse3,+sse3,+popcnt,+sse,+sse2,+sse4.1,+sse4.2" "unsafe-fp-math"="false" "use-soft-float"="false" }
555 attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+ssse3,+sse3,+popcnt,+sse,+sse2,+sse4.1,+sse4.2" "unsafe-fp-math"="false" "use-soft-float"="false" }
556 attributes #2 = { nounwind readnone }