Skip to content

Commit af0087c

Browse files
committed
[ConstraintElimination] Add additional pointercast tests.
Add coverage for pointercasts other than bitcast. addrspacecast are not handled properly at the moment.
1 parent b0797e0 commit af0087c

File tree

1 file changed

+156
-1
lines changed

1 file changed

+156
-1
lines changed

llvm/test/Transforms/ConstraintElimination/pointercast.ll

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
; RUN: opt -constraint-elimination -S %s | FileCheck %s
33

44
define i1 @bitcast_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
5-
;
65
; CHECK-LABEL: @bitcast_and_cmp(
76
; CHECK-NEXT: check.0.min:
87
; CHECK-NEXT: [[SRC_C:%.*]] = bitcast i32* [[SRC:%.*]] to i8*
@@ -79,3 +78,159 @@ checks:
7978

8079
ret i1 %res.7
8180
}
81+
82+
define i1 @gep0_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
83+
; CHECK-LABEL: @gep0_and_cmp(
84+
; CHECK-NEXT: check.0.min:
85+
; CHECK-NEXT: [[SRC_C:%.*]] = getelementptr i32, i32* [[SRC:%.*]], i64 0
86+
; CHECK-NEXT: [[MIN_C:%.*]] = getelementptr i32, i32* [[MIN:%.*]], i64 0
87+
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
88+
; CHECK-NEXT: [[GEP_3_C:%.*]] = getelementptr i32, i32* [[GEP_3]], i32 0
89+
; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult i32* [[SRC_C]], [[MIN_C]]
90+
; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt i32* [[GEP_3_C]], [[MAX:%.*]]
91+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]]
92+
; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]]
93+
; CHECK: trap:
94+
; CHECK-NEXT: ret i1 false
95+
; CHECK: checks:
96+
; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]]
97+
; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]]
98+
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]]
99+
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
100+
; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]]
101+
; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]]
102+
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 false, true
103+
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
104+
; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]]
105+
; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]]
106+
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true
107+
; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4
108+
; CHECK-NEXT: [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]]
109+
; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]]
110+
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]]
111+
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]]
112+
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]]
113+
; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]]
114+
; CHECK-NEXT: ret i1 [[RES_7]]
115+
;
116+
check.0.min:
117+
%src.c = getelementptr i32, i32* %src, i64 0
118+
%min.c = getelementptr i32, i32* %min, i64 0
119+
120+
%gep.3 = getelementptr inbounds i32, i32* %src, i64 3
121+
%gep.3.c = getelementptr i32, i32* %gep.3, i32 0
122+
%c.min.0 = icmp ult i32* %src.c, %min.c
123+
%c.max.3 = icmp ugt i32* %gep.3.c, %max
124+
125+
%or = or i1 %c.min.0, %c.max.3
126+
br i1 %or, label %trap, label %checks
127+
128+
trap:
129+
ret i1 0
130+
131+
checks:
132+
%c.3.min = icmp ult i32* %gep.3, %min
133+
%c.3.max = icmp ult i32* %gep.3, %max
134+
%res.1 = xor i1 %c.3.min, %c.3.max
135+
136+
%gep.1 = getelementptr inbounds i32, i32* %src, i64 1
137+
%c.1.min = icmp ult i32* %gep.1, %min
138+
%c.1.max = icmp ult i32* %gep.1, %max
139+
%res.2 = xor i1 %c.1.min, %c.1.max
140+
141+
%gep.2 = getelementptr inbounds i32, i32* %src, i64 2
142+
%c.2.min = icmp ult i32* %gep.2, %min
143+
%c.2.max = icmp ult i32* %gep.2, %max
144+
%res.3 = xor i1 %c.2.min, %c.2.max
145+
146+
%gep.4 = getelementptr inbounds i32, i32* %src, i64 4
147+
%c.4.min = icmp ult i32* %gep.4, %min
148+
%c.4.max = icmp ult i32* %gep.4, %max
149+
%res.4 = xor i1 %c.4.min, %c.4.max
150+
151+
%res.5 = xor i1 %res.1, %res.2
152+
%res.6 = xor i1 %res.5, %res.3
153+
%res.7 = xor i1 %res.6, %res.4
154+
155+
ret i1 %res.7
156+
}
157+
158+
; Should not look through addresspacecast, because it may change the pointer
159+
; value.
160+
define i1 @addrspacecast_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
161+
; CHECK-LABEL: @addrspacecast_and_cmp(
162+
; CHECK-NEXT: check.0.min:
163+
; CHECK-NEXT: [[SRC_C:%.*]] = addrspacecast i32* [[SRC:%.*]] to i8 addrspace(1)*
164+
; CHECK-NEXT: [[MIN_C:%.*]] = addrspacecast i32* [[MIN:%.*]] to i8 addrspace(1)*
165+
; CHECK-NEXT: [[MAX_C:%.*]] = addrspacecast i32* [[MAX:%.*]] to i16 addrspace(1)*
166+
; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3
167+
; CHECK-NEXT: [[GEP_3_C:%.*]] = addrspacecast i32* [[GEP_3]] to i16 addrspace(1)*
168+
; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult i8 addrspace(1)* [[SRC_C]], [[MIN_C]]
169+
; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt i16 addrspace(1)* [[GEP_3_C]], [[MAX_C]]
170+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]]
171+
; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]]
172+
; CHECK: trap:
173+
; CHECK-NEXT: ret i1 false
174+
; CHECK: checks:
175+
; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]]
176+
; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]]
177+
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]]
178+
; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1
179+
; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]]
180+
; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]]
181+
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 false, true
182+
; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2
183+
; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]]
184+
; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]]
185+
; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true
186+
; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4
187+
; CHECK-NEXT: [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]]
188+
; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]]
189+
; CHECK-NEXT: [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]]
190+
; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]]
191+
; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]]
192+
; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]]
193+
; CHECK-NEXT: ret i1 [[RES_7]]
194+
;
195+
check.0.min:
196+
%src.c = addrspacecast i32* %src to i8 addrspace(1)*
197+
%min.c = addrspacecast i32* %min to i8 addrspace(1)*
198+
%max.c = addrspacecast i32* %max to i16 addrspace(1)*
199+
200+
%gep.3 = getelementptr inbounds i32, i32* %src, i64 3
201+
%gep.3.c = addrspacecast i32* %gep.3 to i16 addrspace(1) *
202+
%c.min.0 = icmp ult i8 addrspace(1)* %src.c, %min.c
203+
%c.max.3 = icmp ugt i16 addrspace(1)* %gep.3.c, %max.c
204+
205+
%or = or i1 %c.min.0, %c.max.3
206+
br i1 %or, label %trap, label %checks
207+
208+
trap:
209+
ret i1 0
210+
211+
checks:
212+
%c.3.min = icmp ult i32* %gep.3, %min
213+
%c.3.max = icmp ult i32* %gep.3, %max
214+
%res.1 = xor i1 %c.3.min, %c.3.max
215+
216+
%gep.1 = getelementptr inbounds i32, i32* %src, i64 1
217+
%c.1.min = icmp ult i32* %gep.1, %min
218+
%c.1.max = icmp ult i32* %gep.1, %max
219+
%res.2 = xor i1 %c.1.min, %c.1.max
220+
221+
%gep.2 = getelementptr inbounds i32, i32* %src, i64 2
222+
%c.2.min = icmp ult i32* %gep.2, %min
223+
%c.2.max = icmp ult i32* %gep.2, %max
224+
%res.3 = xor i1 %c.2.min, %c.2.max
225+
226+
%gep.4 = getelementptr inbounds i32, i32* %src, i64 4
227+
%c.4.min = icmp ult i32* %gep.4, %min
228+
%c.4.max = icmp ult i32* %gep.4, %max
229+
%res.4 = xor i1 %c.4.min, %c.4.max
230+
231+
%res.5 = xor i1 %res.1, %res.2
232+
%res.6 = xor i1 %res.5, %res.3
233+
%res.7 = xor i1 %res.6, %res.4
234+
235+
ret i1 %res.7
236+
}

0 commit comments

Comments
 (0)