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