362 lines · plain
1; RUN: opt -mattr=+simd128 -passes=loop-vectorize %s | llc -mtriple=wasm32 -mattr=+simd128 -verify-machineinstrs -o - | FileCheck %s2 3target triple = "wasm32"4target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"5 6%struct.Output32x2 = type { i32, i32 }7%struct.Input8x2 = type { i8, i8 }8%struct.Output32x4 = type { i32, i32, i32, i32 }9%struct.Input8x4 = type { i8, i8, i8, i8 }10%struct.Input16x2 = type { i16, i16 }11%struct.Input16x4 = type { i16, i16, i16, i16 }12%struct.Input32x2 = type { i32, i32 }13%struct.Input32x4 = type { i32, i32, i32, i32 }14 15; Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite)16define hidden void @accumulate8x2(ptr dead_on_unwind noalias writable sret(%struct.Output32x2) align 4 captures(none) %0, ptr noundef readonly captures(none) %1, i32 noundef %2) local_unnamed_addr #0 {17; CHECK-LABEL: accumulate8x2:18; CHECK: loop19; CHECK: v128.load64_zero20; CHECK: i8x16.shuffle 1, 3, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 021; CHECK: i16x8.extend_low_i8x16_u22; CHECK: i32x4.extend_low_i16x8_u23; CHECK: i32x4.add24; CHECK: i8x16.shuffle 0, 2, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 025; CHECK: i16x8.extend_low_i8x16_u26; CHECK: i32x4.extend_low_i16x8_u27; CHECK: i32x4.add28 %4 = load i32, ptr %0, align 429 %5 = icmp eq i32 %2, 030 br i1 %5, label %10, label %631 326: ; preds = %333 %7 = getelementptr inbounds nuw i8, ptr %0, i32 434 %8 = load i32, ptr %7, align 435 br label %1236 379: ; preds = %1238 store i32 %23, ptr %7, align 439 br label %1040 4110: ; preds = %9, %342 %11 = phi i32 [ %21, %9 ], [ %4, %3 ]43 store i32 %11, ptr %0, align 444 ret void45 4612: ; preds = %6, %1247 %13 = phi i32 [ %8, %6 ], [ %23, %12 ]48 %14 = phi i32 [ 0, %6 ], [ %24, %12 ]49 %15 = phi i32 [ %4, %6 ], [ %21, %12 ]50 %16 = getelementptr inbounds nuw %struct.Input8x2, ptr %1, i32 %1451 %17 = load i8, ptr %16, align 152 %18 = getelementptr inbounds nuw i8, ptr %16, i32 153 %19 = load i8, ptr %18, align 154 %20 = zext i8 %17 to i3255 %21 = add i32 %15, %2056 %22 = zext i8 %19 to i3257 %23 = add i32 %13, %2258 %24 = add nuw i32 %14, 159 %25 = icmp eq i32 %24, %260 br i1 %25, label %9, label %1261}62 63; Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite)64define hidden void @accumulate8x4(ptr dead_on_unwind noalias writable sret(%struct.Output32x4) align 4 captures(none) %0, ptr noundef readonly captures(none) %1, i32 noundef %2) local_unnamed_addr #0 {65; CHECK-LABEL: accumulate8x466; CHECK: loop67; CHECK: v128.load68; CHECK: i8x16.shuffle 3, 7, 11, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 069; CHECK: i16x8.extend_low_i8x16_u70; CHECK: i32x4.extend_low_i16x8_u71; CHECK: i32x4.add72; CHECK: i8x16.shuffle 2, 6, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 073; CHECK: i16x8.extend_low_i8x16_u74; CHECK: i32x4.extend_low_i16x8_u75; CHECK: i32x4.add76; CHECK: i8x16.shuffle 1, 5, 9, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 077; CHECK: i16x8.extend_low_i8x16_u78; CHECK: i32x4.extend_low_i16x8_u79; CHECK: i32x4.add80; CHECK: i8x16.shuffle 0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 081; CHECK: i16x8.extend_low_i8x16_u82; CHECK: i32x4.extend_low_i16x8_u83; CHECK: i32x4.add84 %4 = load i32, ptr %0, align 485 %5 = icmp eq i32 %2, 086 br i1 %5, label %14, label %687 886: ; preds = %389 %7 = getelementptr inbounds nuw i8, ptr %0, i32 490 %8 = getelementptr inbounds nuw i8, ptr %0, i32 891 %9 = getelementptr inbounds nuw i8, ptr %0, i32 1292 %10 = load i32, ptr %7, align 493 %11 = load i32, ptr %8, align 494 %12 = load i32, ptr %9, align 495 br label %1696 9713: ; preds = %1698 store i32 %33, ptr %7, align 499 store i32 %35, ptr %8, align 4100 store i32 %37, ptr %9, align 4101 br label %14102 10314: ; preds = %13, %3104 %15 = phi i32 [ %31, %13 ], [ %4, %3 ]105 store i32 %15, ptr %0, align 4106 ret void107 10816: ; preds = %6, %16109 %17 = phi i32 [ %12, %6 ], [ %37, %16 ]110 %18 = phi i32 [ %11, %6 ], [ %35, %16 ]111 %19 = phi i32 [ %10, %6 ], [ %33, %16 ]112 %20 = phi i32 [ 0, %6 ], [ %38, %16 ]113 %21 = phi i32 [ %4, %6 ], [ %31, %16 ]114 %22 = getelementptr inbounds nuw %struct.Input8x4, ptr %1, i32 %20115 %23 = load i8, ptr %22, align 1116 %24 = getelementptr inbounds nuw i8, ptr %22, i32 1117 %25 = load i8, ptr %24, align 1118 %26 = getelementptr inbounds nuw i8, ptr %22, i32 2119 %27 = load i8, ptr %26, align 1120 %28 = getelementptr inbounds nuw i8, ptr %22, i32 3121 %29 = load i8, ptr %28, align 1122 %30 = zext i8 %23 to i32123 %31 = add i32 %21, %30124 %32 = zext i8 %25 to i32125 %33 = add i32 %19, %32126 %34 = zext i8 %27 to i32127 %35 = add i32 %18, %34128 %36 = zext i8 %29 to i32129 %37 = add i32 %17, %36130 %38 = add nuw i32 %20, 1131 %39 = icmp eq i32 %38, %2132 br i1 %39, label %13, label %16133}134 135; Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite)136define hidden void @accumulate16x2(ptr dead_on_unwind noalias writable sret(%struct.Output32x2) align 4 captures(none) %0, ptr noundef readonly captures(none) %1, i32 noundef %2) local_unnamed_addr #0 {137; CHECK-LABEL: accumulate16x2138; CHECK: loop139; CHECK: v128.load140; CHECK: i8x16.shuffle 2, 3, 6, 7, 10, 11, 14, 15, 0, 1, 0, 1, 0, 1, 0, 1141; CHECK: i32x4.extend_low_i16x8_u142; CHECK: i32x4.add143; CHECK: i8x16.shuffle 0, 1, 4, 5, 8, 9, 12, 13, 0, 1, 0, 1, 0, 1, 0, 1144; CHECK: i32x4.extend_low_i16x8_u145; CHECK: i32x4.add146 %4 = load i32, ptr %0, align 4147 %5 = icmp eq i32 %2, 0148 br i1 %5, label %10, label %6149 1506: ; preds = %3151 %7 = getelementptr inbounds nuw i8, ptr %0, i32 4152 %8 = load i32, ptr %7, align 4153 br label %12154 1559: ; preds = %12156 store i32 %23, ptr %7, align 4157 br label %10158 15910: ; preds = %9, %3160 %11 = phi i32 [ %21, %9 ], [ %4, %3 ]161 store i32 %11, ptr %0, align 4162 ret void163 16412: ; preds = %6, %12165 %13 = phi i32 [ %8, %6 ], [ %23, %12 ]166 %14 = phi i32 [ 0, %6 ], [ %24, %12 ]167 %15 = phi i32 [ %4, %6 ], [ %21, %12 ]168 %16 = getelementptr inbounds nuw %struct.Input16x2, ptr %1, i32 %14169 %17 = load i16, ptr %16, align 2170 %18 = getelementptr inbounds nuw i8, ptr %16, i32 2171 %19 = load i16, ptr %18, align 2172 %20 = zext i16 %17 to i32173 %21 = add i32 %15, %20174 %22 = zext i16 %19 to i32175 %23 = add i32 %13, %22176 %24 = add nuw i32 %14, 1177 %25 = icmp eq i32 %24, %2178 br i1 %25, label %9, label %12179}180 181; Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite)182define hidden void @accumulate16x4(ptr dead_on_unwind noalias writable sret(%struct.Output32x4) align 4 captures(none) %0, ptr noundef readonly captures(none) %1, i32 noundef %2) local_unnamed_addr #0 {183; CHECK-LABEL: accumulate16x4184; CHECK: loop185; CHECK: v128.load 0:p2align=1186; CHECK: v128.load 16:p2align=1187; CHECK: i8x16.shuffle 6, 7, 14, 15, 22, 23, 30, 31, 0, 1, 0, 1, 0, 1, 0, 1188; CHECK: i32x4.extend_low_i16x8_u189; CHECK: i32x4.add190; CHECK: i8x16.shuffle 4, 5, 12, 13, 20, 21, 28, 29, 0, 1, 0, 1, 0, 1, 0, 1191; CHECK: i32x4.extend_low_i16x8_u192; CHECK: i32x4.add193; CHECK: i8x16.shuffle 2, 3, 10, 11, 18, 19, 26, 27, 0, 1, 0, 1, 0, 1, 0, 1194; CHECK: i32x4.extend_low_i16x8_u195; CHECK: i32x4.add196; CHECK: i8x16.shuffle 0, 1, 8, 9, 16, 17, 24, 25, 0, 1, 0, 1, 0, 1, 0, 1197; CHECK: i32x4.extend_low_i16x8_u198; CHECK: i32x4.add199 %4 = load i32, ptr %0, align 4200 %5 = icmp eq i32 %2, 0201 br i1 %5, label %14, label %6202 2036: ; preds = %3204 %7 = getelementptr inbounds nuw i8, ptr %0, i32 4205 %8 = getelementptr inbounds nuw i8, ptr %0, i32 8206 %9 = getelementptr inbounds nuw i8, ptr %0, i32 12207 %10 = load i32, ptr %7, align 4208 %11 = load i32, ptr %8, align 4209 %12 = load i32, ptr %9, align 4210 br label %16211 21213: ; preds = %16213 store i32 %33, ptr %7, align 4214 store i32 %35, ptr %8, align 4215 store i32 %37, ptr %9, align 4216 br label %14217 21814: ; preds = %13, %3219 %15 = phi i32 [ %31, %13 ], [ %4, %3 ]220 store i32 %15, ptr %0, align 4221 ret void222 22316: ; preds = %6, %16224 %17 = phi i32 [ %12, %6 ], [ %37, %16 ]225 %18 = phi i32 [ %11, %6 ], [ %35, %16 ]226 %19 = phi i32 [ %10, %6 ], [ %33, %16 ]227 %20 = phi i32 [ 0, %6 ], [ %38, %16 ]228 %21 = phi i32 [ %4, %6 ], [ %31, %16 ]229 %22 = getelementptr inbounds nuw %struct.Input16x4, ptr %1, i32 %20230 %23 = load i16, ptr %22, align 2231 %24 = getelementptr inbounds nuw i8, ptr %22, i32 2232 %25 = load i16, ptr %24, align 2233 %26 = getelementptr inbounds nuw i8, ptr %22, i32 4234 %27 = load i16, ptr %26, align 2235 %28 = getelementptr inbounds nuw i8, ptr %22, i32 6236 %29 = load i16, ptr %28, align 2237 %30 = zext i16 %23 to i32238 %31 = add i32 %21, %30239 %32 = zext i16 %25 to i32240 %33 = add i32 %19, %32241 %34 = zext i16 %27 to i32242 %35 = add i32 %18, %34243 %36 = zext i16 %29 to i32244 %37 = add i32 %17, %36245 %38 = add nuw i32 %20, 1246 %39 = icmp eq i32 %38, %2247 br i1 %39, label %13, label %16248}249 250; Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite)251define hidden void @accumulate32x2(ptr dead_on_unwind noalias writable sret(%struct.Output32x2) align 4 captures(none) %0, ptr noundef readonly captures(none) %1, i32 noundef %2) local_unnamed_addr #0 {252; CHECK-LABEL: accumulate32x2253; CHECK: loop254; CHECK: v128.load 0:p2align=2255; CHECK: v128.load 16:p2align=2256; CHECK: i8x16.shuffle 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31257; CHECK: i32x4.add258; CHECK: i8x16.shuffle 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27259; CHECK: i32x4.add260 %4 = load i32, ptr %0, align 4261 %5 = icmp eq i32 %2, 0262 br i1 %5, label %10, label %6263 2646: ; preds = %3265 %7 = getelementptr inbounds nuw i8, ptr %0, i32 4266 %8 = load i32, ptr %7, align 4267 br label %12268 2699: ; preds = %12270 store i32 %21, ptr %7, align 4271 br label %10272 27310: ; preds = %9, %3274 %11 = phi i32 [ %20, %9 ], [ %4, %3 ]275 store i32 %11, ptr %0, align 4276 ret void277 27812: ; preds = %6, %12279 %13 = phi i32 [ %8, %6 ], [ %21, %12 ]280 %14 = phi i32 [ 0, %6 ], [ %22, %12 ]281 %15 = phi i32 [ %4, %6 ], [ %20, %12 ]282 %16 = getelementptr inbounds nuw %struct.Input32x2, ptr %1, i32 %14283 %17 = load i32, ptr %16, align 4284 %18 = getelementptr inbounds nuw i8, ptr %16, i32 4285 %19 = load i32, ptr %18, align 4286 %20 = add i32 %15, %17287 %21 = add i32 %13, %19288 %22 = add nuw i32 %14, 1289 %23 = icmp eq i32 %22, %2290 br i1 %23, label %9, label %12291}292 293; Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite)294define hidden void @accumulate32x4(ptr dead_on_unwind noalias writable sret(%struct.Output32x4) align 4 captures(none) %0, ptr noundef readonly captures(none) %1, i32 noundef %2) local_unnamed_addr #0 {295; CHECK-LABEL: accumulate32x4296; CHECK: v128.load 0:p2align=2297; CHECK: v128.load 16:p2align=2298; CHECK: i8x16.shuffle 12, 13, 14, 15, 28, 29, 30, 31, 0, 1, 2, 3, 0, 1, 2, 3299; CHECK: v128.load 32:p2align=2300; CHECK: v128.load 48:p2align=2301; CHECK: i8x16.shuffle 0, 1, 2, 3, 0, 1, 2, 3, 12, 13, 14, 15, 28, 29, 30, 31302; CHECK: i8x16.shuffle 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31303; CHECK: i32x4.add304; CHECK: i8x16.shuffle 8, 9, 10, 11, 24, 25, 26, 27, 0, 1, 2, 3, 0, 1, 2, 3305; CHECK: i8x16.shuffle 0, 1, 2, 3, 0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27306; CHECK: i8x16.shuffle 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31307; CHECK: i32x4.add308; CHECK: i8x16.shuffle 4, 5, 6, 7, 20, 21, 22, 23, 0, 1, 2, 3, 0, 1, 2, 3309; CHECK: i8x16.shuffle 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23310; CHECK: i8x16.shuffle 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31311; CHECK: i32x4.add312; CHECK: i8x16.shuffle 0, 1, 2, 3, 16, 17, 18, 19, 0, 1, 2, 3, 0, 1, 2, 3313; CHECK: i8x16.shuffle 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 16, 17, 18, 19314; CHECK: i8x16.shuffle 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31315; CHECK: i32x4.add316 %4 = load i32, ptr %0, align 4317 %5 = icmp eq i32 %2, 0318 br i1 %5, label %14, label %6319 3206: ; preds = %3321 %7 = getelementptr inbounds nuw i8, ptr %0, i32 4322 %8 = getelementptr inbounds nuw i8, ptr %0, i32 8323 %9 = getelementptr inbounds nuw i8, ptr %0, i32 12324 %10 = load i32, ptr %7, align 4325 %11 = load i32, ptr %8, align 4326 %12 = load i32, ptr %9, align 4327 br label %16328 32913: ; preds = %16330 store i32 %31, ptr %7, align 4331 store i32 %32, ptr %8, align 4332 store i32 %33, ptr %9, align 4333 br label %14334 33514: ; preds = %13, %3336 %15 = phi i32 [ %30, %13 ], [ %4, %3 ]337 store i32 %15, ptr %0, align 4338 ret void339 34016: ; preds = %6, %16341 %17 = phi i32 [ %12, %6 ], [ %33, %16 ]342 %18 = phi i32 [ %11, %6 ], [ %32, %16 ]343 %19 = phi i32 [ %10, %6 ], [ %31, %16 ]344 %20 = phi i32 [ 0, %6 ], [ %34, %16 ]345 %21 = phi i32 [ %4, %6 ], [ %30, %16 ]346 %22 = getelementptr inbounds nuw %struct.Input32x4, ptr %1, i32 %20347 %23 = load i32, ptr %22, align 4348 %24 = getelementptr inbounds nuw i8, ptr %22, i32 4349 %25 = load i32, ptr %24, align 4350 %26 = getelementptr inbounds nuw i8, ptr %22, i32 8351 %27 = load i32, ptr %26, align 4352 %28 = getelementptr inbounds nuw i8, ptr %22, i32 12353 %29 = load i32, ptr %28, align 4354 %30 = add i32 %21, %23355 %31 = add i32 %19, %25356 %32 = add i32 %18, %27357 %33 = add i32 %17, %29358 %34 = add nuw i32 %20, 1359 %35 = icmp eq i32 %34, %2360 br i1 %35, label %13, label %16361}362