Files
clang-p2996/llvm/test/Transforms/SimplifyCFG/tautological-conditional-branch.ll
Max Kazantsev 29d054bf12 [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
2021-09-08 14:05:17 +07:00

68 lines
2.3 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
%0 = type { %1*, %2* }
%1 = type { %0* }
%2 = type { %0*, %2* }
define void @eggs(i1 %arg, i1 %arg16, %0* %arg17, %0* %arg18, %0* %arg19) {
; CHECK-LABEL: @eggs(
; CHECK-NEXT: bb:
; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB20:%.*]], label [[BB21:%.*]]
; CHECK: bb20:
; CHECK-NEXT: call void @wombat()
; 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: [[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()
; CHECK-NEXT: ret void
;
bb:
br i1 %arg, label %bb20, label %bb21
bb20: ; preds = %bb
call void @wombat()
br label %bb24
bb21: ; preds = %bb
%i = icmp eq %0* %arg17, null
br i1 %i, label %bb24, label %bb22
bb22: ; preds = %bb21
call void @hoge()
br i1 %arg16, label %bb24, label %bb23
bb23: ; preds = %bb22
br label %bb24
bb24: ; preds = %bb23, %bb22, %bb21, %bb20
%i25 = phi i1 [ false, %bb21 ], [ false, %bb20 ], [ false, %bb23 ], [ false, %bb22 ]
%i26 = phi %0* [ null, %bb21 ], [ null, %bb20 ], [ %arg19, %bb23 ], [ null, %bb22 ]
%i27 = getelementptr inbounds %0, %0* %i26, i64 0, i32 0
%i28 = load %1*, %1** %i27, align 8
call void @pluto.1(%1* %i28)
br i1 %i25, label %bb30, label %bb29
bb29: ; preds = %bb24
call void @pluto()
ret void
bb30: ; preds = %bb24
call void @spam()
ret void
}
declare void @wombat()
declare void @pluto()
declare void @spam()
declare void @hoge()
declare void @pluto.1(%1*)