Jay Foad d2e5d3512b [StructurizeCFG] Clean up some boolean not instructions
In some cases StructurizeCFG inserts i1 xor instructions to invert
predicates. Add a quick loop to clean these up afterwards if we can get
away with modifying an existing compare instruction instead.
(StructurizeCFG is generally run late in the pipeline so instcombine
does not clean them up for us.)

Differential Revision: https://reviews.llvm.org/D118623
2022-02-01 09:35:37 +00:00

55 lines
1.5 KiB
LLVM

; RUN: opt -S -structurizecfg %s | FileCheck %s
; r321751 introduced a bug where control flow branching from if to exit was
; not handled properly and instead ended up in an infinite loop.
define void @bug36015(i32 %cmp0, i32 %count) {
entry:
br label %loop.outer
loop.outer:
%ctr.loop.outer = phi i32 [ 0, %entry ], [ %ctr.else, %else ]
call void @foo(i32 0)
br label %loop.inner
loop.inner:
%ctr.loop.inner = phi i32 [ %ctr.loop.outer, %loop.outer ], [ %ctr.if, %if ]
call void @foo(i32 1)
%cond.inner = icmp eq i32 %cmp0, %ctr.loop.inner
br i1 %cond.inner, label %if, label %else
; CHECK: if:
; CHECK: %cond.if = icmp sge i32 %ctr.if, %count
; CHECK: br label %Flow
if:
%ctr.if = add i32 %ctr.loop.inner, 1
call void @foo(i32 2)
%cond.if = icmp slt i32 %ctr.if, %count
br i1 %cond.if, label %loop.inner, label %exit
; CHECK: Flow:
; CHECK: %1 = phi i1 [ %cond.if, %if ], [ true, %loop.inner ]
; CHECK: %2 = phi i1 [ false, %if ], [ true, %loop.inner ]
; CHECK: br i1 %1, label %Flow1, label %loop.inner
; CHECK: Flow1:
; CHECK: br i1 %2, label %else, label %Flow2
; CHECK: else:
; CHECK: %cond.else = icmp sge i32 %ctr.else, %count
; CHECK: br label %Flow2
else:
%ctr.else = add i32 %ctr.loop.inner, 1
call void @foo(i32 3)
%cond.else = icmp slt i32 %ctr.else, %count
br i1 %cond.else, label %loop.outer, label %exit
; CHECK: Flow2:
; CHECK: %4 = phi i1 [ %cond.else, %else ], [ true, %Flow1 ]
; CHECK: br i1 %4, label %exit, label %loop.outer
exit:
ret void
}
declare void @foo(i32)