llvm.org GIT mirror llvm / 7e587dd
Loop predication expand both sides of the widened condition This is a fix for a loop predication bug which resulted in malformed IR generation. Loop invariant side of the widened condition is not guaranteed to be available in the preheader as is, so we need to expand it as well. See added unsigned_loop_0_to_n_hoist_length test for example. Reviewed By: sanjoy, mkazantsev Differential Revision: https://reviews.llvm.org/D30099 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296345 91177308-0d34-0410-b5e6-96231b3b80d8 Artur Pilipenko 2 years ago
2 changed file(s) with 85 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
140140 std::swap(LHSS, RHSS);
141141 Pred = ICmpInst::getSwappedPredicate(Pred);
142142 }
143 if (!SE->isLoopInvariant(RHSS, L))
144 return None;
145
146 Value *Bound = RHS;
143 if (!SE->isLoopInvariant(RHSS, L) || !isSafeToExpand(RHSS, *SE))
144 return None;
145
147146 const SCEVAddRecExpr *IndexAR = dyn_cast(LHSS);
148147 if (!IndexAR || IndexAR->getLoop() != L)
149148 return None;
175174
176175 DEBUG(dbgs() << "NewLHSS is loop invariant and safe to expand. Expand!\n");
177176
178 Value *NewLHS = Expander.expandCodeFor(NewLHSS, Bound->getType(),
179 Preheader->getTerminator());
180 return Builder.CreateICmp(Pred, NewLHS, Bound);
177 Type *Ty = LHS->getType();
178 Instruction *InsertAt = Preheader->getTerminator();
179 assert(Ty == RHS->getType() && "icmp operands have different types?");
180 Value *NewLHS = Expander.expandCodeFor(NewLHSS, Ty, InsertAt);
181 Value *NewRHS = Expander.expandCodeFor(RHSS, Ty, InsertAt);
182 return Builder.CreateICmp(Pred, NewLHS, NewRHS);
181183 }
182184
183185 bool LoopPredication::widenGuardConditions(IntrinsicInst *Guard,
492492 exit:
493493 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
494494 ret i32 %result
495 }
495 }
496
497 define i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) {
498 ; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length
499 entry:
500 %tmp5 = icmp eq i32 %n, 0
501 br i1 %tmp5, label %exit, label %loop.preheader
502
503 loop.preheader:
504 ; CHECK: loop.preheader:
505 ; CHECK: [[max_index:[^ ]+]] = add i32 %n, -1
506 ; CHECK-NEXT: [[length:[^ ]+]] = zext i16 %length.i16 to i32
507 ; CHECK-NEXT: [[wide_cond:[^ ]+]] = icmp ult i32 [[max_index]], [[length]]
508 ; CHECK-NEXT: br label %loop
509 br label %loop
510
511 loop:
512 ; CHECK: loop:
513 ; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
514 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
515 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
516 %length = zext i16 %length.i16 to i32
517 %within.bounds = icmp ult i32 %i, %length
518 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
519
520 %i.i64 = zext i32 %i to i64
521 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
522 %array.i = load i32, i32* %array.i.ptr, align 4
523 %loop.acc.next = add i32 %loop.acc, %array.i
524
525 %i.next = add nuw i32 %i, 1
526 %continue = icmp ult i32 %i.next, %n
527 br i1 %continue, label %loop, label %exit
528
529 exit:
530 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
531 ret i32 %result
532 }
533
534 define i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) {
535 ; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length
536 entry:
537 %tmp5 = icmp eq i32 %n, 0
538 br i1 %tmp5, label %exit, label %loop.preheader
539
540 loop.preheader:
541 ; CHECK: loop.preheader:
542 ; CHECK-NEXT: br label %loop
543 br label %loop
544
545 loop:
546 ; CHECK: loop:
547 ; CHECK-NEXT: %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
548 ; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
549 ; CHECK-NEXT: %length.udiv = udiv i32 %length, %divider
550 ; CHECK-NEXT: %within.bounds = icmp ult i32 %i, %length.udiv
551 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
552 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
553 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
554 %length.udiv = udiv i32 %length, %divider
555 %within.bounds = icmp ult i32 %i, %length.udiv
556 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
557
558 %i.i64 = zext i32 %i to i64
559 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
560 %array.i = load i32, i32* %array.i.ptr, align 4
561 %loop.acc.next = add i32 %loop.acc, %array.i
562
563 %i.next = add nuw i32 %i, 1
564 %continue = icmp ult i32 %i.next, %n
565 br i1 %continue, label %loop, label %exit
566
567 exit:
568 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
569 ret i32 %result
570 }