[ELF] Reorder SectionBase/InputSectionBase members
[llvm-project.git] / llvm / test / CodeGen / AArch64 / extract-subvec-combine.ll
blob75d55773b3681e7e4826300d6207af229804327f
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3 ; RUN: llc -mtriple=aarch64 -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
5 define <2 x i32> @and_extract_zext_idx0(<4 x i16> %vec) nounwind {
6 ; CHECK-SD-LABEL: and_extract_zext_idx0:
7 ; CHECK-SD:       // %bb.0:
8 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
9 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
10 ; CHECK-SD-NEXT:    ret
12 ; CHECK-GI-LABEL: and_extract_zext_idx0:
13 ; CHECK-GI:       // %bb.0:
14 ; CHECK-GI-NEXT:    movi d1, #0x00ffff0000ffff
15 ; CHECK-GI-NEXT:    ushll v0.4s, v0.4h, #0
16 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v1.8b
17 ; CHECK-GI-NEXT:    ret
18   %zext = zext <4 x i16> %vec to <4 x i32>
19   %extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 0)
20   %and = and <2 x i32> %extract, <i32 65535, i32 65535>
21   ret <2 x i32> %and
24 define <4 x i16> @and_extract_sext_idx0(<8 x i8> %vec) nounwind {
25 ; CHECK-SD-LABEL: and_extract_sext_idx0:
26 ; CHECK-SD:       // %bb.0:
27 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
28 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
29 ; CHECK-SD-NEXT:    ret
31 ; CHECK-GI-LABEL: and_extract_sext_idx0:
32 ; CHECK-GI:       // %bb.0:
33 ; CHECK-GI-NEXT:    movi d1, #0xff00ff00ff00ff
34 ; CHECK-GI-NEXT:    sshll v0.8h, v0.8b, #0
35 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v1.8b
36 ; CHECK-GI-NEXT:    ret
37   %sext = sext <8 x i8> %vec to <8 x i16>
38   %extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 0)
39   %and = and <4 x i16> %extract, <i16 255, i16 255, i16 255, i16 255>
40   ret <4 x i16> %and
43 define <2 x i32> @and_extract_zext_idx2(<4 x i16> %vec) nounwind {
44 ; CHECK-SD-LABEL: and_extract_zext_idx2:
45 ; CHECK-SD:       // %bb.0:
46 ; CHECK-SD-NEXT:    ushll v0.4s, v0.4h, #0
47 ; CHECK-SD-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
48 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
49 ; CHECK-SD-NEXT:    ret
51 ; CHECK-GI-LABEL: and_extract_zext_idx2:
52 ; CHECK-GI:       // %bb.0:
53 ; CHECK-GI-NEXT:    ushll v0.4s, v0.4h, #0
54 ; CHECK-GI-NEXT:    movi d1, #0x00ffff0000ffff
55 ; CHECK-GI-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
56 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v1.8b
57 ; CHECK-GI-NEXT:    ret
58   %zext = zext <4 x i16> %vec to <4 x i32>
59   %extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 2)
60   %and = and <2 x i32> %extract, <i32 65535, i32 65535>
61   ret <2 x i32> %and
64 define <4 x i16> @and_extract_sext_idx4(<8 x i8> %vec) nounwind {
65 ; CHECK-SD-LABEL: and_extract_sext_idx4:
66 ; CHECK-SD:       // %bb.0:
67 ; CHECK-SD-NEXT:    ushll v0.8h, v0.8b, #0
68 ; CHECK-SD-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
69 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
70 ; CHECK-SD-NEXT:    ret
72 ; CHECK-GI-LABEL: and_extract_sext_idx4:
73 ; CHECK-GI:       // %bb.0:
74 ; CHECK-GI-NEXT:    sshll v0.8h, v0.8b, #0
75 ; CHECK-GI-NEXT:    movi d1, #0xff00ff00ff00ff
76 ; CHECK-GI-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
77 ; CHECK-GI-NEXT:    and v0.8b, v0.8b, v1.8b
78 ; CHECK-GI-NEXT:    ret
79   %sext = sext <8 x i8> %vec to <8 x i16>
80   %extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 4)
81   %and = and <4 x i16> %extract, <i16 255, i16 255, i16 255, i16 255>
82   ret <4 x i16> %and
85 define <2 x i32> @sext_extract_zext_idx0(<4 x i16> %vec) nounwind {
86 ; CHECK-SD-LABEL: sext_extract_zext_idx0:
87 ; CHECK-SD:       // %bb.0:
88 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
89 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
90 ; CHECK-SD-NEXT:    ret
92 ; CHECK-GI-LABEL: sext_extract_zext_idx0:
93 ; CHECK-GI:       // %bb.0:
94 ; CHECK-GI-NEXT:    ushll v0.4s, v0.4h, #0
95 ; CHECK-GI-NEXT:    shl v0.2s, v0.2s, #16
96 ; CHECK-GI-NEXT:    sshr v0.2s, v0.2s, #16
97 ; CHECK-GI-NEXT:    ret
98   %zext = zext <4 x i16> %vec to <4 x i32>
99   %extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 0)
100   %sext_inreg_step0 = shl <2 x i32> %extract, <i32 16, i32 16>
101   %sext_inreg = ashr <2 x i32> %sext_inreg_step0, <i32 16, i32 16>
102   ret <2 x i32> %sext_inreg
105 ; Negative test, combine should not fire if sign extension is for a different width.
106 define <2 x i32> @sext_extract_zext_idx0_negtest(<4 x i16> %vec) nounwind {
107 ; CHECK-LABEL: sext_extract_zext_idx0_negtest:
108 ; CHECK:       // %bb.0:
109 ; CHECK-NEXT:    ushll v0.4s, v0.4h, #0
110 ; CHECK-NEXT:    shl v0.2s, v0.2s, #17
111 ; CHECK-NEXT:    sshr v0.2s, v0.2s, #17
112 ; CHECK-NEXT:    ret
113   %zext = zext <4 x i16> %vec to <4 x i32>
114   %extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 0)
115   %sext_inreg_step0 = shl <2 x i32> %extract, <i32 17, i32 17>
116   %sext_inreg = ashr <2 x i32> %sext_inreg_step0, <i32 17, i32 17>
117   ret <2 x i32> %sext_inreg
120 define <4 x i16> @sext_extract_sext_idx0(<8 x i8> %vec) nounwind {
121 ; CHECK-SD-LABEL: sext_extract_sext_idx0:
122 ; CHECK-SD:       // %bb.0:
123 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
124 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
125 ; CHECK-SD-NEXT:    ret
127 ; CHECK-GI-LABEL: sext_extract_sext_idx0:
128 ; CHECK-GI:       // %bb.0:
129 ; CHECK-GI-NEXT:    sshll v0.8h, v0.8b, #0
130 ; CHECK-GI-NEXT:    shl v0.4h, v0.4h, #8
131 ; CHECK-GI-NEXT:    sshr v0.4h, v0.4h, #8
132 ; CHECK-GI-NEXT:    ret
133   %sext = sext <8 x i8> %vec to <8 x i16>
134   %extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 0)
135   %sext_inreg_step0 = shl <4 x i16> %extract, <i16 8, i16 8, i16 8, i16 8>
136   %sext_inreg = ashr <4 x i16> %sext_inreg_step0, <i16 8, i16 8, i16 8, i16 8>
137   ret <4 x i16> %sext_inreg
140 define <2 x i32> @sext_extract_zext_idx2(<4 x i16> %vec) nounwind {
141 ; CHECK-SD-LABEL: sext_extract_zext_idx2:
142 ; CHECK-SD:       // %bb.0:
143 ; CHECK-SD-NEXT:    sshll v0.4s, v0.4h, #0
144 ; CHECK-SD-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
145 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
146 ; CHECK-SD-NEXT:    ret
148 ; CHECK-GI-LABEL: sext_extract_zext_idx2:
149 ; CHECK-GI:       // %bb.0:
150 ; CHECK-GI-NEXT:    ushll v0.4s, v0.4h, #0
151 ; CHECK-GI-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
152 ; CHECK-GI-NEXT:    shl v0.2s, v0.2s, #16
153 ; CHECK-GI-NEXT:    sshr v0.2s, v0.2s, #16
154 ; CHECK-GI-NEXT:    ret
155   %zext = zext <4 x i16> %vec to <4 x i32>
156   %extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 2)
157   %sext_inreg_step0 = shl <2 x i32> %extract, <i32 16, i32 16>
158   %sext_inreg = ashr <2 x i32> %sext_inreg_step0, <i32 16, i32 16>
159   ret <2 x i32> %sext_inreg
162 define <4 x i16> @sext_extract_sext_idx4(<8 x i8> %vec) nounwind {
163 ; CHECK-SD-LABEL: sext_extract_sext_idx4:
164 ; CHECK-SD:       // %bb.0:
165 ; CHECK-SD-NEXT:    sshll v0.8h, v0.8b, #0
166 ; CHECK-SD-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
167 ; CHECK-SD-NEXT:    // kill: def $d0 killed $d0 killed $q0
168 ; CHECK-SD-NEXT:    ret
170 ; CHECK-GI-LABEL: sext_extract_sext_idx4:
171 ; CHECK-GI:       // %bb.0:
172 ; CHECK-GI-NEXT:    sshll v0.8h, v0.8b, #0
173 ; CHECK-GI-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
174 ; CHECK-GI-NEXT:    shl v0.4h, v0.4h, #8
175 ; CHECK-GI-NEXT:    sshr v0.4h, v0.4h, #8
176 ; CHECK-GI-NEXT:    ret
177   %sext = sext <8 x i8> %vec to <8 x i16>
178   %extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 4)
179   %sext_inreg_step0 = shl <4 x i16> %extract, <i16 8, i16 8, i16 8, i16 8>
180   %sext_inreg = ashr <4 x i16> %sext_inreg_step0, <i16 8, i16 8, i16 8, i16 8>
181   ret <4 x i16> %sext_inreg
184 define <8 x i8> @sext_extract_idx(<16 x i8> %vec) nounwind {
185 ; CHECK-LABEL: sext_extract_idx:
186 ; CHECK:       // %bb.0:
187 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
188 ; CHECK-NEXT:    ret
189   %extract = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> %vec, i64 0)
190   ret <8 x i8> %extract
193 declare <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32>, i64)
194 declare <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16>, i64)
195 declare <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8>, i64)