1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt -codegenprepare -S < %s -mtriple=aarch64-none-linux-gnu -mattr=+sve | FileCheck %s
4 define i64 @select_or_reduce_v2i1(ptr nocapture noundef readonly %src) {
5 ; CHECK-LABEL: define i64 @select_or_reduce_v2i1(
6 ; CHECK-SAME: ptr noundef readonly captures(none) [[SRC:%.*]]) #[[ATTR0:[0-9]+]] {
7 ; CHECK-NEXT: [[ENTRY:.*]]:
8 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
9 ; CHECK: [[VECTOR_BODY]]:
10 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
11 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[INDEX]]
12 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x ptr>, ptr [[ARRAYIDX]], align 8
13 ; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x ptr> [[WIDE_LOAD]], zeroinitializer
14 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
15 ; CHECK-NEXT: [[OR_REDUC:%.*]] = tail call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[COND]])
16 ; CHECK-NEXT: [[IV_CMP:%.*]] = icmp eq i64 [[INDEX_NEXT]], 4
17 ; CHECK-NEXT: [[EXIT_COND:%.*]] = or i1 [[OR_REDUC]], [[IV_CMP]]
18 ; CHECK-NEXT: br i1 [[EXIT_COND]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]]
19 ; CHECK: [[MIDDLE_SPLIT]]:
20 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[OR_REDUC]], i64 1, i64 0
21 ; CHECK-NEXT: ret i64 [[SEL]]
27 %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
28 %arrayidx = getelementptr inbounds ptr, ptr %src, i64 %index
29 %wide.load = load <2 x ptr>, ptr %arrayidx, align 8
30 %cond = icmp eq <2 x ptr> %wide.load, splat(ptr zeroinitializer)
31 %index.next = add nuw i64 %index, 2
32 %or.reduc = tail call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> %cond)
33 %iv.cmp = icmp eq i64 %index.next, 4
34 %exit.cond = or i1 %or.reduc, %iv.cmp
35 br i1 %exit.cond, label %middle.split, label %vector.body
38 %sel = select i1 %or.reduc, i64 1, i64 0
42 define i64 @br_or_reduce_v2i1(ptr nocapture noundef readonly %src, ptr noundef readnone %p) {
43 ; CHECK-LABEL: define i64 @br_or_reduce_v2i1(
44 ; CHECK-SAME: ptr noundef readonly captures(none) [[SRC:%.*]], ptr noundef readnone [[P:%.*]]) #[[ATTR0]] {
45 ; CHECK-NEXT: [[ENTRY:.*]]:
46 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
47 ; CHECK: [[VECTOR_BODY]]:
48 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
49 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[INDEX]]
50 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x ptr>, ptr [[ARRAYIDX]], align 8
51 ; CHECK-NEXT: [[COND:%.*]] = icmp eq <2 x ptr> [[WIDE_LOAD]], zeroinitializer
52 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
53 ; CHECK-NEXT: [[OR_REDUC:%.*]] = tail call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[COND]])
54 ; CHECK-NEXT: [[IV_CMP:%.*]] = icmp eq i64 [[INDEX_NEXT]], 4
55 ; CHECK-NEXT: [[EXIT_COND:%.*]] = or i1 [[OR_REDUC]], [[IV_CMP]]
56 ; CHECK-NEXT: br i1 [[EXIT_COND]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]]
57 ; CHECK: [[MIDDLE_SPLIT]]:
58 ; CHECK-NEXT: br i1 [[OR_REDUC]], label %[[FOUND:.*]], label %[[NOTFOUND:.*]]
60 ; CHECK-NEXT: store i64 56, ptr [[P]], align 8
61 ; CHECK-NEXT: ret i64 1
62 ; CHECK: [[NOTFOUND]]:
63 ; CHECK-NEXT: ret i64 0
69 %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
70 %arrayidx = getelementptr inbounds ptr, ptr %src, i64 %index
71 %wide.load = load <2 x ptr>, ptr %arrayidx, align 8
72 %cond = icmp eq <2 x ptr> %wide.load, splat(ptr zeroinitializer)
73 %index.next = add nuw i64 %index, 2
74 %or.reduc = tail call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> %cond)
75 %iv.cmp = icmp eq i64 %index.next, 4
76 %exit.cond = or i1 %or.reduc, %iv.cmp
77 br i1 %exit.cond, label %middle.split, label %vector.body
80 br i1 %or.reduc, label %found, label %notfound
83 store i64 56, ptr %p, align 8
90 define i64 @select_or_reduce_nxv2i1(ptr nocapture noundef readonly %src) {
91 ; CHECK-LABEL: define i64 @select_or_reduce_nxv2i1(
92 ; CHECK-SAME: ptr noundef readonly captures(none) [[SRC:%.*]]) #[[ATTR0]] {
93 ; CHECK-NEXT: [[ENTRY:.*]]:
94 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
95 ; CHECK: [[VECTOR_BODY]]:
96 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
97 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[INDEX]]
98 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <vscale x 2 x ptr>, ptr [[ARRAYIDX]], align 8
99 ; CHECK-NEXT: [[COND:%.*]] = icmp eq <vscale x 2 x ptr> [[WIDE_LOAD]], zeroinitializer
100 ; CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.vscale.i64()
101 ; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i64 [[TMP0]], 1
102 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP1]]
103 ; CHECK-NEXT: [[OR_REDUC:%.*]] = tail call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> [[COND]])
104 ; CHECK-NEXT: [[IV_CMP:%.*]] = icmp eq i64 [[INDEX_NEXT]], 4
105 ; CHECK-NEXT: [[EXIT_COND:%.*]] = or i1 [[OR_REDUC]], [[IV_CMP]]
106 ; CHECK-NEXT: br i1 [[EXIT_COND]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]]
107 ; CHECK: [[MIDDLE_SPLIT]]:
108 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <vscale x 2 x ptr> [[WIDE_LOAD]], zeroinitializer
109 ; CHECK-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> [[TMP2]])
110 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[TMP3]], i64 1, i64 0
111 ; CHECK-NEXT: ret i64 [[SEL]]
114 %vscale = tail call i64 @llvm.vscale.i64()
115 %vf = shl nuw nsw i64 %vscale, 1
116 br label %vector.body
119 %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
120 %arrayidx = getelementptr inbounds ptr, ptr %src, i64 %index
121 %wide.load = load <vscale x 2 x ptr>, ptr %arrayidx, align 8
122 %cond = icmp eq <vscale x 2 x ptr> %wide.load, splat(ptr zeroinitializer)
123 %index.next = add nuw i64 %index, %vf
124 %or.reduc = tail call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> %cond)
125 %iv.cmp = icmp eq i64 %index.next, 4
126 %exit.cond = or i1 %or.reduc, %iv.cmp
127 br i1 %exit.cond, label %middle.split, label %vector.body
130 %sel = select i1 %or.reduc, i64 1, i64 0
134 define i64 @br_or_reduce_nxv2i1(ptr nocapture noundef readonly %src, ptr noundef readnone %p) {
135 ; CHECK-LABEL: define i64 @br_or_reduce_nxv2i1(
136 ; CHECK-SAME: ptr noundef readonly captures(none) [[SRC:%.*]], ptr noundef readnone [[P:%.*]]) #[[ATTR0]] {
137 ; CHECK-NEXT: [[ENTRY:.*]]:
138 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
139 ; CHECK: [[VECTOR_BODY]]:
140 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
141 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[SRC]], i64 [[INDEX]]
142 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <vscale x 2 x ptr>, ptr [[ARRAYIDX]], align 8
143 ; CHECK-NEXT: [[COND:%.*]] = icmp eq <vscale x 2 x ptr> [[WIDE_LOAD]], zeroinitializer
144 ; CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.vscale.i64()
145 ; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i64 [[TMP0]], 1
146 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP1]]
147 ; CHECK-NEXT: [[OR_REDUC:%.*]] = tail call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> [[COND]])
148 ; CHECK-NEXT: [[IV_CMP:%.*]] = icmp eq i64 [[INDEX_NEXT]], 4
149 ; CHECK-NEXT: [[EXIT_COND:%.*]] = or i1 [[OR_REDUC]], [[IV_CMP]]
150 ; CHECK-NEXT: br i1 [[EXIT_COND]], label %[[MIDDLE_SPLIT:.*]], label %[[VECTOR_BODY]]
151 ; CHECK: [[MIDDLE_SPLIT]]:
152 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <vscale x 2 x ptr> [[WIDE_LOAD]], zeroinitializer
153 ; CHECK-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> [[TMP2]])
154 ; CHECK-NEXT: br i1 [[TMP3]], label %[[FOUND:.*]], label %[[NOTFOUND:.*]]
156 ; CHECK-NEXT: store i64 56, ptr [[P]], align 8
157 ; CHECK-NEXT: ret i64 1
158 ; CHECK: [[NOTFOUND]]:
159 ; CHECK-NEXT: ret i64 0
162 %vscale = tail call i64 @llvm.vscale.i64()
163 %vf = shl nuw nsw i64 %vscale, 1
164 br label %vector.body
167 %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
168 %arrayidx = getelementptr inbounds ptr, ptr %src, i64 %index
169 %wide.load = load <vscale x 2 x ptr>, ptr %arrayidx, align 8
170 %cond = icmp eq <vscale x 2 x ptr> %wide.load, splat(ptr zeroinitializer)
171 %index.next = add nuw i64 %index, %vf
172 %or.reduc = tail call i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1> %cond)
173 %iv.cmp = icmp eq i64 %index.next, 4
174 %exit.cond = or i1 %or.reduc, %iv.cmp
175 br i1 %exit.cond, label %middle.split, label %vector.body
178 br i1 %or.reduc, label %found, label %notfound
181 store i64 56, ptr %p, align 8
188 declare i1 @llvm.vector.reduce.or.v2i1(<2 x i1>)
189 declare i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1>)