xref: /llvm-project/llvm/test/CodeGen/AArch64/arm64-ext.ll (revision 61510b51c33464a6bc15e4cf5b1ee07e2e0ec1c9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2; RUN: llc < %s -mtriple=arm64-eabi -global-isel=0 | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3; RUN: llc < %s -mtriple=arm64-eabi -global-isel=1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4
5define <8 x i8> @test_vextd(<8 x i8> %tmp1, <8 x i8> %tmp2) {
6; CHECK-LABEL: test_vextd:
7; CHECK:       // %bb.0:
8; CHECK-NEXT:    ext v0.8b, v0.8b, v1.8b, #3
9; CHECK-NEXT:    ret
10  %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <8 x i32> <i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10>
11  ret <8 x i8> %tmp3
12}
13
14define <8 x i8> @test_vextRd(<8 x i8> %tmp1, <8 x i8> %tmp2) {
15; CHECK-LABEL: test_vextRd:
16; CHECK:       // %bb.0:
17; CHECK-NEXT:    ext v0.8b, v1.8b, v0.8b, #5
18; CHECK-NEXT:    ret
19  %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <8 x i32> <i32 13, i32 14, i32 15, i32 0, i32 1, i32 2, i32 3, i32 4>
20  ret <8 x i8> %tmp3
21}
22
23define <16 x i8> @test_vextq(<16 x i8> %tmp1, <16 x i8> %tmp2) {
24; CHECK-LABEL: test_vextq:
25; CHECK:       // %bb.0:
26; CHECK-NEXT:    ext v0.16b, v0.16b, v1.16b, #3
27; CHECK-NEXT:    ret
28  %tmp3 = shufflevector <16 x i8> %tmp1, <16 x i8> %tmp2, <16 x i32> <i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18>
29  ret <16 x i8> %tmp3
30}
31
32define <16 x i8> @test_vextRq(<16 x i8> %tmp1, <16 x i8> %tmp2) {
33; CHECK-LABEL: test_vextRq:
34; CHECK:       // %bb.0:
35; CHECK-NEXT:    ext v0.16b, v1.16b, v0.16b, #7
36; CHECK-NEXT:    ret
37  %tmp3 = shufflevector <16 x i8> %tmp1, <16 x i8> %tmp2, <16 x i32> <i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6>
38  ret <16 x i8> %tmp3
39}
40
41define <4 x i16> @test_vextd16(<4 x i16> %tmp1, <4 x i16> %tmp2) {
42; CHECK-LABEL: test_vextd16:
43; CHECK:       // %bb.0:
44; CHECK-NEXT:    ext v0.8b, v0.8b, v1.8b, #6
45; CHECK-NEXT:    ret
46  %tmp3 = shufflevector <4 x i16> %tmp1, <4 x i16> %tmp2, <4 x i32> <i32 3, i32 4, i32 5, i32 6>
47  ret <4 x i16> %tmp3
48}
49
50define <4 x i32> @test_vextq32(<4 x i32> %tmp1, <4 x i32> %tmp2) {
51; CHECK-LABEL: test_vextq32:
52; CHECK:       // %bb.0:
53; CHECK-NEXT:    ext v0.16b, v0.16b, v1.16b, #12
54; CHECK-NEXT:    ret
55  %tmp3 = shufflevector <4 x i32> %tmp1, <4 x i32> %tmp2, <4 x i32> <i32 3, i32 4, i32 5, i32 6>
56  ret <4 x i32> %tmp3
57}
58
59; Undef shuffle indices should not prevent matching to VEXT:
60
61define <8 x i8> @test_vextd_undef(<8 x i8> %tmp1, <8 x i8> %tmp2) {
62; CHECK-LABEL: test_vextd_undef:
63; CHECK:       // %bb.0:
64; CHECK-NEXT:    ext v0.8b, v0.8b, v1.8b, #3
65; CHECK-NEXT:    ret
66  %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <8 x i32> <i32 3, i32 undef, i32 undef, i32 6, i32 7, i32 8, i32 9, i32 10>
67  ret <8 x i8> %tmp3
68}
69
70define <8 x i8> @test_vextd_undef2(<8 x i8> %tmp1, <8 x i8> %tmp2) {
71; CHECK-LABEL: test_vextd_undef2:
72; CHECK:       // %bb.0:
73; CHECK-NEXT:    ext v0.8b, v0.8b, v0.8b, #6
74; CHECK-NEXT:    ret
75  %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <8 x i32> <i32 undef, i32 undef, i32 undef, i32 undef, i32 2, i32 3, i32 4, i32 5>
76  ret <8 x i8> %tmp3
77}
78
79define <16 x i8> @test_vextRq_undef(<16 x i8> %tmp1, <16 x i8> %tmp2) {
80; CHECK-LABEL: test_vextRq_undef:
81; CHECK:       // %bb.0:
82; CHECK-NEXT:    ext v0.16b, v1.16b, v0.16b, #7
83; CHECK-NEXT:    ret
84  %tmp3 = shufflevector <16 x i8> %tmp1, <16 x i8> %tmp2, <16 x i32> <i32 23, i32 24, i32 25, i32 26, i32 undef, i32 undef, i32 29, i32 30, i32 31, i32 0, i32 1, i32 2, i32 3, i32 4, i32 undef, i32 6>
85  ret <16 x i8> %tmp3
86}
87
88define <8 x i16> @test_vextRq_undef2(<8 x i16> %tmp1) nounwind {
89; CHECK-LABEL: test_vextRq_undef2:
90; CHECK:       // %bb.0:
91; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #10
92; CHECK-NEXT:    ret
93  %vext = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> <i32 undef, i32 undef, i32 undef, i32 undef, i32 1, i32 2, i32 3, i32 4>
94  ret <8 x i16> %vext;
95}
96
97; Tests for ReconstructShuffle function. Indices have to be carefully
98; chosen to reach lowering phase as a BUILD_VECTOR.
99
100; An undef in the shuffle list should still be optimizable
101define <4 x i16> @test_undef(<8 x i16> %tmp1, <8 x i16> %tmp2) {
102; CHECK-SD-LABEL: test_undef:
103; CHECK-SD:       // %bb.0:
104; CHECK-SD-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
105; CHECK-SD-NEXT:    zip1 v0.4h, v0.4h, v1.4h
106; CHECK-SD-NEXT:    ret
107;
108; CHECK-GI-LABEL: test_undef:
109; CHECK-GI:       // %bb.0:
110; CHECK-GI-NEXT:    adrp x8, .LCPI10_0
111; CHECK-GI-NEXT:    // kill: def $q0 killed $q0 killed $q0_q1 def $q0_q1
112; CHECK-GI-NEXT:    ldr q2, [x8, :lo12:.LCPI10_0]
113; CHECK-GI-NEXT:    // kill: def $q1 killed $q1 killed $q0_q1 def $q0_q1
114; CHECK-GI-NEXT:    tbl v0.16b, { v0.16b, v1.16b }, v2.16b
115; CHECK-GI-NEXT:    // kill: def $d0 killed $d0 killed $q0
116; CHECK-GI-NEXT:    ret
117  %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <4 x i32> <i32 undef, i32 8, i32 5, i32 9>
118  ret <4 x i16> %tmp3
119}
120
121define <2 x i64> @test_v2s64(<2 x i64> %a, <2 x i64> %b) {
122; CHECK-LABEL: test_v2s64:
123; CHECK:       // %bb.0:
124; CHECK-NEXT:    ext v0.16b, v1.16b, v0.16b, #8
125; CHECK-NEXT:    ret
126  %s = shufflevector <2 x i64> %a, <2 x i64> %b, <2 x i32> <i32 3, i32 0>
127  ret <2 x i64> %s
128}
129
130define <2 x ptr> @test_v2p0(<2 x ptr> %a, <2 x ptr> %b) {
131; CHECK-LABEL: test_v2p0:
132; CHECK:       // %bb.0:
133; CHECK-NEXT:    ext v0.16b, v1.16b, v0.16b, #8
134; CHECK-NEXT:    ret
135  %s = shufflevector <2 x ptr> %a, <2 x ptr> %b, <2 x i32> <i32 3, i32 0>
136  ret <2 x ptr> %s
137}
138