llvm.org GIT mirror llvm / a3d1fd2
[LoopPred] Be uniform about proving generated conditions We'd been optimizing the case where the predicate was obviously true, do the same for the false case. Mostly just for completeness sake, but also may improve compile time in loops which will exit through the guard. Such loops are presumed rare in fastpath code, but may be present down untaken paths, so optimizing for them is still useful. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357408 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 5 months ago
2 changed file(s) with 52 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
395395
396396 if (SE->isLoopEntryGuardedByCond(L, Pred, LHS, RHS))
397397 return Builder.getTrue();
398 if (SE->isLoopEntryGuardedByCond(L, ICmpInst::getInversePredicate(Pred),
399 LHS, RHS))
400 return Builder.getFalse();
398401
399402 Instruction *InsertAt = &*Builder.GetInsertPoint();
400403 Value *LHSV = Expander.expandCodeFor(LHS, Ty, InsertAt);
15431543 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
15441544 ret i32 %result
15451545 }
1546
1547
1548 ; This is a case where the length information tells us that the guard
1549 ; must trigger on some iteration.
1550 define i32 @provably_taken(i32* %array, i32* %length.ptr) {
1551 ; CHECK-LABEL: @provably_taken(
1552 ; CHECK-NEXT: loop.preheader:
1553 ; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], !range !1
1554 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 0, [[LENGTH]]
1555 ; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], false
1556 ; CHECK-NEXT: br label [[LOOP:%.*]]
1557 ; CHECK: loop:
1558 ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
1559 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
1560 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[TMP1]], i32 9) [ "deopt"() ]
1561 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1562 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1563 ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1564 ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1565 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1566 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], 200
1567 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1568 ; CHECK: exit:
1569 ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[LOOP]] ]
1570 ; CHECK-NEXT: ret i32 [[RESULT]]
1571 ;
1572 loop.preheader:
1573 %length = load i32, i32* %length.ptr, !range !{i32 0, i32 50}
1574 br label %loop
1575
1576 loop:
1577 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
1578 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
1579 %within.bounds = icmp ult i32 %i, %length
1580 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
1581
1582 %i.i64 = zext i32 %i to i64
1583 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1584 %array.i = load i32, i32* %array.i.ptr, align 4
1585 %loop.acc.next = add i32 %loop.acc, %array.i
1586
1587 %i.next = add nuw i32 %i, 1
1588 %continue = icmp slt i32 %i.next, 200
1589 br i1 %continue, label %loop, label %exit
1590
1591 exit:
1592 %result = phi i32 [ %loop.acc.next, %loop ]
1593 ret i32 %result
1594 }