llvm.org GIT mirror llvm / 2a07913
[LoopPredication] Check whether the loop is already guarded by the first iteration check condition git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315623 91177308-0d34-0410-b5e6-96231b3b80d8 Artur Pilipenko 1 year, 11 months ago
4 changed file(s) with 78 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
288288
289289 Type *Ty = LHS->getType();
290290 assert(Ty == RHS->getType() && "expandCheck operands have different types?");
291
292 if (SE->isLoopEntryGuardedByCond(L, Pred, LHS, RHS))
293 return Builder.getTrue();
294
291295 Value *LHSV = Expander.expandCodeFor(LHS, Ty, InsertAt);
292296 Value *RHSV = Expander.expandCodeFor(RHS, Ty, InsertAt);
293297 return Builder.CreateICmp(Pred, LHSV, RHSV);
357361 return None;
358362
359363 Instruction *InsertAt = Preheader->getTerminator();
364 auto *LimitCheck = expandCheck(Expander, Builder, LimitCheckPred,
365 LatchCheck.Limit, RangeCheck->Limit, InsertAt);
360366 auto *FirstIterationCheck = expandCheck(Expander, Builder, RangeCheck->Pred,
361367 Start, RangeCheck->Limit, InsertAt);
362 auto *LimitCheck = expandCheck(Expander, Builder, LimitCheckPred,
363 LatchCheck.Limit, RangeCheck->Limit, InsertAt);
364368 return Builder.CreateAnd(FirstIterationCheck, LimitCheck);
365369 }
366370
1010
1111 loop.preheader:
1212 ; CHECK: loop.preheader:
13 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
14 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
13 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
14 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
1515 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
1616 ; CHECK-NEXT: br label %loop
1717 br label %loop
4646
4747 loop.preheader:
4848 ; CHECK: loop.preheader:
49 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
50 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ult i32 %n, %length
49 ; CHECK: [[limit_check:[^ ]+]] = icmp ult i32 %n, %length
50 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
5151 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
5252 ; CHECK-NEXT: br label %loop
5353 br label %loop
8282
8383 loop.preheader:
8484 ; CHECK: loop.preheader:
85 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
86 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
85 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
86 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
8787 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
8888 ; CHECK-NEXT: br label %loop
8989 br label %loop
118118
119119 loop.preheader:
120120 ; CHECK: loop.preheader:
121 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
122 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
123 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
121 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
122 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
123 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
124 ; CHECK-NEXT: br label %loop
125 br label %loop
126
127 loop:
128 ; CHECK: loop:
129 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
130 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
131 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
132 %within.bounds = icmp ult i32 %i, %length
133 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
134
135 %i.i64 = zext i32 %i to i64
136 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
137 %array.i = load i32, i32* %array.i.ptr, align 4
138 %loop.acc.next = add i32 %loop.acc, %array.i
139
140 %i.next = add nuw i32 %i, 1
141 %continue = icmp slt i32 %i.next, %n
142 br i1 %continue, label %loop, label %exit
143
144 exit:
145 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
146 ret i32 %result
147 }
148
149 define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) {
150 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known
151 entry:
152 %tmp5 = icmp sle i32 %n, 0
153 %length = load i32, i32* %length.ptr, !range !{i32 1, i32 2147483648}
154 br i1 %tmp5, label %exit, label %loop.preheader
155
156 loop.preheader:
157 ; CHECK: loop.preheader:
158 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
159 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 true, [[limit_check]]
124160 ; CHECK-NEXT: br label %loop
125161 br label %loop
126162
154190
155191 loop.preheader:
156192 ; CHECK: loop.preheader:
157 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
158 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
193 ; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
194 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
159195 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
160196 ; CHECK-NEXT: br label %loop
161197 br label %loop
190226
191227 loop.preheader:
192228 ; CHECK: loop.preheader:
193 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
194 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
229 ; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length
230 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
195231 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
196232 ; CHECK-NEXT: br label %loop
197233 br label %loop
294330
295331 loop.preheader:
296332 ; CHECK: loop.preheader:
297 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
298 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
333 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
334 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
299335 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
300336 ; CHECK-NEXT: br label %loop
301337 br label %loop
371407
372408 loop.preheader:
373409 ; CHECK: loop.preheader:
374 ; CHECK: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2}}
375 ; CHECK-NEXT: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}}
410 ; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}}
411 ; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2}}
376412 ; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
413 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}}
377414 ; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2}}
378 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}}
379415 ; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
380416 ; CHECK-NEXT: br label %loop
381417 br label %loop
419455
420456 loop.preheader:
421457 ; CHECK: loop.preheader:
422 ; CHECK: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
423 ; CHECK-NEXT: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
458 ; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
459 ; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
424460 ; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
461 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
425462 ; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
426 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
427463 ; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
464 ; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
428465 ; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
429 ; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
430466 ; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]]
431467 ; CHECK-NEXT: br label %loop
432468 br label %loop
477513
478514 loop.preheader:
479515 ; CHECK: loop.preheader:
480 ; CHECK: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
481 ; CHECK-NEXT: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
516 ; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
517 ; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
482518 ; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]]
519 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
483520 ; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
484 ; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
485521 ; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]]
522 ; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
486523 ; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}}
487 ; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}}
488524 ; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]]
489525 ; CHECK-NEXT: br label %loop
490526 br label %loop
537573
538574 loop.preheader:
539575 ; CHECK: loop.preheader:
540 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
541 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
576 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
577 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
542578 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
543579 ; CHECK-NEXT: br label %loop
544580 br label %loop
692728 loop.preheader:
693729 ; CHECK: loop.preheader:
694730 ; CHECK: [[length:[^ ]+]] = zext i16 %length.i16 to i32
731 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, [[length]]
695732 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, [[length]]
696 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, [[length]]
697733 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
698734 ; CHECK-NEXT: br label %loop
699735 br label %loop
1919
2020 inner.loop.preheader:
2121 ; CHECK: inner.loop.preheader:
22 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
23 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %l, %length
22 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %l, %length
23 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
2424 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
2525 ; CHECK-NEXT: br label %inner.loop
2626 br label %inner.loop
6262
6363 outer.loop.preheader:
6464 ; CHECK: outer.loop.preheader:
65 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
66 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
65 ; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
66 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
6767 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
6868 ; CHECK-NEXT: br label %outer.loop
6969 br label %outer.loop
115115
116116 outer.loop.preheader:
117117 ; CHECK: outer.loop.preheader:
118 ; CHECK-NEXT: [[limit_check_outer:[^ ]+]] = icmp sle i32 %n, %length
118119 ; CHECK-NEXT: [[first_iteration_check_outer:[^ ]+]] = icmp ult i32 0, %length
119 ; CHECK-NEXT: [[limit_check_outer:[^ ]+]] = icmp sle i32 %n, %length
120120 ; CHECK-NEXT: [[wide_cond_outer:[^ ]+]] = and i1 [[first_iteration_check_outer]], [[limit_check_outer]]
121121 ; CHECK-NEXT: br label %outer.loop
122122 br label %outer.loop
1010
1111 loop.preheader:
1212 ; CHECK: loop.preheader:
13 ; CHECK: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
14 ; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
13 ; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
14 ; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
1515 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
1616 ; CHECK-NEXT: br label %loop
1717 br label %loop