xref: /llvm-project/llvm/test/CodeGen/PowerPC/ctrloop-constrained-fp.ll (revision 5c2a133b1342881dc4f42a896e7e5f4b85d20508)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple powerpc64le < %s | FileCheck %s
3
4; Check constrained ops converted to call
5define void @test(ptr %cast) strictfp {
6; CHECK-LABEL: test:
7; CHECK:       # %bb.0: # %root
8; CHECK-NEXT:    mflr 0
9; CHECK-NEXT:    .cfi_def_cfa_offset 64
10; CHECK-NEXT:    .cfi_offset lr, 16
11; CHECK-NEXT:    .cfi_offset r29, -24
12; CHECK-NEXT:    .cfi_offset r30, -16
13; CHECK-NEXT:    std 29, -24(1) # 8-byte Folded Spill
14; CHECK-NEXT:    std 30, -16(1) # 8-byte Folded Spill
15; CHECK-NEXT:    stdu 1, -64(1)
16; CHECK-NEXT:    addi 30, 3, -8
17; CHECK-NEXT:    li 29, 255
18; CHECK-NEXT:    std 0, 80(1)
19; CHECK-NEXT:    .p2align 5
20; CHECK-NEXT:  .LBB0_1: # %for.body
21; CHECK-NEXT:    #
22; CHECK-NEXT:    lfdu 1, 8(30)
23; CHECK-NEXT:    bl cos
24; CHECK-NEXT:    nop
25; CHECK-NEXT:    addi 29, 29, -1
26; CHECK-NEXT:    stfd 1, 0(30)
27; CHECK-NEXT:    cmpldi 29, 0
28; CHECK-NEXT:    bc 12, 1, .LBB0_1
29; CHECK-NEXT:  # %bb.2: # %exit
30; CHECK-NEXT:    addi 1, 1, 64
31; CHECK-NEXT:    ld 0, 16(1)
32; CHECK-NEXT:    ld 30, -16(1) # 8-byte Folded Reload
33; CHECK-NEXT:    ld 29, -24(1) # 8-byte Folded Reload
34; CHECK-NEXT:    mtlr 0
35; CHECK-NEXT:    blr
36root:
37  br label %for.body
38
39exit:
40  ret void
41
42for.body:
43  %i = phi i64 [ 0, %root ], [ %next, %for.body ]
44  %idx = getelementptr inbounds double, ptr %cast, i64 %i
45  %val = load double, ptr %idx
46  %cos = tail call nnan ninf nsz arcp double @llvm.experimental.constrained.cos.f64(double %val, metadata !"round.dynamic", metadata !"fpexcept.strict")
47  store double %cos, ptr %idx, align 8
48  %next = add nuw nsw i64 %i, 1
49  %cond = icmp eq i64 %next, 255
50  br i1 %cond, label %exit, label %for.body
51}
52
53; Check constrained ops converted to native instruction
54define void @test2(ptr %cast) strictfp {
55; CHECK-LABEL: test2:
56; CHECK:       # %bb.0: # %entry
57; CHECK-NEXT:    li 4, 255
58; CHECK-NEXT:    addi 3, 3, -8
59; CHECK-NEXT:    mtctr 4
60; CHECK-NEXT:    .p2align 4
61; CHECK-NEXT:  .LBB1_1: # %for.body
62; CHECK-NEXT:    #
63; CHECK-NEXT:    lfdu 0, 8(3)
64; CHECK-NEXT:    xssqrtdp 0, 0
65; CHECK-NEXT:    stfd 0, 0(3)
66; CHECK-NEXT:    bdnz .LBB1_1
67; CHECK-NEXT:  # %bb.2: # %exit
68; CHECK-NEXT:    blr
69entry:
70  br label %for.body
71
72for.body:
73  %i = phi i64 [ 0, %entry ], [ %next, %for.body ]
74  %idx = getelementptr inbounds double, ptr %cast, i64 %i
75  %val = load double, ptr %idx
76  %cos = tail call nnan ninf nsz arcp double @llvm.experimental.constrained.sqrt.f64(double %val, metadata !"round.dynamic", metadata !"fpexcept.strict")
77  store double %cos, ptr %idx, align 8
78  %next = add nuw nsw i64 %i, 1
79  %cond = icmp eq i64 %next, 255
80  br i1 %cond, label %exit, label %for.body
81
82exit:
83  ret void
84}
85
86; Check constrained ops converted to call
87define void @testTan(ptr %cast) strictfp {
88; CHECK-LABEL: testTan:
89; CHECK:       # %bb.0: # %root
90; CHECK-NEXT:    mflr 0
91; CHECK-NEXT:    .cfi_def_cfa_offset 64
92; CHECK-NEXT:    .cfi_offset lr, 16
93; CHECK-NEXT:    .cfi_offset r29, -24
94; CHECK-NEXT:    .cfi_offset r30, -16
95; CHECK-NEXT:    std 29, -24(1) # 8-byte Folded Spill
96; CHECK-NEXT:    std 30, -16(1) # 8-byte Folded Spill
97; CHECK-NEXT:    stdu 1, -64(1)
98; CHECK-NEXT:    addi 30, 3, -8
99; CHECK-NEXT:    li 29, 255
100; CHECK-NEXT:    std 0, 80(1)
101; CHECK-NEXT:    .p2align 5
102; CHECK-NEXT:  .LBB2_1: # %for.body
103; CHECK-NEXT:    #
104; CHECK-NEXT:    lfdu 1, 8(30)
105; CHECK-NEXT:    bl tan
106; CHECK-NEXT:    nop
107; CHECK-NEXT:    addi 29, 29, -1
108; CHECK-NEXT:    stfd 1, 0(30)
109; CHECK-NEXT:    cmpldi 29, 0
110; CHECK-NEXT:    bc 12, 1, .LBB2_1
111; CHECK-NEXT:  # %bb.2: # %exit
112; CHECK-NEXT:    addi 1, 1, 64
113; CHECK-NEXT:    ld 0, 16(1)
114; CHECK-NEXT:    ld 30, -16(1) # 8-byte Folded Reload
115; CHECK-NEXT:    ld 29, -24(1) # 8-byte Folded Reload
116; CHECK-NEXT:    mtlr 0
117; CHECK-NEXT:    blr
118root:
119  br label %for.body
120
121exit:
122  ret void
123
124for.body:
125  %i = phi i64 [ 0, %root ], [ %next, %for.body ]
126  %idx = getelementptr inbounds double, ptr %cast, i64 %i
127  %val = load double, ptr %idx
128  %tan = tail call nnan ninf nsz arcp double @llvm.experimental.constrained.tan.f64(double %val, metadata !"round.dynamic", metadata !"fpexcept.strict")
129  store double %tan, ptr %idx, align 8
130  %next = add nuw nsw i64 %i, 1
131  %cond = icmp eq i64 %next, 255
132  br i1 %cond, label %exit, label %for.body
133}
134
135; Check constrained ops converted to call
136define void @testAtan2(ptr %cast1, ptr %cast2) strictfp {
137; CHECK-LABEL: testAtan2:
138; CHECK:       # %bb.0: # %root
139; CHECK-NEXT:    mflr 0
140; CHECK-NEXT:    .cfi_def_cfa_offset 64
141; CHECK-NEXT:    .cfi_offset lr, 16
142; CHECK-NEXT:    .cfi_offset r28, -32
143; CHECK-NEXT:    .cfi_offset r29, -24
144; CHECK-NEXT:    .cfi_offset r30, -16
145; CHECK-NEXT:    std 28, -32(1) # 8-byte Folded Spill
146; CHECK-NEXT:    std 29, -24(1) # 8-byte Folded Spill
147; CHECK-NEXT:    std 30, -16(1) # 8-byte Folded Spill
148; CHECK-NEXT:    stdu 1, -64(1)
149; CHECK-NEXT:    addi 30, 3, -8
150; CHECK-NEXT:    addi 29, 4, -8
151; CHECK-NEXT:    li 28, 255
152; CHECK-NEXT:    std 0, 80(1)
153; CHECK-NEXT:    .p2align 5
154; CHECK-NEXT:  .LBB3_1: # %for.body
155; CHECK-NEXT:    #
156; CHECK-NEXT:    lfdu 2, 8(29)
157; CHECK-NEXT:    lfdu 1, 8(30)
158; CHECK-NEXT:    bl atan2
159; CHECK-NEXT:    nop
160; CHECK-NEXT:    addi 28, 28, -1
161; CHECK-NEXT:    stfd 1, 0(30)
162; CHECK-NEXT:    cmpldi 28, 0
163; CHECK-NEXT:    bc 12, 1, .LBB3_1
164; CHECK-NEXT:  # %bb.2: # %exit
165; CHECK-NEXT:    addi 1, 1, 64
166; CHECK-NEXT:    ld 0, 16(1)
167; CHECK-NEXT:    ld 30, -16(1) # 8-byte Folded Reload
168; CHECK-NEXT:    ld 29, -24(1) # 8-byte Folded Reload
169; CHECK-NEXT:    ld 28, -32(1) # 8-byte Folded Reload
170; CHECK-NEXT:    mtlr 0
171; CHECK-NEXT:    blr
172root:
173  br label %for.body
174
175exit:
176  ret void
177
178for.body:
179  %i = phi i64 [ 0, %root ], [ %next, %for.body ]
180  %idx1 = getelementptr inbounds double, ptr %cast1, i64 %i
181  %idx2 = getelementptr inbounds double, ptr %cast2, i64 %i
182  %val1 = load double, ptr %idx1
183  %val2 = load double, ptr %idx2
184  %tan = tail call nnan ninf nsz arcp double @llvm.experimental.constrained.atan2.f64(double %val1, double %val2, metadata !"round.dynamic", metadata !"fpexcept.strict")
185  store double %tan, ptr %idx1, align 8
186  %next = add nuw nsw i64 %i, 1
187  %cond = icmp eq i64 %next, 255
188  br i1 %cond, label %exit, label %for.body
189}
190
191declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata)
192declare double @llvm.experimental.constrained.tan.f64(double, metadata, metadata)
193declare double @llvm.experimental.constrained.atan2.f64(double, double, metadata, metadata)
194declare double @llvm.experimental.constrained.sqrt.f64(double, metadata, metadata)
195