1; RUN: llc -march=arm64 -aarch64-neon-syntax=apple < %s -mcpu=cyclone | FileCheck %s
2; ModuleID = 'arm64_vecCmpBr.c'
3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64-S128"
4target triple = "arm64-apple-ios3.0.0"
5
6
7define i32 @anyZero64(<4 x i16> %a) #0 {
8; CHECK: _anyZero64:
9; CHECK: uminv.8b b[[REGNO1:[0-9]+]], v0
10; CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
11; CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[A-Z_0-9]+]]
12; CHECK: [[LABEL]]:
13; CHECK-NEXT: b _bar
14entry:
15  %0 = bitcast <4 x i16> %a to <8 x i8>
16  %vminv.i = tail call i32 @llvm.aarch64.neon.uminv.i32.v8i8(<8 x i8> %0) #3
17  %1 = trunc i32 %vminv.i to i8
18  %tobool = icmp eq i8 %1, 0
19  br i1 %tobool, label %if.then, label %return
20
21if.then:                                          ; preds = %entry
22  %call1 = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() #4
23  br label %return
24
25return:                                           ; preds = %entry, %if.then
26  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
27  ret i32 %retval.0
28}
29
30declare i32 @bar(...) #1
31
32define i32 @anyZero128(<8 x i16> %a) #0 {
33; CHECK: _anyZero128:
34; CHECK: uminv.16b b[[REGNO1:[0-9]+]], v0
35; CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
36; CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[A-Z_0-9]+]]
37; CHECK: [[LABEL]]:
38; CHECK-NEXT: b _bar
39
40entry:
41  %0 = bitcast <8 x i16> %a to <16 x i8>
42  %vminv.i = tail call i32 @llvm.aarch64.neon.uminv.i32.v16i8(<16 x i8> %0) #3
43  %1 = trunc i32 %vminv.i to i8
44  %tobool = icmp eq i8 %1, 0
45  br i1 %tobool, label %if.then, label %return
46
47if.then:                                          ; preds = %entry
48  %call1 = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() #4
49  br label %return
50
51return:                                           ; preds = %entry, %if.then
52  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
53  ret i32 %retval.0
54}
55
56define i32 @anyNonZero64(<4 x i16> %a) #0 {
57; CHECK: _anyNonZero64:
58; CHECK: umaxv.8b b[[REGNO1:[0-9]+]], v0
59; CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
60; CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[A-Z_0-9]+]]
61; CHECK: [[LABEL]]:
62; CHECK-NEXT: movz w0, #0
63
64entry:
65  %0 = bitcast <4 x i16> %a to <8 x i8>
66  %vmaxv.i = tail call i32 @llvm.aarch64.neon.umaxv.i32.v8i8(<8 x i8> %0) #3
67  %1 = trunc i32 %vmaxv.i to i8
68  %tobool = icmp eq i8 %1, 0
69  br i1 %tobool, label %return, label %if.then
70
71if.then:                                          ; preds = %entry
72  %call1 = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() #4
73  br label %return
74
75return:                                           ; preds = %entry, %if.then
76  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
77  ret i32 %retval.0
78}
79
80define i32 @anyNonZero128(<8 x i16> %a) #0 {
81; CHECK: _anyNonZero128:
82; CHECK: umaxv.16b b[[REGNO1:[0-9]+]], v0
83; CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
84; CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[A-Z_0-9]+]]
85; CHECK: [[LABEL]]:
86; CHECK-NEXT: movz w0, #0
87entry:
88  %0 = bitcast <8 x i16> %a to <16 x i8>
89  %vmaxv.i = tail call i32 @llvm.aarch64.neon.umaxv.i32.v16i8(<16 x i8> %0) #3
90  %1 = trunc i32 %vmaxv.i to i8
91  %tobool = icmp eq i8 %1, 0
92  br i1 %tobool, label %return, label %if.then
93
94if.then:                                          ; preds = %entry
95  %call1 = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() #4
96  br label %return
97
98return:                                           ; preds = %entry, %if.then
99  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
100  ret i32 %retval.0
101}
102
103define i32 @allZero64(<4 x i16> %a) #0 {
104; CHECK: _allZero64:
105; CHECK: umaxv.8b b[[REGNO1:[0-9]+]], v0
106; CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
107; CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[A-Z_0-9]+]]
108; CHECK: [[LABEL]]:
109; CHECK-NEXT: b _bar
110entry:
111  %0 = bitcast <4 x i16> %a to <8 x i8>
112  %vmaxv.i = tail call i32 @llvm.aarch64.neon.umaxv.i32.v8i8(<8 x i8> %0) #3
113  %1 = trunc i32 %vmaxv.i to i8
114  %tobool = icmp eq i8 %1, 0
115  br i1 %tobool, label %if.then, label %return
116
117if.then:                                          ; preds = %entry
118  %call1 = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() #4
119  br label %return
120
121return:                                           ; preds = %entry, %if.then
122  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
123  ret i32 %retval.0
124}
125
126define i32 @allZero128(<8 x i16> %a) #0 {
127; CHECK: _allZero128:
128; CHECK: umaxv.16b b[[REGNO1:[0-9]+]], v0
129; CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
130; CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[A-Z_0-9]+]]
131; CHECK: [[LABEL]]:
132; CHECK-NEXT: b _bar
133entry:
134  %0 = bitcast <8 x i16> %a to <16 x i8>
135  %vmaxv.i = tail call i32 @llvm.aarch64.neon.umaxv.i32.v16i8(<16 x i8> %0) #3
136  %1 = trunc i32 %vmaxv.i to i8
137  %tobool = icmp eq i8 %1, 0
138  br i1 %tobool, label %if.then, label %return
139
140if.then:                                          ; preds = %entry
141  %call1 = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() #4
142  br label %return
143
144return:                                           ; preds = %entry, %if.then
145  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
146  ret i32 %retval.0
147}
148
149define i32 @allNonZero64(<4 x i16> %a) #0 {
150; CHECK: _allNonZero64:
151; CHECK: uminv.8b b[[REGNO1:[0-9]+]], v0
152; CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
153; CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[A-Z_0-9]+]]
154; CHECK: [[LABEL]]:
155; CHECK-NEXT: movz w0, #0
156entry:
157  %0 = bitcast <4 x i16> %a to <8 x i8>
158  %vminv.i = tail call i32 @llvm.aarch64.neon.uminv.i32.v8i8(<8 x i8> %0) #3
159  %1 = trunc i32 %vminv.i to i8
160  %tobool = icmp eq i8 %1, 0
161  br i1 %tobool, label %return, label %if.then
162
163if.then:                                          ; preds = %entry
164  %call1 = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() #4
165  br label %return
166
167return:                                           ; preds = %entry, %if.then
168  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
169  ret i32 %retval.0
170}
171
172define i32 @allNonZero128(<8 x i16> %a) #0 {
173; CHECK: _allNonZero128:
174; CHECK: uminv.16b b[[REGNO1:[0-9]+]], v0
175; CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
176; CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[A-Z_0-9]+]]
177; CHECK: [[LABEL]]:
178; CHECK-NEXT: movz w0, #0
179entry:
180  %0 = bitcast <8 x i16> %a to <16 x i8>
181  %vminv.i = tail call i32 @llvm.aarch64.neon.uminv.i32.v16i8(<16 x i8> %0) #3
182  %1 = trunc i32 %vminv.i to i8
183  %tobool = icmp eq i8 %1, 0
184  br i1 %tobool, label %return, label %if.then
185
186if.then:                                          ; preds = %entry
187  %call1 = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() #4
188  br label %return
189
190return:                                           ; preds = %entry, %if.then
191  %retval.0 = phi i32 [ %call1, %if.then ], [ 0, %entry ]
192  ret i32 %retval.0
193}
194
195declare i32 @llvm.aarch64.neon.umaxv.i32.v16i8(<16 x i8>) #2
196
197declare i32 @llvm.aarch64.neon.umaxv.i32.v8i8(<8 x i8>) #2
198
199declare i32 @llvm.aarch64.neon.uminv.i32.v16i8(<16 x i8>) #2
200
201declare i32 @llvm.aarch64.neon.uminv.i32.v8i8(<8 x i8>) #2
202
203attributes #0 = { nounwind ssp "target-cpu"="cyclone" }
204attributes #1 = { "target-cpu"="cyclone" }
205attributes #2 = { nounwind readnone }
206attributes #3 = { nounwind }
207attributes #4 = { nobuiltin nounwind }
208