1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
3 ; RUN: llc -mtriple=thumbv8.1m.main -mattr=+mve -tail-predication=enabled \
4 ; RUN: %s -o - --verify-machineinstrs | FileCheck %s --check-prefix=ENABLED
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
10 define dso_local void @check_option(ptr noalias nocapture %A, ptr noalias nocapture readonly %B, ptr 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}
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: vctp.32 r6
61 ; DISABLED-NEXT: mov lr, r7
62 ; DISABLED-NEXT: vpstt
63 ; DISABLED-NEXT: vldrwt.u32 q0, [r5], #16
64 ; DISABLED-NEXT: vldrwt.u32 q1, [r4], #16
65 ; DISABLED-NEXT: subs r7, #1
66 ; DISABLED-NEXT: subs r6, #4
67 ; DISABLED-NEXT: vadd.i32 q0, q1, q0
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}
75 %cmp8 = icmp sgt i32 %N, 0
78 %2 = shl nuw i32 %1, 2
81 %5 = add nuw nsw i32 %4, 1
82 br i1 %cmp8, label %vector.ph, label %for.cond.cleanup
84 vector.ph: ; preds = %entry
85 %start = call i32 @llvm.start.loop.iterations.i32(i32 %5)
88 vector.body: ; preds = %vector.body, %vector.ph
89 %lsr.iv17 = phi ptr [ %scevgep18, %vector.body ], [ %A, %vector.ph ]
90 %lsr.iv14 = phi ptr [ %scevgep15, %vector.body ], [ %C, %vector.ph ]
91 %lsr.iv = phi ptr [ %scevgep, %vector.body ], [ %B, %vector.ph ]
92 %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
93 %6 = phi i32 [ %start, %vector.ph ], [ %8, %vector.body ]
94 %active.lane.mask = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %index, i32 %N)
95 %wide.masked.load = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %lsr.iv, i32 4, <4 x i1> %active.lane.mask, <4 x i32> undef)
96 %wide.masked.load12 = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %lsr.iv14, i32 4, <4 x i1> %active.lane.mask, <4 x i32> undef)
97 %7 = add nsw <4 x i32> %wide.masked.load12, %wide.masked.load
98 call void @llvm.masked.store.v4i32.p0(<4 x i32> %7, ptr %lsr.iv17, i32 4, <4 x i1> %active.lane.mask)
99 %index.next = add i32 %index, 4
100 %scevgep = getelementptr i32, ptr %lsr.iv, i32 4
101 %scevgep15 = getelementptr i32, ptr %lsr.iv14, i32 4
102 %scevgep18 = getelementptr i32, ptr %lsr.iv17, i32 4
103 %8 = call i32 @llvm.loop.decrement.reg.i32(i32 %6, i32 1)
104 %9 = icmp ne i32 %8, 0
105 ;br i1 %9, label %vector.body, label %for.cond.cleanup
106 br i1 %9, label %vector.body, label %vector.ph
108 for.cond.cleanup: ; preds = %vector.body, %entry
112 declare <4 x i32> @llvm.masked.load.v4i32.p0(ptr, i32 immarg, <4 x i1>, <4 x i32>)
113 declare void @llvm.masked.store.v4i32.p0(<4 x i32>, ptr, i32 immarg, <4 x i1>)
114 declare i32 @llvm.start.loop.iterations.i32(i32)
115 declare i32 @llvm.loop.decrement.reg.i32(i32, i32)
116 declare <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32, i32)