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