Prevent `invertCondition` from creating the inversion instruction, in case the given value is an argument which has already been inverted. Note that this approach has already been taken in case the given value is an instruction (and not an argument). Differential Revision: https://reviews.llvm.org/D80399
54 lines
1.5 KiB
LLVM
54 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.inv = xor i1 %cond.if, true
|
|
; 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.inv, %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: 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.inv, %else ], [ true, %Flow1 ]
|
|
; CHECK: br i1 %4, label %exit, label %loop.outer
|
|
|
|
exit:
|
|
ret void
|
|
}
|
|
|
|
declare void @foo(i32)
|