Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid LLVM IR for certain iteration pattern #27594

Closed
martinholters opened this issue Jun 15, 2018 · 0 comments
Closed

Invalid LLVM IR for certain iteration pattern #27594

martinholters opened this issue Jun 15, 2018 · 0 comments
Assignees
Labels
bug Indicates an unexpected problem or unintended behavior

Comments

@martinholters
Copy link
Member

Reduced from the problem I've observed in #27434 (comment).

struct Iter end
Base.iterate(::Iter) = (1, nothing)
Base.iterate(::Iter, ::Any) = nothing

function foo()
    ind = 0
    for x in (1,)
        for y in Iter()
            ind += 1
        end
    end
end

code_llvm(foo, Tuple{})

gives

PHI node has multiple entries for the same basic block with different incoming values!
  %value_phi2 = phi i64 [ %36, %L11 ], [ %37, %L11 ], [ %value_phi, %L5.L13_crit_edge ]
label %L11
  %37 = load i64, i64* %8, align 8, !dbg !28, !tbaa !21
  %36 = load i64, i64* %8, align 8, !dbg !28, !tbaa !21
LLVM ERROR: Broken function found, compilation aborted!

Tentatively assigning @Keno whom I suspect to be the best one to fix this.

@JeffBezanson JeffBezanson added the bug Indicates an unexpected problem or unintended behavior label Jun 15, 2018
Keno added a commit that referenced this issue Jun 16, 2018
It is possible, after optimziations for the two branches of a conditional
to go to the same basic block. We have an IR invariant that requires the
incoming value to be the same for both incoming edges in this case. LLVM
has the same invariant. However, translating from a julia-incoming-value
to an LLVM one may require additional code generation, and without further
GVN, LLVM does not know that the two values are identical and thus believes
its invariants are violated. The fix is relatively straightforward. Since
we don't have user-inserted switch terminators, we can simply emit a
conditional branch with equal successors as unconditional branches and
skip codegening one of the phi paths. This avoids the issue and also
generates less code in this case.

Fixes #27594
Keno added a commit that referenced this issue Jun 16, 2018
It is possible, after optimziations for the two branches of a conditional
to go to the same basic block. We have an IR invariant that requires the
incoming value to be the same for both incoming edges in this case. LLVM
has the same invariant. However, translating from a julia-incoming-value
to an LLVM one may require additional code generation, and without further
GVN, LLVM does not know that the two values are identical and thus believes
its invariants are violated. The fix is relatively straightforward. Since
we don't have user-inserted switch terminators, we can simply emit a
conditional branch with equal successors as unconditional branches and
skip codegening one of the phi paths. This avoids the issue and also
generates less code in this case.

Fixes #27594
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

3 participants