390 lines · plain
1; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck %s2 3; This is the IR generated by Clang's __builtin_shufflevector for two 16x uint8_t vectors.4define <16 x i8> @shuffle16_with_and_mask(<16 x i8> %src, <16 x i8> %mask) {5; CHECK-LABEL: shuffle16_with_and_mask:6; CHECK: // %bb.0:7; CHECK-NEXT: movi.16b v2, #158; CHECK-NEXT: and.16b v1, v1, v29; CHECK-NEXT: tbl.16b v0, { v0 }, v110; CHECK-NEXT: ret11 12 %masked_mask = and <16 x i8> %mask, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>13 %1 = extractelement <16 x i8> %masked_mask, i64 014 %2 = extractelement <16 x i8> %src, i8 %115 %3 = insertelement <16 x i8> undef, i8 %2, i64 016 %4 = extractelement <16 x i8> %masked_mask, i64 117 %5 = extractelement <16 x i8> %src, i8 %418 %6 = insertelement <16 x i8> %3, i8 %5, i64 119 %7 = extractelement <16 x i8> %masked_mask, i64 220 %8 = extractelement <16 x i8> %src, i8 %721 %9 = insertelement <16 x i8> %6, i8 %8, i64 222 %10 = extractelement <16 x i8> %masked_mask, i64 323 %11 = extractelement <16 x i8> %src, i8 %1024 %12 = insertelement <16 x i8> %9, i8 %11, i64 325 %13 = extractelement <16 x i8> %masked_mask, i64 426 %14 = extractelement <16 x i8> %src, i8 %1327 %15 = insertelement <16 x i8> %12, i8 %14, i64 428 %16 = extractelement <16 x i8> %masked_mask, i64 529 %17 = extractelement <16 x i8> %src, i8 %1630 %18 = insertelement <16 x i8> %15, i8 %17, i64 531 %19 = extractelement <16 x i8> %masked_mask, i64 632 %20 = extractelement <16 x i8> %src, i8 %1933 %21 = insertelement <16 x i8> %18, i8 %20, i64 634 %22 = extractelement <16 x i8> %masked_mask, i64 735 %23 = extractelement <16 x i8> %src, i8 %2236 %24 = insertelement <16 x i8> %21, i8 %23, i64 737 %25 = extractelement <16 x i8> %masked_mask, i64 838 %26 = extractelement <16 x i8> %src, i8 %2539 %27 = insertelement <16 x i8> %24, i8 %26, i64 840 %28 = extractelement <16 x i8> %masked_mask, i64 941 %29 = extractelement <16 x i8> %src, i8 %2842 %30 = insertelement <16 x i8> %27, i8 %29, i64 943 %31 = extractelement <16 x i8> %masked_mask, i64 1044 %32 = extractelement <16 x i8> %src, i8 %3145 %33 = insertelement <16 x i8> %30, i8 %32, i64 1046 %34 = extractelement <16 x i8> %masked_mask, i64 1147 %35 = extractelement <16 x i8> %src, i8 %3448 %36 = insertelement <16 x i8> %33, i8 %35, i64 1149 %37 = extractelement <16 x i8> %masked_mask, i64 1250 %38 = extractelement <16 x i8> %src, i8 %3751 %39 = insertelement <16 x i8> %36, i8 %38, i64 1252 %40 = extractelement <16 x i8> %masked_mask, i64 1353 %41 = extractelement <16 x i8> %src, i8 %4054 %42 = insertelement <16 x i8> %39, i8 %41, i64 1355 %43 = extractelement <16 x i8> %masked_mask, i64 1456 %44 = extractelement <16 x i8> %src, i8 %4357 %45 = insertelement <16 x i8> %42, i8 %44, i64 1458 %46 = extractelement <16 x i8> %masked_mask, i64 1559 ; Make sure that ANY_EXTEND is ignored60 %47 = zext i8 %46 to i3261 %48 = extractelement <16 x i8> %src, i32 %4762 %49 = insertelement <16 x i8> %45, i8 %48, i64 1563 ret <16 x i8> %4964}65 66define <8 x i8> @shuffle8_with_and_mask(<8 x i8> %src, <8 x i8> %mask) {67; CHECK-LABEL: shuffle8_with_and_mask:68; CHECK: // %bb.0:69; CHECK-NEXT: movi.8b v2, #770; CHECK-NEXT: // kill: def $d0 killed $d0 def $q071; CHECK-NEXT: and.8b v1, v1, v272; CHECK-NEXT: tbl.8b v0, { v0 }, v173; CHECK-NEXT: ret74 75 %masked_mask = and <8 x i8> %mask, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>76 %1 = extractelement <8 x i8> %masked_mask, i64 077 %2 = extractelement <8 x i8> %src, i8 %178 %3 = insertelement <8 x i8> undef, i8 %2, i64 079 %4 = extractelement <8 x i8> %masked_mask, i64 180 %5 = extractelement <8 x i8> %src, i8 %481 %6 = insertelement <8 x i8> %3, i8 %5, i64 182 %7 = extractelement <8 x i8> %masked_mask, i64 283 %8 = extractelement <8 x i8> %src, i8 %784 %9 = insertelement <8 x i8> %6, i8 %8, i64 285 %10 = extractelement <8 x i8> %masked_mask, i64 386 %11 = extractelement <8 x i8> %src, i8 %1087 %12 = insertelement <8 x i8> %9, i8 %11, i64 388 %13 = extractelement <8 x i8> %masked_mask, i64 489 %14 = extractelement <8 x i8> %src, i8 %1390 %15 = insertelement <8 x i8> %12, i8 %14, i64 491 %16 = extractelement <8 x i8> %masked_mask, i64 592 %17 = extractelement <8 x i8> %src, i8 %1693 %18 = insertelement <8 x i8> %15, i8 %17, i64 594 %19 = extractelement <8 x i8> %masked_mask, i64 695 %20 = extractelement <8 x i8> %src, i8 %1996 %21 = insertelement <8 x i8> %18, i8 %20, i64 697 %22 = extractelement <8 x i8> %masked_mask, i64 798 %23 = extractelement <8 x i8> %src, i8 %2299 %24 = insertelement <8 x i8> %21, i8 %23, i64 7100 ret <8 x i8> %24101}102 103define <8 x i8> @shuffle8_with_and_mask_different_constants(<8 x i8> %src, <8 x i8> %mask) {104; CHECK-LABEL: LCPI2_0:105; CHECK-NEXT: .byte 3106; CHECK-NEXT: .byte 1107; CHECK-NEXT: .byte 7108; CHECK-NEXT: .byte 1109; CHECK-NEXT: .byte 7110; CHECK-NEXT: .byte 3111; CHECK-NEXT: .byte 7112; CHECK-NEXT: .byte 7113 114; CHECK-LABEL: shuffle8_with_and_mask_different_constants:115; CHECK: // %bb.0:116; CHECK-NEXT: adrp x8, .LCPI2_0117; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0118; CHECK-NEXT: ldr d2, [x8, :lo12:.LCPI2_0]119; CHECK-NEXT: and.8b v1, v1, v2120; CHECK-NEXT: tbl.8b v0, { v0 }, v1121; CHECK-NEXT: ret122 123 %masked_mask = and <8 x i8> %mask, <i8 3, i8 1, i8 7, i8 1, i8 7, i8 3, i8 7, i8 7>124 %1 = extractelement <8 x i8> %masked_mask, i64 0125 %2 = extractelement <8 x i8> %src, i8 %1126 %3 = insertelement <8 x i8> undef, i8 %2, i64 0127 %4 = extractelement <8 x i8> %masked_mask, i64 1128 %5 = extractelement <8 x i8> %src, i8 %4129 %6 = insertelement <8 x i8> %3, i8 %5, i64 1130 %7 = extractelement <8 x i8> %masked_mask, i64 2131 %8 = extractelement <8 x i8> %src, i8 %7132 %9 = insertelement <8 x i8> %6, i8 %8, i64 2133 %10 = extractelement <8 x i8> %masked_mask, i64 3134 %11 = extractelement <8 x i8> %src, i8 %10135 %12 = insertelement <8 x i8> %9, i8 %11, i64 3136 %13 = extractelement <8 x i8> %masked_mask, i64 4137 %14 = extractelement <8 x i8> %src, i8 %13138 %15 = insertelement <8 x i8> %12, i8 %14, i64 4139 %16 = extractelement <8 x i8> %masked_mask, i64 5140 %17 = extractelement <8 x i8> %src, i8 %16141 %18 = insertelement <8 x i8> %15, i8 %17, i64 5142 %19 = extractelement <8 x i8> %masked_mask, i64 6143 %20 = extractelement <8 x i8> %src, i8 %19144 %21 = insertelement <8 x i8> %18, i8 %20, i64 6145 %22 = extractelement <8 x i8> %masked_mask, i64 7146 %23 = extractelement <8 x i8> %src, i8 %22147 %24 = insertelement <8 x i8> %21, i8 %23, i64 7148 ret <8 x i8> %24149}150 151define <8 x i8> @shuffle8_with_mask(<8 x i8> %src, <8 x i8> %mask) {152; CHECK-LABEL: shuffle8_with_mask:153; CHECK: // %bb.0:154; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0155; CHECK-NEXT: tbl.8b v0, { v0 }, v1156; CHECK-NEXT: ret157 158 %1 = extractelement <8 x i8> %mask, i64 0159 %2 = extractelement <8 x i8> %src, i8 %1160 %3 = insertelement <8 x i8> undef, i8 %2, i64 0161 %4 = extractelement <8 x i8> %mask, i64 1162 %5 = extractelement <8 x i8> %src, i8 %4163 %6 = insertelement <8 x i8> %3, i8 %5, i64 1164 %7 = extractelement <8 x i8> %mask, i64 2165 %8 = extractelement <8 x i8> %src, i8 %7166 %9 = insertelement <8 x i8> %6, i8 %8, i64 2167 %10 = extractelement <8 x i8> %mask, i64 3168 %11 = extractelement <8 x i8> %src, i8 %10169 %12 = insertelement <8 x i8> %9, i8 %11, i64 3170 %13 = extractelement <8 x i8> %mask, i64 4171 %14 = extractelement <8 x i8> %src, i8 %13172 %15 = insertelement <8 x i8> %12, i8 %14, i64 4173 %16 = extractelement <8 x i8> %mask, i64 5174 %17 = extractelement <8 x i8> %src, i8 %16175 %18 = insertelement <8 x i8> %15, i8 %17, i64 5176 %19 = extractelement <8 x i8> %mask, i64 6177 %20 = extractelement <8 x i8> %src, i8 %19178 %21 = insertelement <8 x i8> %18, i8 %20, i64 6179 %22 = extractelement <8 x i8> %mask, i64 7180 %23 = extractelement <8 x i8> %src, i8 %22181 %24 = insertelement <8 x i8> %21, i8 %23, i64 7182 ret <8 x i8> %24183}184 185define <8 x i8> @no_shuffle_only_some_and_constants(<8 x i8> %src, <8 x i8> %mask) {186; CHECK-LABEL: no_shuffle_only_some_and_constants:187; CHECK: // %bb.0:188; CHECK-NOT: tbl.16b189 190 ; Element at 0 has a AND mask, element at 1 does not.191 %1 = extractelement <8 x i8> %mask, i64 0192 %masked_elt1 = and i8 %1, 7193 %2 = extractelement <8 x i8> %src, i8 %masked_elt1194 %3 = insertelement <8 x i8> undef, i8 %2, i64 0195 %4 = extractelement <8 x i8> %mask, i64 1196 %5 = extractelement <8 x i8> %src, i8 %4197 %6 = insertelement <8 x i8> %3, i8 %5, i64 1198 199 %7 = extractelement <8 x i8> %mask, i64 2200 %8 = extractelement <8 x i8> %src, i8 %7201 %9 = insertelement <8 x i8> %6, i8 %8, i64 2202 %10 = extractelement <8 x i8> %mask, i64 3203 %11 = extractelement <8 x i8> %src, i8 %10204 %12 = insertelement <8 x i8> %9, i8 %11, i64 3205 %13 = extractelement <8 x i8> %mask, i64 4206 %14 = extractelement <8 x i8> %src, i8 %13207 %15 = insertelement <8 x i8> %12, i8 %14, i64 4208 %16 = extractelement <8 x i8> %mask, i64 5209 %17 = extractelement <8 x i8> %src, i8 %16210 %18 = insertelement <8 x i8> %15, i8 %17, i64 5211 %19 = extractelement <8 x i8> %mask, i64 6212 %20 = extractelement <8 x i8> %src, i8 %19213 %21 = insertelement <8 x i8> %18, i8 %20, i64 6214 %22 = extractelement <8 x i8> %mask, i64 7215 %23 = extractelement <8 x i8> %src, i8 %22216 %24 = insertelement <8 x i8> %21, i8 %23, i64 7217 ret <8 x i8> %24218}219 220; Takes alternating entries from two mask source vectors. Currently not supported.221define <16 x i8> @no_shuffle_with_two_mask_sources(<16 x i8> %src, <16 x i8> %mask1, <16 x i8> %mask2) {222; CHECK-LABEL: shuffle_with_two_mask_sources:223; CHECK: // %bb.0:224; CHECK-NOT: tbl.16b225 226 %masked_mask1 = and <16 x i8> %mask1, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>227 %masked_mask2 = and <16 x i8> %mask2, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>228 %1 = extractelement <16 x i8> %masked_mask1, i64 0229 %2 = extractelement <16 x i8> %src, i8 %1230 %3 = insertelement <16 x i8> undef, i8 %2, i64 0231 %4 = extractelement <16 x i8> %masked_mask2, i64 1232 %5 = extractelement <16 x i8> %src, i8 %4233 %6 = insertelement <16 x i8> %3, i8 %5, i64 1234 %7 = extractelement <16 x i8> %masked_mask1, i64 2235 %8 = extractelement <16 x i8> %src, i8 %7236 %9 = insertelement <16 x i8> %6, i8 %8, i64 2237 %10 = extractelement <16 x i8> %masked_mask2, i64 3238 %11 = extractelement <16 x i8> %src, i8 %10239 %12 = insertelement <16 x i8> %9, i8 %11, i64 3240 %13 = extractelement <16 x i8> %masked_mask1, i64 4241 %14 = extractelement <16 x i8> %src, i8 %13242 %15 = insertelement <16 x i8> %12, i8 %14, i64 4243 %16 = extractelement <16 x i8> %masked_mask2, i64 5244 %17 = extractelement <16 x i8> %src, i8 %16245 %18 = insertelement <16 x i8> %15, i8 %17, i64 5246 %19 = extractelement <16 x i8> %masked_mask1, i64 6247 %20 = extractelement <16 x i8> %src, i8 %19248 %21 = insertelement <16 x i8> %18, i8 %20, i64 6249 %22 = extractelement <16 x i8> %masked_mask2, i64 7250 %23 = extractelement <16 x i8> %src, i8 %22251 %24 = insertelement <16 x i8> %21, i8 %23, i64 7252 %25 = extractelement <16 x i8> %masked_mask1, i64 8253 %26 = extractelement <16 x i8> %src, i8 %25254 %27 = insertelement <16 x i8> %24, i8 %26, i64 8255 %28 = extractelement <16 x i8> %masked_mask2, i64 9256 %29 = extractelement <16 x i8> %src, i8 %28257 %30 = insertelement <16 x i8> %27, i8 %29, i64 9258 %31 = extractelement <16 x i8> %masked_mask1, i64 10259 %32 = extractelement <16 x i8> %src, i8 %31260 %33 = insertelement <16 x i8> %30, i8 %32, i64 10261 %34 = extractelement <16 x i8> %masked_mask2, i64 11262 %35 = extractelement <16 x i8> %src, i8 %34263 %36 = insertelement <16 x i8> %33, i8 %35, i64 11264 %37 = extractelement <16 x i8> %masked_mask1, i64 12265 %38 = extractelement <16 x i8> %src, i8 %37266 %39 = insertelement <16 x i8> %36, i8 %38, i64 12267 %40 = extractelement <16 x i8> %masked_mask2, i64 13268 %41 = extractelement <16 x i8> %src, i8 %40269 %42 = insertelement <16 x i8> %39, i8 %41, i64 13270 %43 = extractelement <16 x i8> %masked_mask1, i64 14271 %44 = extractelement <16 x i8> %src, i8 %43272 %45 = insertelement <16 x i8> %42, i8 %44, i64 14273 %46 = extractelement <16 x i8> %masked_mask2, i64 15274 %47 = extractelement <16 x i8> %src, i8 %46275 %48 = insertelement <16 x i8> %45, i8 %47, i64 15276 ret <16 x i8> %48277}278 279; Non-supported vector type.280define <4 x i32> @no_for_shuffle_int_vector(<4 x i32> %src, <4 x i32> %mask) {281; CHECK-LABEL: no_for_shuffle_int_vector:282; CHECK: // %bb.0:283; CHECK-NOT: tbl.16b284 285 %masked_mask = and <4 x i32> %mask, <i32 3, i32 3, i32 3, i32 3>286 %1 = extractelement <4 x i32> %masked_mask, i64 0287 %2 = extractelement <4 x i32> %src, i32 %1288 %3 = insertelement <4 x i32> undef, i32 %2, i64 0289 %4 = extractelement <4 x i32> %masked_mask, i64 1290 %5 = extractelement <4 x i32> %src, i32 %4291 %6 = insertelement <4 x i32> %3, i32 %5, i64 1292 %7 = extractelement <4 x i32> %masked_mask, i64 2293 %8 = extractelement <4 x i32> %src, i32 %7294 %9 = insertelement <4 x i32> %6, i32 %8, i64 2295 %10 = extractelement <4 x i32> %masked_mask, i64 3296 %11 = extractelement <4 x i32> %src, i32 %10297 %12 = insertelement <4 x i32> %9, i32 %11, i64 3298 ret <4 x i32> %12299}300 301define <8 x i8> @no_shuffle_not_enough_elements(<8 x i8> %src, <8 x i8> %mask) {302; CHECK-LABEL: no_shuffle_not_enough_elements:303; CHECK: // %bb.0:304; CHECK-NOT: tbl.16b305 306 %masked_mask = and <8 x i8> %mask, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>307 %1 = extractelement <8 x i8> %masked_mask, i64 0308 %2 = extractelement <8 x i8> %src, i8 %1309 %3 = insertelement <8 x i8> undef, i8 %2, i64 0310 %4 = extractelement <8 x i8> %masked_mask, i64 1311 %5 = extractelement <8 x i8> %src, i8 %4312 %6 = insertelement <8 x i8> %3, i8 %5, i64 1313 %7 = extractelement <8 x i8> %masked_mask, i64 2314 %8 = extractelement <8 x i8> %src, i8 %7315 %9 = insertelement <8 x i8> %6, i8 %8, i64 2316 %10 = extractelement <8 x i8> %masked_mask, i64 3317 %11 = extractelement <8 x i8> %src, i8 %10318 %12 = insertelement <8 x i8> %9, i8 %11, i64 3319 ret <8 x i8> %12320}321 322define <8 x i8> @no_shuffle_different_vector_types(<8 x i8> %src, <16 x i8> %mask) {323; CHECK-LABEL: no_shuffle_different_vector_types:324; CHECK: // %bb.0:325; CHECK-NOT: tbl.16b326 327 %masked_mask = and <16 x i8> %mask, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>328 %1 = extractelement <16 x i8> %masked_mask, i64 0329 %2 = extractelement <8 x i8> %src, i8 %1330 %3 = insertelement <8 x i8> undef, i8 %2, i64 0331 %4 = extractelement <16 x i8> %masked_mask, i64 1332 %5 = extractelement <8 x i8> %src, i8 %4333 %6 = insertelement <8 x i8> %3, i8 %5, i64 1334 %7 = extractelement <16 x i8> %masked_mask, i64 2335 %8 = extractelement <8 x i8> %src, i8 %7336 %9 = insertelement <8 x i8> %6, i8 %8, i64 2337 %10 = extractelement <16 x i8> %masked_mask, i64 3338 %11 = extractelement <8 x i8> %src, i8 %10339 %12 = insertelement <8 x i8> %9, i8 %11, i64 3340 %13 = extractelement <16 x i8> %masked_mask, i64 4341 %14 = extractelement <8 x i8> %src, i8 %13342 %15 = insertelement <8 x i8> %12, i8 %14, i64 4343 %16 = extractelement <16 x i8> %masked_mask, i64 5344 %17 = extractelement <8 x i8> %src, i8 %16345 %18 = insertelement <8 x i8> %15, i8 %17, i64 5346 %19 = extractelement <16 x i8> %masked_mask, i64 6347 %20 = extractelement <8 x i8> %src, i8 %19348 %21 = insertelement <8 x i8> %18, i8 %20, i64 6349 %22 = extractelement <16 x i8> %masked_mask, i64 7350 %23 = extractelement <8 x i8> %src, i8 %22351 %24 = insertelement <8 x i8> %21, i8 %23, i64 7352 ret <8 x i8> %24353}354 355define <8 x i8> @no_shuffle_bad_mask_index(<8 x i8> %src, <8 x i8> %mask) {356; CHECK-LABEL: no_shuffle_bad_mask_index:357; CHECK: // %bb.0:358; CHECK-NOT: tbl.16b359 360 %masked_mask = and <8 x i8> %mask, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>361 362 ; This should extract at 0, but because it extracts at 1, the pattern does not match.363 %1 = extractelement <8 x i8> %masked_mask, i64 1364 365 %2 = extractelement <8 x i8> %src, i8 %1366 %3 = insertelement <8 x i8> undef, i8 %2, i64 0367 %4 = extractelement <8 x i8> %masked_mask, i64 1368 %5 = extractelement <8 x i8> %src, i8 %4369 %6 = insertelement <8 x i8> %3, i8 %5, i64 1370 %7 = extractelement <8 x i8> %masked_mask, i64 2371 %8 = extractelement <8 x i8> %src, i8 %7372 %9 = insertelement <8 x i8> %6, i8 %8, i64 2373 %10 = extractelement <8 x i8> %masked_mask, i64 3374 %11 = extractelement <8 x i8> %src, i8 %10375 %12 = insertelement <8 x i8> %9, i8 %11, i64 3376 %13 = extractelement <8 x i8> %masked_mask, i64 4377 %14 = extractelement <8 x i8> %src, i8 %13378 %15 = insertelement <8 x i8> %12, i8 %14, i64 4379 %16 = extractelement <8 x i8> %masked_mask, i64 5380 %17 = extractelement <8 x i8> %src, i8 %16381 %18 = insertelement <8 x i8> %15, i8 %17, i64 5382 %19 = extractelement <8 x i8> %masked_mask, i64 6383 %20 = extractelement <8 x i8> %src, i8 %19384 %21 = insertelement <8 x i8> %18, i8 %20, i64 6385 %22 = extractelement <8 x i8> %masked_mask, i64 7386 %23 = extractelement <8 x i8> %src, i8 %22387 %24 = insertelement <8 x i8> %21, i8 %23, i64 7388 ret <8 x i8> %24389}390