Skip to content

Commit 36bfe77

Browse files
author
git apple-llvm automerger
committed
Merge commit '473deaf34bc9' from llvm.org/master into apple/master
2 parents 667b950 + 473deaf commit 36bfe77

File tree

2 files changed

+297
-0
lines changed

2 files changed

+297
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
3+
4+
; Fold
5+
; ptr - (ptr & mask)
6+
; To
7+
; ptr & (~mask)
8+
;
9+
; This needs to be a backend-level fold because only by now pointers
10+
; are just registers; in middle-end IR this can only be done via @llvm.ptrmask()
11+
; intrinsic which is not sufficiently widely-spread yet.
12+
;
13+
; https://bugs.llvm.org/show_bug.cgi?id=44448
14+
15+
; The basic positive tests
16+
17+
define i32 @t0_32(i32 %ptr, i32 %mask) nounwind {
18+
; CHECK-LABEL: t0_32:
19+
; CHECK: // %bb.0:
20+
; CHECK-NEXT: and w8, w0, w1
21+
; CHECK-NEXT: sub w0, w0, w8
22+
; CHECK-NEXT: ret
23+
%bias = and i32 %ptr, %mask
24+
%r = sub i32 %ptr, %bias
25+
ret i32 %r
26+
}
27+
define i64 @t1_64(i64 %ptr, i64 %mask) nounwind {
28+
; CHECK-LABEL: t1_64:
29+
; CHECK: // %bb.0:
30+
; CHECK-NEXT: and x8, x0, x1
31+
; CHECK-NEXT: sub x0, x0, x8
32+
; CHECK-NEXT: ret
33+
%bias = and i64 %ptr, %mask
34+
%r = sub i64 %ptr, %bias
35+
ret i64 %r
36+
}
37+
38+
define i32 @t2_commutative(i32 %ptr, i32 %mask) nounwind {
39+
; CHECK-LABEL: t2_commutative:
40+
; CHECK: // %bb.0:
41+
; CHECK-NEXT: and w8, w1, w0
42+
; CHECK-NEXT: sub w0, w0, w8
43+
; CHECK-NEXT: ret
44+
%bias = and i32 %mask, %ptr ; swapped
45+
%r = sub i32 %ptr, %bias
46+
ret i32 %r
47+
}
48+
49+
; Extra use tests
50+
51+
define i32 @n3_extrause1(i32 %ptr, i32 %mask, i32* %bias_storage) nounwind {
52+
; CHECK-LABEL: n3_extrause1:
53+
; CHECK: // %bb.0:
54+
; CHECK-NEXT: and w8, w0, w1
55+
; CHECK-NEXT: sub w0, w0, w8
56+
; CHECK-NEXT: str w8, [x2]
57+
; CHECK-NEXT: ret
58+
%bias = and i32 %ptr, %mask ; has extra uses, can't fold
59+
store i32 %bias, i32* %bias_storage
60+
%r = sub i32 %ptr, %bias
61+
ret i32 %r
62+
}
63+
64+
; Negative tests
65+
66+
define i32 @n4_different_ptrs(i32 %ptr0, i32 %ptr1, i32 %mask) nounwind {
67+
; CHECK-LABEL: n4_different_ptrs:
68+
; CHECK: // %bb.0:
69+
; CHECK-NEXT: and w8, w1, w2
70+
; CHECK-NEXT: sub w0, w0, w8
71+
; CHECK-NEXT: ret
72+
%bias = and i32 %ptr1, %mask ; not %ptr0
73+
%r = sub i32 %ptr0, %bias ; not %ptr1
74+
ret i32 %r
75+
}
76+
define i32 @n5_different_ptrs_commutative(i32 %ptr0, i32 %ptr1, i32 %mask) nounwind {
77+
; CHECK-LABEL: n5_different_ptrs_commutative:
78+
; CHECK: // %bb.0:
79+
; CHECK-NEXT: and w8, w2, w1
80+
; CHECK-NEXT: sub w0, w0, w8
81+
; CHECK-NEXT: ret
82+
%bias = and i32 %mask, %ptr1 ; swapped, not %ptr0
83+
%r = sub i32 %ptr0, %bias ; not %ptr1
84+
ret i32 %r
85+
}
86+
87+
define i32 @n6_not_lowbit_mask(i32 %ptr, i32 %mask) nounwind {
88+
; CHECK-LABEL: n6_not_lowbit_mask:
89+
; CHECK: // %bb.0:
90+
; CHECK-NEXT: and w8, w0, w1
91+
; CHECK-NEXT: sub w0, w0, w8
92+
; CHECK-NEXT: ret
93+
%bias = and i32 %ptr, %mask
94+
%r = sub i32 %ptr, %bias
95+
ret i32 %r
96+
}
97+
98+
define i32 @n7_sub_is_not_commutative(i32 %ptr, i32 %mask) nounwind {
99+
; CHECK-LABEL: n7_sub_is_not_commutative:
100+
; CHECK: // %bb.0:
101+
; CHECK-NEXT: and w8, w0, w1
102+
; CHECK-NEXT: sub w0, w8, w0
103+
; CHECK-NEXT: ret
104+
%bias = and i32 %ptr, %mask
105+
%r = sub i32 %bias, %ptr ; wrong order
106+
ret i32 %r
107+
}

llvm/test/CodeGen/X86/sub-of-bias.ll

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=i686-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,NOBMI,X86,NOBMI-X86
3+
; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+bmi < %s | FileCheck %s --check-prefixes=CHECK,BMI,X86,BMI-X86
4+
; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,NOBMI,X64,NOBMI-X64
5+
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+bmi < %s | FileCheck %s --check-prefixes=CHECK,BMI,X64,BMI-X64
6+
7+
; Fold
8+
; ptr - (ptr & mask)
9+
; To
10+
; ptr & (~mask)
11+
;
12+
; This needs to be a backend-level fold because only by now pointers
13+
; are just registers; in middle-end IR this can only be done via @llvm.ptrmask()
14+
; intrinsic which is not sufficiently widely-spread yet.
15+
;
16+
; https://bugs.llvm.org/show_bug.cgi?id=44448
17+
18+
; The basic positive tests
19+
20+
define i32 @t0_32(i32 %ptr, i32 %mask) nounwind {
21+
; X86-LABEL: t0_32:
22+
; X86: # %bb.0:
23+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
24+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
25+
; X86-NEXT: andl %eax, %ecx
26+
; X86-NEXT: subl %ecx, %eax
27+
; X86-NEXT: retl
28+
;
29+
; X64-LABEL: t0_32:
30+
; X64: # %bb.0:
31+
; X64-NEXT: movl %edi, %eax
32+
; X64-NEXT: andl %edi, %esi
33+
; X64-NEXT: subl %esi, %eax
34+
; X64-NEXT: retq
35+
%bias = and i32 %ptr, %mask
36+
%r = sub i32 %ptr, %bias
37+
ret i32 %r
38+
}
39+
define i64 @t1_64(i64 %ptr, i64 %mask) nounwind {
40+
; X86-LABEL: t1_64:
41+
; X86: # %bb.0:
42+
; X86-NEXT: pushl %esi
43+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
44+
; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
45+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
46+
; X86-NEXT: andl %edx, %ecx
47+
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
48+
; X86-NEXT: andl %eax, %esi
49+
; X86-NEXT: subl %esi, %eax
50+
; X86-NEXT: sbbl %ecx, %edx
51+
; X86-NEXT: popl %esi
52+
; X86-NEXT: retl
53+
;
54+
; X64-LABEL: t1_64:
55+
; X64: # %bb.0:
56+
; X64-NEXT: movq %rdi, %rax
57+
; X64-NEXT: andq %rdi, %rsi
58+
; X64-NEXT: subq %rsi, %rax
59+
; X64-NEXT: retq
60+
%bias = and i64 %ptr, %mask
61+
%r = sub i64 %ptr, %bias
62+
ret i64 %r
63+
}
64+
65+
define i32 @t2_commutative(i32 %ptr, i32 %mask) nounwind {
66+
; X86-LABEL: t2_commutative:
67+
; X86: # %bb.0:
68+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
69+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
70+
; X86-NEXT: andl %eax, %ecx
71+
; X86-NEXT: subl %ecx, %eax
72+
; X86-NEXT: retl
73+
;
74+
; X64-LABEL: t2_commutative:
75+
; X64: # %bb.0:
76+
; X64-NEXT: movl %edi, %eax
77+
; X64-NEXT: andl %edi, %esi
78+
; X64-NEXT: subl %esi, %eax
79+
; X64-NEXT: retq
80+
%bias = and i32 %mask, %ptr ; swapped
81+
%r = sub i32 %ptr, %bias
82+
ret i32 %r
83+
}
84+
85+
; Extra use tests
86+
87+
define i32 @n3_extrause1(i32 %ptr, i32 %mask, i32* %bias_storage) nounwind {
88+
; X86-LABEL: n3_extrause1:
89+
; X86: # %bb.0:
90+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
91+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
92+
; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
93+
; X86-NEXT: andl %eax, %edx
94+
; X86-NEXT: movl %edx, (%ecx)
95+
; X86-NEXT: subl %edx, %eax
96+
; X86-NEXT: retl
97+
;
98+
; X64-LABEL: n3_extrause1:
99+
; X64: # %bb.0:
100+
; X64-NEXT: movl %edi, %eax
101+
; X64-NEXT: andl %edi, %esi
102+
; X64-NEXT: movl %esi, (%rdx)
103+
; X64-NEXT: subl %esi, %eax
104+
; X64-NEXT: retq
105+
%bias = and i32 %ptr, %mask ; has extra uses, can't fold
106+
store i32 %bias, i32* %bias_storage
107+
%r = sub i32 %ptr, %bias
108+
ret i32 %r
109+
}
110+
111+
; Negative tests
112+
113+
define i32 @n4_different_ptrs(i32 %ptr0, i32 %ptr1, i32 %mask) nounwind {
114+
; X86-LABEL: n4_different_ptrs:
115+
; X86: # %bb.0:
116+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
117+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
118+
; X86-NEXT: andl {{[0-9]+}}(%esp), %ecx
119+
; X86-NEXT: subl %ecx, %eax
120+
; X86-NEXT: retl
121+
;
122+
; X64-LABEL: n4_different_ptrs:
123+
; X64: # %bb.0:
124+
; X64-NEXT: movl %edi, %eax
125+
; X64-NEXT: andl %edx, %esi
126+
; X64-NEXT: subl %esi, %eax
127+
; X64-NEXT: retq
128+
%bias = and i32 %ptr1, %mask ; not %ptr0
129+
%r = sub i32 %ptr0, %bias ; not %ptr1
130+
ret i32 %r
131+
}
132+
define i32 @n5_different_ptrs_commutative(i32 %ptr0, i32 %ptr1, i32 %mask) nounwind {
133+
; X86-LABEL: n5_different_ptrs_commutative:
134+
; X86: # %bb.0:
135+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
136+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
137+
; X86-NEXT: andl {{[0-9]+}}(%esp), %ecx
138+
; X86-NEXT: subl %ecx, %eax
139+
; X86-NEXT: retl
140+
;
141+
; X64-LABEL: n5_different_ptrs_commutative:
142+
; X64: # %bb.0:
143+
; X64-NEXT: movl %edi, %eax
144+
; X64-NEXT: andl %edx, %esi
145+
; X64-NEXT: subl %esi, %eax
146+
; X64-NEXT: retq
147+
%bias = and i32 %mask, %ptr1 ; swapped, not %ptr0
148+
%r = sub i32 %ptr0, %bias ; not %ptr1
149+
ret i32 %r
150+
}
151+
152+
define i32 @n6_not_lowbit_mask(i32 %ptr, i32 %mask) nounwind {
153+
; X86-LABEL: n6_not_lowbit_mask:
154+
; X86: # %bb.0:
155+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
156+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
157+
; X86-NEXT: andl %eax, %ecx
158+
; X86-NEXT: subl %ecx, %eax
159+
; X86-NEXT: retl
160+
;
161+
; X64-LABEL: n6_not_lowbit_mask:
162+
; X64: # %bb.0:
163+
; X64-NEXT: movl %edi, %eax
164+
; X64-NEXT: andl %edi, %esi
165+
; X64-NEXT: subl %esi, %eax
166+
; X64-NEXT: retq
167+
%bias = and i32 %ptr, %mask
168+
%r = sub i32 %ptr, %bias
169+
ret i32 %r
170+
}
171+
172+
define i32 @n7_sub_is_not_commutative(i32 %ptr, i32 %mask) nounwind {
173+
; X86-LABEL: n7_sub_is_not_commutative:
174+
; X86: # %bb.0:
175+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
176+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
177+
; X86-NEXT: andl %ecx, %eax
178+
; X86-NEXT: subl %ecx, %eax
179+
; X86-NEXT: retl
180+
;
181+
; X64-LABEL: n7_sub_is_not_commutative:
182+
; X64: # %bb.0:
183+
; X64-NEXT: movl %esi, %eax
184+
; X64-NEXT: andl %edi, %eax
185+
; X64-NEXT: subl %edi, %eax
186+
; X64-NEXT: retq
187+
%bias = and i32 %ptr, %mask
188+
%r = sub i32 %bias, %ptr ; wrong order
189+
ret i32 %r
190+
}

0 commit comments

Comments
 (0)