[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AArch64 / logical_shifted_reg.ll
blob2c2c50004b01422a49ff317baf09d7e8921dc774
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
4 @var1_32 = global i32 0
5 @var2_32 = global i32 0
7 @var1_64 = global i64 0
8 @var2_64 = global i64 0
10 define void @logical_32bit() minsize {
11 ; CHECK-LABEL: logical_32bit:
12 ; CHECK:       // %bb.0:
13 ; CHECK-NEXT:    str x19, [sp, #-16]! // 8-byte Folded Spill
14 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
15 ; CHECK-NEXT:    .cfi_offset w19, -16
16 ; CHECK-NEXT:    adrp x8, :got:var1_32
17 ; CHECK-NEXT:    adrp x9, :got:var2_32
18 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:var1_32]
19 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:var2_32]
20 ; CHECK-NEXT:    ldr w10, [x8]
21 ; CHECK-NEXT:    ldr w9, [x9]
22 ; CHECK-NEXT:    and w11, w10, w9
23 ; CHECK-NEXT:    bic w12, w10, w9
24 ; CHECK-NEXT:    orr w13, w10, w9
25 ; CHECK-NEXT:    orn w14, w10, w9
26 ; CHECK-NEXT:    eor w15, w10, w9
27 ; CHECK-NEXT:    eon w16, w9, w10
28 ; CHECK-NEXT:    and w17, w10, w9, lsl #31
29 ; CHECK-NEXT:    bic w18, w10, w9, lsl #31
30 ; CHECK-NEXT:    orr w0, w10, w9, lsl #31
31 ; CHECK-NEXT:    orn w1, w10, w9, lsl #31
32 ; CHECK-NEXT:    eor w2, w10, w9, lsl #31
33 ; CHECK-NEXT:    eon w3, w10, w9, lsl #31
34 ; CHECK-NEXT:    bic w4, w10, w9, asr #10
35 ; CHECK-NEXT:    eor w5, w10, w9, asr #10
36 ; CHECK-NEXT:    orn w6, w10, w9, lsr #1
37 ; CHECK-NEXT:    eor w7, w10, w9, lsr #1
38 ; CHECK-NEXT:    eon w19, w10, w9, ror #20
39 ; CHECK-NEXT:    and w9, w10, w9, ror #20
40 ; CHECK-NEXT:    str w11, [x8]
41 ; CHECK-NEXT:    str w12, [x8]
42 ; CHECK-NEXT:    str w13, [x8]
43 ; CHECK-NEXT:    str w14, [x8]
44 ; CHECK-NEXT:    str w15, [x8]
45 ; CHECK-NEXT:    str w16, [x8]
46 ; CHECK-NEXT:    str w17, [x8]
47 ; CHECK-NEXT:    str w18, [x8]
48 ; CHECK-NEXT:    str w0, [x8]
49 ; CHECK-NEXT:    str w1, [x8]
50 ; CHECK-NEXT:    str w2, [x8]
51 ; CHECK-NEXT:    str w3, [x8]
52 ; CHECK-NEXT:    str w4, [x8]
53 ; CHECK-NEXT:    str w5, [x8]
54 ; CHECK-NEXT:    str w6, [x8]
55 ; CHECK-NEXT:    str w7, [x8]
56 ; CHECK-NEXT:    str w19, [x8]
57 ; CHECK-NEXT:    str w9, [x8]
58 ; CHECK-NEXT:    ldr x19, [sp], #16 // 8-byte Folded Reload
59 ; CHECK-NEXT:    ret
60   %val1 = load i32, i32* @var1_32
61   %val2 = load i32, i32* @var2_32
63   ; First check basic and/bic/or/orn/eor/eon patterns with no shift
64   %neg_val2 = xor i32 -1, %val2
66   %and_noshift = and i32 %val1, %val2
67   store volatile i32 %and_noshift, i32* @var1_32
68   %bic_noshift = and i32 %neg_val2, %val1
69   store volatile i32 %bic_noshift, i32* @var1_32
71   %or_noshift = or i32 %val1, %val2
72   store volatile i32 %or_noshift, i32* @var1_32
73   %orn_noshift = or i32 %neg_val2, %val1
74   store volatile i32 %orn_noshift, i32* @var1_32
76   %xor_noshift = xor i32 %val1, %val2
77   store volatile i32 %xor_noshift, i32* @var1_32
78   %xorn_noshift = xor i32 %neg_val2, %val1
79   store volatile i32 %xorn_noshift, i32* @var1_32
81   ; Check the maximum shift on each
82   %operand_lsl31 = shl i32 %val2, 31
83   %neg_operand_lsl31 = xor i32 -1, %operand_lsl31
85   %and_lsl31 = and i32 %val1, %operand_lsl31
86   store volatile i32 %and_lsl31, i32* @var1_32
87   %bic_lsl31 = and i32 %val1, %neg_operand_lsl31
88   store volatile i32 %bic_lsl31, i32* @var1_32
90   %or_lsl31 = or i32 %val1, %operand_lsl31
91   store volatile i32 %or_lsl31, i32* @var1_32
92   %orn_lsl31 = or i32 %val1, %neg_operand_lsl31
93   store volatile i32 %orn_lsl31, i32* @var1_32
95   %xor_lsl31 = xor i32 %val1, %operand_lsl31
96   store volatile i32 %xor_lsl31, i32* @var1_32
97   %xorn_lsl31 = xor i32 %val1, %neg_operand_lsl31
98   store volatile i32 %xorn_lsl31, i32* @var1_32
100   ; Check other shifts on a subset
101   %operand_asr10 = ashr i32 %val2, 10
102   %neg_operand_asr10 = xor i32 -1, %operand_asr10
104   %bic_asr10 = and i32 %val1, %neg_operand_asr10
105   store volatile i32 %bic_asr10, i32* @var1_32
106   %xor_asr10 = xor i32 %val1, %operand_asr10
107   store volatile i32 %xor_asr10, i32* @var1_32
109   %operand_lsr1 = lshr i32 %val2, 1
110   %neg_operand_lsr1 = xor i32 -1, %operand_lsr1
112   %orn_lsr1 = or i32 %val1, %neg_operand_lsr1
113   store volatile i32 %orn_lsr1, i32* @var1_32
114   %xor_lsr1 = xor i32 %val1, %operand_lsr1
115   store volatile i32 %xor_lsr1, i32* @var1_32
117   %operand_ror20_big = shl i32 %val2, 12
118   %operand_ror20_small = lshr i32 %val2, 20
119   %operand_ror20 = or i32 %operand_ror20_big, %operand_ror20_small
120   %neg_operand_ror20 = xor i32 -1, %operand_ror20
122   %xorn_ror20 = xor i32 %val1, %neg_operand_ror20
123   store volatile i32 %xorn_ror20, i32* @var1_32
124   %and_ror20 = and i32 %val1, %operand_ror20
125   store volatile i32 %and_ror20, i32* @var1_32
127   ret void
130 define void @logical_64bit() minsize {
131 ; CHECK-LABEL: logical_64bit:
132 ; CHECK:       // %bb.0:
133 ; CHECK-NEXT:    str x19, [sp, #-16]! // 8-byte Folded Spill
134 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
135 ; CHECK-NEXT:    .cfi_offset w19, -16
136 ; CHECK-NEXT:    adrp x8, :got:var1_64
137 ; CHECK-NEXT:    adrp x9, :got:var2_64
138 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:var1_64]
139 ; CHECK-NEXT:    ldr x9, [x9, :got_lo12:var2_64]
140 ; CHECK-NEXT:    ldr x10, [x8]
141 ; CHECK-NEXT:    ldr x9, [x9]
142 ; CHECK-NEXT:    and x11, x10, x9
143 ; CHECK-NEXT:    bic x12, x10, x9
144 ; CHECK-NEXT:    orr x13, x10, x9
145 ; CHECK-NEXT:    orn x14, x10, x9
146 ; CHECK-NEXT:    eor x15, x10, x9
147 ; CHECK-NEXT:    eon x16, x9, x10
148 ; CHECK-NEXT:    and x17, x10, x9, lsl #63
149 ; CHECK-NEXT:    bic x18, x10, x9, lsl #63
150 ; CHECK-NEXT:    orr x0, x10, x9, lsl #63
151 ; CHECK-NEXT:    orn x1, x10, x9, lsl #63
152 ; CHECK-NEXT:    eor x2, x10, x9, lsl #63
153 ; CHECK-NEXT:    eon x3, x10, x9, lsl #63
154 ; CHECK-NEXT:    bic x4, x10, x9, asr #10
155 ; CHECK-NEXT:    eor x5, x10, x9, asr #10
156 ; CHECK-NEXT:    orn x6, x10, x9, lsr #1
157 ; CHECK-NEXT:    eor x7, x10, x9, lsr #1
158 ; CHECK-NEXT:    eon x19, x10, x9, ror #20
159 ; CHECK-NEXT:    and x9, x10, x9, ror #20
160 ; CHECK-NEXT:    str x11, [x8]
161 ; CHECK-NEXT:    str x12, [x8]
162 ; CHECK-NEXT:    str x13, [x8]
163 ; CHECK-NEXT:    str x14, [x8]
164 ; CHECK-NEXT:    str x15, [x8]
165 ; CHECK-NEXT:    str x16, [x8]
166 ; CHECK-NEXT:    str x17, [x8]
167 ; CHECK-NEXT:    str x18, [x8]
168 ; CHECK-NEXT:    str x0, [x8]
169 ; CHECK-NEXT:    str x1, [x8]
170 ; CHECK-NEXT:    str x2, [x8]
171 ; CHECK-NEXT:    str x3, [x8]
172 ; CHECK-NEXT:    str x4, [x8]
173 ; CHECK-NEXT:    str x5, [x8]
174 ; CHECK-NEXT:    str x6, [x8]
175 ; CHECK-NEXT:    str x7, [x8]
176 ; CHECK-NEXT:    str x19, [x8]
177 ; CHECK-NEXT:    str x9, [x8]
178 ; CHECK-NEXT:    ldr x19, [sp], #16 // 8-byte Folded Reload
179 ; CHECK-NEXT:    ret
180   %val1 = load i64, i64* @var1_64
181   %val2 = load i64, i64* @var2_64
183   ; First check basic and/bic/or/orn/eor/eon patterns with no shift
184   %neg_val2 = xor i64 -1, %val2
186   %and_noshift = and i64 %val1, %val2
187   store volatile i64 %and_noshift, i64* @var1_64
188   %bic_noshift = and i64 %neg_val2, %val1
189   store volatile i64 %bic_noshift, i64* @var1_64
191   %or_noshift = or i64 %val1, %val2
192   store volatile i64 %or_noshift, i64* @var1_64
193   %orn_noshift = or i64 %neg_val2, %val1
194   store volatile i64 %orn_noshift, i64* @var1_64
196   %xor_noshift = xor i64 %val1, %val2
197   store volatile i64 %xor_noshift, i64* @var1_64
198   %xorn_noshift = xor i64 %neg_val2, %val1
199   store volatile i64 %xorn_noshift, i64* @var1_64
201   ; Check the maximum shift on each
202   %operand_lsl63 = shl i64 %val2, 63
203   %neg_operand_lsl63 = xor i64 -1, %operand_lsl63
205   %and_lsl63 = and i64 %val1, %operand_lsl63
206   store volatile i64 %and_lsl63, i64* @var1_64
207   %bic_lsl63 = and i64 %val1, %neg_operand_lsl63
208   store volatile i64 %bic_lsl63, i64* @var1_64
210   %or_lsl63 = or i64 %val1, %operand_lsl63
211   store volatile i64 %or_lsl63, i64* @var1_64
212   %orn_lsl63 = or i64 %val1, %neg_operand_lsl63
213   store volatile i64 %orn_lsl63, i64* @var1_64
215   %xor_lsl63 = xor i64 %val1, %operand_lsl63
216   store volatile i64 %xor_lsl63, i64* @var1_64
217   %xorn_lsl63 = xor i64 %val1, %neg_operand_lsl63
218   store volatile i64 %xorn_lsl63, i64* @var1_64
220   ; Check other shifts on a subset
221   %operand_asr10 = ashr i64 %val2, 10
222   %neg_operand_asr10 = xor i64 -1, %operand_asr10
224   %bic_asr10 = and i64 %val1, %neg_operand_asr10
225   store volatile i64 %bic_asr10, i64* @var1_64
226   %xor_asr10 = xor i64 %val1, %operand_asr10
227   store volatile i64 %xor_asr10, i64* @var1_64
229   %operand_lsr1 = lshr i64 %val2, 1
230   %neg_operand_lsr1 = xor i64 -1, %operand_lsr1
232   %orn_lsr1 = or i64 %val1, %neg_operand_lsr1
233   store volatile i64 %orn_lsr1, i64* @var1_64
234   %xor_lsr1 = xor i64 %val1, %operand_lsr1
235   store volatile i64 %xor_lsr1, i64* @var1_64
237   ; Construct a rotate-right from a bunch of other logical
238   ; operations. DAGCombiner should ensure we the ROTR during
239   ; selection
240   %operand_ror20_big = shl i64 %val2, 44
241   %operand_ror20_small = lshr i64 %val2, 20
242   %operand_ror20 = or i64 %operand_ror20_big, %operand_ror20_small
243   %neg_operand_ror20 = xor i64 -1, %operand_ror20
245   %xorn_ror20 = xor i64 %val1, %neg_operand_ror20
246   store volatile i64 %xorn_ror20, i64* @var1_64
247   %and_ror20 = and i64 %val1, %operand_ror20
248   store volatile i64 %and_ror20, i64* @var1_64
250   ret void
253 define void @flag_setting() {
254 ; CHECK-LABEL: flag_setting:
255 ; CHECK:       // %bb.0:
256 ; CHECK-NEXT:    adrp x8, :got:var1_64
257 ; CHECK-NEXT:    adrp x10, :got:var2_64
258 ; CHECK-NEXT:    ldr x8, [x8, :got_lo12:var1_64]
259 ; CHECK-NEXT:    ldr x10, [x10, :got_lo12:var2_64]
260 ; CHECK-NEXT:    ldr x9, [x8]
261 ; CHECK-NEXT:    ldr x10, [x10]
262 ; CHECK-NEXT:    tst x9, x10
263 ; CHECK-NEXT:    b.gt .LBB2_4
264 ; CHECK-NEXT:  // %bb.1: // %test2
265 ; CHECK-NEXT:    tst x9, x10, lsl #63
266 ; CHECK-NEXT:    b.lt .LBB2_4
267 ; CHECK-NEXT:  // %bb.2: // %test3
268 ; CHECK-NEXT:    and x10, x9, x10, asr #12
269 ; CHECK-NEXT:    cmp x10, #1
270 ; CHECK-NEXT:    b.ge .LBB2_4
271 ; CHECK-NEXT:  // %bb.3: // %other_exit
272 ; CHECK-NEXT:    str x9, [x8]
273 ; CHECK-NEXT:  .LBB2_4: // %common.ret
274 ; CHECK-NEXT:    ret
275   %val1 = load i64, i64* @var1_64
276   %val2 = load i64, i64* @var2_64
278   %simple_and = and i64 %val1, %val2
279   %tst1 = icmp sgt i64 %simple_and, 0
280   br i1 %tst1, label %ret, label %test2, !prof !1
282 test2:
283   %shifted_op = shl i64 %val2, 63
284   %shifted_and = and i64 %val1, %shifted_op
285   %tst2 = icmp slt i64 %shifted_and, 0
286   br i1 %tst2, label %ret, label %test3, !prof !1
288 test3:
289   %asr_op = ashr i64 %val2, 12
290   %asr_and = and i64 %asr_op, %val1
291   %tst3 = icmp sgt i64 %asr_and, 0
292   br i1 %tst3, label %ret, label %other_exit, !prof !1
294 other_exit:
295   store volatile i64 %val1, i64* @var1_64
296   ret void
297 ret:
298   ret void
301 !1 = !{!"branch_weights", i32 1, i32 1}