1776 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-none-linux-gnu < %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5define void @matrix_mul_unsigned(i32 %N, ptr nocapture %C, ptr nocapture readonly %A, i16 %val) {6; CHECK-SD-LABEL: matrix_mul_unsigned:7; CHECK-SD: // %bb.0: // %vector.header8; CHECK-SD-NEXT: dup v0.4h, w39; CHECK-SD-NEXT: // kill: def $w0 killed $w0 def $x010; CHECK-SD-NEXT: and x8, x0, #0xfffffff811; CHECK-SD-NEXT: .LBB0_1: // %vector.body12; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=113; CHECK-SD-NEXT: add x9, x2, w0, uxtw #114; CHECK-SD-NEXT: subs x8, x8, #815; CHECK-SD-NEXT: ldp d1, d2, [x9]16; CHECK-SD-NEXT: add x9, x1, w0, uxtw #217; CHECK-SD-NEXT: add w0, w0, #818; CHECK-SD-NEXT: umull v1.4s, v0.4h, v1.4h19; CHECK-SD-NEXT: umull v2.4s, v0.4h, v2.4h20; CHECK-SD-NEXT: stp q1, q2, [x9]21; CHECK-SD-NEXT: b.ne .LBB0_122; CHECK-SD-NEXT: // %bb.2: // %for.end1223; CHECK-SD-NEXT: ret24;25; CHECK-GI-LABEL: matrix_mul_unsigned:26; CHECK-GI: // %bb.0: // %vector.header27; CHECK-GI-NEXT: and w8, w3, #0xffff28; CHECK-GI-NEXT: dup v0.4s, w829; CHECK-GI-NEXT: mov w8, w030; CHECK-GI-NEXT: and x8, x8, #0xfffffff831; CHECK-GI-NEXT: xtn v0.4h, v0.4s32; CHECK-GI-NEXT: .LBB0_1: // %vector.body33; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=134; CHECK-GI-NEXT: add x9, x2, w0, uxtw #135; CHECK-GI-NEXT: subs x8, x8, #836; CHECK-GI-NEXT: ldp d1, d2, [x9]37; CHECK-GI-NEXT: add x9, x1, w0, uxtw #238; CHECK-GI-NEXT: add w0, w0, #839; CHECK-GI-NEXT: umull v1.4s, v0.4h, v1.4h40; CHECK-GI-NEXT: umull v2.4s, v0.4h, v2.4h41; CHECK-GI-NEXT: stp q1, q2, [x9]42; CHECK-GI-NEXT: b.ne .LBB0_143; CHECK-GI-NEXT: // %bb.2: // %for.end1244; CHECK-GI-NEXT: ret45vector.header:46 %conv4 = zext i16 %val to i3247 %wide.trip.count = zext i32 %N to i6448 %0 = add nsw i64 %wide.trip.count, -149 %min.iters.check = icmp ult i32 %N, 850 %1 = trunc i64 %0 to i3251 %2 = icmp ugt i64 %0, 429496729552 %n.vec = and i64 %wide.trip.count, 429496728853 %broadcast.splatinsert = insertelement <4 x i32> undef, i32 %conv4, i32 054 %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer55 %broadcast.splatinsert31 = insertelement <4 x i32> undef, i32 %conv4, i32 056 %broadcast.splat32 = shufflevector <4 x i32> %broadcast.splatinsert31, <4 x i32> undef, <4 x i32> zeroinitializer57 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count58 br label %vector.body59 60vector.body: ; preds = %vector.header, %vector.body61 %index = phi i64 [ %index.next, %vector.body ], [ 0, %vector.header ]62 %3 = trunc i64 %index to i3263 %4 = add i32 %N, %364 %5 = zext i32 %4 to i6465 %6 = getelementptr inbounds i16, ptr %A, i64 %566 %7 = bitcast ptr %6 to ptr67 %wide.load = load <4 x i16>, ptr %7, align 268 %8 = getelementptr inbounds i16, ptr %6, i64 469 %9 = bitcast ptr %8 to ptr70 %wide.load30 = load <4 x i16>, ptr %9, align 271 %10 = zext <4 x i16> %wide.load to <4 x i32>72 %11 = zext <4 x i16> %wide.load30 to <4 x i32>73 %12 = mul nuw nsw <4 x i32> %broadcast.splat, %1074 %13 = mul nuw nsw <4 x i32> %broadcast.splat32, %1175 %14 = getelementptr inbounds i32, ptr %C, i64 %576 %15 = bitcast ptr %14 to ptr77 store <4 x i32> %12, ptr %15, align 478 %16 = getelementptr inbounds i32, ptr %14, i64 479 %17 = bitcast ptr %16 to ptr80 store <4 x i32> %13, ptr %17, align 481 %index.next = add i64 %index, 882 %18 = icmp eq i64 %index.next, %n.vec83 br i1 %18, label %for.end12, label %vector.body84 85for.end12: ; preds = %vector.body86 ret void87}88 89define void @matrix_mul_signed(i32 %N, ptr nocapture %C, ptr nocapture readonly %A, i16 %val) {90; CHECK-SD-LABEL: matrix_mul_signed:91; CHECK-SD: // %bb.0: // %vector.header92; CHECK-SD-NEXT: dup v0.4h, w393; CHECK-SD-NEXT: // kill: def $w0 killed $w0 def $x094; CHECK-SD-NEXT: and x8, x0, #0xfffffff895; CHECK-SD-NEXT: .LBB1_1: // %vector.body96; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=197; CHECK-SD-NEXT: add x9, x2, w0, sxtw #198; CHECK-SD-NEXT: subs x8, x8, #899; CHECK-SD-NEXT: ldp d1, d2, [x9]100; CHECK-SD-NEXT: add x9, x1, w0, sxtw #2101; CHECK-SD-NEXT: add w0, w0, #8102; CHECK-SD-NEXT: smull v1.4s, v0.4h, v1.4h103; CHECK-SD-NEXT: smull v2.4s, v0.4h, v2.4h104; CHECK-SD-NEXT: stp q1, q2, [x9]105; CHECK-SD-NEXT: b.ne .LBB1_1106; CHECK-SD-NEXT: // %bb.2: // %for.end12107; CHECK-SD-NEXT: ret108;109; CHECK-GI-LABEL: matrix_mul_signed:110; CHECK-GI: // %bb.0: // %vector.header111; CHECK-GI-NEXT: sxth w8, w3112; CHECK-GI-NEXT: // kill: def $w0 killed $w0 def $x0113; CHECK-GI-NEXT: dup v0.4s, w8114; CHECK-GI-NEXT: sxtw x8, w0115; CHECK-GI-NEXT: and x8, x8, #0xfffffff8116; CHECK-GI-NEXT: xtn v0.4h, v0.4s117; CHECK-GI-NEXT: .LBB1_1: // %vector.body118; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1119; CHECK-GI-NEXT: add x9, x2, w0, sxtw #1120; CHECK-GI-NEXT: subs x8, x8, #8121; CHECK-GI-NEXT: ldp d1, d2, [x9]122; CHECK-GI-NEXT: add x9, x1, w0, sxtw #2123; CHECK-GI-NEXT: add w0, w0, #8124; CHECK-GI-NEXT: smull v1.4s, v0.4h, v1.4h125; CHECK-GI-NEXT: smull v2.4s, v0.4h, v2.4h126; CHECK-GI-NEXT: stp q1, q2, [x9]127; CHECK-GI-NEXT: b.ne .LBB1_1128; CHECK-GI-NEXT: // %bb.2: // %for.end12129; CHECK-GI-NEXT: ret130vector.header:131 %conv4 = sext i16 %val to i32132 %wide.trip.count = sext i32 %N to i64133 %0 = add nsw i64 %wide.trip.count, -1134 %min.iters.check = icmp ult i32 %N, 8135 %1 = trunc i64 %0 to i32136 %2 = icmp ugt i64 %0, 4294967295137 %n.vec = and i64 %wide.trip.count, 4294967288138 %broadcast.splatinsert = insertelement <4 x i32> undef, i32 %conv4, i32 0139 %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer140 %broadcast.splatinsert31 = insertelement <4 x i32> undef, i32 %conv4, i32 0141 %broadcast.splat32 = shufflevector <4 x i32> %broadcast.splatinsert31, <4 x i32> undef, <4 x i32> zeroinitializer142 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count143 br label %vector.body144 145vector.body: ; preds = %vector.header, %vector.body146 %index = phi i64 [ %index.next, %vector.body ], [ 0, %vector.header ]147 %3 = trunc i64 %index to i32148 %4 = add i32 %N, %3149 %5 = sext i32 %4 to i64150 %6 = getelementptr inbounds i16, ptr %A, i64 %5151 %7 = bitcast ptr %6 to ptr152 %wide.load = load <4 x i16>, ptr %7, align 2153 %8 = getelementptr inbounds i16, ptr %6, i64 4154 %9 = bitcast ptr %8 to ptr155 %wide.load30 = load <4 x i16>, ptr %9, align 2156 %10 = sext <4 x i16> %wide.load to <4 x i32>157 %11 = sext <4 x i16> %wide.load30 to <4 x i32>158 %12 = mul nsw <4 x i32> %broadcast.splat, %10159 %13 = mul nsw <4 x i32> %broadcast.splat32, %11160 %14 = getelementptr inbounds i32, ptr %C, i64 %5161 %15 = bitcast ptr %14 to ptr162 store <4 x i32> %12, ptr %15, align 4163 %16 = getelementptr inbounds i32, ptr %14, i64 4164 %17 = bitcast ptr %16 to ptr165 store <4 x i32> %13, ptr %17, align 4166 %index.next = add i64 %index, 8167 %18 = icmp eq i64 %index.next, %n.vec168 br i1 %18, label %for.end12, label %vector.body169 170for.end12: ; preds = %vector.body171 ret void172}173 174 175define void @matrix_mul_double_shuffle(i32 %N, ptr nocapture %C, ptr nocapture readonly %A, i16 %val) {176; CHECK-SD-LABEL: matrix_mul_double_shuffle:177; CHECK-SD: // %bb.0: // %vector.header178; CHECK-SD-NEXT: dup v0.4h, w3179; CHECK-SD-NEXT: // kill: def $w0 killed $w0 def $x0180; CHECK-SD-NEXT: and x8, x0, #0xfffffff8181; CHECK-SD-NEXT: // kill: def $w0 killed $w0 killed $x0 def $x0182; CHECK-SD-NEXT: .LBB2_1: // %vector.body183; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1184; CHECK-SD-NEXT: ldrh w9, [x2], #16185; CHECK-SD-NEXT: subs x8, x8, #8186; CHECK-SD-NEXT: dup v1.4h, w9187; CHECK-SD-NEXT: ubfiz x9, x0, #2, #32188; CHECK-SD-NEXT: add w0, w0, #8189; CHECK-SD-NEXT: umull v1.4s, v0.4h, v1.4h190; CHECK-SD-NEXT: str q1, [x1, x9]191; CHECK-SD-NEXT: b.ne .LBB2_1192; CHECK-SD-NEXT: // %bb.2: // %for.end12193; CHECK-SD-NEXT: ret194;195; CHECK-GI-LABEL: matrix_mul_double_shuffle:196; CHECK-GI: // %bb.0: // %vector.header197; CHECK-GI-NEXT: and w9, w3, #0xffff198; CHECK-GI-NEXT: adrp x8, .LCPI2_0199; CHECK-GI-NEXT: dup v0.4s, w9200; CHECK-GI-NEXT: mov w9, w0201; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI2_0]202; CHECK-GI-NEXT: and x8, x9, #0xfffffff8203; CHECK-GI-NEXT: .LBB2_1: // %vector.body204; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1205; CHECK-GI-NEXT: ldrh w9, [x2], #16206; CHECK-GI-NEXT: subs x8, x8, #8207; CHECK-GI-NEXT: fmov s2, w9208; CHECK-GI-NEXT: mov w9, w0209; CHECK-GI-NEXT: add w0, w0, #8210; CHECK-GI-NEXT: lsl x9, x9, #2211; CHECK-GI-NEXT: tbl v2.16b, { v2.16b, v3.16b }, v1.16b212; CHECK-GI-NEXT: mul v2.4s, v0.4s, v2.4s213; CHECK-GI-NEXT: str q2, [x1, x9]214; CHECK-GI-NEXT: b.ne .LBB2_1215; CHECK-GI-NEXT: // %bb.2: // %for.end12216; CHECK-GI-NEXT: ret217vector.header:218 %conv4 = zext i16 %val to i32219 %wide.trip.count = zext i32 %N to i64220 %0 = add nsw i64 %wide.trip.count, -1221 %min.iters.check = icmp ult i32 %N, 8222 %1 = trunc i64 %0 to i32223 %2 = icmp ugt i64 %0, 4294967295224 %n.vec = and i64 %wide.trip.count, 4294967288225 %broadcast.splatinsert = insertelement <4 x i32> undef, i32 %conv4, i32 0226 %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer227 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count228 br label %vector.body229 230vector.body: ; preds = %vector.header, %vector.body231 %index = phi i64 [ %index.next, %vector.body ], [ 0, %vector.header ]232 %g = getelementptr inbounds i16, ptr %A, i64 %index233 %val1 = load i16, ptr %g234 %splat.input.ext = zext i16 %val1 to i32235 %broadcast.splatinsert31 = insertelement <4 x i32> undef, i32 %splat.input.ext, i32 0236 %broadcast.splat32 = shufflevector <4 x i32> %broadcast.splatinsert31, <4 x i32> %broadcast.splat, <4 x i32> <i32 0, i32 1, i32 0, i32 1>237 %3 = trunc i64 %index to i32238 %4 = add i32 %N, %3239 %5 = zext i32 %4 to i64240 %6 = mul nuw nsw <4 x i32> %broadcast.splat, %broadcast.splat32241 %7 = getelementptr inbounds i32, ptr %C, i64 %5242 %8 = bitcast ptr %7 to ptr243 store <4 x i32> %6, ptr %8, align 4244 %index.next = add i64 %index, 8245 %9 = icmp eq i64 %index.next, %n.vec246 br i1 %9, label %for.end12, label %vector.body247 248for.end12: ; preds = %vector.body249 ret void250}251 252 253define void @larger_smull(ptr nocapture noundef readonly %x, i16 noundef %y, ptr noalias nocapture noundef writeonly %s, i32 noundef %n) {254; CHECK-SD-LABEL: larger_smull:255; CHECK-SD: // %bb.0: // %entry256; CHECK-SD-NEXT: cmp w3, #1257; CHECK-SD-NEXT: b.lt .LBB3_8258; CHECK-SD-NEXT: // %bb.1: // %for.body.preheader259; CHECK-SD-NEXT: cmp w3, #15260; CHECK-SD-NEXT: mov w8, w3261; CHECK-SD-NEXT: b.hi .LBB3_3262; CHECK-SD-NEXT: // %bb.2:263; CHECK-SD-NEXT: mov x9, xzr264; CHECK-SD-NEXT: b .LBB3_6265; CHECK-SD-NEXT: .LBB3_3: // %vector.ph266; CHECK-SD-NEXT: dup v0.8h, w1267; CHECK-SD-NEXT: and x9, x8, #0xfffffff0268; CHECK-SD-NEXT: add x10, x2, #32269; CHECK-SD-NEXT: add x11, x0, #16270; CHECK-SD-NEXT: and x12, x8, #0xfffffff0271; CHECK-SD-NEXT: .LBB3_4: // %vector.body272; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1273; CHECK-SD-NEXT: ldp q1, q2, [x11, #-16]274; CHECK-SD-NEXT: subs x12, x12, #16275; CHECK-SD-NEXT: add x11, x11, #32276; CHECK-SD-NEXT: smull2 v3.4s, v0.8h, v1.8h277; CHECK-SD-NEXT: smull v1.4s, v0.4h, v1.4h278; CHECK-SD-NEXT: smull2 v4.4s, v0.8h, v2.8h279; CHECK-SD-NEXT: smull v2.4s, v0.4h, v2.4h280; CHECK-SD-NEXT: stp q1, q3, [x10, #-32]281; CHECK-SD-NEXT: stp q2, q4, [x10], #64282; CHECK-SD-NEXT: b.ne .LBB3_4283; CHECK-SD-NEXT: // %bb.5: // %middle.block284; CHECK-SD-NEXT: cmp x9, x8285; CHECK-SD-NEXT: b.eq .LBB3_8286; CHECK-SD-NEXT: .LBB3_6: // %for.body.preheader1287; CHECK-SD-NEXT: sxth w10, w1288; CHECK-SD-NEXT: add x11, x2, x9, lsl #2289; CHECK-SD-NEXT: add x12, x0, x9, lsl #1290; CHECK-SD-NEXT: sub x8, x8, x9291; CHECK-SD-NEXT: .LBB3_7: // %for.body292; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1293; CHECK-SD-NEXT: ldrsh w9, [x12], #2294; CHECK-SD-NEXT: subs x8, x8, #1295; CHECK-SD-NEXT: mul w9, w9, w10296; CHECK-SD-NEXT: str w9, [x11], #4297; CHECK-SD-NEXT: b.ne .LBB3_7298; CHECK-SD-NEXT: .LBB3_8: // %for.cond.cleanup299; CHECK-SD-NEXT: ret300;301; CHECK-GI-LABEL: larger_smull:302; CHECK-GI: // %bb.0: // %entry303; CHECK-GI-NEXT: cmp w3, #0304; CHECK-GI-NEXT: b.le .LBB3_7305; CHECK-GI-NEXT: // %bb.1: // %for.body.preheader306; CHECK-GI-NEXT: sxth w8, w1307; CHECK-GI-NEXT: mov x10, xzr308; CHECK-GI-NEXT: cmp w3, #16309; CHECK-GI-NEXT: mov w9, w3310; CHECK-GI-NEXT: b.lo .LBB3_5311; CHECK-GI-NEXT: // %bb.2: // %vector.ph312; CHECK-GI-NEXT: dup v0.4s, w8313; CHECK-GI-NEXT: and x10, x9, #0xfffffff0314; CHECK-GI-NEXT: add x11, x2, #32315; CHECK-GI-NEXT: add x12, x0, #16316; CHECK-GI-NEXT: and x13, x9, #0xfffffff0317; CHECK-GI-NEXT: xtn v0.4h, v0.4s318; CHECK-GI-NEXT: .LBB3_3: // %vector.body319; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1320; CHECK-GI-NEXT: ldp q1, q2, [x12, #-16]321; CHECK-GI-NEXT: mov x14, x11322; CHECK-GI-NEXT: subs x13, x13, #16323; CHECK-GI-NEXT: add x12, x12, #32324; CHECK-GI-NEXT: mov d3, v1.d[1]325; CHECK-GI-NEXT: mov d4, v2.d[1]326; CHECK-GI-NEXT: smull v1.4s, v0.4h, v1.4h327; CHECK-GI-NEXT: smull v2.4s, v0.4h, v2.4h328; CHECK-GI-NEXT: smull v3.4s, v0.4h, v3.4h329; CHECK-GI-NEXT: smull v4.4s, v0.4h, v4.4h330; CHECK-GI-NEXT: stp q1, q3, [x14, #-32]!331; CHECK-GI-NEXT: stp q2, q4, [x11], #64332; CHECK-GI-NEXT: b.ne .LBB3_3333; CHECK-GI-NEXT: // %bb.4: // %middle.block334; CHECK-GI-NEXT: cmp x10, x9335; CHECK-GI-NEXT: b.eq .LBB3_7336; CHECK-GI-NEXT: .LBB3_5: // %for.body.preheader1337; CHECK-GI-NEXT: add x11, x2, x10, lsl #2338; CHECK-GI-NEXT: add x12, x0, x10, lsl #1339; CHECK-GI-NEXT: sub x9, x9, x10340; CHECK-GI-NEXT: .LBB3_6: // %for.body341; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1342; CHECK-GI-NEXT: ldrsh w10, [x12], #2343; CHECK-GI-NEXT: subs x9, x9, #1344; CHECK-GI-NEXT: mul w10, w10, w8345; CHECK-GI-NEXT: str w10, [x11], #4346; CHECK-GI-NEXT: b.ne .LBB3_6347; CHECK-GI-NEXT: .LBB3_7: // %for.cond.cleanup348; CHECK-GI-NEXT: ret349entry:350 %conv1 = sext i16 %y to i32351 %cmp8 = icmp sgt i32 %n, 0352 br i1 %cmp8, label %for.body.preheader, label %for.cond.cleanup353 354for.body.preheader: ; preds = %entry355 %wide.trip.count = zext i32 %n to i64356 %min.iters.check = icmp ult i32 %n, 16357 br i1 %min.iters.check, label %for.body.preheader14, label %vector.ph358 359vector.ph: ; preds = %for.body.preheader360 %n.vec = and i64 %wide.trip.count, 4294967280361 %broadcast.splatinsert = insertelement <8 x i32> poison, i32 %conv1, i64 0362 %broadcast.splat = shufflevector <8 x i32> %broadcast.splatinsert, <8 x i32> poison, <8 x i32> zeroinitializer363 %broadcast.splatinsert12 = insertelement <8 x i32> poison, i32 %conv1, i64 0364 %broadcast.splat13 = shufflevector <8 x i32> %broadcast.splatinsert12, <8 x i32> poison, <8 x i32> zeroinitializer365 br label %vector.body366 367vector.body: ; preds = %vector.body, %vector.ph368 %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]369 %0 = getelementptr inbounds i16, ptr %x, i64 %index370 %1 = bitcast ptr %0 to ptr371 %wide.load = load <8 x i16>, ptr %1, align 2372 %2 = getelementptr inbounds i16, ptr %0, i64 8373 %3 = bitcast ptr %2 to ptr374 %wide.load11 = load <8 x i16>, ptr %3, align 2375 %4 = sext <8 x i16> %wide.load to <8 x i32>376 %5 = sext <8 x i16> %wide.load11 to <8 x i32>377 %6 = mul nsw <8 x i32> %broadcast.splat, %4378 %7 = mul nsw <8 x i32> %broadcast.splat13, %5379 %8 = getelementptr inbounds i32, ptr %s, i64 %index380 %9 = bitcast ptr %8 to ptr381 store <8 x i32> %6, ptr %9, align 4382 %10 = getelementptr inbounds i32, ptr %8, i64 8383 %11 = bitcast ptr %10 to ptr384 store <8 x i32> %7, ptr %11, align 4385 %index.next = add nuw i64 %index, 16386 %12 = icmp eq i64 %index.next, %n.vec387 br i1 %12, label %middle.block, label %vector.body388 389middle.block: ; preds = %vector.body390 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count391 br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader14392 393for.body.preheader14: ; preds = %for.body.preheader, %middle.block394 %indvars.iv.ph = phi i64 [ 0, %for.body.preheader ], [ %n.vec, %middle.block ]395 br label %for.body396 397for.cond.cleanup: ; preds = %for.body, %middle.block, %entry398 ret void399 400for.body: ; preds = %for.body.preheader14, %for.body401 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader14 ]402 %arrayidx = getelementptr inbounds i16, ptr %x, i64 %indvars.iv403 %13 = load i16, ptr %arrayidx, align 2404 %conv = sext i16 %13 to i32405 %mul = mul nsw i32 %conv, %conv1406 %arrayidx3 = getelementptr inbounds i32, ptr %s, i64 %indvars.iv407 store i32 %mul, ptr %arrayidx3, align 4408 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1409 %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count410 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body411}412 413 414define void @larger_umull(ptr nocapture noundef readonly %x, i16 noundef %y, ptr noalias nocapture noundef writeonly %s, i32 noundef %n) {415; CHECK-SD-LABEL: larger_umull:416; CHECK-SD: // %bb.0: // %entry417; CHECK-SD-NEXT: cmp w3, #1418; CHECK-SD-NEXT: b.lt .LBB4_8419; CHECK-SD-NEXT: // %bb.1: // %for.body.preheader420; CHECK-SD-NEXT: cmp w3, #15421; CHECK-SD-NEXT: mov w8, w3422; CHECK-SD-NEXT: b.hi .LBB4_3423; CHECK-SD-NEXT: // %bb.2:424; CHECK-SD-NEXT: mov x9, xzr425; CHECK-SD-NEXT: b .LBB4_6426; CHECK-SD-NEXT: .LBB4_3: // %vector.ph427; CHECK-SD-NEXT: dup v0.8h, w1428; CHECK-SD-NEXT: and x9, x8, #0xfffffff0429; CHECK-SD-NEXT: add x10, x2, #32430; CHECK-SD-NEXT: add x11, x0, #16431; CHECK-SD-NEXT: and x12, x8, #0xfffffff0432; CHECK-SD-NEXT: .LBB4_4: // %vector.body433; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1434; CHECK-SD-NEXT: ldp q1, q2, [x11, #-16]435; CHECK-SD-NEXT: subs x12, x12, #16436; CHECK-SD-NEXT: add x11, x11, #32437; CHECK-SD-NEXT: umull2 v3.4s, v0.8h, v1.8h438; CHECK-SD-NEXT: umull v1.4s, v0.4h, v1.4h439; CHECK-SD-NEXT: umull2 v4.4s, v0.8h, v2.8h440; CHECK-SD-NEXT: umull v2.4s, v0.4h, v2.4h441; CHECK-SD-NEXT: stp q1, q3, [x10, #-32]442; CHECK-SD-NEXT: stp q2, q4, [x10], #64443; CHECK-SD-NEXT: b.ne .LBB4_4444; CHECK-SD-NEXT: // %bb.5: // %middle.block445; CHECK-SD-NEXT: cmp x9, x8446; CHECK-SD-NEXT: b.eq .LBB4_8447; CHECK-SD-NEXT: .LBB4_6: // %for.body.preheader1448; CHECK-SD-NEXT: add x10, x2, x9, lsl #2449; CHECK-SD-NEXT: add x11, x0, x9, lsl #1450; CHECK-SD-NEXT: and w12, w1, #0xffff451; CHECK-SD-NEXT: sub x8, x8, x9452; CHECK-SD-NEXT: .LBB4_7: // %for.body453; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1454; CHECK-SD-NEXT: ldrh w9, [x11], #2455; CHECK-SD-NEXT: subs x8, x8, #1456; CHECK-SD-NEXT: mul w9, w9, w12457; CHECK-SD-NEXT: str w9, [x10], #4458; CHECK-SD-NEXT: b.ne .LBB4_7459; CHECK-SD-NEXT: .LBB4_8: // %for.cond.cleanup460; CHECK-SD-NEXT: ret461;462; CHECK-GI-LABEL: larger_umull:463; CHECK-GI: // %bb.0: // %entry464; CHECK-GI-NEXT: cmp w3, #0465; CHECK-GI-NEXT: b.le .LBB4_7466; CHECK-GI-NEXT: // %bb.1: // %for.body.preheader467; CHECK-GI-NEXT: mov x8, xzr468; CHECK-GI-NEXT: cmp w3, #16469; CHECK-GI-NEXT: mov w9, w3470; CHECK-GI-NEXT: b.lo .LBB4_5471; CHECK-GI-NEXT: // %bb.2: // %vector.ph472; CHECK-GI-NEXT: and x8, x9, #0xfffffff0473; CHECK-GI-NEXT: add x10, x2, #32474; CHECK-GI-NEXT: add x11, x0, #16475; CHECK-GI-NEXT: and x12, x9, #0xfffffff0476; CHECK-GI-NEXT: .LBB4_3: // %vector.body477; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1478; CHECK-GI-NEXT: and w13, w1, #0xffff479; CHECK-GI-NEXT: ldp q1, q2, [x11, #-16]480; CHECK-GI-NEXT: dup v0.4s, w13481; CHECK-GI-NEXT: mov x13, x10482; CHECK-GI-NEXT: subs x12, x12, #16483; CHECK-GI-NEXT: add x11, x11, #32484; CHECK-GI-NEXT: mov d3, v1.d[1]485; CHECK-GI-NEXT: mov d4, v2.d[1]486; CHECK-GI-NEXT: xtn v0.4h, v0.4s487; CHECK-GI-NEXT: umull v1.4s, v0.4h, v1.4h488; CHECK-GI-NEXT: umull v3.4s, v0.4h, v3.4h489; CHECK-GI-NEXT: umull v2.4s, v0.4h, v2.4h490; CHECK-GI-NEXT: umull v0.4s, v0.4h, v4.4h491; CHECK-GI-NEXT: stp q1, q3, [x13, #-32]!492; CHECK-GI-NEXT: stp q2, q0, [x10], #64493; CHECK-GI-NEXT: b.ne .LBB4_3494; CHECK-GI-NEXT: // %bb.4: // %middle.block495; CHECK-GI-NEXT: cmp x8, x9496; CHECK-GI-NEXT: b.eq .LBB4_7497; CHECK-GI-NEXT: .LBB4_5: // %for.body.preheader1498; CHECK-GI-NEXT: add x10, x2, x8, lsl #2499; CHECK-GI-NEXT: add x11, x0, x8, lsl #1500; CHECK-GI-NEXT: and w12, w1, #0xffff501; CHECK-GI-NEXT: sub x8, x9, x8502; CHECK-GI-NEXT: .LBB4_6: // %for.body503; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1504; CHECK-GI-NEXT: ldrh w9, [x11], #2505; CHECK-GI-NEXT: subs x8, x8, #1506; CHECK-GI-NEXT: mul w9, w9, w12507; CHECK-GI-NEXT: str w9, [x10], #4508; CHECK-GI-NEXT: b.ne .LBB4_6509; CHECK-GI-NEXT: .LBB4_7: // %for.cond.cleanup510; CHECK-GI-NEXT: ret511entry:512 %conv1 = zext i16 %y to i32513 %cmp8 = icmp sgt i32 %n, 0514 br i1 %cmp8, label %for.body.preheader, label %for.cond.cleanup515 516for.body.preheader: ; preds = %entry517 %wide.trip.count = zext i32 %n to i64518 %min.iters.check = icmp ult i32 %n, 16519 br i1 %min.iters.check, label %for.body.preheader14, label %vector.ph520 521vector.ph: ; preds = %for.body.preheader522 %n.vec = and i64 %wide.trip.count, 4294967280523 %broadcast.splatinsert = insertelement <8 x i32> poison, i32 %conv1, i64 0524 %broadcast.splat = shufflevector <8 x i32> %broadcast.splatinsert, <8 x i32> poison, <8 x i32> zeroinitializer525 %broadcast.splatinsert12 = insertelement <8 x i32> poison, i32 %conv1, i64 0526 %broadcast.splat13 = shufflevector <8 x i32> %broadcast.splatinsert12, <8 x i32> poison, <8 x i32> zeroinitializer527 br label %vector.body528 529vector.body: ; preds = %vector.body, %vector.ph530 %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]531 %0 = getelementptr inbounds i16, ptr %x, i64 %index532 %1 = bitcast ptr %0 to ptr533 %wide.load = load <8 x i16>, ptr %1, align 2534 %2 = getelementptr inbounds i16, ptr %0, i64 8535 %3 = bitcast ptr %2 to ptr536 %wide.load11 = load <8 x i16>, ptr %3, align 2537 %4 = zext <8 x i16> %wide.load to <8 x i32>538 %5 = zext <8 x i16> %wide.load11 to <8 x i32>539 %6 = mul nuw <8 x i32> %broadcast.splat, %4540 %7 = mul nuw <8 x i32> %broadcast.splat13, %5541 %8 = getelementptr inbounds i32, ptr %s, i64 %index542 %9 = bitcast ptr %8 to ptr543 store <8 x i32> %6, ptr %9, align 4544 %10 = getelementptr inbounds i32, ptr %8, i64 8545 %11 = bitcast ptr %10 to ptr546 store <8 x i32> %7, ptr %11, align 4547 %index.next = add nuw i64 %index, 16548 %12 = icmp eq i64 %index.next, %n.vec549 br i1 %12, label %middle.block, label %vector.body550 551middle.block: ; preds = %vector.body552 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count553 br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader14554 555for.body.preheader14: ; preds = %for.body.preheader, %middle.block556 %indvars.iv.ph = phi i64 [ 0, %for.body.preheader ], [ %n.vec, %middle.block ]557 br label %for.body558 559for.cond.cleanup: ; preds = %for.body, %middle.block, %entry560 ret void561 562for.body: ; preds = %for.body.preheader14, %for.body563 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader14 ]564 %arrayidx = getelementptr inbounds i16, ptr %x, i64 %indvars.iv565 %13 = load i16, ptr %arrayidx, align 2566 %conv = zext i16 %13 to i32567 %mul = mul nuw i32 %conv, %conv1568 %arrayidx3 = getelementptr inbounds i32, ptr %s, i64 %indvars.iv569 store i32 %mul, ptr %arrayidx3, align 4570 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1571 %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count572 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body573}574 575 576define i16 @red_mla_dup_ext_u8_s8_s16(ptr noalias nocapture noundef readonly %A, i8 noundef %B, i32 noundef %n) {577; CHECK-SD-LABEL: red_mla_dup_ext_u8_s8_s16:578; CHECK-SD: // %bb.0: // %entry579; CHECK-SD-NEXT: cbz w2, .LBB5_3580; CHECK-SD-NEXT: // %bb.1: // %for.body.preheader581; CHECK-SD-NEXT: sxtb w9, w1582; CHECK-SD-NEXT: cmp w2, #15583; CHECK-SD-NEXT: mov w10, w2584; CHECK-SD-NEXT: b.hi .LBB5_4585; CHECK-SD-NEXT: // %bb.2:586; CHECK-SD-NEXT: mov x11, xzr587; CHECK-SD-NEXT: mov w8, wzr588; CHECK-SD-NEXT: b .LBB5_7589; CHECK-SD-NEXT: .LBB5_3:590; CHECK-SD-NEXT: mov w8, wzr591; CHECK-SD-NEXT: mov w0, w8592; CHECK-SD-NEXT: ret593; CHECK-SD-NEXT: .LBB5_4: // %vector.ph594; CHECK-SD-NEXT: movi v0.2d, #0000000000000000595; CHECK-SD-NEXT: movi v1.2d, #0000000000000000596; CHECK-SD-NEXT: and x11, x10, #0xfffffff0597; CHECK-SD-NEXT: fmov s2, w9598; CHECK-SD-NEXT: add x8, x0, #8599; CHECK-SD-NEXT: and x12, x10, #0xfffffff0600; CHECK-SD-NEXT: .LBB5_5: // %vector.body601; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1602; CHECK-SD-NEXT: ldp d3, d4, [x8, #-8]603; CHECK-SD-NEXT: subs x12, x12, #16604; CHECK-SD-NEXT: add x8, x8, #16605; CHECK-SD-NEXT: ushll v3.8h, v3.8b, #0606; CHECK-SD-NEXT: ushll v4.8h, v4.8b, #0607; CHECK-SD-NEXT: mla v0.8h, v3.8h, v2.h[0]608; CHECK-SD-NEXT: mla v1.8h, v4.8h, v2.h[0]609; CHECK-SD-NEXT: b.ne .LBB5_5610; CHECK-SD-NEXT: // %bb.6: // %middle.block611; CHECK-SD-NEXT: add v0.8h, v1.8h, v0.8h612; CHECK-SD-NEXT: cmp x11, x10613; CHECK-SD-NEXT: addv h0, v0.8h614; CHECK-SD-NEXT: fmov w8, s0615; CHECK-SD-NEXT: b.eq .LBB5_9616; CHECK-SD-NEXT: .LBB5_7: // %for.body.preheader1617; CHECK-SD-NEXT: sub x10, x10, x11618; CHECK-SD-NEXT: add x11, x0, x11619; CHECK-SD-NEXT: .LBB5_8: // %for.body620; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1621; CHECK-SD-NEXT: ldrb w12, [x11], #1622; CHECK-SD-NEXT: subs x10, x10, #1623; CHECK-SD-NEXT: madd w8, w12, w9, w8624; CHECK-SD-NEXT: b.ne .LBB5_8625; CHECK-SD-NEXT: .LBB5_9: // %for.cond.cleanup626; CHECK-SD-NEXT: mov w0, w8627; CHECK-SD-NEXT: ret628;629; CHECK-GI-LABEL: red_mla_dup_ext_u8_s8_s16:630; CHECK-GI: // %bb.0: // %entry631; CHECK-GI-NEXT: cbz w2, .LBB5_3632; CHECK-GI-NEXT: // %bb.1: // %for.body.preheader633; CHECK-GI-NEXT: cmp w2, #16634; CHECK-GI-NEXT: mov w8, w2635; CHECK-GI-NEXT: b.hs .LBB5_4636; CHECK-GI-NEXT: // %bb.2:637; CHECK-GI-NEXT: mov w10, #0 // =0x0638; CHECK-GI-NEXT: mov x9, xzr639; CHECK-GI-NEXT: fmov s0, w10640; CHECK-GI-NEXT: b .LBB5_8641; CHECK-GI-NEXT: .LBB5_3:642; CHECK-GI-NEXT: mov w0, wzr643; CHECK-GI-NEXT: ret644; CHECK-GI-NEXT: .LBB5_4: // %vector.ph645; CHECK-GI-NEXT: lsl w9, w1, #8646; CHECK-GI-NEXT: movi v0.2d, #0000000000000000647; CHECK-GI-NEXT: movi v1.2d, #0000000000000000648; CHECK-GI-NEXT: add x10, x0, #8649; CHECK-GI-NEXT: and x11, x8, #0xfffffff0650; CHECK-GI-NEXT: sbfx w9, w9, #8, #8651; CHECK-GI-NEXT: dup v2.8h, w9652; CHECK-GI-NEXT: and x9, x8, #0xfffffff0653; CHECK-GI-NEXT: .LBB5_5: // %vector.body654; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1655; CHECK-GI-NEXT: ldp d3, d4, [x10, #-8]656; CHECK-GI-NEXT: subs x11, x11, #16657; CHECK-GI-NEXT: add x10, x10, #16658; CHECK-GI-NEXT: ushll v3.8h, v3.8b, #0659; CHECK-GI-NEXT: ushll v4.8h, v4.8b, #0660; CHECK-GI-NEXT: mla v0.8h, v2.8h, v3.8h661; CHECK-GI-NEXT: mla v1.8h, v2.8h, v4.8h662; CHECK-GI-NEXT: b.ne .LBB5_5663; CHECK-GI-NEXT: // %bb.6: // %middle.block664; CHECK-GI-NEXT: add v0.8h, v1.8h, v0.8h665; CHECK-GI-NEXT: cmp x9, x8666; CHECK-GI-NEXT: addv h0, v0.8h667; CHECK-GI-NEXT: b.ne .LBB5_8668; CHECK-GI-NEXT: // %bb.7:669; CHECK-GI-NEXT: fmov w0, s0670; CHECK-GI-NEXT: ret671; CHECK-GI-NEXT: .LBB5_8: // %for.body.preheader1672; CHECK-GI-NEXT: sxtb w10, w1673; CHECK-GI-NEXT: sub x8, x8, x9674; CHECK-GI-NEXT: add x9, x0, x9675; CHECK-GI-NEXT: .LBB5_9: // %for.body676; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1677; CHECK-GI-NEXT: ldrb w11, [x9], #1678; CHECK-GI-NEXT: fmov w12, s0679; CHECK-GI-NEXT: subs x8, x8, #1680; CHECK-GI-NEXT: mul w11, w11, w10681; CHECK-GI-NEXT: add w0, w11, w12, uxth682; CHECK-GI-NEXT: fmov s0, w0683; CHECK-GI-NEXT: b.ne .LBB5_9684; CHECK-GI-NEXT: // %bb.10: // %for.cond.cleanup685; CHECK-GI-NEXT: ret686entry:687 %conv2 = sext i8 %B to i16688 %cmp10.not = icmp eq i32 %n, 0689 br i1 %cmp10.not, label %for.cond.cleanup, label %for.body.preheader690 691for.body.preheader: ; preds = %entry692 %wide.trip.count = zext i32 %n to i64693 %min.iters.check = icmp ult i32 %n, 16694 br i1 %min.iters.check, label %for.body.preheader17, label %vector.ph695 696vector.ph: ; preds = %for.body.preheader697 %n.vec = and i64 %wide.trip.count, 4294967280698 %broadcast.splatinsert = insertelement <8 x i16> poison, i16 %conv2, i64 0699 %broadcast.splat = shufflevector <8 x i16> %broadcast.splatinsert, <8 x i16> poison, <8 x i32> zeroinitializer700 %broadcast.splatinsert15 = insertelement <8 x i16> poison, i16 %conv2, i64 0701 %broadcast.splat16 = shufflevector <8 x i16> %broadcast.splatinsert15, <8 x i16> poison, <8 x i32> zeroinitializer702 br label %vector.body703 704vector.body: ; preds = %vector.body, %vector.ph705 %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]706 %vec.phi = phi <8 x i16> [ zeroinitializer, %vector.ph ], [ %8, %vector.body ]707 %vec.phi13 = phi <8 x i16> [ zeroinitializer, %vector.ph ], [ %9, %vector.body ]708 %0 = getelementptr inbounds i8, ptr %A, i64 %index709 %1 = bitcast ptr %0 to ptr710 %wide.load = load <8 x i8>, ptr %1, align 1711 %2 = getelementptr inbounds i8, ptr %0, i64 8712 %3 = bitcast ptr %2 to ptr713 %wide.load14 = load <8 x i8>, ptr %3, align 1714 %4 = zext <8 x i8> %wide.load to <8 x i16>715 %5 = zext <8 x i8> %wide.load14 to <8 x i16>716 %6 = mul nsw <8 x i16> %broadcast.splat, %4717 %7 = mul nsw <8 x i16> %broadcast.splat16, %5718 %8 = add <8 x i16> %6, %vec.phi719 %9 = add <8 x i16> %7, %vec.phi13720 %index.next = add nuw i64 %index, 16721 %10 = icmp eq i64 %index.next, %n.vec722 br i1 %10, label %middle.block, label %vector.body723 724middle.block: ; preds = %vector.body725 %bin.rdx = add <8 x i16> %9, %8726 %11 = call i16 @llvm.vector.reduce.add.v8i16(<8 x i16> %bin.rdx)727 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count728 br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader17729 730for.body.preheader17: ; preds = %for.body.preheader, %middle.block731 %indvars.iv.ph = phi i64 [ 0, %for.body.preheader ], [ %n.vec, %middle.block ]732 %s.011.ph = phi i16 [ 0, %for.body.preheader ], [ %11, %middle.block ]733 br label %for.body734 735for.cond.cleanup: ; preds = %for.body, %middle.block, %entry736 %s.0.lcssa = phi i16 [ 0, %entry ], [ %11, %middle.block ], [ %add, %for.body ]737 ret i16 %s.0.lcssa738 739for.body: ; preds = %for.body.preheader17, %for.body740 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader17 ]741 %s.011 = phi i16 [ %add, %for.body ], [ %s.011.ph, %for.body.preheader17 ]742 %arrayidx = getelementptr inbounds i8, ptr %A, i64 %indvars.iv743 %12 = load i8, ptr %arrayidx, align 1744 %13 = zext i8 %12 to i16745 %mul = mul nsw i16 %13, %conv2746 %add = add i16 %mul, %s.011747 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1748 %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count749 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body750}751 752define i64 @red_mla_dup_ext_u8_s8_s64(ptr noalias noundef readonly captures(none) %A, i8 noundef %B, i32 noundef %n) {753; CHECK-SD-LABEL: red_mla_dup_ext_u8_s8_s64:754; CHECK-SD: // %bb.0: // %entry755; CHECK-SD-NEXT: // kill: def $w1 killed $w1 def $x1756; CHECK-SD-NEXT: cbz w2, .LBB6_3757; CHECK-SD-NEXT: // %bb.1: // %iter.check758; CHECK-SD-NEXT: cmp w2, #3759; CHECK-SD-NEXT: mov w9, w2760; CHECK-SD-NEXT: b.hi .LBB6_4761; CHECK-SD-NEXT: // %bb.2:762; CHECK-SD-NEXT: mov x10, xzr763; CHECK-SD-NEXT: mov x8, xzr764; CHECK-SD-NEXT: b .LBB6_13765; CHECK-SD-NEXT: .LBB6_3:766; CHECK-SD-NEXT: mov x8, xzr767; CHECK-SD-NEXT: mov x0, x8768; CHECK-SD-NEXT: ret769; CHECK-SD-NEXT: .LBB6_4: // %vector.main.loop.iter.check770; CHECK-SD-NEXT: cmp w2, #16771; CHECK-SD-NEXT: b.hs .LBB6_6772; CHECK-SD-NEXT: // %bb.5:773; CHECK-SD-NEXT: mov x10, xzr774; CHECK-SD-NEXT: mov x8, xzr775; CHECK-SD-NEXT: b .LBB6_10776; CHECK-SD-NEXT: .LBB6_6: // %vector.ph777; CHECK-SD-NEXT: mov w8, w1778; CHECK-SD-NEXT: movi v0.2d, #0000000000000000779; CHECK-SD-NEXT: movi v1.2d, #0000000000000000780; CHECK-SD-NEXT: sxtb x8, w8781; CHECK-SD-NEXT: movi v3.2d, #0000000000000000782; CHECK-SD-NEXT: movi v2.2d, #0000000000000000783; CHECK-SD-NEXT: movi v6.2d, #0000000000000000784; CHECK-SD-NEXT: movi v4.2d, #0000000000000000785; CHECK-SD-NEXT: and x11, x9, #0xc786; CHECK-SD-NEXT: movi v7.2d, #0000000000000000787; CHECK-SD-NEXT: movi v5.2d, #0000000000000000788; CHECK-SD-NEXT: and x10, x9, #0xfffffff0789; CHECK-SD-NEXT: dup v16.4s, w8790; CHECK-SD-NEXT: mov x8, x0791; CHECK-SD-NEXT: and x12, x9, #0xfffffff0792; CHECK-SD-NEXT: .LBB6_7: // %vector.body793; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1794; CHECK-SD-NEXT: ldr q17, [x8], #16795; CHECK-SD-NEXT: subs x12, x12, #16796; CHECK-SD-NEXT: ushll v18.8h, v17.8b, #0797; CHECK-SD-NEXT: ushll2 v17.8h, v17.16b, #0798; CHECK-SD-NEXT: ushll2 v19.4s, v18.8h, #0799; CHECK-SD-NEXT: ushll v20.4s, v17.4h, #0800; CHECK-SD-NEXT: ushll v18.4s, v18.4h, #0801; CHECK-SD-NEXT: ushll2 v17.4s, v17.8h, #0802; CHECK-SD-NEXT: smlal2 v2.2d, v16.4s, v19.4s803; CHECK-SD-NEXT: smlal2 v4.2d, v16.4s, v20.4s804; CHECK-SD-NEXT: smlal v6.2d, v16.2s, v20.2s805; CHECK-SD-NEXT: smlal v3.2d, v16.2s, v19.2s806; CHECK-SD-NEXT: smlal2 v0.2d, v16.4s, v18.4s807; CHECK-SD-NEXT: smlal v7.2d, v16.2s, v17.2s808; CHECK-SD-NEXT: smlal v1.2d, v16.2s, v18.2s809; CHECK-SD-NEXT: smlal2 v5.2d, v16.4s, v17.4s810; CHECK-SD-NEXT: b.ne .LBB6_7811; CHECK-SD-NEXT: // %bb.8: // %middle.block812; CHECK-SD-NEXT: add v1.2d, v1.2d, v6.2d813; CHECK-SD-NEXT: add v3.2d, v3.2d, v7.2d814; CHECK-SD-NEXT: cmp x10, x9815; CHECK-SD-NEXT: add v0.2d, v0.2d, v4.2d816; CHECK-SD-NEXT: add v2.2d, v2.2d, v5.2d817; CHECK-SD-NEXT: add v1.2d, v1.2d, v3.2d818; CHECK-SD-NEXT: add v0.2d, v0.2d, v2.2d819; CHECK-SD-NEXT: add v0.2d, v1.2d, v0.2d820; CHECK-SD-NEXT: addp d0, v0.2d821; CHECK-SD-NEXT: fmov x8, d0822; CHECK-SD-NEXT: b.eq .LBB6_15823; CHECK-SD-NEXT: // %bb.9: // %vec.epilog.iter.check824; CHECK-SD-NEXT: cbz x11, .LBB6_13825; CHECK-SD-NEXT: .LBB6_10: // %vec.epilog.ph826; CHECK-SD-NEXT: movi v0.2d, #0000000000000000827; CHECK-SD-NEXT: mov w11, w1828; CHECK-SD-NEXT: movi v1.2d, #0000000000000000829; CHECK-SD-NEXT: sxtb x11, w11830; CHECK-SD-NEXT: movi v3.2d, #0x000000000000ff831; CHECK-SD-NEXT: dup v2.2s, w11832; CHECK-SD-NEXT: mov x11, x10833; CHECK-SD-NEXT: and x10, x9, #0xfffffffc834; CHECK-SD-NEXT: mov v0.d[0], x8835; CHECK-SD-NEXT: sub x8, x11, x10836; CHECK-SD-NEXT: add x11, x0, x11837; CHECK-SD-NEXT: .LBB6_11: // %vec.epilog.vector.body838; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1839; CHECK-SD-NEXT: ldr s4, [x11], #4840; CHECK-SD-NEXT: adds x8, x8, #4841; CHECK-SD-NEXT: ushll v4.8h, v4.8b, #0842; CHECK-SD-NEXT: ushll v4.4s, v4.4h, #0843; CHECK-SD-NEXT: ushll v5.2d, v4.2s, #0844; CHECK-SD-NEXT: ushll2 v4.2d, v4.4s, #0845; CHECK-SD-NEXT: and v5.16b, v5.16b, v3.16b846; CHECK-SD-NEXT: and v4.16b, v4.16b, v3.16b847; CHECK-SD-NEXT: xtn v5.2s, v5.2d848; CHECK-SD-NEXT: xtn v4.2s, v4.2d849; CHECK-SD-NEXT: smlal v1.2d, v2.2s, v4.2s850; CHECK-SD-NEXT: smlal v0.2d, v2.2s, v5.2s851; CHECK-SD-NEXT: b.ne .LBB6_11852; CHECK-SD-NEXT: // %bb.12: // %vec.epilog.middle.block853; CHECK-SD-NEXT: add v0.2d, v0.2d, v1.2d854; CHECK-SD-NEXT: cmp x10, x9855; CHECK-SD-NEXT: addp d0, v0.2d856; CHECK-SD-NEXT: fmov x8, d0857; CHECK-SD-NEXT: b.eq .LBB6_15858; CHECK-SD-NEXT: .LBB6_13: // %for.body.preheader859; CHECK-SD-NEXT: sxtb x11, w1860; CHECK-SD-NEXT: sub x9, x9, x10861; CHECK-SD-NEXT: add x10, x0, x10862; CHECK-SD-NEXT: .LBB6_14: // %for.body863; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1864; CHECK-SD-NEXT: ldrb w12, [x10], #1865; CHECK-SD-NEXT: subs x9, x9, #1866; CHECK-SD-NEXT: smaddl x8, w12, w11, x8867; CHECK-SD-NEXT: b.ne .LBB6_14868; CHECK-SD-NEXT: .LBB6_15: // %for.cond.cleanup869; CHECK-SD-NEXT: mov x0, x8870; CHECK-SD-NEXT: ret871;872; CHECK-GI-LABEL: red_mla_dup_ext_u8_s8_s64:873; CHECK-GI: // %bb.0: // %entry874; CHECK-GI-NEXT: // kill: def $w1 killed $w1 def $x1875; CHECK-GI-NEXT: cbz w2, .LBB6_7876; CHECK-GI-NEXT: // %bb.1: // %iter.check877; CHECK-GI-NEXT: movi d0, #0000000000000000878; CHECK-GI-NEXT: mov x10, xzr879; CHECK-GI-NEXT: cmp w2, #4880; CHECK-GI-NEXT: mov w9, w2881; CHECK-GI-NEXT: b.lo .LBB6_12882; CHECK-GI-NEXT: // %bb.2: // %vector.main.loop.iter.check883; CHECK-GI-NEXT: movi d0, #0000000000000000884; CHECK-GI-NEXT: mov x10, xzr885; CHECK-GI-NEXT: cmp w2, #16886; CHECK-GI-NEXT: b.lo .LBB6_9887; CHECK-GI-NEXT: // %bb.3: // %vector.ph888; CHECK-GI-NEXT: mov w8, w1889; CHECK-GI-NEXT: movi v0.2d, #0000000000000000890; CHECK-GI-NEXT: movi v1.2d, #0000000000000000891; CHECK-GI-NEXT: sxtb x8, w8892; CHECK-GI-NEXT: movi v2.2d, #0000000000000000893; CHECK-GI-NEXT: movi v3.2d, #0000000000000000894; CHECK-GI-NEXT: movi v4.2d, #0000000000000000895; CHECK-GI-NEXT: movi v6.2d, #0000000000000000896; CHECK-GI-NEXT: and x10, x9, #0xfffffff0897; CHECK-GI-NEXT: dup v5.2d, x8898; CHECK-GI-NEXT: movi v7.2d, #0000000000000000899; CHECK-GI-NEXT: and x8, x9, #0xc900; CHECK-GI-NEXT: mov x11, x0901; CHECK-GI-NEXT: and x12, x9, #0xfffffff0902; CHECK-GI-NEXT: xtn v16.2s, v5.2d903; CHECK-GI-NEXT: movi v5.2d, #0000000000000000904; CHECK-GI-NEXT: .LBB6_4: // %vector.body905; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1906; CHECK-GI-NEXT: ldr q17, [x11], #16907; CHECK-GI-NEXT: subs x12, x12, #16908; CHECK-GI-NEXT: ushll v18.8h, v17.8b, #0909; CHECK-GI-NEXT: ushll2 v17.8h, v17.16b, #0910; CHECK-GI-NEXT: ushll v19.4s, v18.4h, #0911; CHECK-GI-NEXT: ushll2 v18.4s, v18.8h, #0912; CHECK-GI-NEXT: ushll v20.4s, v17.4h, #0913; CHECK-GI-NEXT: ushll2 v17.4s, v17.8h, #0914; CHECK-GI-NEXT: mov d21, v19.d[1]915; CHECK-GI-NEXT: mov d22, v18.d[1]916; CHECK-GI-NEXT: mov d23, v20.d[1]917; CHECK-GI-NEXT: mov d24, v17.d[1]918; CHECK-GI-NEXT: smlal v0.2d, v16.2s, v19.2s919; CHECK-GI-NEXT: smlal v2.2d, v16.2s, v18.2s920; CHECK-GI-NEXT: smlal v4.2d, v16.2s, v20.2s921; CHECK-GI-NEXT: smlal v6.2d, v16.2s, v17.2s922; CHECK-GI-NEXT: smlal v1.2d, v16.2s, v21.2s923; CHECK-GI-NEXT: smlal v3.2d, v16.2s, v22.2s924; CHECK-GI-NEXT: smlal v5.2d, v16.2s, v23.2s925; CHECK-GI-NEXT: smlal v7.2d, v16.2s, v24.2s926; CHECK-GI-NEXT: b.ne .LBB6_4927; CHECK-GI-NEXT: // %bb.5: // %middle.block928; CHECK-GI-NEXT: add v0.2d, v0.2d, v1.2d929; CHECK-GI-NEXT: add v1.2d, v2.2d, v3.2d930; CHECK-GI-NEXT: cmp x10, x9931; CHECK-GI-NEXT: add v2.2d, v4.2d, v5.2d932; CHECK-GI-NEXT: add v3.2d, v6.2d, v7.2d933; CHECK-GI-NEXT: add v0.2d, v0.2d, v1.2d934; CHECK-GI-NEXT: add v1.2d, v2.2d, v3.2d935; CHECK-GI-NEXT: add v0.2d, v0.2d, v1.2d936; CHECK-GI-NEXT: addp d0, v0.2d937; CHECK-GI-NEXT: b.ne .LBB6_8938; CHECK-GI-NEXT: // %bb.6:939; CHECK-GI-NEXT: fmov x8, d0940; CHECK-GI-NEXT: mov x0, x8941; CHECK-GI-NEXT: ret942; CHECK-GI-NEXT: .LBB6_7:943; CHECK-GI-NEXT: mov x8, xzr944; CHECK-GI-NEXT: mov x0, x8945; CHECK-GI-NEXT: ret946; CHECK-GI-NEXT: .LBB6_8: // %vec.epilog.iter.check947; CHECK-GI-NEXT: cbz x8, .LBB6_12948; CHECK-GI-NEXT: .LBB6_9: // %vec.epilog.ph949; CHECK-GI-NEXT: mov w8, w1950; CHECK-GI-NEXT: mov v0.d[1], xzr951; CHECK-GI-NEXT: movi v1.2d, #0000000000000000952; CHECK-GI-NEXT: sxtb x8, w8953; CHECK-GI-NEXT: mov x11, x10954; CHECK-GI-NEXT: and x10, x9, #0xfffffffc955; CHECK-GI-NEXT: dup v2.2d, x8956; CHECK-GI-NEXT: sub x8, x11, x10957; CHECK-GI-NEXT: add x11, x0, x11958; CHECK-GI-NEXT: xtn v2.2s, v2.2d959; CHECK-GI-NEXT: .LBB6_10: // %vec.epilog.vector.body960; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1961; CHECK-GI-NEXT: ldr w12, [x11], #4962; CHECK-GI-NEXT: adds x8, x8, #4963; CHECK-GI-NEXT: fmov s3, w12964; CHECK-GI-NEXT: uxtb w12, w12965; CHECK-GI-NEXT: mov b4, v3.b[2]966; CHECK-GI-NEXT: mov b5, v3.b[1]967; CHECK-GI-NEXT: mov b6, v3.b[3]968; CHECK-GI-NEXT: fmov s3, w12969; CHECK-GI-NEXT: fmov w13, s4970; CHECK-GI-NEXT: fmov w14, s5971; CHECK-GI-NEXT: fmov w15, s6972; CHECK-GI-NEXT: uxtb w13, w13973; CHECK-GI-NEXT: uxtb w14, w14974; CHECK-GI-NEXT: uxtb w15, w15975; CHECK-GI-NEXT: fmov s4, w13976; CHECK-GI-NEXT: mov v3.s[1], w14977; CHECK-GI-NEXT: mov v4.s[1], w15978; CHECK-GI-NEXT: smlal v0.2d, v2.2s, v3.2s979; CHECK-GI-NEXT: smlal v1.2d, v2.2s, v4.2s980; CHECK-GI-NEXT: b.ne .LBB6_10981; CHECK-GI-NEXT: // %bb.11: // %vec.epilog.middle.block982; CHECK-GI-NEXT: add v0.2d, v0.2d, v1.2d983; CHECK-GI-NEXT: cmp x10, x9984; CHECK-GI-NEXT: addp d0, v0.2d985; CHECK-GI-NEXT: fmov x8, d0986; CHECK-GI-NEXT: b.eq .LBB6_14987; CHECK-GI-NEXT: .LBB6_12: // %for.body.preheader988; CHECK-GI-NEXT: sxtb x11, w1989; CHECK-GI-NEXT: sub x9, x9, x10990; CHECK-GI-NEXT: add x10, x0, x10991; CHECK-GI-NEXT: .LBB6_13: // %for.body992; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1993; CHECK-GI-NEXT: ldrb w8, [x10], #1994; CHECK-GI-NEXT: fmov x12, d0995; CHECK-GI-NEXT: subs x9, x9, #1996; CHECK-GI-NEXT: madd x8, x8, x11, x12997; CHECK-GI-NEXT: fmov d0, x8998; CHECK-GI-NEXT: b.ne .LBB6_13999; CHECK-GI-NEXT: .LBB6_14: // %for.cond.cleanup1000; CHECK-GI-NEXT: mov x0, x81001; CHECK-GI-NEXT: ret1002entry:1003 %cmp5.not = icmp eq i32 %n, 01004 br i1 %cmp5.not, label %for.cond.cleanup, label %iter.check1005 1006iter.check: ; preds = %entry1007 %conv1 = sext i8 %B to i641008 %wide.trip.count = zext i32 %n to i641009 %min.iters.check = icmp ult i32 %n, 41010 br i1 %min.iters.check, label %for.body.preheader, label %vector.main.loop.iter.check1011 1012vector.main.loop.iter.check: ; preds = %iter.check1013 %min.iters.check9 = icmp ult i32 %n, 161014 br i1 %min.iters.check9, label %vec.epilog.ph, label %vector.ph1015 1016vector.ph: ; preds = %vector.main.loop.iter.check1017 %n.mod.vf = and i64 %wide.trip.count, 121018 %n.vec = and i64 %wide.trip.count, 42949672801019 %broadcast.splatinsert = insertelement <16 x i64> poison, i64 %conv1, i64 01020 %broadcast.splat = shufflevector <16 x i64> %broadcast.splatinsert, <16 x i64> poison, <16 x i32> zeroinitializer1021 br label %vector.body1022 1023vector.body: ; preds = %vector.body, %vector.ph1024 %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]1025 %vec.phi = phi <16 x i64> [ zeroinitializer, %vector.ph ], [ %3, %vector.body ]1026 %0 = getelementptr inbounds nuw i8, ptr %A, i64 %index1027 %wide.load = load <16 x i8>, ptr %0, align 11028 %1 = zext <16 x i8> %wide.load to <16 x i64>1029 %2 = mul nsw <16 x i64> %broadcast.splat, %11030 %3 = add <16 x i64> %2, %vec.phi1031 %index.next = add nuw i64 %index, 161032 %4 = icmp eq i64 %index.next, %n.vec1033 br i1 %4, label %middle.block, label %vector.body1034 1035middle.block: ; preds = %vector.body1036 %5 = tail call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %3)1037 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count1038 br i1 %cmp.n, label %for.cond.cleanup, label %vec.epilog.iter.check1039 1040vec.epilog.iter.check: ; preds = %middle.block1041 %min.epilog.iters.check = icmp eq i64 %n.mod.vf, 01042 br i1 %min.epilog.iters.check, label %for.body.preheader, label %vec.epilog.ph1043 1044vec.epilog.ph: ; preds = %vector.main.loop.iter.check, %vec.epilog.iter.check1045 %vec.epilog.resume.val = phi i64 [ %n.vec, %vec.epilog.iter.check ], [ 0, %vector.main.loop.iter.check ]1046 %bc.merge.rdx = phi i64 [ %5, %vec.epilog.iter.check ], [ 0, %vector.main.loop.iter.check ]1047 %n.vec11 = and i64 %wide.trip.count, 42949672921048 %6 = insertelement <4 x i64> <i64 poison, i64 0, i64 0, i64 0>, i64 %bc.merge.rdx, i64 01049 %broadcast.splatinsert12 = insertelement <4 x i64> poison, i64 %conv1, i64 01050 %broadcast.splat13 = shufflevector <4 x i64> %broadcast.splatinsert12, <4 x i64> poison, <4 x i32> zeroinitializer1051 br label %vec.epilog.vector.body1052 1053vec.epilog.vector.body: ; preds = %vec.epilog.vector.body, %vec.epilog.ph1054 %index14 = phi i64 [ %vec.epilog.resume.val, %vec.epilog.ph ], [ %index.next17, %vec.epilog.vector.body ]1055 %vec.phi15 = phi <4 x i64> [ %6, %vec.epilog.ph ], [ %10, %vec.epilog.vector.body ]1056 %7 = getelementptr inbounds nuw i8, ptr %A, i64 %index141057 %wide.load16 = load <4 x i8>, ptr %7, align 11058 %8 = zext <4 x i8> %wide.load16 to <4 x i64>1059 %9 = mul nsw <4 x i64> %broadcast.splat13, %81060 %10 = add <4 x i64> %9, %vec.phi151061 %index.next17 = add nuw i64 %index14, 41062 %11 = icmp eq i64 %index.next17, %n.vec111063 br i1 %11, label %vec.epilog.middle.block, label %vec.epilog.vector.body1064 1065vec.epilog.middle.block: ; preds = %vec.epilog.vector.body1066 %12 = tail call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> %10)1067 %cmp.n18 = icmp eq i64 %n.vec11, %wide.trip.count1068 br i1 %cmp.n18, label %for.cond.cleanup, label %for.body.preheader1069 1070for.body.preheader: ; preds = %iter.check, %vec.epilog.iter.check, %vec.epilog.middle.block1071 %indvars.iv.ph = phi i64 [ 0, %iter.check ], [ %n.vec, %vec.epilog.iter.check ], [ %n.vec11, %vec.epilog.middle.block ]1072 %s.06.ph = phi i64 [ 0, %iter.check ], [ %5, %vec.epilog.iter.check ], [ %12, %vec.epilog.middle.block ]1073 br label %for.body1074 1075for.cond.cleanup: ; preds = %for.body, %middle.block, %vec.epilog.middle.block, %entry1076 %s.0.lcssa = phi i64 [ 0, %entry ], [ %5, %middle.block ], [ %12, %vec.epilog.middle.block ], [ %add, %for.body ]1077 ret i64 %s.0.lcssa1078 1079for.body: ; preds = %for.body.preheader, %for.body1080 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ]1081 %s.06 = phi i64 [ %add, %for.body ], [ %s.06.ph, %for.body.preheader ]1082 %arrayidx = getelementptr inbounds nuw i8, ptr %A, i64 %indvars.iv1083 %13 = load i8, ptr %arrayidx, align 11084 %conv = zext i8 %13 to i641085 %mul = mul nsw i64 %conv, %conv11086 %add = add nsw i64 %mul, %s.061087 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 11088 %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count1089 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body1090}1091 1092define void @sink_v2z64_1(ptr %p, ptr %d, i64 %n, <2 x i32> %a) {1093; CHECK-SD-LABEL: sink_v2z64_1:1094; CHECK-SD: // %bb.0: // %entry1095; CHECK-SD-NEXT: mov x8, xzr1096; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q01097; CHECK-SD-NEXT: .LBB7_1: // %loop1098; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=11099; CHECK-SD-NEXT: ldr d1, [x0]1100; CHECK-SD-NEXT: subs x2, x2, #81101; CHECK-SD-NEXT: add x8, x8, #81102; CHECK-SD-NEXT: umull v1.2d, v1.2s, v0.s[1]1103; CHECK-SD-NEXT: shrn v1.2s, v1.2d, #151104; CHECK-SD-NEXT: str d1, [x0], #321105; CHECK-SD-NEXT: b.ne .LBB7_11106; CHECK-SD-NEXT: // %bb.2: // %exit1107; CHECK-SD-NEXT: ret1108;1109; CHECK-GI-LABEL: sink_v2z64_1:1110; CHECK-GI: // %bb.0: // %entry1111; CHECK-GI-NEXT: ushll v0.2d, v0.2s, #01112; CHECK-GI-NEXT: mov x8, xzr1113; CHECK-GI-NEXT: dup v0.2d, v0.d[1]1114; CHECK-GI-NEXT: xtn v0.2s, v0.2d1115; CHECK-GI-NEXT: .LBB7_1: // %loop1116; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=11117; CHECK-GI-NEXT: ldr d1, [x0]1118; CHECK-GI-NEXT: subs x2, x2, #81119; CHECK-GI-NEXT: add x8, x8, #81120; CHECK-GI-NEXT: umull v1.2d, v1.2s, v0.2s1121; CHECK-GI-NEXT: shrn v1.2s, v1.2d, #151122; CHECK-GI-NEXT: str d1, [x0], #321123; CHECK-GI-NEXT: b.ne .LBB7_11124; CHECK-GI-NEXT: // %bb.2: // %exit1125; CHECK-GI-NEXT: ret1126entry:1127 %ext = zext <2 x i32> %a to <2 x i64>1128 %broadcast.splat = shufflevector <2 x i64> %ext, <2 x i64> poison, <2 x i32> <i32 1, i32 1>1129 br label %loop1130 1131loop:1132 %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]1133 %g = getelementptr inbounds i32, ptr %p, i64 %index1134 %gb = bitcast ptr %g to ptr1135 %l = load <2 x i32>, ptr %gb, align 41136 %e = zext <2 x i32> %l to <2 x i64>1137 %m = mul <2 x i64> %e, %broadcast.splat1138 %s = ashr <2 x i64> %m, <i64 15, i64 15>1139 %t = trunc <2 x i64> %s to <2 x i32>1140 %h = getelementptr inbounds i32, ptr %d, i64 %index1141 %hb = bitcast ptr %g to ptr1142 store <2 x i32> %t, ptr %hb, align 41143 %index.next = add nuw i64 %index, 81144 %c = icmp eq i64 %index.next, %n1145 br i1 %c, label %exit, label %loop1146 1147exit:1148 ret void1149}1150 1151define void @sink_v4i64_1(ptr %p, ptr %d, i64 %n, <2 x i32> %a) {1152; CHECK-SD-LABEL: sink_v4i64_1:1153; CHECK-SD: // %bb.0: // %entry1154; CHECK-SD-NEXT: mov x8, xzr1155; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q01156; CHECK-SD-NEXT: .LBB8_1: // %loop1157; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=11158; CHECK-SD-NEXT: ldr q1, [x0]1159; CHECK-SD-NEXT: subs x2, x2, #81160; CHECK-SD-NEXT: add x8, x8, #81161; CHECK-SD-NEXT: smull v2.2d, v1.2s, v0.s[1]1162; CHECK-SD-NEXT: smull2 v1.2d, v1.4s, v0.s[1]1163; CHECK-SD-NEXT: shrn v2.2s, v2.2d, #151164; CHECK-SD-NEXT: shrn2 v2.4s, v1.2d, #151165; CHECK-SD-NEXT: str q2, [x0], #321166; CHECK-SD-NEXT: b.ne .LBB8_11167; CHECK-SD-NEXT: // %bb.2: // %exit1168; CHECK-SD-NEXT: ret1169;1170; CHECK-GI-LABEL: sink_v4i64_1:1171; CHECK-GI: // %bb.0: // %entry1172; CHECK-GI-NEXT: sshll v0.2d, v0.2s, #01173; CHECK-GI-NEXT: mov x8, xzr1174; CHECK-GI-NEXT: dup v0.2d, v0.d[1]1175; CHECK-GI-NEXT: xtn v0.2s, v0.2d1176; CHECK-GI-NEXT: .LBB8_1: // %loop1177; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=11178; CHECK-GI-NEXT: ldr q1, [x0]1179; CHECK-GI-NEXT: subs x2, x2, #81180; CHECK-GI-NEXT: add x8, x8, #81181; CHECK-GI-NEXT: mov d2, v1.d[1]1182; CHECK-GI-NEXT: smull v1.2d, v1.2s, v0.2s1183; CHECK-GI-NEXT: smull v2.2d, v2.2s, v0.2s1184; CHECK-GI-NEXT: shrn v1.2s, v1.2d, #151185; CHECK-GI-NEXT: shrn2 v1.4s, v2.2d, #151186; CHECK-GI-NEXT: str q1, [x0], #321187; CHECK-GI-NEXT: b.ne .LBB8_11188; CHECK-GI-NEXT: // %bb.2: // %exit1189; CHECK-GI-NEXT: ret1190entry:1191 %ext = sext <2 x i32> %a to <2 x i64>1192 %broadcast.splat = shufflevector <2 x i64> %ext, <2 x i64> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>1193 br label %loop1194 1195loop:1196 %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]1197 %g = getelementptr inbounds i32, ptr %p, i64 %index1198 %gb = bitcast ptr %g to ptr1199 %l = load <4 x i32>, ptr %gb, align 41200 %e = sext <4 x i32> %l to <4 x i64>1201 %m = mul <4 x i64> %e, %broadcast.splat1202 %s = ashr <4 x i64> %m, <i64 15, i64 15, i64 15, i64 15>1203 %t = trunc <4 x i64> %s to <4 x i32>1204 %h = getelementptr inbounds i32, ptr %d, i64 %index1205 %hb = bitcast ptr %g to ptr1206 store <4 x i32> %t, ptr %hb, align 41207 %index.next = add nuw i64 %index, 81208 %c = icmp eq i64 %index.next, %n1209 br i1 %c, label %exit, label %loop1210 1211exit:1212 ret void1213}1214 1215define void @sink_v8z16_0(ptr %p, ptr %d, i64 %n, <16 x i8> %a) {1216; CHECK-SD-LABEL: sink_v8z16_0:1217; CHECK-SD: // %bb.0: // %entry1218; CHECK-SD-NEXT: dup v0.8b, v0.b[0]1219; CHECK-SD-NEXT: mov x8, xzr1220; CHECK-SD-NEXT: .LBB9_1: // %loop1221; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=11222; CHECK-SD-NEXT: ldr d1, [x0]1223; CHECK-SD-NEXT: subs x2, x2, #81224; CHECK-SD-NEXT: add x8, x8, #81225; CHECK-SD-NEXT: umull v1.8h, v1.8b, v0.8b1226; CHECK-SD-NEXT: cmlt v1.8h, v1.8h, #01227; CHECK-SD-NEXT: xtn v1.8b, v1.8h1228; CHECK-SD-NEXT: str d1, [x0], #321229; CHECK-SD-NEXT: b.ne .LBB9_11230; CHECK-SD-NEXT: // %bb.2: // %exit1231; CHECK-SD-NEXT: ret1232;1233; CHECK-GI-LABEL: sink_v8z16_0:1234; CHECK-GI: // %bb.0: // %entry1235; CHECK-GI-NEXT: ushll v0.8h, v0.8b, #01236; CHECK-GI-NEXT: mov x8, xzr1237; CHECK-GI-NEXT: dup v0.8h, v0.h[0]1238; CHECK-GI-NEXT: xtn v0.8b, v0.8h1239; CHECK-GI-NEXT: .LBB9_1: // %loop1240; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=11241; CHECK-GI-NEXT: ldr d1, [x0]1242; CHECK-GI-NEXT: subs x2, x2, #81243; CHECK-GI-NEXT: add x8, x8, #81244; CHECK-GI-NEXT: umull v1.8h, v1.8b, v0.8b1245; CHECK-GI-NEXT: cmlt v1.8h, v1.8h, #01246; CHECK-GI-NEXT: xtn v1.8b, v1.8h1247; CHECK-GI-NEXT: str d1, [x0], #321248; CHECK-GI-NEXT: b.ne .LBB9_11249; CHECK-GI-NEXT: // %bb.2: // %exit1250; CHECK-GI-NEXT: ret1251entry:1252 %ext = zext <16 x i8> %a to <16 x i16>1253 %broadcast.splat = shufflevector <16 x i16> %ext, <16 x i16> poison, <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>1254 br label %loop1255 1256loop:1257 %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]1258 %g = getelementptr inbounds i32, ptr %p, i64 %index1259 %gb = bitcast ptr %g to ptr1260 %l = load <8 x i8>, ptr %gb, align 41261 %e = zext <8 x i8> %l to <8 x i16>1262 %m = mul <8 x i16> %e, %broadcast.splat1263 %s = ashr <8 x i16> %m, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>1264 %t = trunc <8 x i16> %s to <8 x i8>1265 %h = getelementptr inbounds i32, ptr %d, i64 %index1266 %hb = bitcast ptr %g to ptr1267 store <8 x i8> %t, ptr %hb, align 41268 %index.next = add nuw i64 %index, 81269 %c = icmp eq i64 %index.next, %n1270 br i1 %c, label %exit, label %loop1271 1272exit:1273 ret void1274}1275 1276define void @sink_v16s16_8(ptr %p, ptr %d, i64 %n, <16 x i8> %a) {1277; CHECK-SD-LABEL: sink_v16s16_8:1278; CHECK-SD: // %bb.0: // %entry1279; CHECK-SD-NEXT: dup v0.16b, v0.b[10]1280; CHECK-SD-NEXT: mov x8, xzr1281; CHECK-SD-NEXT: .LBB10_1: // %loop1282; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=11283; CHECK-SD-NEXT: ldr q1, [x0]1284; CHECK-SD-NEXT: subs x2, x2, #81285; CHECK-SD-NEXT: add x8, x8, #81286; CHECK-SD-NEXT: smull v2.8h, v1.8b, v0.8b1287; CHECK-SD-NEXT: smull2 v1.8h, v1.16b, v0.16b1288; CHECK-SD-NEXT: cmlt v1.8h, v1.8h, #01289; CHECK-SD-NEXT: cmlt v2.8h, v2.8h, #01290; CHECK-SD-NEXT: uzp1 v1.16b, v2.16b, v1.16b1291; CHECK-SD-NEXT: str q1, [x0], #321292; CHECK-SD-NEXT: b.ne .LBB10_11293; CHECK-SD-NEXT: // %bb.2: // %exit1294; CHECK-SD-NEXT: ret1295;1296; CHECK-GI-LABEL: sink_v16s16_8:1297; CHECK-GI: // %bb.0: // %entry1298; CHECK-GI-NEXT: sshll2 v0.8h, v0.16b, #01299; CHECK-GI-NEXT: mov x8, xzr1300; CHECK-GI-NEXT: dup v0.8h, v0.h[2]1301; CHECK-GI-NEXT: xtn v0.8b, v0.8h1302; CHECK-GI-NEXT: .LBB10_1: // %loop1303; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=11304; CHECK-GI-NEXT: ldr q1, [x0]1305; CHECK-GI-NEXT: subs x2, x2, #81306; CHECK-GI-NEXT: add x8, x8, #81307; CHECK-GI-NEXT: mov d2, v1.d[1]1308; CHECK-GI-NEXT: smull v1.8h, v1.8b, v0.8b1309; CHECK-GI-NEXT: smull v2.8h, v2.8b, v0.8b1310; CHECK-GI-NEXT: cmlt v1.8h, v1.8h, #01311; CHECK-GI-NEXT: cmlt v2.8h, v2.8h, #01312; CHECK-GI-NEXT: uzp1 v1.16b, v1.16b, v2.16b1313; CHECK-GI-NEXT: str q1, [x0], #321314; CHECK-GI-NEXT: b.ne .LBB10_11315; CHECK-GI-NEXT: // %bb.2: // %exit1316; CHECK-GI-NEXT: ret1317entry:1318 %ext = sext <16 x i8> %a to <16 x i16>1319 %broadcast.splat = shufflevector <16 x i16> %ext, <16 x i16> poison, <16 x i32> <i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10, i32 10>1320 br label %loop1321 1322loop:1323 %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]1324 %g = getelementptr inbounds i32, ptr %p, i64 %index1325 %gb = bitcast ptr %g to ptr1326 %l = load <16 x i8>, ptr %gb, align 41327 %e = sext <16 x i8> %l to <16 x i16>1328 %m = mul <16 x i16> %e, %broadcast.splat1329 %s = ashr <16 x i16> %m, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>1330 %t = trunc <16 x i16> %s to <16 x i8>1331 %h = getelementptr inbounds i32, ptr %d, i64 %index1332 %hb = bitcast ptr %g to ptr1333 store <16 x i8> %t, ptr %hb, align 41334 %index.next = add nuw i64 %index, 81335 %c = icmp eq i64 %index.next, %n1336 br i1 %c, label %exit, label %loop1337 1338exit:1339 ret void1340}1341 1342define void @matrix_mul_unsigned_and(i32 %N, ptr nocapture %C, ptr nocapture readonly %A, i32 %val) {1343; CHECK-SD-LABEL: matrix_mul_unsigned_and:1344; CHECK-SD: // %bb.0: // %vector.header1345; CHECK-SD-NEXT: dup v0.4h, w31346; CHECK-SD-NEXT: // kill: def $w0 killed $w0 def $x01347; CHECK-SD-NEXT: and x8, x0, #0xfffffff81348; CHECK-SD-NEXT: .LBB11_1: // %vector.body1349; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=11350; CHECK-SD-NEXT: add x9, x2, w0, uxtw #11351; CHECK-SD-NEXT: subs x8, x8, #81352; CHECK-SD-NEXT: ldp d1, d2, [x9]1353; CHECK-SD-NEXT: add x9, x1, w0, uxtw #21354; CHECK-SD-NEXT: add w0, w0, #81355; CHECK-SD-NEXT: umull v1.4s, v0.4h, v1.4h1356; CHECK-SD-NEXT: umull v2.4s, v0.4h, v2.4h1357; CHECK-SD-NEXT: stp q1, q2, [x9]1358; CHECK-SD-NEXT: b.ne .LBB11_11359; CHECK-SD-NEXT: // %bb.2: // %for.end121360; CHECK-SD-NEXT: ret1361;1362; CHECK-GI-LABEL: matrix_mul_unsigned_and:1363; CHECK-GI: // %bb.0: // %vector.header1364; CHECK-GI-NEXT: and w8, w3, #0xffff1365; CHECK-GI-NEXT: dup v0.4s, w81366; CHECK-GI-NEXT: mov w8, w01367; CHECK-GI-NEXT: and x8, x8, #0xfffffff81368; CHECK-GI-NEXT: xtn v0.4h, v0.4s1369; CHECK-GI-NEXT: .LBB11_1: // %vector.body1370; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=11371; CHECK-GI-NEXT: add x9, x2, w0, uxtw #11372; CHECK-GI-NEXT: subs x8, x8, #81373; CHECK-GI-NEXT: ldp d1, d2, [x9]1374; CHECK-GI-NEXT: add x9, x1, w0, uxtw #21375; CHECK-GI-NEXT: add w0, w0, #81376; CHECK-GI-NEXT: umull v1.4s, v0.4h, v1.4h1377; CHECK-GI-NEXT: umull v2.4s, v0.4h, v2.4h1378; CHECK-GI-NEXT: stp q1, q2, [x9]1379; CHECK-GI-NEXT: b.ne .LBB11_11380; CHECK-GI-NEXT: // %bb.2: // %for.end121381; CHECK-GI-NEXT: ret1382vector.header:1383 %conv4 = and i32 %val, 655351384 %wide.trip.count = zext i32 %N to i641385 %0 = add nsw i64 %wide.trip.count, -11386 %min.iters.check = icmp ult i32 %N, 81387 %1 = trunc i64 %0 to i321388 %2 = icmp ugt i64 %0, 42949672951389 %n.vec = and i64 %wide.trip.count, 42949672881390 %broadcast.splatinsert = insertelement <4 x i32> undef, i32 %conv4, i32 01391 %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer1392 %broadcast.splatinsert31 = insertelement <4 x i32> undef, i32 %conv4, i32 01393 %broadcast.splat32 = shufflevector <4 x i32> %broadcast.splatinsert31, <4 x i32> undef, <4 x i32> zeroinitializer1394 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count1395 br label %vector.body1396 1397vector.body: ; preds = %vector.header, %vector.body1398 %index = phi i64 [ %index.next, %vector.body ], [ 0, %vector.header ]1399 %3 = trunc i64 %index to i321400 %4 = add i32 %N, %31401 %5 = zext i32 %4 to i641402 %6 = getelementptr inbounds i16, ptr %A, i64 %51403 %7 = bitcast ptr %6 to ptr1404 %wide.load = load <4 x i16>, ptr %7, align 21405 %8 = getelementptr inbounds i16, ptr %6, i64 41406 %9 = bitcast ptr %8 to ptr1407 %wide.load30 = load <4 x i16>, ptr %9, align 21408 %10 = zext <4 x i16> %wide.load to <4 x i32>1409 %11 = zext <4 x i16> %wide.load30 to <4 x i32>1410 %12 = mul nuw nsw <4 x i32> %broadcast.splat, %101411 %13 = mul nuw nsw <4 x i32> %broadcast.splat32, %111412 %14 = getelementptr inbounds i32, ptr %C, i64 %51413 %15 = bitcast ptr %14 to ptr1414 store <4 x i32> %12, ptr %15, align 41415 %16 = getelementptr inbounds i32, ptr %14, i64 41416 %17 = bitcast ptr %16 to ptr1417 store <4 x i32> %13, ptr %17, align 41418 %index.next = add i64 %index, 81419 %18 = icmp eq i64 %index.next, %n.vec1420 br i1 %18, label %for.end12, label %vector.body1421 1422for.end12: ; preds = %vector.body1423 ret void1424}1425 1426define void @matrix_mul_unsigned_and_double(i32 %N, ptr nocapture %C, ptr nocapture readonly %A, i32 %val) {1427; CHECK-SD-LABEL: matrix_mul_unsigned_and_double:1428; CHECK-SD: // %bb.0: // %vector.header1429; CHECK-SD-NEXT: dup v0.8h, w31430; CHECK-SD-NEXT: // kill: def $w0 killed $w0 def $x01431; CHECK-SD-NEXT: and x8, x0, #0xfffffff01432; CHECK-SD-NEXT: .LBB12_1: // %vector.body1433; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=11434; CHECK-SD-NEXT: add x9, x2, w0, uxtw #11435; CHECK-SD-NEXT: subs x8, x8, #161436; CHECK-SD-NEXT: ldr q1, [x9]1437; CHECK-SD-NEXT: ldur q2, [x9, #8]1438; CHECK-SD-NEXT: add x9, x1, w0, uxtw #21439; CHECK-SD-NEXT: add w0, w0, #161440; CHECK-SD-NEXT: umull2 v3.4s, v0.8h, v1.8h1441; CHECK-SD-NEXT: umull v1.4s, v0.4h, v1.4h1442; CHECK-SD-NEXT: umull2 v4.4s, v0.8h, v2.8h1443; CHECK-SD-NEXT: umull v2.4s, v0.4h, v2.4h1444; CHECK-SD-NEXT: stp q1, q3, [x9]1445; CHECK-SD-NEXT: stp q2, q4, [x9, #32]1446; CHECK-SD-NEXT: b.ne .LBB12_11447; CHECK-SD-NEXT: // %bb.2: // %for.end121448; CHECK-SD-NEXT: ret1449;1450; CHECK-GI-LABEL: matrix_mul_unsigned_and_double:1451; CHECK-GI: // %bb.0: // %vector.header1452; CHECK-GI-NEXT: and w8, w3, #0xffff1453; CHECK-GI-NEXT: dup v0.4s, w81454; CHECK-GI-NEXT: mov w8, w01455; CHECK-GI-NEXT: and x8, x8, #0xfffffff01456; CHECK-GI-NEXT: xtn v0.4h, v0.4s1457; CHECK-GI-NEXT: .LBB12_1: // %vector.body1458; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=11459; CHECK-GI-NEXT: add x9, x2, w0, uxtw #11460; CHECK-GI-NEXT: subs x8, x8, #161461; CHECK-GI-NEXT: ldr q1, [x9]1462; CHECK-GI-NEXT: ldur q2, [x9, #8]1463; CHECK-GI-NEXT: add x9, x1, w0, uxtw #21464; CHECK-GI-NEXT: add w0, w0, #161465; CHECK-GI-NEXT: mov d3, v1.d[1]1466; CHECK-GI-NEXT: mov d4, v2.d[1]1467; CHECK-GI-NEXT: umull v1.4s, v0.4h, v1.4h1468; CHECK-GI-NEXT: umull v2.4s, v0.4h, v2.4h1469; CHECK-GI-NEXT: umull v3.4s, v0.4h, v3.4h1470; CHECK-GI-NEXT: umull v4.4s, v0.4h, v4.4h1471; CHECK-GI-NEXT: stp q1, q3, [x9]1472; CHECK-GI-NEXT: stp q2, q4, [x9, #32]!1473; CHECK-GI-NEXT: b.ne .LBB12_11474; CHECK-GI-NEXT: // %bb.2: // %for.end121475; CHECK-GI-NEXT: ret1476vector.header:1477 %conv4 = and i32 %val, 655351478 %wide.trip.count = zext i32 %N to i641479 %0 = add nsw i64 %wide.trip.count, -11480 %min.iters.check = icmp ult i32 %N, 161481 %1 = trunc i64 %0 to i321482 %2 = icmp ugt i64 %0, 42949672951483 %n.vec = and i64 %wide.trip.count, 42949672801484 %broadcast.splatinsert = insertelement <8 x i32> undef, i32 %conv4, i32 01485 %broadcast.splat = shufflevector <8 x i32> %broadcast.splatinsert, <8 x i32> undef, <8 x i32> zeroinitializer1486 %broadcast.splatinsert31 = insertelement <8 x i32> undef, i32 %conv4, i32 01487 %broadcast.splat32 = shufflevector <8 x i32> %broadcast.splatinsert31, <8 x i32> undef, <8 x i32> zeroinitializer1488 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count1489 br label %vector.body1490 1491vector.body: ; preds = %vector.header, %vector.body1492 %index = phi i64 [ %index.next, %vector.body ], [ 0, %vector.header ]1493 %3 = trunc i64 %index to i321494 %4 = add i32 %N, %31495 %5 = zext i32 %4 to i641496 %6 = getelementptr inbounds i16, ptr %A, i64 %51497 %7 = bitcast ptr %6 to ptr1498 %wide.load = load <8 x i16>, ptr %7, align 21499 %8 = getelementptr inbounds i16, ptr %6, i64 41500 %9 = bitcast ptr %8 to ptr1501 %wide.load30 = load <8 x i16>, ptr %9, align 21502 %10 = zext <8 x i16> %wide.load to <8 x i32>1503 %11 = zext <8 x i16> %wide.load30 to <8 x i32>1504 %12 = mul nuw nsw <8 x i32> %broadcast.splat, %101505 %13 = mul nuw nsw <8 x i32> %broadcast.splat32, %111506 %14 = getelementptr inbounds i32, ptr %C, i64 %51507 %15 = bitcast ptr %14 to ptr1508 store <8 x i32> %12, ptr %15, align 41509 %16 = getelementptr inbounds i32, ptr %14, i64 81510 %17 = bitcast ptr %16 to ptr1511 store <8 x i32> %13, ptr %17, align 41512 %index.next = add i64 %index, 161513 %18 = icmp eq i64 %index.next, %n.vec1514 br i1 %18, label %for.end12, label %vector.body1515 1516for.end12: ; preds = %vector.body1517 ret void1518}1519 1520define void @matrix_mul_signed_and(i32 %N, ptr nocapture %C, ptr nocapture readonly %A, i32 %val) {1521; CHECK-SD-LABEL: matrix_mul_signed_and:1522; CHECK-SD: // %bb.0: // %vector.header1523; CHECK-SD-NEXT: and w9, w3, #0xffff1524; CHECK-SD-NEXT: // kill: def $w0 killed $w0 def $x01525; CHECK-SD-NEXT: and x8, x0, #0xfffffff81526; CHECK-SD-NEXT: fmov s0, w91527; CHECK-SD-NEXT: .LBB13_1: // %vector.body1528; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=11529; CHECK-SD-NEXT: add x9, x2, w0, uxtw #11530; CHECK-SD-NEXT: subs x8, x8, #81531; CHECK-SD-NEXT: ldp d1, d2, [x9]1532; CHECK-SD-NEXT: add x9, x1, w0, uxtw #21533; CHECK-SD-NEXT: add w0, w0, #81534; CHECK-SD-NEXT: sshll v1.4s, v1.4h, #01535; CHECK-SD-NEXT: sshll v2.4s, v2.4h, #01536; CHECK-SD-NEXT: mul v1.4s, v1.4s, v0.s[0]1537; CHECK-SD-NEXT: mul v2.4s, v2.4s, v0.s[0]1538; CHECK-SD-NEXT: stp q1, q2, [x9]1539; CHECK-SD-NEXT: b.ne .LBB13_11540; CHECK-SD-NEXT: // %bb.2: // %for.end121541; CHECK-SD-NEXT: ret1542;1543; CHECK-GI-LABEL: matrix_mul_signed_and:1544; CHECK-GI: // %bb.0: // %vector.header1545; CHECK-GI-NEXT: and w8, w3, #0xffff1546; CHECK-GI-NEXT: dup v0.4s, w81547; CHECK-GI-NEXT: mov w8, w01548; CHECK-GI-NEXT: and x8, x8, #0xfffffff81549; CHECK-GI-NEXT: .LBB13_1: // %vector.body1550; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=11551; CHECK-GI-NEXT: add x9, x2, w0, uxtw #11552; CHECK-GI-NEXT: subs x8, x8, #81553; CHECK-GI-NEXT: ldp d1, d2, [x9]1554; CHECK-GI-NEXT: add x9, x1, w0, uxtw #21555; CHECK-GI-NEXT: add w0, w0, #81556; CHECK-GI-NEXT: sshll v1.4s, v1.4h, #01557; CHECK-GI-NEXT: sshll v2.4s, v2.4h, #01558; CHECK-GI-NEXT: mul v1.4s, v0.4s, v1.4s1559; CHECK-GI-NEXT: mul v2.4s, v0.4s, v2.4s1560; CHECK-GI-NEXT: stp q1, q2, [x9]1561; CHECK-GI-NEXT: b.ne .LBB13_11562; CHECK-GI-NEXT: // %bb.2: // %for.end121563; CHECK-GI-NEXT: ret1564vector.header:1565 %conv4 = and i32 %val, 655351566 %wide.trip.count = zext i32 %N to i641567 %0 = add nsw i64 %wide.trip.count, -11568 %min.iters.check = icmp ult i32 %N, 81569 %1 = trunc i64 %0 to i321570 %2 = icmp ugt i64 %0, 42949672951571 %n.vec = and i64 %wide.trip.count, 42949672881572 %broadcast.splatinsert = insertelement <4 x i32> undef, i32 %conv4, i32 01573 %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> undef, <4 x i32> zeroinitializer1574 %broadcast.splatinsert31 = insertelement <4 x i32> undef, i32 %conv4, i32 01575 %broadcast.splat32 = shufflevector <4 x i32> %broadcast.splatinsert31, <4 x i32> undef, <4 x i32> zeroinitializer1576 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count1577 br label %vector.body1578 1579vector.body: ; preds = %vector.header, %vector.body1580 %index = phi i64 [ %index.next, %vector.body ], [ 0, %vector.header ]1581 %3 = trunc i64 %index to i321582 %4 = add i32 %N, %31583 %5 = zext i32 %4 to i641584 %6 = getelementptr inbounds i16, ptr %A, i64 %51585 %7 = bitcast ptr %6 to ptr1586 %wide.load = load <4 x i16>, ptr %7, align 21587 %8 = getelementptr inbounds i16, ptr %6, i64 41588 %9 = bitcast ptr %8 to ptr1589 %wide.load30 = load <4 x i16>, ptr %9, align 21590 %10 = sext <4 x i16> %wide.load to <4 x i32>1591 %11 = sext <4 x i16> %wide.load30 to <4 x i32>1592 %12 = mul nuw nsw <4 x i32> %broadcast.splat, %101593 %13 = mul nuw nsw <4 x i32> %broadcast.splat32, %111594 %14 = getelementptr inbounds i32, ptr %C, i64 %51595 %15 = bitcast ptr %14 to ptr1596 store <4 x i32> %12, ptr %15, align 41597 %16 = getelementptr inbounds i32, ptr %14, i64 41598 %17 = bitcast ptr %16 to ptr1599 store <4 x i32> %13, ptr %17, align 41600 %index.next = add i64 %index, 81601 %18 = icmp eq i64 %index.next, %n.vec1602 br i1 %18, label %for.end12, label %vector.body1603 1604for.end12: ; preds = %vector.body1605 ret void1606}1607 1608define void @matrix_mul_signed_and_double(i32 %N, ptr nocapture %C, ptr nocapture readonly %A, i32 %val) {1609; CHECK-SD-LABEL: matrix_mul_signed_and_double:1610; CHECK-SD: // %bb.0: // %vector.header1611; CHECK-SD-NEXT: and w9, w3, #0xffff1612; CHECK-SD-NEXT: // kill: def $w0 killed $w0 def $x01613; CHECK-SD-NEXT: and x8, x0, #0xfffffff01614; CHECK-SD-NEXT: fmov s0, w91615; CHECK-SD-NEXT: .LBB14_1: // %vector.body1616; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=11617; CHECK-SD-NEXT: add x9, x2, w0, uxtw #11618; CHECK-SD-NEXT: subs x8, x8, #161619; CHECK-SD-NEXT: ldr q1, [x9]1620; CHECK-SD-NEXT: ldur q2, [x9, #8]1621; CHECK-SD-NEXT: add x9, x1, w0, uxtw #21622; CHECK-SD-NEXT: add w0, w0, #161623; CHECK-SD-NEXT: sshll2 v3.4s, v1.8h, #01624; CHECK-SD-NEXT: sshll v1.4s, v1.4h, #01625; CHECK-SD-NEXT: sshll2 v4.4s, v2.8h, #01626; CHECK-SD-NEXT: sshll v2.4s, v2.4h, #01627; CHECK-SD-NEXT: mul v3.4s, v3.4s, v0.s[0]1628; CHECK-SD-NEXT: mul v1.4s, v1.4s, v0.s[0]1629; CHECK-SD-NEXT: mul v4.4s, v4.4s, v0.s[0]1630; CHECK-SD-NEXT: mul v2.4s, v2.4s, v0.s[0]1631; CHECK-SD-NEXT: stp q1, q3, [x9]1632; CHECK-SD-NEXT: stp q2, q4, [x9, #32]1633; CHECK-SD-NEXT: b.ne .LBB14_11634; CHECK-SD-NEXT: // %bb.2: // %for.end121635; CHECK-SD-NEXT: ret1636;1637; CHECK-GI-LABEL: matrix_mul_signed_and_double:1638; CHECK-GI: // %bb.0: // %vector.header1639; CHECK-GI-NEXT: and w8, w3, #0xffff1640; CHECK-GI-NEXT: dup v0.4s, w81641; CHECK-GI-NEXT: mov w8, w01642; CHECK-GI-NEXT: and x8, x8, #0xfffffff01643; CHECK-GI-NEXT: .LBB14_1: // %vector.body1644; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=11645; CHECK-GI-NEXT: add x9, x2, w0, uxtw #11646; CHECK-GI-NEXT: subs x8, x8, #161647; CHECK-GI-NEXT: ldr q1, [x9]1648; CHECK-GI-NEXT: ldur q2, [x9, #8]1649; CHECK-GI-NEXT: add x9, x1, w0, uxtw #21650; CHECK-GI-NEXT: add w0, w0, #161651; CHECK-GI-NEXT: sshll v3.4s, v1.4h, #01652; CHECK-GI-NEXT: sshll2 v1.4s, v1.8h, #01653; CHECK-GI-NEXT: sshll v4.4s, v2.4h, #01654; CHECK-GI-NEXT: sshll2 v2.4s, v2.8h, #01655; CHECK-GI-NEXT: mul v3.4s, v0.4s, v3.4s1656; CHECK-GI-NEXT: mul v1.4s, v0.4s, v1.4s1657; CHECK-GI-NEXT: mul v4.4s, v0.4s, v4.4s1658; CHECK-GI-NEXT: mul v2.4s, v0.4s, v2.4s1659; CHECK-GI-NEXT: stp q3, q1, [x9]1660; CHECK-GI-NEXT: stp q4, q2, [x9, #32]!1661; CHECK-GI-NEXT: b.ne .LBB14_11662; CHECK-GI-NEXT: // %bb.2: // %for.end121663; CHECK-GI-NEXT: ret1664vector.header:1665 %conv4 = and i32 %val, 655351666 %wide.trip.count = zext i32 %N to i641667 %0 = add nsw i64 %wide.trip.count, -11668 %min.iters.check = icmp ult i32 %N, 161669 %1 = trunc i64 %0 to i321670 %2 = icmp ugt i64 %0, 42949672951671 %n.vec = and i64 %wide.trip.count, 42949672801672 %broadcast.splatinsert = insertelement <8 x i32> undef, i32 %conv4, i32 01673 %broadcast.splat = shufflevector <8 x i32> %broadcast.splatinsert, <8 x i32> undef, <8 x i32> zeroinitializer1674 %broadcast.splatinsert31 = insertelement <8 x i32> undef, i32 %conv4, i32 01675 %broadcast.splat32 = shufflevector <8 x i32> %broadcast.splatinsert31, <8 x i32> undef, <8 x i32> zeroinitializer1676 %cmp.n = icmp eq i64 %n.vec, %wide.trip.count1677 br label %vector.body1678 1679vector.body: ; preds = %vector.header, %vector.body1680 %index = phi i64 [ %index.next, %vector.body ], [ 0, %vector.header ]1681 %3 = trunc i64 %index to i321682 %4 = add i32 %N, %31683 %5 = zext i32 %4 to i641684 %6 = getelementptr inbounds i16, ptr %A, i64 %51685 %7 = bitcast ptr %6 to ptr1686 %wide.load = load <8 x i16>, ptr %7, align 21687 %8 = getelementptr inbounds i16, ptr %6, i64 41688 %9 = bitcast ptr %8 to ptr1689 %wide.load30 = load <8 x i16>, ptr %9, align 21690 %10 = sext <8 x i16> %wide.load to <8 x i32>1691 %11 = sext <8 x i16> %wide.load30 to <8 x i32>1692 %12 = mul nuw nsw <8 x i32> %broadcast.splat, %101693 %13 = mul nuw nsw <8 x i32> %broadcast.splat32, %111694 %14 = getelementptr inbounds i32, ptr %C, i64 %51695 %15 = bitcast ptr %14 to ptr1696 store <8 x i32> %12, ptr %15, align 41697 %16 = getelementptr inbounds i32, ptr %14, i64 81698 %17 = bitcast ptr %16 to ptr1699 store <8 x i32> %13, ptr %17, align 41700 %index.next = add i64 %index, 161701 %18 = icmp eq i64 %index.next, %n.vec1702 br i1 %18, label %for.end12, label %vector.body1703 1704for.end12: ; preds = %vector.body1705 ret void1706}1707 1708define noundef <8 x i16> @cmplx_mul_combined_re_im(<8 x i16> noundef %a, i64 %scale.coerce) {1709; CHECK-SD-LABEL: cmplx_mul_combined_re_im:1710; CHECK-SD: // %bb.0: // %entry1711; CHECK-SD-NEXT: lsr x9, x0, #161712; CHECK-SD-NEXT: adrp x8, .LCPI15_01713; CHECK-SD-NEXT: dup v4.8h, w01714; CHECK-SD-NEXT: ldr q3, [x8, :lo12:.LCPI15_0]1715; CHECK-SD-NEXT: dup v2.8h, w91716; CHECK-SD-NEXT: sqneg v1.8h, v2.8h1717; CHECK-SD-NEXT: tbl v1.16b, { v1.16b, v2.16b }, v3.16b1718; CHECK-SD-NEXT: rev32 v2.8h, v0.8h1719; CHECK-SD-NEXT: sqdmull v3.4s, v0.4h, v4.4h1720; CHECK-SD-NEXT: sqdmull2 v0.4s, v0.8h, v4.8h1721; CHECK-SD-NEXT: sqdmlal v3.4s, v2.4h, v1.4h1722; CHECK-SD-NEXT: sqdmlal2 v0.4s, v2.8h, v1.8h1723; CHECK-SD-NEXT: uzp2 v0.8h, v3.8h, v0.8h1724; CHECK-SD-NEXT: ret1725;1726; CHECK-GI-LABEL: cmplx_mul_combined_re_im:1727; CHECK-GI: // %bb.0: // %entry1728; CHECK-GI-NEXT: lsr w9, w0, #161729; CHECK-GI-NEXT: adrp x8, .LCPI15_01730; CHECK-GI-NEXT: rev32 v4.8h, v0.8h1731; CHECK-GI-NEXT: dup v1.8h, w91732; CHECK-GI-NEXT: fmov s3, w91733; CHECK-GI-NEXT: sqneg v2.8h, v1.8h1734; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI15_0]1735; CHECK-GI-NEXT: tbl v1.16b, { v2.16b, v3.16b }, v1.16b1736; CHECK-GI-NEXT: mov d2, v0.d[1]1737; CHECK-GI-NEXT: dup v3.8h, w01738; CHECK-GI-NEXT: sqdmull v2.4s, v2.4h, v3.4h1739; CHECK-GI-NEXT: sqdmull v5.4s, v4.4h, v1.4h1740; CHECK-GI-NEXT: sqdmlal v5.4s, v0.4h, v3.4h1741; CHECK-GI-NEXT: sqdmlal2 v2.4s, v4.8h, v1.8h1742; CHECK-GI-NEXT: uzp2 v0.8h, v5.8h, v2.8h1743; CHECK-GI-NEXT: ret1744entry:1745 %scale.sroa.0.0.extract.trunc = trunc i64 %scale.coerce to i161746 %scale.sroa.2.0.extract.shift23 = lshr i64 %scale.coerce, 161747 %scale.sroa.2.0.extract.trunc = trunc i64 %scale.sroa.2.0.extract.shift23 to i161748 %shuffle.i = shufflevector <8 x i16> %a, <8 x i16> poison, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>1749 %vecinit.i24 = insertelement <8 x i16> poison, i16 %scale.sroa.0.0.extract.trunc, i64 01750 %vecinit.i = insertelement <8 x i16> poison, i16 %scale.sroa.2.0.extract.trunc, i64 01751 %vecinit7.i = shufflevector <8 x i16> %vecinit.i, <8 x i16> poison, <8 x i32> zeroinitializer1752 %vqnegq_v1.i = tail call noundef <8 x i16> @llvm.aarch64.neon.sqneg.v8i16(<8 x i16> %vecinit7.i)1753 %vbsl5.i = shufflevector <8 x i16> %vqnegq_v1.i, <8 x i16> %vecinit.i, <8 x i32> <i32 0, i32 8, i32 2, i32 8, i32 4, i32 8, i32 6, i32 8>1754 %shuffle.i40 = shufflevector <8 x i16> %a, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>1755 %shuffle.i39 = shufflevector <8 x i16> %vecinit.i24, <8 x i16> poison, <4 x i32> zeroinitializer1756 %vqdmull_v2.i36 = tail call noundef <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %shuffle.i40, <4 x i16> %shuffle.i39)1757 %shuffle.i44 = shufflevector <8 x i16> %a, <8 x i16> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>1758 %vqdmull_v2.i = tail call noundef <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %shuffle.i44, <4 x i16> %shuffle.i39)1759 %shuffle.i38 = shufflevector <8 x i16> %shuffle.i, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>1760 %shuffle.i37 = shufflevector <8 x i16> %vbsl5.i, <8 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>1761 %vqdmlal2.i45 = tail call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %shuffle.i38, <4 x i16> %shuffle.i37)1762 %vqdmlal_v3.i46 = tail call noundef <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> %vqdmull_v2.i36, <4 x i32> %vqdmlal2.i45)1763 %shuffle.i42 = shufflevector <8 x i16> %shuffle.i, <8 x i16> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>1764 %shuffle.i41 = shufflevector <8 x i16> %vbsl5.i, <8 x i16> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>1765 %vqdmlal2.i = tail call <4 x i32> @llvm.aarch64.neon.sqdmull.v4i32(<4 x i16> %shuffle.i42, <4 x i16> %shuffle.i41)1766 %vqdmlal_v3.i = tail call noundef <4 x i32> @llvm.aarch64.neon.sqadd.v4i32(<4 x i32> %vqdmull_v2.i, <4 x i32> %vqdmlal2.i)1767 %0 = bitcast <4 x i32> %vqdmlal_v3.i46 to <8 x i16>1768 %1 = bitcast <4 x i32> %vqdmlal_v3.i to <8 x i16>1769 %shuffle.i35 = shufflevector <8 x i16> %0, <8 x i16> %1, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>1770 ret <8 x i16> %shuffle.i351771}1772 1773 1774;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:1775; CHECK: {{.*}}1776