-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Segfault in collect in HierarchialUtilities #44501
Comments
Reduced to the following (which only fails on struct a
end
struct b{c}
ch::c
end
children(d) = (d,)
e(i) = children(i)
f = a
g = b(f)
h = g, nothing
[e(d) for d in h if isnothing(d)] |
There does seem to be a lot of badness there of this sort: %value_phi19 = phi {} addrspace(10)* [ null, %L62 ], [ %119, %L73 ], [ addrspacecast ({}* inttoptr (i64 139967715850432 to {}*) to {} addrspace(10)*), %L68 ]
%123 = bitcast {} addrspace(10)* %value_phi19 to i64 addrspace(10)*, !dbg !25
%124 = getelementptr inbounds i64, i64 addrspace(10)* %123, i64 -1, !dbg !25
%125 = load atomic i64, i64 addrspace(10)* %124 unordered, align 8, !dbg !25, !tbaa !30, !range !38 Which is confusing to codegen, since it probably wants to union-unbox this from the phi node
To make it applicable to the next phi node:
What likely happened here is that the optimizer generates code it knows is illegal (moving non-existent values into places they cannot go), but which it wants to be valid at runtime (since we promise we won't observe the value later, codegen is expected to simply discard the impossible) julia> begin
struct b{c}
ch::c
end
e(i) = (i,)
h = b(Int), nothing
end
(b{DataType}(Int64), nothing)
julia> # collect(Base.Generator(e, Base.Iterators.Filter(isnothing, h)))
julia> code_llvm(Base.grow_to!, (Array{Tuple{Nothing}, 1}, Base.Generator{Base.Iterators.Filter{typeof(isnothing), typeof(h)}, typeof(e)}, Int64), raw=true, optimize=false) |
Bump. @vtjnash (or someone else) did you manage to get any further with this? |
Yes, I wrote a fix for this |
The optimization pass often uses values for phi values (and thus by extension, also for pi, phic and upsilon values) that are invalid. We make sure that these have a null pointer, so that we can detect that case at runtime (at the cost of slightly worse code generation for them), but it means we need to be very careful to check for that. This is identical to #39747, which added the equivalent code to the other side of the conditional there, but missed some additional relevant, but rare, cases that are observed to be possible. The `emit_isa_and_defined` is derived from the LLVM name for this operation: `isa_and_nonnull<T>`. Secondly, we also optimize `emit_unionmove` to change a bad IR case to a better IR form. Fix #44501
The optimization pass often uses values for phi values (and thus by extension, also for pi, phic and upsilon values) that are invalid. We make sure that these have a null pointer, so that we can detect that case at runtime (at the cost of slightly worse code generation for them), but it means we need to be very careful to check for that. This is identical to #39747, which added the equivalent code to the other side of the conditional there, but missed some additional relevant, but rare, cases that are observed to be possible. The `emit_isa_and_defined` is derived from the LLVM name for this operation: `isa_and_nonnull<T>`. Secondly, we also optimize `emit_unionmove` to change a bad IR case to a better IR form. Fix #44501
The optimization pass often uses values for phi values (and thus by extension, also for pi, phic and upsilon values) that are invalid. We make sure that these have a null pointer, so that we can detect that case at runtime (at the cost of slightly worse code generation for them), but it means we need to be very careful to check for that. This is identical to #39747, which added the equivalent code to the other side of the conditional there, but missed some additional relevant, but rare, cases that are observed to be possible. The `emit_isa_and_defined` is derived from the LLVM name for this operation: `isa_and_nonnull<T>`. Secondly, we also optimize `emit_unionmove` to change a bad IR case to a better IR form. Fix #44501
The optimization pass often uses values for phi values (and thus by extension, also for pi, phic and upsilon values) that are invalid. We make sure that these have a null pointer, so that we can detect that case at runtime (at the cost of slightly worse code generation for them), but it means we need to be very careful to check for that. This is identical to #39747, which added the equivalent code to the other side of the conditional there, but missed some additional relevant, but rare, cases that are observed to be possible. The `emit_isa_and_defined` is derived from the LLVM name for this operation: `isa_and_nonnull<T>`. Secondly, we also optimize `emit_unionmove` to change a bad IR case to a better IR form. Fix #44501 (cherry picked from commit 72b80e2)
The optimization pass often uses values for phi values (and thus by extension, also for pi, phic and upsilon values) that are invalid. We make sure that these have a null pointer, so that we can detect that case at runtime (at the cost of slightly worse code generation for them), but it means we need to be very careful to check for that. This is identical to #39747, which added the equivalent code to the other side of the conditional there, but missed some additional relevant, but rare, cases that are observed to be possible. The `emit_isa_and_defined` is derived from the LLVM name for this operation: `isa_and_nonnull<T>`. Secondly, we also optimize `emit_unionmove` to change a bad IR case to a better IR form. Fix #44501 (cherry picked from commit 72b80e2)
Somewhat of an MWE:
Tested on the
backports-release-1.8
branchThe text was updated successfully, but these errors were encountered: