Issue 146442
Summary [SimplifyCFG] Optimization missed to reduce a conditional branch to unconditional
Labels new issue
Assignees
Reporter davidzhengyes
    I have created the following test case: 

``` llvm
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=simplifycfg -S | FileCheck %s


define void @mainfunc(i16 %0) {
; CHECK-LABEL: define void @mainfunc(
; CHECK-SAME: i16 [[TMP0:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i16 [[TMP0]], 10
; CHECK-NEXT:    br i1 [[TMP1]], label %[[OTHERLOOPEND:.*]], label %[[FOR_BODY_CRITEDGE:.*]]
; CHECK:       [[OTHERLOOPEND]]:
; CHECK-NEXT:    [[OTHERLOOPIV:%.*]] = call i16 @ivfunc()
; CHECK-NEXT: [[OTHERLOOPPRED:%.*]] = icmp slt i16 [[OTHERLOOPIV]], 100
; CHECK-NEXT: br i1 [[OTHERLOOPPRED]], label %[[OTHERLOOPEND]], label %[[VADDEXIT:.*]]
; CHECK:       [[VADDEXIT]]:
; CHECK-NEXT:    call void @voidfunc()
; CHECK-NEXT:    br label %[[END:.*]]
; CHECK:       [[FOR_BODY_CRITEDGE]]:
; CHECK-NEXT:    call void @voidfunc()
; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
; CHECK:       [[FOR_BODY]]:
; CHECK-NEXT:    [[IV:%.*]] = phi i16 [ [[IV_NEXT:%.*]], %[[FOR_BODY]] ], [ 0, %[[FOR_BODY_CRITEDGE]] ]
; CHECK-NEXT:    [[VAL:%.*]] = tail call <256 x i1> @helperfunc()
; CHECK-NEXT:    [[VAL2:%.*]] = tail call <1 x i32> @helperfunc2()
; CHECK-NEXT:    [[IV_NEXT]] = add i16 [[IV]], 1
; CHECK-NEXT:    [[PRED:%.*]] = icmp slt i16 [[IV_NEXT]], 100
; CHECK-NEXT:    br i1 [[PRED]], label %[[FOR_BODY]], label %[[END]]
; CHECK:       [[END]]:
; CHECK-NEXT:    ret void
;
entry:
  br label %otherlooppreheader

otherlooppreheader:
  %1 = icmp ugt i16 %0, 10
  br i1 %1, label %otherloopend, label %VAddExit

otherloopend:
  %otherloopiv = call i16 @ivfunc()
 %otherLoopPred = icmp slt i16 %otherloopiv, 100
  br i1 %otherLoopPred, label %otherloopend, label %VAddExit


VAddExit:
  call void @voidfunc()
  br i1 %1, label %end, label %for.body

for.body:
  %iv = phi i16 [ %iv.next, %VMulExit ], [ 0, %VAddExit ]
  %val = tail call <256 x i1> @helperfunc()
  br label %for.body.inner

for.body.inner:
  %val2 = tail call <1 x i32> @helperfunc2()
  br label %VMulExit

VMulExit:
 %iv.next = add i16 %iv, 1
  %pred = icmp slt i16 %iv.next, 100
  br i1 %pred, label %for.body, label %end

end:
  ret void

}


declare i16 @ivfunc()

declare <256 x i1> @helperfunc()

declare <1 x i32> @helperfunc2()

declare void @voidfunc()

```

And it results in the following IR: 

``` llvm
; ModuleID = '<stdin>'
source_filename = "<stdin>"

define void @mainfunc(i16 %0) {
entry:
  %1 = icmp ugt i16 %0, 10
  br i1 %1, label %otherloopend, label %for.body.critedge

otherloopend:                                     ; preds = %otherloopend, %entry
  %otherloopiv = call i16 @ivfunc()
 %otherLoopPred = icmp slt i16 %otherloopiv, 100
  br i1 %otherLoopPred, label %otherloopend, label %VAddExit

VAddExit: ; preds = %otherloopend
  call void @voidfunc()
  br i1 %1, label %end, label %for.body

for.body.critedge: ; preds = %entry
  call void @voidfunc()
  br label %for.body

for.body:                                         ; preds = %for.body.critedge, %for.body, %VAddExit
  %iv = phi i16 [ %iv.next, %for.body ], [ 0, %VAddExit ], [ 0, %for.body.critedge ]
  %val = tail call <256 x i1> @helperfunc()
  %val2 = tail call <1 x i32> @helperfunc2()
 %iv.next = add i16 %iv, 1
  %pred = icmp slt i16 %iv.next, 100
  br i1 %pred, label %for.body, label %end

end: ; preds = %for.body, %VAddExit
  ret void
}

declare i16 @ivfunc()

declare <256 x i1> @helperfunc()

declare <1 x i32> @helperfunc2()

declare void @voidfunc()

```

In the output for.body: block, there is a phi node with three values. If you inspect the rest of the IR, simplifyCFG has simplified the branch in entry (which had otherlooppreheader collapsed into it) to go directly to for.body.critedge because the value is known from the predecessor. 

Specifically, the edge with `[ 0, %VAddExit ]` is dead, as VAddExit will only branch to for.body if %1 is false, but in its predecessors, if %1 is false, it would not reach VAddExit anyway. This edge can be removed in this case.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to