[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / AArch64 / logical_shifted_reg.ll
blob1c15f1521c561f164c1a27312a6ce8bee57f540a
1 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
3 @var1_32 = global i32 0
4 @var2_32 = global i32 0
6 @var1_64 = global i64 0
7 @var2_64 = global i64 0
9 define void @logical_32bit() minsize {
10 ; CHECK-LABEL: logical_32bit:
11   %val1 = load i32, i32* @var1_32
12   %val2 = load i32, i32* @var2_32
14   ; First check basic and/bic/or/orn/eor/eon patterns with no shift
15   %neg_val2 = xor i32 -1, %val2
17   %and_noshift = and i32 %val1, %val2
18 ; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}
19   store volatile i32 %and_noshift, i32* @var1_32
20   %bic_noshift = and i32 %neg_val2, %val1
21 ; CHECK: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}
22   store volatile i32 %bic_noshift, i32* @var1_32
24   %or_noshift = or i32 %val1, %val2
25 ; CHECK: orr {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}
26   store volatile i32 %or_noshift, i32* @var1_32
27   %orn_noshift = or i32 %neg_val2, %val1
28 ; CHECK: orn {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}
29   store volatile i32 %orn_noshift, i32* @var1_32
31   %xor_noshift = xor i32 %val1, %val2
32 ; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}
33   store volatile i32 %xor_noshift, i32* @var1_32
34   %xorn_noshift = xor i32 %neg_val2, %val1
35 ; CHECK: eon {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}
36   store volatile i32 %xorn_noshift, i32* @var1_32
38   ; Check the maximum shift on each
39   %operand_lsl31 = shl i32 %val2, 31
40   %neg_operand_lsl31 = xor i32 -1, %operand_lsl31
42   %and_lsl31 = and i32 %val1, %operand_lsl31
43 ; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31
44   store volatile i32 %and_lsl31, i32* @var1_32
45   %bic_lsl31 = and i32 %val1, %neg_operand_lsl31
46 ; CHECK: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31
47   store volatile i32 %bic_lsl31, i32* @var1_32
49   %or_lsl31 = or i32 %val1, %operand_lsl31
50 ; CHECK: orr {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31
51   store volatile i32 %or_lsl31, i32* @var1_32
52   %orn_lsl31 = or i32 %val1, %neg_operand_lsl31
53 ; CHECK: orn {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31
54   store volatile i32 %orn_lsl31, i32* @var1_32
56   %xor_lsl31 = xor i32 %val1, %operand_lsl31
57 ; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31
58   store volatile i32 %xor_lsl31, i32* @var1_32
59   %xorn_lsl31 = xor i32 %val1, %neg_operand_lsl31
60 ; CHECK: eon {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsl #31
61   store volatile i32 %xorn_lsl31, i32* @var1_32
63   ; Check other shifts on a subset
64   %operand_asr10 = ashr i32 %val2, 10
65   %neg_operand_asr10 = xor i32 -1, %operand_asr10
67   %bic_asr10 = and i32 %val1, %neg_operand_asr10
68 ; CHECK: bic {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, asr #10
69   store volatile i32 %bic_asr10, i32* @var1_32
70   %xor_asr10 = xor i32 %val1, %operand_asr10
71 ; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, asr #10
72   store volatile i32 %xor_asr10, i32* @var1_32
74   %operand_lsr1 = lshr i32 %val2, 1
75   %neg_operand_lsr1 = xor i32 -1, %operand_lsr1
77   %orn_lsr1 = or i32 %val1, %neg_operand_lsr1
78 ; CHECK: orn {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsr #1
79   store volatile i32 %orn_lsr1, i32* @var1_32
80   %xor_lsr1 = xor i32 %val1, %operand_lsr1
81 ; CHECK: eor {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lsr #1
82   store volatile i32 %xor_lsr1, i32* @var1_32
84   %operand_ror20_big = shl i32 %val2, 12
85   %operand_ror20_small = lshr i32 %val2, 20
86   %operand_ror20 = or i32 %operand_ror20_big, %operand_ror20_small
87   %neg_operand_ror20 = xor i32 -1, %operand_ror20
89   %xorn_ror20 = xor i32 %val1, %neg_operand_ror20
90 ; CHECK: eon {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ror #20
91   store volatile i32 %xorn_ror20, i32* @var1_32
92   %and_ror20 = and i32 %val1, %operand_ror20
93 ; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ror #20
94   store volatile i32 %and_ror20, i32* @var1_32
96   ret void
99 define void @logical_64bit() minsize {
100 ; CHECK-LABEL: logical_64bit:
101   %val1 = load i64, i64* @var1_64
102   %val2 = load i64, i64* @var2_64
104   ; First check basic and/bic/or/orn/eor/eon patterns with no shift
105   %neg_val2 = xor i64 -1, %val2
107   %and_noshift = and i64 %val1, %val2
108 ; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}
109   store volatile i64 %and_noshift, i64* @var1_64
110   %bic_noshift = and i64 %neg_val2, %val1
111 ; CHECK: bic {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}
112   store volatile i64 %bic_noshift, i64* @var1_64
114   %or_noshift = or i64 %val1, %val2
115 ; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}
116   store volatile i64 %or_noshift, i64* @var1_64
117   %orn_noshift = or i64 %neg_val2, %val1
118 ; CHECK: orn {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}
119   store volatile i64 %orn_noshift, i64* @var1_64
121   %xor_noshift = xor i64 %val1, %val2
122 ; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}
123   store volatile i64 %xor_noshift, i64* @var1_64
124   %xorn_noshift = xor i64 %neg_val2, %val1
125 ; CHECK: eon {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}
126   store volatile i64 %xorn_noshift, i64* @var1_64
128   ; Check the maximum shift on each
129   %operand_lsl63 = shl i64 %val2, 63
130   %neg_operand_lsl63 = xor i64 -1, %operand_lsl63
132   %and_lsl63 = and i64 %val1, %operand_lsl63
133 ; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63
134   store volatile i64 %and_lsl63, i64* @var1_64
135   %bic_lsl63 = and i64 %val1, %neg_operand_lsl63
136 ; CHECK: bic {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63
137   store volatile i64 %bic_lsl63, i64* @var1_64
139   %or_lsl63 = or i64 %val1, %operand_lsl63
140 ; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63
141   store volatile i64 %or_lsl63, i64* @var1_64
142   %orn_lsl63 = or i64 %val1, %neg_operand_lsl63
143 ; CHECK: orn {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63
144   store volatile i64 %orn_lsl63, i64* @var1_64
146   %xor_lsl63 = xor i64 %val1, %operand_lsl63
147 ; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63
148   store volatile i64 %xor_lsl63, i64* @var1_64
149   %xorn_lsl63 = xor i64 %val1, %neg_operand_lsl63
150 ; CHECK: eon {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsl #63
151   store volatile i64 %xorn_lsl63, i64* @var1_64
153   ; Check other shifts on a subset
154   %operand_asr10 = ashr i64 %val2, 10
155   %neg_operand_asr10 = xor i64 -1, %operand_asr10
157   %bic_asr10 = and i64 %val1, %neg_operand_asr10
158 ; CHECK: bic {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, asr #10
159   store volatile i64 %bic_asr10, i64* @var1_64
160   %xor_asr10 = xor i64 %val1, %operand_asr10
161 ; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, asr #10
162   store volatile i64 %xor_asr10, i64* @var1_64
164   %operand_lsr1 = lshr i64 %val2, 1
165   %neg_operand_lsr1 = xor i64 -1, %operand_lsr1
167   %orn_lsr1 = or i64 %val1, %neg_operand_lsr1
168 ; CHECK: orn {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsr #1
169   store volatile i64 %orn_lsr1, i64* @var1_64
170   %xor_lsr1 = xor i64 %val1, %operand_lsr1
171 ; CHECK: eor {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, lsr #1
172   store volatile i64 %xor_lsr1, i64* @var1_64
174   ; Construct a rotate-right from a bunch of other logical
175   ; operations. DAGCombiner should ensure we the ROTR during
176   ; selection
177   %operand_ror20_big = shl i64 %val2, 44
178   %operand_ror20_small = lshr i64 %val2, 20
179   %operand_ror20 = or i64 %operand_ror20_big, %operand_ror20_small
180   %neg_operand_ror20 = xor i64 -1, %operand_ror20
182   %xorn_ror20 = xor i64 %val1, %neg_operand_ror20
183 ; CHECK: eon {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, ror #20
184   store volatile i64 %xorn_ror20, i64* @var1_64
185   %and_ror20 = and i64 %val1, %operand_ror20
186 ; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, ror #20
187   store volatile i64 %and_ror20, i64* @var1_64
189   ret void
192 define void @flag_setting() {
193 ; CHECK-LABEL: flag_setting:
194   %val1 = load i64, i64* @var1_64
195   %val2 = load i64, i64* @var2_64
197 ; CHECK: tst {{x[0-9]+}}, {{x[0-9]+}}
198 ; CHECK: b.gt .L
199   %simple_and = and i64 %val1, %val2
200   %tst1 = icmp sgt i64 %simple_and, 0
201   br i1 %tst1, label %ret, label %test2, !prof !1
203 test2:
204 ; CHECK: tst {{x[0-9]+}}, {{x[0-9]+}}, lsl #63
205 ; CHECK: b.lt .L
206   %shifted_op = shl i64 %val2, 63
207   %shifted_and = and i64 %val1, %shifted_op
208   %tst2 = icmp slt i64 %shifted_and, 0
209   br i1 %tst2, label %ret, label %test3, !prof !1
211 test3:
212 ; CHECK: tst {{x[0-9]+}}, {{x[0-9]+}}, asr #12
213 ; CHECK: b.gt .L
214   %asr_op = ashr i64 %val2, 12
215   %asr_and = and i64 %asr_op, %val1
216   %tst3 = icmp sgt i64 %asr_and, 0
217   br i1 %tst3, label %ret, label %other_exit, !prof !1
219 other_exit:
220   store volatile i64 %val1, i64* @var1_64
221   ret void
222 ret:
223   ret void
226 !1 = !{!"branch_weights", i32 1, i32 1}