Skip to content

Commit 977f333

Browse files
woruyuworuyu
authored andcommitted
test: add fold-masked-merge-demorgan testcase
1 parent 8a469da commit 977f333

File tree

1 file changed

+265
-0
lines changed

1 file changed

+265
-0
lines changed
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -o - %s -mtriple=x86_64-- | FileCheck %s --check-prefixes=CHECK,NOBMI
3+
; RUN: llc -o - %s -mtriple=x86_64-- -mattr=+bmi | FileCheck %s --check-prefixes=CHECK,BMI
4+
;
5+
; test that masked-merge code is generated as "xor;and;xor" sequence or
6+
; "andn ; and; or" if and-not is available.
7+
8+
define i32 @masked_merge0_demorgan(i32 %a0, i32 %a1, i32 %a2) {
9+
; NOBMI-LABEL: masked_merge0_demorgan:
10+
; NOBMI: # %bb.0:
11+
; NOBMI-NEXT: orl %edi, %edx
12+
; NOBMI-NEXT: movl %edi, %eax
13+
; NOBMI-NEXT: notl %eax
14+
; NOBMI-NEXT: orl %esi, %eax
15+
; NOBMI-NEXT: andl %edx, %eax
16+
; NOBMI-NEXT: retq
17+
;
18+
; BMI-LABEL: masked_merge0_demorgan:
19+
; BMI: # %bb.0:
20+
; BMI-NEXT: orl %edi, %edx
21+
; BMI-NEXT: andnl %edi, %esi, %eax
22+
; BMI-NEXT: andnl %edx, %eax, %eax
23+
; BMI-NEXT: retq
24+
%not = xor i32 %a0, -1
25+
%or0 = or i32 %not, %a1
26+
%or1 = or i32 %a0, %a2
27+
%and = and i32 %or0, %or1
28+
ret i32 %and
29+
}
30+
31+
define i16 @masked_merge1_demorgan(i16 %a0, i16 %a1, i16 %a2) {
32+
; CHECK-LABEL: masked_merge1_demorgan:
33+
; CHECK: # %bb.0:
34+
; CHECK-NEXT: orl %edi, %edx
35+
; CHECK-NEXT: movl %edi, %eax
36+
; CHECK-NEXT: notl %eax
37+
; CHECK-NEXT: orl %esi, %eax
38+
; CHECK-NEXT: andl %edx, %eax
39+
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
40+
; CHECK-NEXT: retq
41+
%not = xor i16 %a0, -1
42+
%or0 = or i16 %not, %a1
43+
%or1 = or i16 %a0, %a2
44+
%and = and i16 %or0, %or1
45+
ret i16 %and
46+
}
47+
48+
define i8 @masked_merge2_demorgan(i8 %a0, i8 %a1, i8 %a2) {
49+
; CHECK-LABEL: masked_merge2_demorgan:
50+
; CHECK: # %bb.0:
51+
; CHECK-NEXT: movl %edi, %eax
52+
; CHECK-NEXT: notb %al
53+
; CHECK-NEXT: orb %sil, %al
54+
; CHECK-NEXT: orb %sil, %dil
55+
; CHECK-NEXT: andb %dil, %al
56+
; CHECK-NEXT: retq
57+
%not = xor i8 %a0, -1
58+
%or0 = or i8 %not, %a1
59+
%or1 = or i8 %a0, %a1
60+
%and = and i8 %or0, %or1
61+
ret i8 %and
62+
}
63+
64+
define i64 @masked_merge3_demorgan(i64 %a0, i64 %a1, i64 %a2) {
65+
; NOBMI-LABEL: masked_merge3_demorgan:
66+
; NOBMI: # %bb.0:
67+
; NOBMI-NEXT: notq %rdx
68+
; NOBMI-NEXT: orq %rdi, %rdx
69+
; NOBMI-NEXT: movq %rdi, %rax
70+
; NOBMI-NEXT: notq %rax
71+
; NOBMI-NEXT: notq %rsi
72+
; NOBMI-NEXT: orq %rsi, %rax
73+
; NOBMI-NEXT: andq %rdx, %rax
74+
; NOBMI-NEXT: retq
75+
;
76+
; BMI-LABEL: masked_merge3_demorgan:
77+
; BMI: # %bb.0:
78+
; BMI-NEXT: andnq %rdx, %rdi, %rax
79+
; BMI-NEXT: andq %rdi, %rsi
80+
; BMI-NEXT: notq %rsi
81+
; BMI-NEXT: andnq %rsi, %rax, %rax
82+
; BMI-NEXT: retq
83+
%not_a0 = xor i64 %a0, -1
84+
%not_a1 = xor i64 %a1, -1
85+
%not_a2 = xor i64 %a2, -1
86+
%or0 = or i64 %not_a0, %not_a1
87+
%or1 = or i64 %a0, %not_a2
88+
%and = and i64 %or0, %or1
89+
ret i64 %and
90+
}
91+
92+
define i32 @not_a_masked_merge0_demorgan(i32 %a0, i32 %a1, i32 %a2) {
93+
; CHECK-LABEL: not_a_masked_merge0_demorgan:
94+
; CHECK: # %bb.0:
95+
; CHECK-NEXT: orl %edi, %edx
96+
; CHECK-NEXT: movl %edi, %eax
97+
; CHECK-NEXT: negl %eax
98+
; CHECK-NEXT: orl %esi, %eax
99+
; CHECK-NEXT: andl %edx, %eax
100+
; CHECK-NEXT: retq
101+
%not_a_not = sub i32 0, %a0
102+
%or0 = or i32 %not_a_not, %a1
103+
%or1 = or i32 %a0, %a2
104+
%and = and i32 %or0, %or1
105+
ret i32 %and
106+
}
107+
108+
; not a masked merge: `not` operand does not match another `and`-operand.
109+
define i32 @not_a_masked_merge1_demorgan(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
110+
; NOBMI-LABEL: not_a_masked_merge1_demorgan:
111+
; NOBMI: # %bb.0:
112+
; NOBMI-NEXT: movl %ecx, %eax
113+
; NOBMI-NEXT: orl %edx, %edi
114+
; NOBMI-NEXT: notl %eax
115+
; NOBMI-NEXT: orl %esi, %eax
116+
; NOBMI-NEXT: andl %edi, %eax
117+
; NOBMI-NEXT: retq
118+
;
119+
; BMI-LABEL: not_a_masked_merge1_demorgan:
120+
; BMI: # %bb.0:
121+
; BMI-NEXT: orl %edx, %edi
122+
; BMI-NEXT: andnl %ecx, %esi, %eax
123+
; BMI-NEXT: andnl %edi, %eax, %eax
124+
; BMI-NEXT: retq
125+
%or1 = or i32 %a0, %a2
126+
%not = xor i32 %a3, -1
127+
%or0 = or i32 %not, %a1
128+
%and = and i32 %or0, %or1
129+
ret i32 %and
130+
}
131+
132+
; not a masked merge: one of the operands of `and` is not an `or`.
133+
define i32 @not_a_masked_merge2_demorgan(i32 %a0, i32 %a1, i32 %a2) {
134+
; NOBMI-LABEL: not_a_masked_merge2_demorgan:
135+
; NOBMI: # %bb.0:
136+
; NOBMI-NEXT: movl %edi, %eax
137+
; NOBMI-NEXT: andl %edi, %edx
138+
; NOBMI-NEXT: notl %eax
139+
; NOBMI-NEXT: orl %esi, %eax
140+
; NOBMI-NEXT: andl %edx, %eax
141+
; NOBMI-NEXT: retq
142+
;
143+
; BMI-LABEL: not_a_masked_merge2_demorgan:
144+
; BMI: # %bb.0:
145+
; BMI-NEXT: andl %edi, %edx
146+
; BMI-NEXT: andnl %edi, %esi, %eax
147+
; BMI-NEXT: andnl %edx, %eax, %eax
148+
; BMI-NEXT: retq
149+
%not_an_or1 = and i32 %a0, %a2
150+
%not = xor i32 %a0, -1
151+
%or0 = or i32 %not, %a1
152+
%and = and i32 %or0, %not_an_or1
153+
ret i32 %and
154+
}
155+
156+
define i32 @not_a_masked_merge3_demorgan(i32 %a0, i32 %a1, i32 %a2) {
157+
; NOBMI-LABEL: not_a_masked_merge3_demorgan:
158+
; NOBMI: # %bb.0:
159+
; NOBMI-NEXT: movl %esi, %eax
160+
; NOBMI-NEXT: orl %edi, %edx
161+
; NOBMI-NEXT: xorl %edi, %eax
162+
; NOBMI-NEXT: notl %eax
163+
; NOBMI-NEXT: andl %edx, %eax
164+
; NOBMI-NEXT: retq
165+
;
166+
; BMI-LABEL: not_a_masked_merge3_demorgan:
167+
; BMI: # %bb.0:
168+
; BMI-NEXT: orl %edi, %edx
169+
; BMI-NEXT: xorl %edi, %esi
170+
; BMI-NEXT: andnl %edx, %esi, %eax
171+
; BMI-NEXT: retq
172+
%or1 = or i32 %a0, %a2
173+
%not = xor i32 %a0, -1
174+
%not_an_or0 = xor i32 %not, %a1
175+
%and = and i32 %not_an_or0, %or1
176+
ret i32 %and
177+
}
178+
179+
; not a masked merge: `not` operand must not be on same `or`.
180+
define i32 @not_a_masked_merge4_demorgan(i32 %a0, i32 %a1, i32 %a2) {
181+
; CHECK-LABEL: not_a_masked_merge4_demorgan:
182+
; CHECK: # %bb.0:
183+
; CHECK-NEXT: movl %edi, %eax
184+
; CHECK-NEXT: orl %edx, %eax
185+
; CHECK-NEXT: retq
186+
%or1 = or i32 %a0, %a2
187+
%not = xor i32 %a1, -1
188+
%or0 = or i32 %not, %a1
189+
%and = and i32 %or0, %or1
190+
ret i32 %and
191+
}
192+
193+
; should not transform when operands have multiple users.
194+
define i32 @masked_merge_no_transform0_demorgan(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {
195+
; NOBMI-LABEL: masked_merge_no_transform0_demorgan:
196+
; NOBMI: # %bb.0:
197+
; NOBMI-NEXT: orl %edi, %edx
198+
; NOBMI-NEXT: movl %edi, %eax
199+
; NOBMI-NEXT: notl %eax
200+
; NOBMI-NEXT: orl %esi, %eax
201+
; NOBMI-NEXT: andl %edx, %eax
202+
; NOBMI-NEXT: movl %edx, (%rcx)
203+
; NOBMI-NEXT: retq
204+
;
205+
; BMI-LABEL: masked_merge_no_transform0_demorgan:
206+
; BMI: # %bb.0:
207+
; BMI-NEXT: orl %edi, %edx
208+
; BMI-NEXT: andnl %edi, %esi, %eax
209+
; BMI-NEXT: andnl %edx, %eax, %eax
210+
; BMI-NEXT: movl %edx, (%rcx)
211+
; BMI-NEXT: retq
212+
%not = xor i32 %a0, -1
213+
%or0 = or i32 %not, %a1
214+
%or1 = or i32 %a0, %a2
215+
%and = and i32 %or0, %or1
216+
store i32 %or1, ptr %p1
217+
ret i32 %and
218+
}
219+
220+
; should not transform when operands have multiple users.
221+
define i32 @masked_merge_no_transform1_demorgan(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {
222+
; NOBMI-LABEL: masked_merge_no_transform1_demorgan:
223+
; NOBMI: # %bb.0:
224+
; NOBMI-NEXT: movl %edx, %eax
225+
; NOBMI-NEXT: orl %edi, %eax
226+
; NOBMI-NEXT: notl %edi
227+
; NOBMI-NEXT: orl %edi, %esi
228+
; NOBMI-NEXT: andl %esi, %eax
229+
; NOBMI-NEXT: movl %edi, (%rcx)
230+
; NOBMI-NEXT: retq
231+
;
232+
; BMI-LABEL: masked_merge_no_transform1_demorgan:
233+
; BMI: # %bb.0:
234+
; BMI-NEXT: orl %edi, %edx
235+
; BMI-NEXT: andnl %edi, %esi, %eax
236+
; BMI-NEXT: notl %edi
237+
; BMI-NEXT: andnl %edx, %eax, %eax
238+
; BMI-NEXT: movl %edi, (%rcx)
239+
; BMI-NEXT: retq
240+
%not = xor i32 %a0, -1
241+
%or0 = or i32 %not, %a1
242+
%or1 = or i32 %a0, %a2
243+
%and = and i32 %or0, %or1
244+
store i32 %not, ptr %p1
245+
ret i32 %and
246+
}
247+
248+
; should not transform when operands have multiple users.
249+
define i32 @masked_merge_no_transform2_demorgan(i32 %a0, i32 %a1, i32 %a2, ptr %p1) {
250+
; CHECK-LABEL: masked_merge_no_transform2_demorgan:
251+
; CHECK: # %bb.0:
252+
; CHECK-NEXT: movl %edx, %eax
253+
; CHECK-NEXT: orl %edi, %eax
254+
; CHECK-NEXT: notl %edi
255+
; CHECK-NEXT: orl %esi, %edi
256+
; CHECK-NEXT: andl %edi, %eax
257+
; CHECK-NEXT: movl %edi, (%rcx)
258+
; CHECK-NEXT: retq
259+
%not = xor i32 %a0, -1
260+
%or0 = or i32 %not, %a1
261+
%or1 = or i32 %a0, %a2
262+
%and = and i32 %or0, %or1
263+
store i32 %or0, ptr %p1
264+
ret i32 %and
265+
}

0 commit comments

Comments
 (0)