Skip to content

Commit 5dcfe54

Browse files
fhahnvinay-deshmukh
authored andcommitted
[InstCombnine] Add test for sinking with dereferneceable assumes.
Add tests showing sinking and dropping dereferenceable assumes prevents vectorization.
1 parent 03200ab commit 5dcfe54

File tree

2 files changed

+156
-16
lines changed

2 files changed

+156
-16
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
2+
; RUN: opt -p instcombine -S %s | FileCheck %s
3+
4+
define i64 @test_sink_with_dereferenceable_assume(ptr %p, ptr %q, i1 %cond) {
5+
; CHECK-LABEL: define i64 @test_sink_with_dereferenceable_assume(
6+
; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[COND:%.*]]) {
7+
; CHECK-NEXT: [[ENTRY:.*:]]
8+
; CHECK-NEXT: br i1 [[COND]], label %[[THEN:.*]], label %[[ELSE:.*]]
9+
; CHECK: [[THEN]]:
10+
; CHECK-NEXT: [[Q_INT:%.*]] = ptrtoint ptr [[Q]] to i64
11+
; CHECK-NEXT: [[P_INT:%.*]] = ptrtoint ptr [[P]] to i64
12+
; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[Q_INT]], [[P_INT]]
13+
; CHECK-NEXT: ret i64 [[DIFF]]
14+
; CHECK: [[ELSE]]:
15+
; CHECK-NEXT: ret i64 0
16+
;
17+
entry:
18+
%p_int = ptrtoint ptr %p to i64
19+
%q_int = ptrtoint ptr %q to i64
20+
%diff = sub i64 %q_int, %p_int
21+
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %p, i64 %diff) ]
22+
br i1 %cond, label %then, label %else
23+
24+
then:
25+
ret i64 %diff
26+
27+
else:
28+
ret i64 0
29+
}
30+
31+
declare void @llvm.assume(i1 noundef)

llvm/test/Transforms/PhaseOrdering/AArch64/std-find.ll

Lines changed: 125 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ entry:
4949
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %0, i64 256) ]
5050
%start.ptr = load ptr, ptr %first, align 8
5151
%1 = load i64, ptr %first, align 8
52-
%coerce.val.pi.i = add i64 %1, 256
53-
%coerce.val.ip = inttoptr i64 %coerce.val.pi.i to ptr
54-
%cmp.not6.i.i = icmp eq ptr %start.ptr, %coerce.val.ip
55-
br i1 %cmp.not6.i.i, label %return, label %loop.ph
52+
%coerce.val.p = add i64 %1, 256
53+
%coerce.val.ip = inttoptr i64 %coerce.val.p to ptr
54+
%ec6. = icmp eq ptr %start.ptr, %coerce.val.ip
55+
br i1 %ec6., label %return, label %loop.ph
5656

5757
loop.ph:
5858
%2 = load i16, ptr %s.addr, align 2
@@ -61,13 +61,13 @@ loop.ph:
6161
loop.header:
6262
%ptr.iv = phi ptr [ %start.ptr, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
6363
%3 = load i16, ptr %ptr.iv, align 2
64-
%cmp2.i.i = icmp eq i16 %3, %2
65-
br i1 %cmp2.i.i, label %return, label %loop.latch
64+
%cmp2. = icmp eq i16 %3, %2
65+
br i1 %cmp2., label %return, label %loop.latch
6666

6767
loop.latch:
6868
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 2
69-
%cmp.not.i.i = icmp eq ptr %ptr.iv.next, %coerce.val.ip
70-
br i1 %cmp.not.i.i, label %return, label %loop.header
69+
%ec. = icmp eq ptr %ptr.iv.next, %coerce.val.ip
70+
br i1 %ec., label %return, label %loop.header
7171

7272
return:
7373
%merge = phi ptr [ %start.ptr, %entry ], [ %coerce.val.ip, %loop.latch ], [ %ptr.iv, %loop.header ]
@@ -103,10 +103,10 @@ entry:
103103
%0 = load ptr, ptr %first, align 8
104104
%start.ptr = load ptr, ptr %first, align 8
105105
%1 = load i64, ptr %first, align 8
106-
%coerce.val.pi.i = add i64 %1, 256
107-
%coerce.val.ip = inttoptr i64 %coerce.val.pi.i to ptr
108-
%cmp.not6.i.i = icmp eq ptr %start.ptr, %coerce.val.ip
109-
br i1 %cmp.not6.i.i, label %return, label %loop.ph
106+
%coerce.val.p = add i64 %1, 256
107+
%coerce.val.ip = inttoptr i64 %coerce.val.p to ptr
108+
%ec6. = icmp eq ptr %start.ptr, %coerce.val.ip
109+
br i1 %ec6., label %return, label %loop.ph
110110

111111
loop.ph:
112112
%2 = load i16, ptr %s.addr, align 2
@@ -115,23 +115,132 @@ loop.ph:
115115
loop.header:
116116
%ptr.iv = phi ptr [ %start.ptr, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
117117
%3 = load i16, ptr %ptr.iv, align 2
118-
%cmp2.i.i = icmp eq i16 %3, %2
119-
br i1 %cmp2.i.i, label %return, label %loop.latch
118+
%cmp2. = icmp eq i16 %3, %2
119+
br i1 %cmp2., label %return, label %loop.latch
120120

121121
loop.latch:
122122
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 2
123-
%cmp.not.i.i = icmp eq ptr %ptr.iv.next, %coerce.val.ip
124-
br i1 %cmp.not.i.i, label %return, label %loop.header
123+
%ec. = icmp eq ptr %ptr.iv.next, %coerce.val.ip
124+
br i1 %ec., label %return, label %loop.header
125125

126126
return:
127127
%merge = phi ptr [ %start.ptr, %entry ], [ %coerce.val.ip, %loop.latch ], [ %ptr.iv, %loop.header ]
128128
%res = ptrtoint ptr %merge to i64
129129
ret i64 %res
130130
}
131131

132+
define ptr @std_find_caller(ptr noundef %first, ptr noundef %last) {
133+
; CHECK-LABEL: define noundef ptr @std_find_caller(
134+
; CHECK-SAME: ptr noundef [[FIRST:%.*]], ptr noundef [[LAST:%.*]]) local_unnamed_addr #[[ATTR0]] {
135+
; CHECK-NEXT: [[ENTRY:.*]]:
136+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[FIRST]], i64 2) ]
137+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[LAST]], i64 2) ]
138+
; CHECK-NEXT: [[PRE_I:%.*]] = icmp eq ptr [[FIRST]], [[LAST]]
139+
; CHECK-NEXT: br i1 [[PRE_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT:.*]], label %[[LOOP_HEADER_I_PREHEADER:.*]]
140+
; CHECK: [[LOOP_HEADER_I_PREHEADER]]:
141+
; CHECK-NEXT: [[LAST2:%.*]] = ptrtoint ptr [[LAST]] to i64
142+
; CHECK-NEXT: [[FIRST3:%.*]] = ptrtoint ptr [[FIRST]] to i64
143+
; CHECK-NEXT: [[LAST_I64:%.*]] = ptrtoint ptr [[LAST]] to i64
144+
; CHECK-NEXT: [[FIRST1:%.*]] = ptrtoint ptr [[FIRST]] to i64
145+
; CHECK-NEXT: [[PTR_SUB:%.*]] = sub i64 [[LAST_I64]], [[FIRST1]]
146+
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[FIRST]], i64 [[PTR_SUB]]
147+
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[LAST2]], -2
148+
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[TMP0]], [[FIRST3]]
149+
; CHECK-NEXT: [[TMP2:%.*]] = lshr exact i64 [[TMP1]], 1
150+
; CHECK-NEXT: [[TMP3:%.*]] = add nuw i64 [[TMP2]], 1
151+
; CHECK-NEXT: [[XTRAITER:%.*]] = and i64 [[TMP3]], 3
152+
; CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP1]], 6
153+
; CHECK-NEXT: [[LCMP_MOD_NOT:%.*]] = icmp eq i64 [[TMP4]], 6
154+
; CHECK-NEXT: br i1 [[LCMP_MOD_NOT]], label %[[LOOP_HEADER_I_PROL_LOOPEXIT:.*]], label %[[LOOP_HEADER_I_PROL:.*]]
155+
; CHECK: [[LOOP_HEADER_I_PROL]]:
156+
; CHECK-NEXT: [[PTR_IV_I_PROL:%.*]] = phi ptr [ [[PTR_IV_NEXT_I_PROL:%.*]], %[[LOOP_LATCH_I_PROL:.*]] ], [ [[FIRST]], %[[LOOP_HEADER_I_PREHEADER]] ]
157+
; CHECK-NEXT: [[PROL_ITER:%.*]] = phi i64 [ [[PROL_ITER_NEXT:%.*]], %[[LOOP_LATCH_I_PROL]] ], [ 0, %[[LOOP_HEADER_I_PREHEADER]] ]
158+
; CHECK-NEXT: [[L_I_PROL:%.*]] = load i16, ptr [[PTR_IV_I_PROL]], align 2
159+
; CHECK-NEXT: [[C_1_I_PROL:%.*]] = icmp eq i16 [[L_I_PROL]], 1
160+
; CHECK-NEXT: br i1 [[C_1_I_PROL]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_LATCH_I_PROL]]
161+
; CHECK: [[LOOP_LATCH_I_PROL]]:
162+
; CHECK-NEXT: [[PTR_IV_NEXT_I_PROL]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I_PROL]], i64 2
163+
; CHECK-NEXT: [[PROL_ITER_NEXT]] = add i64 [[PROL_ITER]], 1
164+
; CHECK-NEXT: [[PROL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[PROL_ITER_NEXT]], [[XTRAITER]]
165+
; CHECK-NEXT: br i1 [[PROL_ITER_CMP_NOT]], label %[[LOOP_HEADER_I_PROL_LOOPEXIT]], label %[[LOOP_HEADER_I_PROL]], !llvm.loop [[LOOP3:![0-9]+]]
166+
; CHECK: [[LOOP_HEADER_I_PROL_LOOPEXIT]]:
167+
; CHECK-NEXT: [[PTR_IV_I_UNR:%.*]] = phi ptr [ [[FIRST]], %[[LOOP_HEADER_I_PREHEADER]] ], [ [[PTR_IV_NEXT_I_PROL]], %[[LOOP_LATCH_I_PROL]] ]
168+
; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i64 [[TMP1]], 6
169+
; CHECK-NEXT: br i1 [[TMP5]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_HEADER_I:.*]]
170+
; CHECK: [[LOOP_HEADER_I]]:
171+
; CHECK-NEXT: [[PTR_IV_I:%.*]] = phi ptr [ [[PTR_IV_NEXT_I_3:%.*]], %[[LOOP_LATCH_I_3:.*]] ], [ [[PTR_IV_I_UNR]], %[[LOOP_HEADER_I_PROL_LOOPEXIT]] ]
172+
; CHECK-NEXT: [[L_I:%.*]] = load i16, ptr [[PTR_IV_I]], align 2
173+
; CHECK-NEXT: [[C_1_I:%.*]] = icmp eq i16 [[L_I]], 1
174+
; CHECK-NEXT: br i1 [[C_1_I]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_LATCH_I:.*]]
175+
; CHECK: [[LOOP_LATCH_I]]:
176+
; CHECK-NEXT: [[PTR_IV_NEXT_I:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 2
177+
; CHECK-NEXT: [[L_I_1:%.*]] = load i16, ptr [[PTR_IV_NEXT_I]], align 2
178+
; CHECK-NEXT: [[C_1_I_1:%.*]] = icmp eq i16 [[L_I_1]], 1
179+
; CHECK-NEXT: br i1 [[C_1_I_1]], label %[[STD_FIND_GENERIC_IMPL_EXIT_LOOPEXIT_UNR_LCSSA_LOOPEXIT_SPLIT_LOOP_EXIT11:.*]], label %[[LOOP_LATCH_I_1:.*]]
180+
; CHECK: [[LOOP_LATCH_I_1]]:
181+
; CHECK-NEXT: [[PTR_IV_NEXT_I_1:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 4
182+
; CHECK-NEXT: [[L_I_2:%.*]] = load i16, ptr [[PTR_IV_NEXT_I_1]], align 2
183+
; CHECK-NEXT: [[C_1_I_2:%.*]] = icmp eq i16 [[L_I_2]], 1
184+
; CHECK-NEXT: br i1 [[C_1_I_2]], label %[[STD_FIND_GENERIC_IMPL_EXIT_LOOPEXIT_UNR_LCSSA_LOOPEXIT_SPLIT_LOOP_EXIT9:.*]], label %[[LOOP_LATCH_I_2:.*]]
185+
; CHECK: [[LOOP_LATCH_I_2]]:
186+
; CHECK-NEXT: [[PTR_IV_NEXT_I_2:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 6
187+
; CHECK-NEXT: [[L_I_3:%.*]] = load i16, ptr [[PTR_IV_NEXT_I_2]], align 2
188+
; CHECK-NEXT: [[C_1_I_3:%.*]] = icmp eq i16 [[L_I_3]], 1
189+
; CHECK-NEXT: br i1 [[C_1_I_3]], label %[[STD_FIND_GENERIC_IMPL_EXIT_LOOPEXIT_UNR_LCSSA_LOOPEXIT_SPLIT_LOOP_EXIT7:.*]], label %[[LOOP_LATCH_I_3]]
190+
; CHECK: [[LOOP_LATCH_I_3]]:
191+
; CHECK-NEXT: [[PTR_IV_NEXT_I_3]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 8
192+
; CHECK-NEXT: [[EC_I_3:%.*]] = icmp eq ptr [[PTR_IV_NEXT_I_3]], [[LAST]]
193+
; CHECK-NEXT: br i1 [[EC_I_3]], label %[[STD_FIND_GENERIC_IMPL_EXIT]], label %[[LOOP_HEADER_I]]
194+
; CHECK: [[STD_FIND_GENERIC_IMPL_EXIT_LOOPEXIT_UNR_LCSSA_LOOPEXIT_SPLIT_LOOP_EXIT7]]:
195+
; CHECK-NEXT: [[PTR_IV_NEXT_I_2_LE:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 6
196+
; CHECK-NEXT: br label %[[STD_FIND_GENERIC_IMPL_EXIT]]
197+
; CHECK: [[STD_FIND_GENERIC_IMPL_EXIT_LOOPEXIT_UNR_LCSSA_LOOPEXIT_SPLIT_LOOP_EXIT9]]:
198+
; CHECK-NEXT: [[PTR_IV_NEXT_I_1_LE:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 4
199+
; CHECK-NEXT: br label %[[STD_FIND_GENERIC_IMPL_EXIT]]
200+
; CHECK: [[STD_FIND_GENERIC_IMPL_EXIT_LOOPEXIT_UNR_LCSSA_LOOPEXIT_SPLIT_LOOP_EXIT11]]:
201+
; CHECK-NEXT: [[PTR_IV_NEXT_I_LE:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR_IV_I]], i64 2
202+
; CHECK-NEXT: br label %[[STD_FIND_GENERIC_IMPL_EXIT]]
203+
; CHECK: [[STD_FIND_GENERIC_IMPL_EXIT]]:
204+
; CHECK-NEXT: [[RES_I:%.*]] = phi ptr [ [[FIRST]], %[[ENTRY]] ], [ [[SCEVGEP]], %[[LOOP_HEADER_I_PROL_LOOPEXIT]] ], [ [[PTR_IV_NEXT_I_2_LE]], %[[STD_FIND_GENERIC_IMPL_EXIT_LOOPEXIT_UNR_LCSSA_LOOPEXIT_SPLIT_LOOP_EXIT7]] ], [ [[PTR_IV_NEXT_I_1_LE]], %[[STD_FIND_GENERIC_IMPL_EXIT_LOOPEXIT_UNR_LCSSA_LOOPEXIT_SPLIT_LOOP_EXIT9]] ], [ [[PTR_IV_NEXT_I_LE]], %[[STD_FIND_GENERIC_IMPL_EXIT_LOOPEXIT_UNR_LCSSA_LOOPEXIT_SPLIT_LOOP_EXIT11]] ], [ [[SCEVGEP]], %[[LOOP_LATCH_I_3]] ], [ [[PTR_IV_I]], %[[LOOP_HEADER_I]] ], [ [[PTR_IV_I_PROL]], %[[LOOP_HEADER_I_PROL]] ]
205+
; CHECK-NEXT: ret ptr [[RES_I]]
206+
;
207+
entry:
208+
%last.i64 = ptrtoint ptr %last to i64
209+
%first.i64 = ptrtoint ptr %first to i64
210+
%ptr.sub = sub i64 %last.i64, %first.i64
211+
call void @llvm.assume(i1 true) [ "align"(ptr %first, i64 2) ]
212+
call void @llvm.assume(i1 true) [ "align"(ptr %last, i64 2) ]
213+
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %first, i64 %ptr.sub) ]
214+
%call = call noundef ptr @std_find_generic_impl(ptr noundef nonnull %first, ptr noundef %last, i16 noundef signext 1)
215+
ret ptr %call
216+
}
217+
218+
define linkonce_odr noundef ptr @std_find_generic_impl(ptr noundef %first, ptr noundef %last, i16 noundef %value) {
219+
entry:
220+
%pre = icmp eq ptr %first, %last
221+
br i1 %pre, label %exit, label %loop.header
222+
223+
loop.header:
224+
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %first, %entry ]
225+
%l = load i16, ptr %ptr.iv, align 2
226+
%c.1 = icmp eq i16 %l, %value
227+
br i1 %c.1, label %exit, label %loop.latch
228+
229+
loop.latch:
230+
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 2
231+
%ec = icmp eq ptr %ptr.iv.next, %last
232+
br i1 %ec, label %exit, label %loop.header
233+
234+
exit:
235+
%res = phi ptr [ %first, %entry ], [ %ptr.iv, %loop.header ], [ %ptr.iv.next, %loop.latch ]
236+
ret ptr %res
237+
}
238+
132239
declare void @llvm.assume(i1 noundef)
133240
;.
134241
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
135242
; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
136243
; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
244+
; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META4:![0-9]+]]}
245+
; CHECK: [[META4]] = !{!"llvm.loop.unroll.disable"}
137246
;.

0 commit comments

Comments
 (0)