[clang][bytecode][NFC] Only get expr when checking for UB (#125397)
[llvm-project.git] / llvm / test / Transforms / CodeGenPrepare / AArch64 / reduce-or-opt.ll
blob14a6b2f6e9c4f2be015474d57b8abece5ca60920
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]]
23 entry:
24   br label %vector.body
26 vector.body:
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
37 middle.split:
38   %sel = select i1 %or.reduc, i64 1, i64 0
39   ret i64 %sel
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:.*]]
59 ; CHECK:       [[FOUND]]:
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
65 entry:
66   br label %vector.body
68 vector.body:
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
79 middle.split:
80   br i1 %or.reduc, label %found, label %notfound
82 found:
83   store i64 56, ptr %p, align 8
84   ret i64 1
86 notfound:
87   ret i64 0
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]]
113 entry:
114   %vscale = tail call i64 @llvm.vscale.i64()
115   %vf = shl nuw nsw i64 %vscale, 1
116   br label %vector.body
118 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
129 middle.split:
130   %sel = select i1 %or.reduc, i64 1, i64 0
131   ret i64 %sel
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:.*]]
155 ; CHECK:       [[FOUND]]:
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
161 entry:
162   %vscale = tail call i64 @llvm.vscale.i64()
163   %vf = shl nuw nsw i64 %vscale, 1
164   br label %vector.body
166 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
177 middle.split:
178   br i1 %or.reduc, label %found, label %notfound
180 found:
181   store i64 56, ptr %p, align 8
182   ret i64 1
184 notfound:
185   ret i64 0
188 declare i1 @llvm.vector.reduce.or.v2i1(<2 x i1>)
189 declare i1 @llvm.vector.reduce.or.nxv2i1(<vscale x 2 x i1>)