[yaml2obj/obj2yaml] - Add support for .stack_sizes sections.
[llvm-complete.git] / test / Transforms / InstCombine / unfold-masked-merge-with-const-mask-scalar.ll
blobb3bc74d3cfe08cff898cd2f55d2e07f9b9882a0e
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; If we have a masked merge, in the form of: (M is constant)
5 ;   ((x ^ y) & M) ^ y
6 ; Unfold it to
7 ;   (x & M) | (y & ~M)
9 define i4 @scalar0 (i4 %x, i4 %y) {
10 ; CHECK-LABEL: @scalar0(
11 ; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[X:%.*]], 1
12 ; CHECK-NEXT:    [[TMP2:%.*]] = and i4 [[Y:%.*]], -2
13 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[TMP2]]
14 ; CHECK-NEXT:    ret i4 [[R]]
16   %n0 = xor i4 %x, %y
17   %n1 = and i4 %n0, 1
18   %r  = xor i4 %n1, %y
19   ret i4 %r
22 define i4 @scalar1 (i4 %x, i4 %y) {
23 ; CHECK-LABEL: @scalar1(
24 ; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[X:%.*]], -2
25 ; CHECK-NEXT:    [[TMP2:%.*]] = and i4 [[Y:%.*]], 1
26 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[TMP2]]
27 ; CHECK-NEXT:    ret i4 [[R]]
29   %n0 = xor i4 %x, %y
30   %n1 = and i4 %n0, -2
31   %r  = xor i4 %n1, %y
32   ret i4 %r
35 ; ============================================================================ ;
36 ; Various cases with %x and/or %y being a constant
37 ; ============================================================================ ;
39 define i4 @in_constant_varx_mone(i4 %x, i4 %mask) {
40 ; CHECK-LABEL: @in_constant_varx_mone(
41 ; CHECK-NEXT:    [[R1:%.*]] = or i4 [[X:%.*]], -2
42 ; CHECK-NEXT:    ret i4 [[R1]]
44   %n0 = xor i4 %x, -1 ; %x
45   %n1 = and i4 %n0, 1
46   %r = xor i4 %n1, -1
47   ret i4 %r
50 define i4 @in_constant_varx_14(i4 %x, i4 %mask) {
51 ; CHECK-LABEL: @in_constant_varx_14(
52 ; CHECK-NEXT:    [[R1:%.*]] = or i4 [[X:%.*]], -2
53 ; CHECK-NEXT:    ret i4 [[R1]]
55   %n0 = xor i4 %x, 14 ; %x
56   %n1 = and i4 %n0, 1
57   %r = xor i4 %n1, 14
58   ret i4 %r
61 define i4 @in_constant_mone_vary(i4 %y, i4 %mask) {
62 ; CHECK-LABEL: @in_constant_mone_vary(
63 ; CHECK-NEXT:    [[N0:%.*]] = and i4 [[Y:%.*]], 1
64 ; CHECK-NEXT:    [[N1:%.*]] = xor i4 [[N0]], 1
65 ; CHECK-NEXT:    [[R:%.*]] = xor i4 [[N1]], [[Y]]
66 ; CHECK-NEXT:    ret i4 [[R]]
68   %n0 = xor i4 %y, -1 ; %x
69   %n1 = and i4 %n0, 1
70   %r = xor i4 %n1, %y
71   ret i4 %r
74 define i4 @in_constant_14_vary(i4 %y, i4 %mask) {
75 ; CHECK-LABEL: @in_constant_14_vary(
76 ; CHECK-NEXT:    [[R:%.*]] = and i4 [[Y:%.*]], -2
77 ; CHECK-NEXT:    ret i4 [[R]]
79   %n0 = xor i4 %y, 14 ; %x
80   %n1 = and i4 %n0, 1
81   %r = xor i4 %n1, %y
82   ret i4 %r
85 ; ============================================================================ ;
86 ; Commutativity
87 ; ============================================================================ ;
89 ; Used to make sure that the IR complexity sorting does not interfere.
90 declare i4 @gen4()
92 define i4 @c_1_0_0 (i4 %x, i4 %y) {
93 ; CHECK-LABEL: @c_1_0_0(
94 ; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[X:%.*]], -2
95 ; CHECK-NEXT:    [[TMP2:%.*]] = and i4 [[Y:%.*]], 1
96 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[TMP2]]
97 ; CHECK-NEXT:    ret i4 [[R]]
99   %n0 = xor i4 %y, %x ; swapped order
100   %n1 = and i4 %n0, -2
101   %r  = xor i4 %n1, %y
102   ret i4 %r
105 define i4 @c_0_1_0 (i4 %x, i4 %y) {
106 ; CHECK-LABEL: @c_0_1_0(
107 ; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[Y:%.*]], -2
108 ; CHECK-NEXT:    [[TMP2:%.*]] = and i4 [[X:%.*]], 1
109 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[TMP2]]
110 ; CHECK-NEXT:    ret i4 [[R]]
112   %n0 = xor i4 %x, %y
113   %n1 = and i4 %n0, -2
114   %r  = xor i4 %n1, %x ; %x instead of %y
115   ret i4 %r
118 define i4 @c_0_0_1 () {
119 ; CHECK-LABEL: @c_0_0_1(
120 ; CHECK-NEXT:    [[X:%.*]] = call i4 @gen4()
121 ; CHECK-NEXT:    [[Y:%.*]] = call i4 @gen4()
122 ; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[X]], -2
123 ; CHECK-NEXT:    [[TMP2:%.*]] = and i4 [[Y]], 1
124 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[TMP2]]
125 ; CHECK-NEXT:    ret i4 [[R]]
127   %x  = call i4 @gen4()
128   %y  = call i4 @gen4()
129   %n0 = xor i4 %x, %y
130   %n1 = and i4 %n0, -2
131   %r  = xor i4 %y, %n1 ; swapped order
132   ret i4 %r
135 define i4 @c_1_1_0 (i4 %x, i4 %y) {
136 ; CHECK-LABEL: @c_1_1_0(
137 ; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[Y:%.*]], -2
138 ; CHECK-NEXT:    [[TMP2:%.*]] = and i4 [[X:%.*]], 1
139 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[TMP2]]
140 ; CHECK-NEXT:    ret i4 [[R]]
142   %n0 = xor i4 %y, %x ; swapped order
143   %n1 = and i4 %n0, -2
144   %r  = xor i4 %n1, %x ; %x instead of %y
145   ret i4 %r
148 define i4 @c_1_0_1 (i4 %x) {
149 ; CHECK-LABEL: @c_1_0_1(
150 ; CHECK-NEXT:    [[Y:%.*]] = call i4 @gen4()
151 ; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[X:%.*]], -2
152 ; CHECK-NEXT:    [[TMP2:%.*]] = and i4 [[Y]], 1
153 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[TMP2]]
154 ; CHECK-NEXT:    ret i4 [[R]]
156   %y  = call i4 @gen4()
157   %n0 = xor i4 %y, %x ; swapped order
158   %n1 = and i4 %n0, -2
159   %r  = xor i4 %y, %n1 ; swapped order
160   ret i4 %r
163 define i4 @c_0_1_1 (i4 %y) {
164 ; CHECK-LABEL: @c_0_1_1(
165 ; CHECK-NEXT:    [[X:%.*]] = call i4 @gen4()
166 ; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[Y:%.*]], -2
167 ; CHECK-NEXT:    [[TMP2:%.*]] = and i4 [[X]], 1
168 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[TMP2]]
169 ; CHECK-NEXT:    ret i4 [[R]]
171   %x  = call i4 @gen4()
172   %n0 = xor i4 %x, %y
173   %n1 = and i4 %n0, -2
174   %r  = xor i4 %x, %n1 ; swapped order, %x instead of %y
175   ret i4 %r
178 define i4 @c_1_1_1 () {
179 ; CHECK-LABEL: @c_1_1_1(
180 ; CHECK-NEXT:    [[X:%.*]] = call i4 @gen4()
181 ; CHECK-NEXT:    [[Y:%.*]] = call i4 @gen4()
182 ; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[Y]], -2
183 ; CHECK-NEXT:    [[TMP2:%.*]] = and i4 [[X]], 1
184 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[TMP2]]
185 ; CHECK-NEXT:    ret i4 [[R]]
187   %x  = call i4 @gen4()
188   %y  = call i4 @gen4()
189   %n0 = xor i4 %y, %x ; swapped order
190   %n1 = and i4 %n0, -2
191   %r  = xor i4 %x, %n1 ; swapped order, %x instead of %y
192   ret i4 %r
195 define i4 @commutativity_constant_14_vary(i4 %y, i4 %mask) {
196 ; CHECK-LABEL: @commutativity_constant_14_vary(
197 ; CHECK-NEXT:    [[R:%.*]] = and i4 [[Y:%.*]], -2
198 ; CHECK-NEXT:    ret i4 [[R]]
200   %n0 = xor i4 %y, 14 ; %x
201   %n1 = and i4 %n0, 1
202   %r = xor i4 %y, %n1 ; swapped
203   ret i4 %r
206 ; ============================================================================ ;
207 ; Negative tests. Should not be folded.
208 ; ============================================================================ ;
210 ; One use only.
212 declare void @use4(i4)
214 define i4 @n_oneuse_D (i4 %x, i4 %y) {
215 ; CHECK-LABEL: @n_oneuse_D(
216 ; CHECK-NEXT:    [[N0:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
217 ; CHECK-NEXT:    [[N1:%.*]] = and i4 [[N0]], -2
218 ; CHECK-NEXT:    [[R:%.*]] = xor i4 [[N1]], [[Y]]
219 ; CHECK-NEXT:    call void @use4(i4 [[N0]])
220 ; CHECK-NEXT:    ret i4 [[R]]
222   %n0 = xor i4 %x, %y ; two uses of %n0, which is going to be replaced
223   %n1 = and i4 %n0, -2
224   %r  = xor i4 %n1, %y
225   call void @use4(i4 %n0)
226   ret i4 %r
229 define i4 @n_oneuse_A (i4 %x, i4 %y) {
230 ; CHECK-LABEL: @n_oneuse_A(
231 ; CHECK-NEXT:    [[N0:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
232 ; CHECK-NEXT:    [[N1:%.*]] = and i4 [[N0]], -2
233 ; CHECK-NEXT:    [[R:%.*]] = xor i4 [[N1]], [[Y]]
234 ; CHECK-NEXT:    call void @use4(i4 [[N1]])
235 ; CHECK-NEXT:    ret i4 [[R]]
237   %n0 = xor i4 %x, %y
238   %n1 = and i4 %n0, -2 ; two uses of %n1, which is going to be replaced
239   %r  = xor i4 %n1, %y
240   call void @use4(i4 %n1)
241   ret i4 %r
244 define i4 @n_oneuse_AD (i4 %x, i4 %y) {
245 ; CHECK-LABEL: @n_oneuse_AD(
246 ; CHECK-NEXT:    [[N0:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
247 ; CHECK-NEXT:    [[N1:%.*]] = and i4 [[N0]], -2
248 ; CHECK-NEXT:    [[R:%.*]] = xor i4 [[N1]], [[Y]]
249 ; CHECK-NEXT:    call void @use4(i4 [[N0]])
250 ; CHECK-NEXT:    call void @use4(i4 [[N1]])
251 ; CHECK-NEXT:    ret i4 [[R]]
253   %n0 = xor i4 %x, %y
254   %n1 = and i4 %n0, -2 ; two uses of %n1, which is going to be replaced
255   %r  = xor i4 %n1, %y
256   call void @use4(i4 %n0)
257   call void @use4(i4 %n1)
258   ret i4 %r
261 ; Mask is not constant
263 define i4 @n_var_mask (i4 %x, i4 %y, i4 %m) {
264 ; CHECK-LABEL: @n_var_mask(
265 ; CHECK-NEXT:    [[N0:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
266 ; CHECK-NEXT:    [[N1:%.*]] = and i4 [[N0]], [[M:%.*]]
267 ; CHECK-NEXT:    [[R:%.*]] = xor i4 [[N1]], [[Y]]
268 ; CHECK-NEXT:    ret i4 [[R]]
270   %n0 = xor i4 %x, %y
271   %n1 = and i4 %n0, %m
272   %r  = xor i4 %n1, %y
273   ret i4 %r
276 ; Some third variable is used
278 define i4 @n_third_var (i4 %x, i4 %y, i4 %z) {
279 ; CHECK-LABEL: @n_third_var(
280 ; CHECK-NEXT:    [[N0:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
281 ; CHECK-NEXT:    [[N1:%.*]] = and i4 [[N0]], -2
282 ; CHECK-NEXT:    [[R:%.*]] = xor i4 [[N1]], [[Z:%.*]]
283 ; CHECK-NEXT:    ret i4 [[R]]
285   %n0 = xor i4 %x, %y
286   %n1 = and i4 %n0, -2
287   %r  = xor i4 %n1, %z ; not %x or %y
288   ret i4 %r