[SimplifyCFG] Preserve knowledge about guarding condition by adding assume

This improvement adds "assume" after removal of branch basing on UB in successor block.

Consider the following example:

```
pred:
  x = ...
  cond = x > 10
  br cond, bb, other.succ

bb:
  phi [nullptr, pred], ... // other possible preds
  load(phi) // UB if we came from pred

other.succ:
  // here we know that x <= 10, but this knowledge is lost
  // after the branch is turned to unconditional unless we
  // preserve it with assume.
```

If we remove the branch basing on knowledge about UB in a successor block,
then the fact that x <= 10 is other.succ might be lost if this condition is
not inferrable from any dominating condition. To preserve this knowledge, we
can add assume intrinsic with (possibly inverted) branch condition.

Patch by Dmitry Bakunevich!

Differential Revision: https://reviews.llvm.org/D109054
Reviewed By: lebedev.ri
This commit is contained in:
Max Kazantsev 2021-09-08 13:17:23 +07:00
parent ca867ef47b
commit 29d054bf12
2 changed files with 14 additions and 2 deletions

View File

@ -6598,9 +6598,17 @@ static bool removeUndefIntroducingPredecessor(BasicBlock *BB,
// destination from conditional branches.
if (BI->isUnconditional())
Builder.CreateUnreachable();
else
else {
// Preserve guarding condition in assume, because it might not be
// inferrable from any dominating condition.
Value *Cond = BI->getCondition();
if (BI->getSuccessor(0) == BB)
Builder.CreateAssumption(Builder.CreateNot(Cond));
else
Builder.CreateAssumption(Cond);
Builder.CreateBr(BI->getSuccessor(0) == BB ? BI->getSuccessor(1)
: BI->getSuccessor(0));
}
BI->eraseFromParent();
if (DTU)
DTU->applyUpdates({{DominatorTree::Delete, Predecessor, BB}});

View File

@ -14,8 +14,12 @@ define void @eggs(i1 %arg, i1 %arg16, %0* %arg17, %0* %arg18, %0* %arg19) {
; CHECK-NEXT: unreachable
; CHECK: bb21:
; CHECK-NEXT: [[I:%.*]] = icmp eq %0* [[ARG17:%.*]], null
; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[I]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]])
; CHECK-NEXT: call void @hoge()
; CHECK-NEXT: [[I27:%.*]] = getelementptr inbounds [[TMP0:%.*]], %0* [[ARG19:%.*]], i64 0, i32 0
; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[ARG16:%.*]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
; CHECK-NEXT: [[I27:%.*]] = getelementptr inbounds [[TMP0]], %0* [[ARG19:%.*]], i64 0, i32 0
; CHECK-NEXT: [[I28:%.*]] = load %1*, %1** [[I27]], align 8
; CHECK-NEXT: call void @pluto.1(%1* [[I28]])
; CHECK-NEXT: call void @pluto()