1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; 3; RUN: llc -mtriple=thumbv8.1m.main -mattr=+mve -tail-predication=enabled \ 4; RUN: %s -o - --verify-machineinstrs | FileCheck %s --check-prefix=ENABLED 5; 6; RUN: llc -mtriple=thumbv8.1m.main -mattr=+mve -tail-predication=enabled \ 7; RUN: -arm-loloops-disable-tailpred %s -o - --verify-machineinstrs | \ 8; RUN: FileCheck %s --check-prefix=DISABLED 9 10define dso_local void @check_option(i32* noalias nocapture %A, i32* noalias nocapture readonly %B, i32* noalias nocapture readonly %C, i32 %N) local_unnamed_addr #0 { 11; ENABLED-LABEL: check_option: 12; ENABLED: @ %bb.0: @ %entry 13; ENABLED-NEXT: push.w {r4, r5, r6, r7, r8, lr} 14; ENABLED-NEXT: cmp r3, #1 15; ENABLED-NEXT: blt .LBB0_4 16; ENABLED-NEXT: @ %bb.1: @ %vector.ph.preheader 17; ENABLED-NEXT: .LBB0_2: @ %vector.ph 18; ENABLED-NEXT: @ =>This Loop Header: Depth=1 19; ENABLED-NEXT: @ Child Loop BB0_3 Depth 2 20; ENABLED-NEXT: mov r12, r0 21; ENABLED-NEXT: mov r4, r2 22; ENABLED-NEXT: mov r5, r1 23; ENABLED-NEXT: mov r6, r3 24; ENABLED-NEXT: dlstp.32 lr, r6 25; ENABLED-NEXT: .LBB0_3: @ %vector.body 26; ENABLED-NEXT: @ Parent Loop BB0_2 Depth=1 27; ENABLED-NEXT: @ => This Inner Loop Header: Depth=2 28; ENABLED-NEXT: vldrw.u32 q0, [r5], #16 29; ENABLED-NEXT: vldrw.u32 q1, [r4], #16 30; ENABLED-NEXT: vadd.i32 q0, q1, q0 31; ENABLED-NEXT: vstrw.32 q0, [r12], #16 32; ENABLED-NEXT: letp lr, .LBB0_3 33; ENABLED-NEXT: b .LBB0_2 34; ENABLED-NEXT: .LBB0_4: @ %for.cond.cleanup 35; ENABLED-NEXT: pop.w {r4, r5, r6, r7, r8, pc} 36; 37; DISABLED-LABEL: check_option: 38; DISABLED: @ %bb.0: @ %entry 39; DISABLED-NEXT: push.w {r4, r5, r6, r7, r8, lr} 40; DISABLED-NEXT: cmp r3, #1 41; DISABLED-NEXT: blt .LBB0_4 42; DISABLED-NEXT: @ %bb.1: @ %vector.ph.preheader 43; DISABLED-NEXT: adds r7, r3, #3 44; DISABLED-NEXT: movs r6, #1 45; DISABLED-NEXT: bic r7, r7, #3 46; DISABLED-NEXT: subs r7, #4 47; DISABLED-NEXT: add.w r8, r6, r7, lsr #2 48; DISABLED-NEXT: .LBB0_2: @ %vector.ph 49; DISABLED-NEXT: @ =>This Loop Header: Depth=1 50; DISABLED-NEXT: @ Child Loop BB0_3 Depth 2 51; DISABLED-NEXT: mov r7, r8 52; DISABLED-NEXT: mov r12, r0 53; DISABLED-NEXT: mov r4, r2 54; DISABLED-NEXT: mov r5, r1 55; DISABLED-NEXT: mov r6, r3 56; DISABLED-NEXT: dls lr, r8 57; DISABLED-NEXT: .LBB0_3: @ %vector.body 58; DISABLED-NEXT: @ Parent Loop BB0_2 Depth=1 59; DISABLED-NEXT: @ => This Inner Loop Header: Depth=2 60; DISABLED-NEXT: mov lr, r7 61; DISABLED-NEXT: vctp.32 r6 62; DISABLED-NEXT: subs r7, #1 63; DISABLED-NEXT: subs r6, #4 64; DISABLED-NEXT: vpstt 65; DISABLED-NEXT: vldrwt.u32 q0, [r5], #16 66; DISABLED-NEXT: vldrwt.u32 q1, [r4], #16 67; DISABLED-NEXT: vadd.i32 q0, q1, q0 68; DISABLED-NEXT: vpst 69; DISABLED-NEXT: vstrwt.32 q0, [r12], #16 70; DISABLED-NEXT: le lr, .LBB0_3 71; DISABLED-NEXT: b .LBB0_2 72; DISABLED-NEXT: .LBB0_4: @ %for.cond.cleanup 73; DISABLED-NEXT: pop.w {r4, r5, r6, r7, r8, pc} 74entry: 75 %cmp8 = icmp sgt i32 %N, 0 76 %0 = add i32 %N, 3 77 %1 = lshr i32 %0, 2 78 %2 = shl nuw i32 %1, 2 79 %3 = add i32 %2, -4 80 %4 = lshr i32 %3, 2 81 %5 = add nuw nsw i32 %4, 1 82 br i1 %cmp8, label %vector.ph, label %for.cond.cleanup 83 84vector.ph: ; preds = %entry 85 %trip.count.minus.1 = add i32 %N, -1 86 %start = call i32 @llvm.start.loop.iterations.i32(i32 %5) 87 br label %vector.body 88 89vector.body: ; preds = %vector.body, %vector.ph 90 %lsr.iv17 = phi i32* [ %scevgep18, %vector.body ], [ %A, %vector.ph ] 91 %lsr.iv14 = phi i32* [ %scevgep15, %vector.body ], [ %C, %vector.ph ] 92 %lsr.iv = phi i32* [ %scevgep, %vector.body ], [ %B, %vector.ph ] 93 %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ] 94 %6 = phi i32 [ %start, %vector.ph ], [ %8, %vector.body ] 95 96 %lsr.iv13 = bitcast i32* %lsr.iv to <4 x i32>* 97 %lsr.iv1416 = bitcast i32* %lsr.iv14 to <4 x i32>* 98 %lsr.iv1719 = bitcast i32* %lsr.iv17 to <4 x i32>* 99 100 %active.lane.mask = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N) 101 102 %wide.masked.load = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %lsr.iv13, i32 4, <4 x i1> %active.lane.mask, <4 x i32> undef) 103 %wide.masked.load12 = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %lsr.iv1416, i32 4, <4 x i1> %active.lane.mask, <4 x i32> undef) 104 %7 = add nsw <4 x i32> %wide.masked.load12, %wide.masked.load 105 call void @llvm.masked.store.v4i32.p0v4i32(<4 x i32> %7, <4 x i32>* %lsr.iv1719, i32 4, <4 x i1> %active.lane.mask) 106 %index.next = add i32 %index, 4 107 %scevgep = getelementptr i32, i32* %lsr.iv, i32 4 108 %scevgep15 = getelementptr i32, i32* %lsr.iv14, i32 4 109 %scevgep18 = getelementptr i32, i32* %lsr.iv17, i32 4 110 %8 = call i32 @llvm.loop.decrement.reg.i32(i32 %6, i32 1) 111 %9 = icmp ne i32 %8, 0 112 ;br i1 %9, label %vector.body, label %for.cond.cleanup 113 br i1 %9, label %vector.body, label %vector.ph 114 115for.cond.cleanup: ; preds = %vector.body, %entry 116 ret void 117} 118 119declare <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>*, i32 immarg, <4 x i1>, <4 x i32>) 120declare void @llvm.masked.store.v4i32.p0v4i32(<4 x i32>, <4 x i32>*, i32 immarg, <4 x i1>) 121declare i32 @llvm.start.loop.iterations.i32(i32) 122declare i32 @llvm.loop.decrement.reg.i32(i32, i32) 123declare <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32, i32) 124