xref: /aosp_15_r20/external/llvm/test/CodeGen/ARM/vrev.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=arm-eabi -mattr=+neon %s -o - | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workerdefine <8 x i8> @test_vrev64D8(<8 x i8>* %A) nounwind {
4*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64D8:
5*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.8
6*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <8 x i8>, <8 x i8>* %A
7*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
8*9880d681SAndroid Build Coastguard Worker	ret <8 x i8> %tmp2
9*9880d681SAndroid Build Coastguard Worker}
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Workerdefine <4 x i16> @test_vrev64D16(<4 x i16>* %A) nounwind {
12*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64D16:
13*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.16
14*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <4 x i16>, <4 x i16>* %A
15*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
16*9880d681SAndroid Build Coastguard Worker	ret <4 x i16> %tmp2
17*9880d681SAndroid Build Coastguard Worker}
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test_vrev64D32(<2 x i32>* %A) nounwind {
20*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64D32:
21*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32
22*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <2 x i32>, <2 x i32>* %A
23*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> <i32 1, i32 0>
24*9880d681SAndroid Build Coastguard Worker	ret <2 x i32> %tmp2
25*9880d681SAndroid Build Coastguard Worker}
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Workerdefine <2 x float> @test_vrev64Df(<2 x float>* %A) nounwind {
28*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Df:
29*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32
30*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <2 x float>, <2 x float>* %A
31*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <2 x i32> <i32 1, i32 0>
32*9880d681SAndroid Build Coastguard Worker	ret <2 x float> %tmp2
33*9880d681SAndroid Build Coastguard Worker}
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Workerdefine <16 x i8> @test_vrev64Q8(<16 x i8>* %A) nounwind {
36*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Q8:
37*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.8
38*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <16 x i8>, <16 x i8>* %A
39*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8>
40*9880d681SAndroid Build Coastguard Worker	ret <16 x i8> %tmp2
41*9880d681SAndroid Build Coastguard Worker}
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @test_vrev64Q16(<8 x i16>* %A) nounwind {
44*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Q16:
45*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.16
46*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <8 x i16>, <8 x i16>* %A
47*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
48*9880d681SAndroid Build Coastguard Worker	ret <8 x i16> %tmp2
49*9880d681SAndroid Build Coastguard Worker}
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @test_vrev64Q32(<4 x i32>* %A) nounwind {
52*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Q32:
53*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32
54*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <4 x i32>, <4 x i32>* %A
55*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <4 x i32> %tmp1, <4 x i32> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
56*9880d681SAndroid Build Coastguard Worker	ret <4 x i32> %tmp2
57*9880d681SAndroid Build Coastguard Worker}
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @test_vrev64Qf(<4 x float>* %A) nounwind {
60*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64Qf:
61*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32
62*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <4 x float>, <4 x float>* %A
63*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <4 x float> %tmp1, <4 x float> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
64*9880d681SAndroid Build Coastguard Worker	ret <4 x float> %tmp2
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Workerdefine <8 x i8> @test_vrev32D8(<8 x i8>* %A) nounwind {
68*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32D8:
69*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.8
70*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <8 x i8>, <8 x i8>* %A
71*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>
72*9880d681SAndroid Build Coastguard Worker	ret <8 x i8> %tmp2
73*9880d681SAndroid Build Coastguard Worker}
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Workerdefine <4 x i16> @test_vrev32D16(<4 x i16>* %A) nounwind {
76*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32D16:
77*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.16
78*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <4 x i16>, <4 x i16>* %A
79*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
80*9880d681SAndroid Build Coastguard Worker	ret <4 x i16> %tmp2
81*9880d681SAndroid Build Coastguard Worker}
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Workerdefine <16 x i8> @test_vrev32Q8(<16 x i8>* %A) nounwind {
84*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32Q8:
85*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.8
86*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <16 x i8>, <16 x i8>* %A
87*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 11, i32 10, i32 9, i32 8, i32 15, i32 14, i32 13, i32 12>
88*9880d681SAndroid Build Coastguard Worker	ret <16 x i8> %tmp2
89*9880d681SAndroid Build Coastguard Worker}
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @test_vrev32Q16(<8 x i16>* %A) nounwind {
92*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32Q16:
93*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.16
94*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <8 x i16>, <8 x i16>* %A
95*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
96*9880d681SAndroid Build Coastguard Worker	ret <8 x i16> %tmp2
97*9880d681SAndroid Build Coastguard Worker}
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Workerdefine <8 x i8> @test_vrev16D8(<8 x i8>* %A) nounwind {
100*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev16D8:
101*9880d681SAndroid Build Coastguard Worker;CHECK: vrev16.8
102*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <8 x i8>, <8 x i8>* %A
103*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
104*9880d681SAndroid Build Coastguard Worker	ret <8 x i8> %tmp2
105*9880d681SAndroid Build Coastguard Worker}
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Workerdefine <16 x i8> @test_vrev16Q8(<16 x i8>* %A) nounwind {
108*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev16Q8:
109*9880d681SAndroid Build Coastguard Worker;CHECK: vrev16.8
110*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <16 x i8>, <16 x i8>* %A
111*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14>
112*9880d681SAndroid Build Coastguard Worker	ret <16 x i8> %tmp2
113*9880d681SAndroid Build Coastguard Worker}
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker; Undef shuffle indices should not prevent matching to VREV:
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Workerdefine <8 x i8> @test_vrev64D8_undef(<8 x i8>* %A) nounwind {
118*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev64D8_undef:
119*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.8
120*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <8 x i8>, <8 x i8>* %A
121*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> <i32 7, i32 undef, i32 undef, i32 4, i32 3, i32 2, i32 1, i32 0>
122*9880d681SAndroid Build Coastguard Worker	ret <8 x i8> %tmp2
123*9880d681SAndroid Build Coastguard Worker}
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @test_vrev32Q16_undef(<8 x i16>* %A) nounwind {
126*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_vrev32Q16_undef:
127*9880d681SAndroid Build Coastguard Worker;CHECK: vrev32.16
128*9880d681SAndroid Build Coastguard Worker	%tmp1 = load <8 x i16>, <8 x i16>* %A
129*9880d681SAndroid Build Coastguard Worker	%tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> <i32 undef, i32 0, i32 undef, i32 2, i32 5, i32 4, i32 7, i32 undef>
130*9880d681SAndroid Build Coastguard Worker	ret <8 x i16> %tmp2
131*9880d681SAndroid Build Coastguard Worker}
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker; A vcombine feeding a VREV should not obscure things.  Radar 8597007.
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Workerdefine void @test_with_vcombine(<4 x float>* %v) nounwind {
136*9880d681SAndroid Build Coastguard Worker;CHECK-LABEL: test_with_vcombine:
137*9880d681SAndroid Build Coastguard Worker;CHECK-NOT: vext
138*9880d681SAndroid Build Coastguard Worker;CHECK: vrev64.32
139*9880d681SAndroid Build Coastguard Worker  %tmp1 = load <4 x float>, <4 x float>* %v, align 16
140*9880d681SAndroid Build Coastguard Worker  %tmp2 = bitcast <4 x float> %tmp1 to <2 x double>
141*9880d681SAndroid Build Coastguard Worker  %tmp3 = extractelement <2 x double> %tmp2, i32 0
142*9880d681SAndroid Build Coastguard Worker  %tmp4 = bitcast double %tmp3 to <2 x float>
143*9880d681SAndroid Build Coastguard Worker  %tmp5 = extractelement <2 x double> %tmp2, i32 1
144*9880d681SAndroid Build Coastguard Worker  %tmp6 = bitcast double %tmp5 to <2 x float>
145*9880d681SAndroid Build Coastguard Worker  %tmp7 = fadd <2 x float> %tmp6, %tmp6
146*9880d681SAndroid Build Coastguard Worker  %tmp8 = shufflevector <2 x float> %tmp4, <2 x float> %tmp7, <4 x i32> <i32 1, i32 0, i32 3, i32 2>
147*9880d681SAndroid Build Coastguard Worker  store <4 x float> %tmp8, <4 x float>* %v, align 16
148*9880d681SAndroid Build Coastguard Worker  ret void
149*9880d681SAndroid Build Coastguard Worker}
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker; The type <2 x i16> is legalized to <2 x i32> and need to be trunc-stored
152*9880d681SAndroid Build Coastguard Worker; to <2 x i16> when stored to memory.
153*9880d681SAndroid Build Coastguard Workerdefine void @test_vrev64(<4 x i16>* nocapture %source, <2 x i16>* nocapture %dst) nounwind ssp {
154*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_vrev64:
155*9880d681SAndroid Build Coastguard Worker; CHECK: vst1.32
156*9880d681SAndroid Build Coastguard Workerentry:
157*9880d681SAndroid Build Coastguard Worker  %0 = bitcast <4 x i16>* %source to <8 x i16>*
158*9880d681SAndroid Build Coastguard Worker  %tmp2 = load <8 x i16>, <8 x i16>* %0, align 4
159*9880d681SAndroid Build Coastguard Worker  %tmp3 = extractelement <8 x i16> %tmp2, i32 6
160*9880d681SAndroid Build Coastguard Worker  %tmp5 = insertelement <2 x i16> undef, i16 %tmp3, i32 0
161*9880d681SAndroid Build Coastguard Worker  %tmp9 = extractelement <8 x i16> %tmp2, i32 5
162*9880d681SAndroid Build Coastguard Worker  %tmp11 = insertelement <2 x i16> %tmp5, i16 %tmp9, i32 1
163*9880d681SAndroid Build Coastguard Worker  store <2 x i16> %tmp11, <2 x i16>* %dst, align 4
164*9880d681SAndroid Build Coastguard Worker  ret void
165*9880d681SAndroid Build Coastguard Worker}
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker; Test vrev of float4
168*9880d681SAndroid Build Coastguard Workerdefine void @float_vrev64(float* nocapture %source, <4 x float>* nocapture %dest) nounwind noinline ssp {
169*9880d681SAndroid Build Coastguard Worker; CHECK: float_vrev64
170*9880d681SAndroid Build Coastguard Worker; CHECK: vext.32
171*9880d681SAndroid Build Coastguard Worker; CHECK: vrev64.32
172*9880d681SAndroid Build Coastguard Workerentry:
173*9880d681SAndroid Build Coastguard Worker  %0 = bitcast float* %source to <4 x float>*
174*9880d681SAndroid Build Coastguard Worker  %tmp2 = load <4 x float>, <4 x float>* %0, align 4
175*9880d681SAndroid Build Coastguard Worker  %tmp5 = shufflevector <4 x float> <float 0.000000e+00, float undef, float undef, float undef>, <4 x float> %tmp2, <4 x i32> <i32 0, i32 7, i32 0, i32 0>
176*9880d681SAndroid Build Coastguard Worker  %arrayidx8 = getelementptr inbounds <4 x float>, <4 x float>* %dest, i32 11
177*9880d681SAndroid Build Coastguard Worker  store <4 x float> %tmp5, <4 x float>* %arrayidx8, align 4
178*9880d681SAndroid Build Coastguard Worker  ret void
179*9880d681SAndroid Build Coastguard Worker}
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @test_vrev32_bswap(<4 x i32> %source) nounwind {
182*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_vrev32_bswap:
183*9880d681SAndroid Build Coastguard Worker; CHECK: vrev32.8
184*9880d681SAndroid Build Coastguard Worker  %bswap = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %source)
185*9880d681SAndroid Build Coastguard Worker  ret <4 x i32> %bswap
186*9880d681SAndroid Build Coastguard Worker}
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Workerdeclare <4 x i32> @llvm.bswap.v4i32(<4 x i32>) nounwind readnone
189