Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

[SimplifyCFG] Hang/Assertion `IterCnt++ < 1000 && "Sanity: iterative simplification didn't converge!"' failed. #51257

Open Quuxplusone opened 3 years ago

Quuxplusone commented 3 years ago
Bugzilla Link PR52290
Status NEW
Importance P enhancement
Reported by Max Kazantsev (max.kazantsev@azul.com)
Reported on 2021-10-25 04:01:30 -0700
Last modified on 2021-10-27 23:54:19 -0700
Version trunk
Hardware PC Windows NT
CC dbakunevich@azul.com, htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments infoForBugGuard.txt (8840 bytes, text/plain)
Blocks
Blocked by
See also
To reproduce: run "opt -simplifycfg -S" on the following test

; RUN: opt < %s -simplifycfg -S | FileCheck %s
; RUN: opt < %s -passes=simplifycfg -S | FileCheck %s

; FIXME: Fails due to infinite loop in iterativelySimplifyCFG.

define i32 @test(float %arg) gc "statepoint-example" personality i32* ()* @blam
{
bb:
  %tmp = call i1 @llvm.experimental.widenable.condition()
  br i1 %tmp, label %bb2, label %bb1

bb1:                                              ; preds = %bb
  br i1 undef, label %bb7, label %bb5

bb2:                                              ; preds = %bb
  %tmp3 = getelementptr inbounds i8, i8 addrspace(1)* undef, i64 16
  br i1 undef, label %bb6, label %bb4

bb4:                                              ; preds = %bb2
  call void @snork() [ "deopt"() ]
  unreachable

bb5:                                              ; preds = %bb1
  ret i32 0

bb6:                                              ; preds = %bb2
  br label %bb7

bb7:                                              ; preds = %bb6, %bb1
  %tmp8 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 10) [ "deopt"() ]
  ret i32 %tmp8
}

declare i32* @blam()

declare void @snork()

declare i32 @llvm.experimental.deoptimize.i32(...)

; Function Attrs: inaccessiblememonly nofree nosync nounwind speculatable
willreturn
declare i1 @llvm.experimental.widenable.condition() #0

attributes #0 = { inaccessiblememonly nofree nosync nounwind speculatable
willreturn }

Originally result was hang (and it's same in product). I've added a sanity
assert and it now is failing. It happens due to infinite execution of
iterativelySimplifyCFG. The IR does not change between iterations, so maybe two
transforms are undoing one another.
Quuxplusone commented 3 years ago
Investigated this bug and found out that there is a looping of the form:
1-st Iteration:

    br i1 undef, label %zero.critedge, label %bci_89.us589.preheader.split ---> br
i1 undef, label %zero, label %bci_89.us589.preheader.split

    zero.critedge:  ---> remove
    br label %zero

    zero:    ; preds = %zero.critedge, %bci_89.us   --->    zero:    ; preds =
%"static void FuzzerUtils.init(jobject, jfloat)541743.exit.split", %bci_89.us

2-nd Iteration:

    bci_89.us:    ; preds = %"static jobject
java.lang.invoke.Invokers$Holder.linkToTargetMethod(jobject)587833.exit" --->
bci_89.us:    ; preds = %"static void FuzzerUtils.init(jobject,
jfloat)541743.exit.split", %"static jobject
java.lang.invoke.Invokers$Holder.linkToTargetMethod(jobject)587833.exit"

    br i1 undef, label %zero, label %bci_89.us589.preheader.split ---> br i1
undef, label %bci_89.us, label %bci_89.us589.preheader.split

    zero:    ; preds = %"static void FuzzerUtils.init(jobject,
jfloat)541743.exit.split", %bci_89.us ---> zero:    ; preds = %bci_89.us

3-d Iteration:

    bci_89.us:    ; preds = %"static void FuzzerUtils.init(jobject,
jfloat)541743.exit.split", %"static jobject
java.lang.invoke.Invokers$Holder.linkToTargetMethod(jobject)587833.exit" --->
bci_89.us:    ; preds = %"static jobject
java.lang.invoke.Invokers$Holder.linkToTargetMethod(jobject)587833.exit"

    br i1 undef, label %bci_89.us, label %bci_89.us589.preheader.split ---> br i1
undef, label %zero.critedge, label %bci_89.us589.preheader.split

    create new BB --->  zero.critedge:                                    ; preds =
%"static void FuzzerUtils.init(jobject, jfloat)541743.exit.split"
                        br label %zero

    zero:    ; preds = %bci_89.us ---> zero:    ; preds = %zero.critedge,
%bci_89.us
Quuxplusone commented 3 years ago
Summary:
   we removed one BB and after 1 iteration we created it.
Quuxplusone commented 3 years ago

Attached infoForBugGuard.txt (8840 bytes, text/plain): More information from my researc

Quuxplusone commented 3 years ago

Dima, I am confused. What test are you referring?

Quuxplusone commented 3 years ago

I'm certain that FoldCondBranchOnPHI has nothing to do with this bug, at least because this test has no phis.

Quuxplusone commented 3 years ago
UPD: indeed, Phi appears there after it's created by

    // Otherwise, if there are multiple predecessors, insert a PHI that merges
    // in the constant and simplify the block result.  Subsequent passes of
    // simplifycfg will thread the block.
    if (BlockIsSimpleEnoughToThreadThrough(BB)) {

Looks like this one and the following one "tryWidenCondBranchToCondBranch" keep
undoing one another.
Quuxplusone commented 3 years ago

This one should be the fix: https://reviews.llvm.org/D112693