ARM64: initial backend import
[oota-llvm.git] / test / CodeGen / ARM64 / csel.ll
1 ; RUN: llc -O3 < %s | FileCheck %s
2 target 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"
3 target triple = "arm64-unknown-unknown"
4
5 ; CHECK: foo1
6 ; CHECK: csinc w{{[0-9]+}}, w[[REG:[0-9]+]],
7 ; CHECK:                                     w[[REG]], eq
8 define i32 @foo1(i32 %b, i32 %c) nounwind readnone ssp {
9 entry:
10   %not.tobool = icmp ne i32 %c, 0
11   %add = zext i1 %not.tobool to i32
12   %b.add = add i32 %c, %b
13   %add1 = add i32 %b.add, %add
14   ret i32 %add1
15 }
16
17 ; CHECK: foo2
18 ; CHECK: csneg w{{[0-9]+}}, w[[REG:[0-9]+]],
19 ; CHECK:                                     w[[REG]], eq
20 define i32 @foo2(i32 %b, i32 %c) nounwind readnone ssp {
21 entry:
22   %mul = sub i32 0, %b
23   %tobool = icmp eq i32 %c, 0
24   %b.mul = select i1 %tobool, i32 %b, i32 %mul
25   %add = add nsw i32 %b.mul, %c
26   ret i32 %add
27 }
28
29 ; CHECK: foo3
30 ; CHECK: csinv w{{[0-9]+}}, w[[REG:[0-9]+]],
31 ; CHECK:                                     w[[REG]], eq
32 define i32 @foo3(i32 %b, i32 %c) nounwind readnone ssp {
33 entry:
34   %not.tobool = icmp ne i32 %c, 0
35   %xor = sext i1 %not.tobool to i32
36   %b.xor = xor i32 %xor, %b
37   %add = add nsw i32 %b.xor, %c
38   ret i32 %add
39 }
40
41 ; rdar://11632325
42 define i32@foo4(i32 %a) nounwind ssp {
43 ; CHECK: foo4
44 ; CHECK: csneg
45 ; CHECK-NEXT: ret
46   %cmp = icmp sgt i32 %a, -1
47   %neg = sub nsw i32 0, %a
48   %cond = select i1 %cmp, i32 %a, i32 %neg
49   ret i32 %cond
50 }
51
52 define i32@foo5(i32 %a, i32 %b) nounwind ssp {
53 entry:
54 ; CHECK: foo5
55 ; CHECK: subs
56 ; CHECK-NEXT: csneg
57 ; CHECK-NEXT: ret
58   %sub = sub nsw i32 %a, %b
59   %cmp = icmp sgt i32 %sub, -1
60   %sub3 = sub nsw i32 0, %sub
61   %cond = select i1 %cmp, i32 %sub, i32 %sub3
62   ret i32 %cond
63 }
64
65 ; make sure we can handle branch instruction in optimizeCompare.
66 define i32@foo6(i32 %a, i32 %b) nounwind ssp {
67 ; CHECK: foo6
68 ; CHECK: b
69   %sub = sub nsw i32 %a, %b
70   %cmp = icmp sgt i32 %sub, 0
71   br i1 %cmp, label %l.if, label %l.else
72
73 l.if:
74   ret i32 1
75
76 l.else:
77   ret i32 %sub
78 }
79
80 ; If CPSR is used multiple times and V flag is used, we don't remove cmp.
81 define i32 @foo7(i32 %a, i32 %b) nounwind {
82 entry:
83 ; CHECK-LABEL: foo7:
84 ; CHECK: sub
85 ; CHECK-next: adds
86 ; CHECK-next: csneg
87 ; CHECK-next: b
88   %sub = sub nsw i32 %a, %b
89   %cmp = icmp sgt i32 %sub, -1
90   %sub3 = sub nsw i32 0, %sub
91   %cond = select i1 %cmp, i32 %sub, i32 %sub3
92   br i1 %cmp, label %if.then, label %if.else
93
94 if.then:
95   %cmp2 = icmp slt i32 %sub, -1
96   %sel = select i1 %cmp2, i32 %cond, i32 %a
97   ret i32 %sel
98
99 if.else:
100   ret i32 %cond
101 }
102
103 define i32 @foo8(i32 %v, i32 %a, i32 %b) nounwind readnone ssp {
104 entry:
105 ; CHECK-LABEL: foo8:
106 ; CHECK: cmp w0, #0
107 ; CHECK: csinv w0, w1, w2, ne
108   %tobool = icmp eq i32 %v, 0
109   %neg = xor i32 -1, %b
110   %cond = select i1 %tobool, i32 %neg, i32 %a
111   ret i32 %cond
112 }
113
114 define i32 @foo9(i32 %v) nounwind readnone optsize ssp {
115 entry:
116 ; CHECK-LABEL: foo9:
117 ; CHECK: cmp w0, #0
118 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
119 ; CHECK: csinv w0, w[[REG]], w[[REG]], ne
120   %tobool = icmp ne i32 %v, 0
121   %cond = select i1 %tobool, i32 4, i32 -5
122   ret i32 %cond
123 }
124
125 define i64 @foo10(i64 %v) nounwind readnone optsize ssp {
126 entry:
127 ; CHECK-LABEL: foo10:
128 ; CHECK: cmp x0, #0
129 ; CHECK: orr x[[REG:[0-9]+]], xzr, #0x4
130 ; CHECK: csinv x0, x[[REG]], x[[REG]], ne
131   %tobool = icmp ne i64 %v, 0
132   %cond = select i1 %tobool, i64 4, i64 -5
133   ret i64 %cond
134 }
135
136 define i32 @foo11(i32 %v) nounwind readnone optsize ssp {
137 entry:
138 ; CHECK-LABEL: foo11:
139 ; CHECK: cmp w0, #0
140 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x4
141 ; CHECK: csneg w0, w[[REG]], w[[REG]], ne
142   %tobool = icmp ne i32 %v, 0
143   %cond = select i1 %tobool, i32 4, i32 -4
144   ret i32 %cond
145 }
146
147 define i64 @foo12(i64 %v) nounwind readnone optsize ssp {
148 entry:
149 ; CHECK-LABEL: foo12:
150 ; CHECK: cmp x0, #0
151 ; CHECK: orr x[[REG:[0-9]+]], xzr, #0x4
152 ; CHECK: csneg x0, x[[REG]], x[[REG]], ne
153   %tobool = icmp ne i64 %v, 0
154   %cond = select i1 %tobool, i64 4, i64 -4
155   ret i64 %cond
156 }
157
158 define i32 @foo13(i32 %v, i32 %a, i32 %b) nounwind readnone optsize ssp {
159 entry:
160 ; CHECK-LABEL: foo13:
161 ; CHECK: cmp w0, #0
162 ; CHECK: csneg w0, w1, w2, ne
163   %tobool = icmp eq i32 %v, 0
164   %sub = sub i32 0, %b
165   %cond = select i1 %tobool, i32 %sub, i32 %a
166   ret i32 %cond
167 }
168
169 define i64 @foo14(i64 %v, i64 %a, i64 %b) nounwind readnone optsize ssp {
170 entry:
171 ; CHECK-LABEL: foo14:
172 ; CHECK: cmp x0, #0
173 ; CHECK: csneg x0, x1, x2, ne
174   %tobool = icmp eq i64 %v, 0
175   %sub = sub i64 0, %b
176   %cond = select i1 %tobool, i64 %sub, i64 %a
177   ret i64 %cond
178 }
179
180 define i32 @foo15(i32 %a, i32 %b) nounwind readnone optsize ssp {
181 entry:
182 ; CHECK-LABEL: foo15:
183 ; CHECK: cmp w0, w1
184 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
185 ; CHECK: csinc w0, w[[REG]], w[[REG]], le
186   %cmp = icmp sgt i32 %a, %b
187   %. = select i1 %cmp, i32 2, i32 1
188   ret i32 %.
189 }
190
191 define i32 @foo16(i32 %a, i32 %b) nounwind readnone optsize ssp {
192 entry:
193 ; CHECK-LABEL: foo16:
194 ; CHECK: cmp w0, w1
195 ; CHECK: orr w[[REG:[0-9]+]], wzr, #0x1
196 ; CHECK: csinc w0, w[[REG]], w[[REG]], gt
197   %cmp = icmp sgt i32 %a, %b
198   %. = select i1 %cmp, i32 1, i32 2
199   ret i32 %.
200 }
201
202 define i64 @foo17(i64 %a, i64 %b) nounwind readnone optsize ssp {
203 entry:
204 ; CHECK-LABEL: foo17:
205 ; CHECK: cmp x0, x1
206 ; CHECK: orr x[[REG:[0-9]+]], xzr, #0x1
207 ; CHECK: csinc x0, x[[REG]], x[[REG]], le
208   %cmp = icmp sgt i64 %a, %b
209   %. = select i1 %cmp, i64 2, i64 1
210   ret i64 %.
211 }
212
213 define i64 @foo18(i64 %a, i64 %b) nounwind readnone optsize ssp {
214 entry:
215 ; CHECK-LABEL: foo18:
216 ; CHECK: cmp x0, x1
217 ; CHECK: orr x[[REG:[0-9]+]], xzr, #0x1
218 ; CHECK: csinc x0, x[[REG]], x[[REG]], gt
219   %cmp = icmp sgt i64 %a, %b
220   %. = select i1 %cmp, i64 1, i64 2
221   ret i64 %.
222 }