llvm/test/Object/ar-error.test: Don't check the message "No such file or directory".
[oota-llvm.git] / test / CodeGen / AArch64 / neon-vector-list-spill.ll
1 ; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -mattr=+neon -fp-contract=fast
2 ; arm64 has separate copy as aarch64-neon-vector-list-spill.ll
3
4 ; FIXME: We should not generate ld/st for such register spill/fill, because the
5 ; test case seems very simple and the register pressure is not high. If the
6 ; spill/fill algorithm is optimized, this test case may not be triggered. And
7 ; then we can delete it.
8 define i32 @spill.DPairReg(i8* %arg1, i32 %arg2) {
9 ; CHECK-LABEL: spill.DPairReg:
10 ; CHECK: ld2 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
11 ; CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
12 ; CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
13 entry:
14   %vld = tail call { <2 x i32>, <2 x i32> } @llvm.arm.neon.vld2.v2i32(i8* %arg1, i32 4)
15   %cmp = icmp eq i32 %arg2, 0
16   br i1 %cmp, label %if.then, label %if.end
17
18 if.then:
19   tail call void @foo()
20   br label %if.end
21
22 if.end:
23   %vld.extract = extractvalue { <2 x i32>, <2 x i32> } %vld, 0
24   %res = extractelement <2 x i32> %vld.extract, i32 1
25   ret i32 %res
26 }
27
28 define i16 @spill.DTripleReg(i8* %arg1, i32 %arg2) {
29 ; CHECK-LABEL: spill.DTripleReg:
30 ; CHECK: ld3 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
31 ; CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
32 ; CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
33 entry:
34   %vld = tail call { <4 x i16>, <4 x i16>, <4 x i16> } @llvm.arm.neon.vld3.v4i16(i8* %arg1, i32 4)
35   %cmp = icmp eq i32 %arg2, 0
36   br i1 %cmp, label %if.then, label %if.end
37
38 if.then:
39   tail call void @foo()
40   br label %if.end
41
42 if.end:
43   %vld.extract = extractvalue { <4 x i16>, <4 x i16>, <4 x i16> } %vld, 0
44   %res = extractelement <4 x i16> %vld.extract, i32 1
45   ret i16 %res
46 }
47
48 define i16 @spill.DQuadReg(i8* %arg1, i32 %arg2) {
49 ; CHECK-LABEL: spill.DQuadReg:
50 ; CHECK: ld4 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
51 ; CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
52 ; CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
53 entry:
54   %vld = tail call { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> } @llvm.arm.neon.vld4.v4i16(i8* %arg1, i32 4)
55   %cmp = icmp eq i32 %arg2, 0
56   br i1 %cmp, label %if.then, label %if.end
57
58 if.then:
59   tail call void @foo()
60   br label %if.end
61
62 if.end:
63   %vld.extract = extractvalue { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> } %vld, 0
64   %res = extractelement <4 x i16> %vld.extract, i32 0
65   ret i16 %res
66 }
67
68 define i32 @spill.QPairReg(i8* %arg1, i32 %arg2) {
69 ; CHECK-LABEL: spill.QPairReg:
70 ; CHECK: ld3 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
71 ; CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
72 ; CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
73 entry:
74   %vld = tail call { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32(i8* %arg1, i32 4)
75   %cmp = icmp eq i32 %arg2, 0
76   br i1 %cmp, label %if.then, label %if.end
77
78 if.then:
79   tail call void @foo()
80   br label %if.end
81
82 if.end:
83   %vld.extract = extractvalue { <4 x i32>, <4 x i32> } %vld, 0
84   %res = extractelement <4 x i32> %vld.extract, i32 1
85   ret i32 %res
86 }
87
88 define float @spill.QTripleReg(i8* %arg1, i32 %arg2) {
89 ; CHECK-LABEL: spill.QTripleReg:
90 ; CHECK: ld3 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
91 ; CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
92 ; CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
93 entry:
94   %vld3 = tail call { <4 x float>, <4 x float>, <4 x float> } @llvm.arm.neon.vld3.v4f32(i8* %arg1, i32 4)
95   %cmp = icmp eq i32 %arg2, 0
96   br i1 %cmp, label %if.then, label %if.end
97
98 if.then:
99   tail call void @foo()
100   br label %if.end
101
102 if.end:
103   %vld3.extract = extractvalue { <4 x float>, <4 x float>, <4 x float> } %vld3, 0
104   %res = extractelement <4 x float> %vld3.extract, i32 1
105   ret float %res
106 }
107
108 define i8 @spill.QQuadReg(i8* %arg1, i32 %arg2) {
109 ; CHECK-LABEL: spill.QQuadReg:
110 ; CHECK: ld4 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
111 ; CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
112 ; CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
113 entry:
114   %vld = tail call { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @llvm.arm.neon.vld4.v16i8(i8* %arg1, i32 4)
115   %cmp = icmp eq i32 %arg2, 0
116   br i1 %cmp, label %if.then, label %if.end
117
118 if.then:
119   tail call void @foo()
120   br label %if.end
121
122 if.end:
123   %vld.extract = extractvalue { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } %vld, 0
124   %res = extractelement <16 x i8> %vld.extract, i32 1
125   ret i8 %res
126 }
127
128 declare { <2 x i32>, <2 x i32> } @llvm.arm.neon.vld2.v2i32(i8*, i32)
129 declare { <4 x i16>, <4 x i16>, <4 x i16> } @llvm.arm.neon.vld3.v4i16(i8*, i32)
130 declare { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> } @llvm.arm.neon.vld4.v4i16(i8*, i32)
131 declare { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32(i8*, i32)
132 declare { <4 x float>, <4 x float>, <4 x float> } @llvm.arm.neon.vld3.v4f32(i8*, i32)
133 declare { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @llvm.arm.neon.vld4.v16i8(i8*, i32)
134
135 declare void @foo()
136
137 ; FIXME: We should not generate ld/st for such register spill/fill, because the
138 ; test case seems very simple and the register pressure is not high. If the
139 ; spill/fill algorithm is optimized, this test case may not be triggered. And
140 ; then we can delete it.
141 ; check the spill for Register Class QPair_with_qsub_0_in_FPR128Lo
142 define <8 x i16> @test_2xFPR128Lo(i64 %got, i8* %ptr, <1 x i64> %a) {
143   tail call void @llvm.arm.neon.vst2lane.v1i64(i8* %ptr, <1 x i64> zeroinitializer, <1 x i64> zeroinitializer, i32 0, i32 8)
144   tail call void @foo()
145   %sv = shufflevector <1 x i64> zeroinitializer, <1 x i64> %a, <2 x i32> <i32 0, i32 1>
146   %1 = bitcast <2 x i64> %sv to <8 x i16>
147   %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
148   %3 = mul <8 x i16> %2, %2
149   ret <8 x i16> %3
150 }
151
152 ; check the spill for Register Class QTriple_with_qsub_0_in_FPR128Lo
153 define <8 x i16> @test_3xFPR128Lo(i64 %got, i8* %ptr, <1 x i64> %a) {
154   tail call void @llvm.arm.neon.vst3lane.v1i64(i8* %ptr, <1 x i64> zeroinitializer, <1 x i64> zeroinitializer, <1 x i64> zeroinitializer, i32 0, i32 8)
155   tail call void @foo()
156   %sv = shufflevector <1 x i64> zeroinitializer, <1 x i64> %a, <2 x i32> <i32 0, i32 1>
157   %1 = bitcast <2 x i64> %sv to <8 x i16>
158   %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
159   %3 = mul <8 x i16> %2, %2
160   ret <8 x i16> %3
161 }
162
163 ; check the spill for Register Class QQuad_with_qsub_0_in_FPR128Lo
164 define <8 x i16> @test_4xFPR128Lo(i64 %got, i8* %ptr, <1 x i64> %a) {
165   tail call void @llvm.arm.neon.vst4lane.v1i64(i8* %ptr, <1 x i64> zeroinitializer, <1 x i64> zeroinitializer, <1 x i64> zeroinitializer, <1 x i64> zeroinitializer, i32 0, i32 8)
166   tail call void @foo()
167   %sv = shufflevector <1 x i64> zeroinitializer, <1 x i64> %a, <2 x i32> <i32 0, i32 1>
168   %1 = bitcast <2 x i64> %sv to <8 x i16>
169   %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
170   %3 = mul <8 x i16> %2, %2
171   ret <8 x i16> %3
172 }
173
174 declare void @llvm.arm.neon.vst2lane.v1i64(i8*, <1 x i64>, <1 x i64>, i32, i32)
175 declare void @llvm.arm.neon.vst3lane.v1i64(i8*, <1 x i64>, <1 x i64>, <1 x i64>, i32, i32)
176 declare void @llvm.arm.neon.vst4lane.v1i64(i8*, <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64>, i32, i32)