@@ -48,3 +48,149 @@ exit:
4848 %res = phi i64 [ 0 , %entry ], [ %i64.iv , %loop.latch ], [ 0 , %loop.header ]
4949 ret i64 %res
5050}
51+
52+ define void @test_sub_cmp (ptr align 8 %start , ptr %end ) {
53+ ; CHECK-LABEL: define void @test_sub_cmp(
54+ ; CHECK-SAME: ptr align 8 [[START:%.*]], ptr [[END:%.*]]) {
55+ ; CHECK-NEXT: [[ENTRY:.*:]]
56+ ; CHECK-NEXT: [[START_INT:%.*]] = ptrtoint ptr [[START]] to i64
57+ ; CHECK-NEXT: [[END_INT:%.*]] = ptrtoint ptr [[END]] to i64
58+ ; CHECK-NEXT: [[PTR_DIFF:%.*]] = sub i64 [[START_INT]], [[END_INT]]
59+ ; CHECK-NEXT: [[CMP_ENTRY:%.*]] = icmp eq ptr [[START]], [[END]]
60+ ; CHECK-NEXT: br i1 [[CMP_ENTRY]], label %[[EXIT:.*]], label %[[LOOP_HEADER_PREHEADER:.*]]
61+ ; CHECK: [[LOOP_HEADER_PREHEADER]]:
62+ ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
63+ ; CHECK: [[LOOP_HEADER]]:
64+ ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ 0, %[[LOOP_HEADER_PREHEADER]] ]
65+ ; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond()
66+ ; CHECK-NEXT: br i1 [[C_1]], label %[[EXIT_EARLY:.*]], label %[[LOOP_LATCH]]
67+ ; CHECK: [[LOOP_LATCH]]:
68+ ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1
69+ ; CHECK-NEXT: [[CMP_LATCH:%.*]] = icmp ult i64 [[IV_NEXT]], [[PTR_DIFF]]
70+ ; CHECK-NEXT: br i1 [[CMP_LATCH]], label %[[LOOP_HEADER]], label %[[EXIT_LOOPEXIT:.*]]
71+ ; CHECK: [[EXIT_EARLY]]:
72+ ; CHECK-NEXT: br label %[[EXIT]]
73+ ; CHECK: [[EXIT_LOOPEXIT]]:
74+ ; CHECK-NEXT: br label %[[EXIT]]
75+ ; CHECK: [[EXIT]]:
76+ ; CHECK-NEXT: ret void
77+ ;
78+ ; N32-LABEL: define void @test_sub_cmp(
79+ ; N32-SAME: ptr align 8 [[START:%.*]], ptr [[END:%.*]]) {
80+ ; N32-NEXT: [[ENTRY:.*:]]
81+ ; N32-NEXT: [[START_INT:%.*]] = ptrtoint ptr [[START]] to i64
82+ ; N32-NEXT: [[END_INT:%.*]] = ptrtoint ptr [[END]] to i64
83+ ; N32-NEXT: [[PTR_DIFF:%.*]] = sub i64 [[START_INT]], [[END_INT]]
84+ ; N32-NEXT: [[CMP_ENTRY:%.*]] = icmp eq ptr [[START]], [[END]]
85+ ; N32-NEXT: br i1 [[CMP_ENTRY]], label %[[EXIT:.*]], label %[[LOOP_HEADER_PREHEADER:.*]]
86+ ; N32: [[LOOP_HEADER_PREHEADER]]:
87+ ; N32-NEXT: br label %[[LOOP_HEADER:.*]]
88+ ; N32: [[LOOP_HEADER]]:
89+ ; N32-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ 0, %[[LOOP_HEADER_PREHEADER]] ]
90+ ; N32-NEXT: [[C_1:%.*]] = call i1 @cond()
91+ ; N32-NEXT: br i1 [[C_1]], label %[[EXIT_EARLY:.*]], label %[[LOOP_LATCH]]
92+ ; N32: [[LOOP_LATCH]]:
93+ ; N32-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1
94+ ; N32-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[PTR_DIFF]]
95+ ; N32-NEXT: br i1 [[EXITCOND]], label %[[LOOP_HEADER]], label %[[EXIT_LOOPEXIT:.*]]
96+ ; N32: [[EXIT_EARLY]]:
97+ ; N32-NEXT: br label %[[EXIT]]
98+ ; N32: [[EXIT_LOOPEXIT]]:
99+ ; N32-NEXT: br label %[[EXIT]]
100+ ; N32: [[EXIT]]:
101+ ; N32-NEXT: ret void
102+ ;
103+ entry:
104+ %start.int = ptrtoint ptr %start to i64
105+ %end.int = ptrtoint ptr %end to i64
106+ %ptr.diff = sub i64 %start.int , %end.int
107+ %cmp.entry = icmp eq ptr %start , %end
108+ br i1 %cmp.entry , label %exit , label %loop.header
109+
110+ loop.header:
111+ %iv = phi i64 [ 0 , %entry ], [ %iv.next , %loop.latch ]
112+ %c.1 = call i1 @cond ()
113+ br i1 %c.1 , label %exit.early , label %loop.latch
114+
115+ loop.latch:
116+ %iv.next = add i64 %iv , 1
117+ %cmp.latch = icmp ult i64 %iv.next , %ptr.diff
118+ br i1 %cmp.latch , label %loop.header , label %exit
119+
120+ exit.early:
121+ br label %exit
122+
123+ exit:
124+ ret void
125+ }
126+
127+
128+ define void @test_ptr_diff_with_assume (ptr align 8 %start , ptr align 8 %end , ptr %P ) {
129+ ; CHECK-LABEL: define void @test_ptr_diff_with_assume(
130+ ; CHECK-SAME: ptr align 8 [[START:%.*]], ptr align 8 [[END:%.*]], ptr [[P:%.*]]) {
131+ ; CHECK-NEXT: [[ENTRY:.*:]]
132+ ; CHECK-NEXT: [[START_INT:%.*]] = ptrtoint ptr [[START]] to i64
133+ ; CHECK-NEXT: [[END_INT:%.*]] = ptrtoint ptr [[END]] to i64
134+ ; CHECK-NEXT: [[PTR_DIFF:%.*]] = sub i64 [[START_INT]], [[END_INT]]
135+ ; CHECK-NEXT: [[DIFF_CMP:%.*]] = icmp ult i64 [[PTR_DIFF]], 2
136+ ; CHECK-NEXT: call void @llvm.assume(i1 [[DIFF_CMP]])
137+ ; CHECK-NEXT: [[COMPUTED_END:%.*]] = getelementptr i8, ptr [[START]], i64 [[PTR_DIFF]]
138+ ; CHECK-NEXT: [[ENTRY_CMP:%.*]] = icmp eq ptr [[START]], [[END]]
139+ ; CHECK-NEXT: br i1 [[ENTRY_CMP]], label %[[EXIT:.*]], label %[[LOOP_BODY_PREHEADER:.*]]
140+ ; CHECK: [[LOOP_BODY_PREHEADER]]:
141+ ; CHECK-NEXT: br label %[[LOOP_BODY:.*]]
142+ ; CHECK: [[LOOP_BODY]]:
143+ ; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[IV_NEXT:%.*]], %[[LOOP_BODY]] ], [ [[START]], %[[LOOP_BODY_PREHEADER]] ]
144+ ; CHECK-NEXT: [[TMP0:%.*]] = call i1 @cond()
145+ ; CHECK-NEXT: [[IV_NEXT]] = getelementptr i8, ptr [[IV]], i64 1
146+ ; CHECK-NEXT: [[LOOP_CMP:%.*]] = icmp eq ptr [[IV_NEXT]], [[COMPUTED_END]]
147+ ; CHECK-NEXT: br i1 [[LOOP_CMP]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP_BODY]]
148+ ; CHECK: [[EXIT_LOOPEXIT]]:
149+ ; CHECK-NEXT: br label %[[EXIT]]
150+ ; CHECK: [[EXIT]]:
151+ ; CHECK-NEXT: ret void
152+ ;
153+ ; N32-LABEL: define void @test_ptr_diff_with_assume(
154+ ; N32-SAME: ptr align 8 [[START:%.*]], ptr align 8 [[END:%.*]], ptr [[P:%.*]]) {
155+ ; N32-NEXT: [[ENTRY:.*:]]
156+ ; N32-NEXT: [[START_INT:%.*]] = ptrtoint ptr [[START]] to i64
157+ ; N32-NEXT: [[END_INT:%.*]] = ptrtoint ptr [[END]] to i64
158+ ; N32-NEXT: [[PTR_DIFF:%.*]] = sub i64 [[START_INT]], [[END_INT]]
159+ ; N32-NEXT: [[DIFF_CMP:%.*]] = icmp ult i64 [[PTR_DIFF]], 2
160+ ; N32-NEXT: call void @llvm.assume(i1 [[DIFF_CMP]])
161+ ; N32-NEXT: [[COMPUTED_END:%.*]] = getelementptr i8, ptr [[START]], i64 [[PTR_DIFF]]
162+ ; N32-NEXT: [[ENTRY_CMP:%.*]] = icmp eq ptr [[START]], [[END]]
163+ ; N32-NEXT: br i1 [[ENTRY_CMP]], label %[[EXIT:.*]], label %[[LOOP_BODY_PREHEADER:.*]]
164+ ; N32: [[LOOP_BODY_PREHEADER]]:
165+ ; N32-NEXT: br label %[[LOOP_BODY:.*]]
166+ ; N32: [[LOOP_BODY]]:
167+ ; N32-NEXT: [[IV:%.*]] = phi ptr [ [[IV_NEXT:%.*]], %[[LOOP_BODY]] ], [ [[START]], %[[LOOP_BODY_PREHEADER]] ]
168+ ; N32-NEXT: [[TMP0:%.*]] = call i1 @cond()
169+ ; N32-NEXT: [[IV_NEXT]] = getelementptr i8, ptr [[IV]], i64 1
170+ ; N32-NEXT: [[LOOP_CMP:%.*]] = icmp eq ptr [[IV_NEXT]], [[COMPUTED_END]]
171+ ; N32-NEXT: br i1 [[LOOP_CMP]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP_BODY]]
172+ ; N32: [[EXIT_LOOPEXIT]]:
173+ ; N32-NEXT: br label %[[EXIT]]
174+ ; N32: [[EXIT]]:
175+ ; N32-NEXT: ret void
176+ ;
177+ entry:
178+ %start.int = ptrtoint ptr %start to i64
179+ %end.int = ptrtoint ptr %end to i64
180+ %ptr.diff = sub i64 %start.int , %end.int
181+ %diff.cmp = icmp ult i64 %ptr.diff , 2
182+ call void @llvm.assume (i1 %diff.cmp )
183+ %computed.end = getelementptr i8 , ptr %start , i64 %ptr.diff
184+ %entry.cmp = icmp eq ptr %start , %end
185+ br i1 %entry.cmp , label %exit , label %loop.body
186+
187+ loop.body:
188+ %iv = phi ptr [ %start , %entry ], [ %iv.next , %loop.body ]
189+ call i1 @cond ()
190+ %iv.next = getelementptr i8 , ptr %iv , i64 1
191+ %loop.cmp = icmp eq ptr %iv.next , %computed.end
192+ br i1 %loop.cmp , label %exit , label %loop.body
193+
194+ exit:
195+ ret void
196+ }
0 commit comments