22; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK,NOBMI
33; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK,BMI
44
5- define i64 @foo (i64 %w , i64 %x , i64 %y , i64 %z ) {
6- ; NOBMI-LABEL: foo :
5+ define i64 @test_i64 (i64 %w , i64 %x , i64 %y , i64 %z ) {
6+ ; NOBMI-LABEL: test_i64 :
77; NOBMI: # %bb.0: # %Entry
88; NOBMI-NEXT: movq %rcx, %rax
99; NOBMI-NEXT: andq %rdx, %rsi
@@ -14,7 +14,7 @@ define i64 @foo(i64 %w, i64 %x, i64 %y, i64 %z) {
1414; NOBMI-NEXT: andq %rsi, %rax
1515; NOBMI-NEXT: retq
1616;
17- ; BMI-LABEL: foo :
17+ ; BMI-LABEL: test_i64 :
1818; BMI: # %bb.0: # %Entry
1919; BMI-NEXT: andq %rdx, %rsi
2020; BMI-NEXT: andnq %rdi, %rsi, %rax
@@ -31,8 +31,91 @@ Entry:
3131 ret i64 %and3
3232}
3333
34- define <16 x i8 > @fooVec (<16 x i8 > %w , <16 x i8 > %x , <16 x i8 > %y , <16 x i8 > %z ) {
35- ; NOBMI-LABEL: fooVec:
34+ define i32 @test_i32 (i32 %w , i32 %x , i32 %y , i32 %z ) {
35+ ; NOBMI-LABEL: test_i32:
36+ ; NOBMI: # %bb.0: # %Entry
37+ ; NOBMI-NEXT: movl %ecx, %eax
38+ ; NOBMI-NEXT: andl %edx, %esi
39+ ; NOBMI-NEXT: notl %esi
40+ ; NOBMI-NEXT: andl %edi, %esi
41+ ; NOBMI-NEXT: notl %eax
42+ ; NOBMI-NEXT: orl %edx, %eax
43+ ; NOBMI-NEXT: andl %esi, %eax
44+ ; NOBMI-NEXT: retq
45+ ;
46+ ; BMI-LABEL: test_i32:
47+ ; BMI: # %bb.0: # %Entry
48+ ; BMI-NEXT: andl %edx, %esi
49+ ; BMI-NEXT: andnl %edi, %esi, %eax
50+ ; BMI-NEXT: andnl %ecx, %edx, %ecx
51+ ; BMI-NEXT: andnl %eax, %ecx, %eax
52+ ; BMI-NEXT: retq
53+ Entry:
54+ %and1 = and i32 %y , %x
55+ %xor1 = xor i32 %and1 , -1
56+ %and2 = and i32 %xor1 , %w
57+ %.not = xor i32 %z , -1
58+ %or1 = or i32 %.not , %y
59+ %and3 = and i32 %and2 , %or1
60+ ret i32 %and3
61+ }
62+
63+ define i16 @test_i16 (i16 %w , i16 %x , i16 %y , i16 %z ) {
64+ ; NOBMI-LABEL: test_i16:
65+ ; NOBMI: # %bb.0: # %Entry
66+ ; NOBMI-NEXT: movl %ecx, %eax
67+ ; NOBMI-NEXT: andl %edx, %esi
68+ ; NOBMI-NEXT: notl %esi
69+ ; NOBMI-NEXT: andl %edi, %esi
70+ ; NOBMI-NEXT: notl %eax
71+ ; NOBMI-NEXT: orl %edx, %eax
72+ ; NOBMI-NEXT: andl %esi, %eax
73+ ; NOBMI-NEXT: # kill: def $ax killed $ax killed $eax
74+ ; NOBMI-NEXT: retq
75+ ;
76+ ; BMI-LABEL: test_i16:
77+ ; BMI: # %bb.0: # %Entry
78+ ; BMI-NEXT: andl %edx, %esi
79+ ; BMI-NEXT: andnl %edi, %esi, %eax
80+ ; BMI-NEXT: notl %ecx
81+ ; BMI-NEXT: orl %edx, %ecx
82+ ; BMI-NEXT: andl %ecx, %eax
83+ ; BMI-NEXT: # kill: def $ax killed $ax killed $eax
84+ ; BMI-NEXT: retq
85+ Entry:
86+ %and1 = and i16 %y , %x
87+ %xor1 = xor i16 %and1 , -1
88+ %and2 = and i16 %xor1 , %w
89+ %.not = xor i16 %z , -1
90+ %or1 = or i16 %.not , %y
91+ %and3 = and i16 %and2 , %or1
92+ ret i16 %and3
93+ }
94+
95+ define i8 @test_i8 (i8 %w , i8 %x , i8 %y , i8 %z ) {
96+ ; CHECK-LABEL: test_i8:
97+ ; CHECK: # %bb.0: # %Entry
98+ ; CHECK-NEXT: movl %edx, %eax
99+ ; CHECK-NEXT: andl %edx, %esi
100+ ; CHECK-NEXT: notb %sil
101+ ; CHECK-NEXT: andb %dil, %sil
102+ ; CHECK-NEXT: notb %cl
103+ ; CHECK-NEXT: orb %cl, %al
104+ ; CHECK-NEXT: andb %sil, %al
105+ ; CHECK-NEXT: # kill: def $al killed $al killed $eax
106+ ; CHECK-NEXT: retq
107+ Entry:
108+ %and1 = and i8 %y , %x
109+ %xor1 = xor i8 %and1 , -1
110+ %and2 = and i8 %xor1 , %w
111+ %.not = xor i8 %z , -1
112+ %or1 = or i8 %.not , %y
113+ %and3 = and i8 %and2 , %or1
114+ ret i8 %and3
115+ }
116+
117+ define <16 x i8 > @test_v16i8 (<16 x i8 > %w , <16 x i8 > %x , <16 x i8 > %y , <16 x i8 > %z ) {
118+ ; NOBMI-LABEL: test_v16i8:
36119; NOBMI: # %bb.0: # %Entry
37120; NOBMI-NEXT: andps %xmm2, %xmm1
38121; NOBMI-NEXT: andnps %xmm0, %xmm1
@@ -41,7 +124,7 @@ define <16 x i8> @fooVec(<16 x i8> %w, <16 x i8> %x, <16 x i8> %y, <16 x i8> %z)
41124; NOBMI-NEXT: movaps %xmm2, %xmm0
42125; NOBMI-NEXT: retq
43126;
44- ; BMI-LABEL: fooVec :
127+ ; BMI-LABEL: test_v16i8 :
45128; BMI: # %bb.0: # %Entry
46129; BMI-NEXT: vandps %xmm1, %xmm2, %xmm1
47130; BMI-NEXT: vandnps %xmm0, %xmm1, %xmm0
@@ -58,6 +141,38 @@ Entry:
58141 ret <16 x i8 > %and3
59142}
60143
144+ define <32 x i8 > @test_v32i8 (<32 x i8 > %w , <32 x i8 > %x , <32 x i8 > %y , <32 x i8 > %z ) {
145+ ; NOBMI-LABEL: test_v32i8:
146+ ; NOBMI: # %bb.0: # %Entry
147+ ; NOBMI-NEXT: andps %xmm4, %xmm2
148+ ; NOBMI-NEXT: andps %xmm5, %xmm3
149+ ; NOBMI-NEXT: andnps %xmm1, %xmm3
150+ ; NOBMI-NEXT: andnps %xmm0, %xmm2
151+ ; NOBMI-NEXT: andnps %xmm6, %xmm4
152+ ; NOBMI-NEXT: andnps %xmm2, %xmm4
153+ ; NOBMI-NEXT: andnps %xmm7, %xmm5
154+ ; NOBMI-NEXT: andnps %xmm3, %xmm5
155+ ; NOBMI-NEXT: movaps %xmm4, %xmm0
156+ ; NOBMI-NEXT: movaps %xmm5, %xmm1
157+ ; NOBMI-NEXT: retq
158+ ;
159+ ; BMI-LABEL: test_v32i8:
160+ ; BMI: # %bb.0: # %Entry
161+ ; BMI-NEXT: vandps %ymm1, %ymm2, %ymm1
162+ ; BMI-NEXT: vandnps %ymm0, %ymm1, %ymm0
163+ ; BMI-NEXT: vandnps %ymm3, %ymm2, %ymm1
164+ ; BMI-NEXT: vandnps %ymm0, %ymm1, %ymm0
165+ ; BMI-NEXT: retq
166+ Entry:
167+ %and1 = and <32 x i8 > %y , %x
168+ %xor1 = xor <32 x i8 > %and1 , <i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 >
169+ %and2 = and <32 x i8 > %xor1 , %w
170+ %.not = xor <32 x i8 > %z , <i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 , i8 -1 >
171+ %or1 = or <32 x i8 > %.not , %y
172+ %and3 = and <32 x i8 > %and2 , %or1
173+ ret <32 x i8 > %and3
174+ }
175+
61176; PR112347 - don't fold if we'd be inverting a constant, as demorgan normalisation will invert it back again.
62177define void @PR112347 (ptr %p0 , ptr %p1 , ptr %p2 ) {
63178; CHECK-LABEL: PR112347:
0 commit comments