xref: /llvm-project/llvm/test/CodeGen/AArch64/fcopysign-noneon.ll (revision aacefaf1ccabdc8f41f2282301807823829b3d68)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64 | FileCheck %s
3; RUN: llc < %s -mtriple=aarch64 -mattr=-neon | FileCheck -check-prefix=CHECK-NONEON %s
4; Check that selection dag legalization of fcopysign works in cases with
5; different modes for the arguments.
6
7declare fp128 @llvm.copysign.f128(fp128, fp128)
8declare float @llvm.copysign.f32(float %a, float %b)
9declare double @llvm.copysign.f64(double %a, double %b)
10declare half @llvm.copysign.f16(half %a, half %b)
11
12@val_float = dso_local global float zeroinitializer, align 4
13@val_double = dso_local global double zeroinitializer, align 8
14@val_fp128 = dso_local global fp128 zeroinitializer, align 16
15
16define fp128 @copysign0() {
17; CHECK-LABEL: copysign0:
18; CHECK:       // %bb.0: // %entry
19; CHECK-NEXT:    adrp x8, .LCPI0_0
20; CHECK-NEXT:    ldr q0, [x8, :lo12:.LCPI0_0]
21; CHECK-NEXT:    adrp x8, val_double
22; CHECK-NEXT:    str q0, [sp, #-16]!
23; CHECK-NEXT:    .cfi_def_cfa_offset 16
24; CHECK-NEXT:    ldr x8, [x8, :lo12:val_double]
25; CHECK-NEXT:    ldrb w9, [sp, #15]
26; CHECK-NEXT:    and x8, x8, #0x8000000000000000
27; CHECK-NEXT:    lsr x8, x8, #56
28; CHECK-NEXT:    bfxil w8, w9, #0, #7
29; CHECK-NEXT:    strb w8, [sp, #15]
30; CHECK-NEXT:    ldr q0, [sp], #16
31; CHECK-NEXT:    ret
32;
33; CHECK-NONEON-LABEL: copysign0:
34; CHECK-NONEON:       // %bb.0: // %entry
35; CHECK-NONEON-NEXT:    adrp x8, .LCPI0_0
36; CHECK-NONEON-NEXT:    ldr q0, [x8, :lo12:.LCPI0_0]
37; CHECK-NONEON-NEXT:    adrp x8, val_double
38; CHECK-NONEON-NEXT:    str q0, [sp, #-16]!
39; CHECK-NONEON-NEXT:    .cfi_def_cfa_offset 16
40; CHECK-NONEON-NEXT:    ldr x8, [x8, :lo12:val_double]
41; CHECK-NONEON-NEXT:    ldrb w9, [sp, #15]
42; CHECK-NONEON-NEXT:    and x8, x8, #0x8000000000000000
43; CHECK-NONEON-NEXT:    lsr x8, x8, #56
44; CHECK-NONEON-NEXT:    bfxil w8, w9, #0, #7
45; CHECK-NONEON-NEXT:    strb w8, [sp, #15]
46; CHECK-NONEON-NEXT:    ldr q0, [sp], #16
47; CHECK-NONEON-NEXT:    ret
48entry:
49  %v = load double, ptr @val_double, align 8
50  %conv = fpext double %v to fp128
51  %call = tail call fp128 @llvm.copysign.f128(fp128 0xL00000000000000007FFF000000000000, fp128 %conv) #2
52  ret fp128 %call
53}
54
55define fp128@copysign1() {
56; CHECK-LABEL: copysign1:
57; CHECK:       // %bb.0: // %entry
58; CHECK-NEXT:    adrp x8, val_fp128
59; CHECK-NEXT:    ldr q0, [x8, :lo12:val_fp128]
60; CHECK-NEXT:    adrp x8, val_float
61; CHECK-NEXT:    str q0, [sp, #-16]!
62; CHECK-NEXT:    .cfi_def_cfa_offset 16
63; CHECK-NEXT:    ldr w8, [x8, :lo12:val_float]
64; CHECK-NEXT:    ldrb w9, [sp, #15]
65; CHECK-NEXT:    and w8, w8, #0x80000000
66; CHECK-NEXT:    and w9, w9, #0x7f
67; CHECK-NEXT:    orr w8, w9, w8, lsr #24
68; CHECK-NEXT:    strb w8, [sp, #15]
69; CHECK-NEXT:    ldr q0, [sp], #16
70; CHECK-NEXT:    ret
71;
72; CHECK-NONEON-LABEL: copysign1:
73; CHECK-NONEON:       // %bb.0: // %entry
74; CHECK-NONEON-NEXT:    adrp x8, val_fp128
75; CHECK-NONEON-NEXT:    ldr q0, [x8, :lo12:val_fp128]
76; CHECK-NONEON-NEXT:    adrp x8, val_float
77; CHECK-NONEON-NEXT:    str q0, [sp, #-16]!
78; CHECK-NONEON-NEXT:    .cfi_def_cfa_offset 16
79; CHECK-NONEON-NEXT:    ldr w8, [x8, :lo12:val_float]
80; CHECK-NONEON-NEXT:    ldrb w9, [sp, #15]
81; CHECK-NONEON-NEXT:    and w8, w8, #0x80000000
82; CHECK-NONEON-NEXT:    and w9, w9, #0x7f
83; CHECK-NONEON-NEXT:    orr w8, w9, w8, lsr #24
84; CHECK-NONEON-NEXT:    strb w8, [sp, #15]
85; CHECK-NONEON-NEXT:    ldr q0, [sp], #16
86; CHECK-NONEON-NEXT:    ret
87entry:
88  %v0 = load fp128, ptr @val_fp128, align 16
89  %v1 = load float, ptr @val_float, align 4
90  %conv = fpext float %v1 to fp128
91  %call = tail call fp128 @llvm.copysign.f128(fp128 %v0, fp128 %conv)
92  ret fp128 %call
93}
94
95define float @copysign32(float %a, float %b) {
96; CHECK-LABEL: copysign32:
97; CHECK:       // %bb.0: // %entry
98; CHECK-NEXT:    mvni v2.4s, #128, lsl #24
99; CHECK-NEXT:    // kill: def $s0 killed $s0 def $q0
100; CHECK-NEXT:    // kill: def $s1 killed $s1 def $q1
101; CHECK-NEXT:    bif v0.16b, v1.16b, v2.16b
102; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $q0
103; CHECK-NEXT:    ret
104;
105; CHECK-NONEON-LABEL: copysign32:
106; CHECK-NONEON:       // %bb.0: // %entry
107; CHECK-NONEON-NEXT:    fabs s0, s0
108; CHECK-NONEON-NEXT:    fmov w8, s1
109; CHECK-NONEON-NEXT:    tst w8, #0x80000000
110; CHECK-NONEON-NEXT:    fneg s2, s0
111; CHECK-NONEON-NEXT:    fcsel s0, s2, s0, ne
112; CHECK-NONEON-NEXT:    ret
113entry:
114  %c = call float @llvm.copysign.f32(float %a, float %b)
115  ret float %c
116}
117
118define double @copysign64(double %a, double %b) {
119; CHECK-LABEL: copysign64:
120; CHECK:       // %bb.0: // %entry
121; CHECK-NEXT:    movi v2.2d, #0xffffffffffffffff
122; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
123; CHECK-NEXT:    // kill: def $d1 killed $d1 def $q1
124; CHECK-NEXT:    fneg v2.2d, v2.2d
125; CHECK-NEXT:    bif v0.16b, v1.16b, v2.16b
126; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
127; CHECK-NEXT:    ret
128;
129; CHECK-NONEON-LABEL: copysign64:
130; CHECK-NONEON:       // %bb.0: // %entry
131; CHECK-NONEON-NEXT:    fabs d0, d0
132; CHECK-NONEON-NEXT:    fmov x8, d1
133; CHECK-NONEON-NEXT:    tst x8, #0x8000000000000000
134; CHECK-NONEON-NEXT:    fneg d2, d0
135; CHECK-NONEON-NEXT:    fcsel d0, d2, d0, ne
136; CHECK-NONEON-NEXT:    ret
137entry:
138  %c = call double @llvm.copysign.f64(double %a, double %b)
139  ret double %c
140}
141
142define half @copysign16(half %a, half %b) {
143; CHECK-LABEL: copysign16:
144; CHECK:       // %bb.0: // %entry
145; CHECK-NEXT:    fcvt s1, h1
146; CHECK-NEXT:    fcvt s0, h0
147; CHECK-NEXT:    mvni v2.4s, #128, lsl #24
148; CHECK-NEXT:    bif v0.16b, v1.16b, v2.16b
149; CHECK-NEXT:    fcvt h0, s0
150; CHECK-NEXT:    ret
151;
152; CHECK-NONEON-LABEL: copysign16:
153; CHECK-NONEON:       // %bb.0: // %entry
154; CHECK-NONEON-NEXT:    sub sp, sp, #16
155; CHECK-NONEON-NEXT:    .cfi_def_cfa_offset 16
156; CHECK-NONEON-NEXT:    fcvt s0, h0
157; CHECK-NONEON-NEXT:    str h1, [sp, #12]
158; CHECK-NONEON-NEXT:    ldrb w8, [sp, #13]
159; CHECK-NONEON-NEXT:    tst w8, #0x80
160; CHECK-NONEON-NEXT:    fabs s0, s0
161; CHECK-NONEON-NEXT:    fneg s1, s0
162; CHECK-NONEON-NEXT:    fcsel s0, s1, s0, ne
163; CHECK-NONEON-NEXT:    fcvt h0, s0
164; CHECK-NONEON-NEXT:    add sp, sp, #16
165; CHECK-NONEON-NEXT:    ret
166entry:
167  %c = call half @llvm.copysign.f16(half %a, half %b)
168  ret half %c
169}
170