Skip to content

Commit abd56cd

Browse files
authored
improve constraint propagation with multiple || (#39618)
fixes #39611
1 parent fc47e95 commit abd56cd

File tree

3 files changed

+39
-28
lines changed

3 files changed

+39
-28
lines changed

src/julia-syntax.scm

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,8 +1927,8 @@
19271927
(blk? (and (pair? test) (eq? (car test) 'block)))
19281928
(stmts (if blk? (cdr (butlast test)) '()))
19291929
(test (if blk? (last test) test)))
1930-
(if (and (pair? test) (eq? (car test) '&&))
1931-
(let ((clauses `(&& ,@(map expand-forms (cdr (flatten-ex '&& test))))))
1930+
(if (and (pair? test) (memq (car test) '(&& |\|\||)))
1931+
(let ((clauses `(,(car test) ,@(map expand-forms (cdr (flatten-ex (car test) test))))))
19321932
`(if ,(if blk?
19331933
`(block ,@(map expand-forms stmts) ,clauses)
19341934
clauses)
@@ -4151,18 +4151,30 @@ f(x) = yt(x)
41514151
(compile (cadr e) break-labels value tail)
41524152
#f))
41534153
((if elseif)
4154-
(let ((tests (let* ((cond (cadr e))
4155-
(cond (if (and (pair? cond) (eq? (car cond) 'block))
4156-
(begin (if (length> cond 2) (compile (butlast cond) break-labels #f #f))
4157-
(last cond))
4158-
cond)))
4159-
(map (lambda (clause)
4160-
(emit `(gotoifnot ,(compile-cond clause break-labels) _)))
4161-
(if (and (pair? cond) (eq? (car cond) '&&))
4162-
(cdr cond)
4163-
(list cond)))))
4164-
(end-jump `(goto _))
4165-
(val (if (and value (not tail)) (new-mutable-var) #f)))
4154+
(let* ((cnd (cadr e))
4155+
(cnd (if (and (pair? cnd) (eq? (car cnd) 'block))
4156+
(begin (if (length> cnd 2) (compile (butlast cnd) break-labels #f #f))
4157+
(last cnd))
4158+
cnd))
4159+
(or? (and (pair? cnd) (eq? (car cnd) '|\|\||)))
4160+
(tests (if or?
4161+
(let ((short-circuit `(goto _)))
4162+
(for-each
4163+
(lambda (clause)
4164+
(let ((jmp (emit `(gotoifnot ,(compile-cond clause break-labels) _))))
4165+
(emit short-circuit)
4166+
(set-car! (cddr jmp) (make&mark-label))))
4167+
(butlast (cdr cnd)))
4168+
(let ((last-jmp (emit `(gotoifnot ,(compile-cond (last (cdr cnd)) break-labels) _))))
4169+
(set-car! (cdr short-circuit) (make&mark-label))
4170+
(list last-jmp)))
4171+
(map (lambda (clause)
4172+
(emit `(gotoifnot ,(compile-cond clause break-labels) _)))
4173+
(if (and (pair? cnd) (eq? (car cnd) '&&))
4174+
(cdr cnd)
4175+
(list cnd)))))
4176+
(end-jump `(goto _))
4177+
(val (if (and value (not tail)) (new-mutable-var) #f)))
41664178
(let ((v1 (compile (caddr e) break-labels value tail)))
41674179
(if val (emit-assignment val v1))
41684180
(if (and (not tail) (or (length> e 3) val))

test/broadcast.jl

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ Base.BroadcastStyle(::Type{T}) where {T<:AD2Dim} = AD2DimStyle()
516516
@test a .+ 1 .* 2 == @inferred(fadd2(aa))
517517
@test a .* a' == @inferred(fprod(aa))
518518
@test isequal(a .+ [missing; 1:9], fadd3(aa))
519-
@test_broken Core.Compiler.return_type(fadd3, (typeof(aa),)) <: Array19745{<:Union{Float64, Missing}}
519+
@test Core.Compiler.return_type(fadd3, (typeof(aa),)) <: Array19745{<:Union{Float64, Missing}}
520520
@test isa(aa .+ 1, Array19745)
521521
@test isa(aa .+ 1 .* 2, Array19745)
522522
@test isa(aa .* aa', Array19745)
@@ -953,29 +953,20 @@ p0 = copy(p)
953953

954954
@testset "Issue #28382: inferrability of broadcast with Union eltype" begin
955955
@test isequal([1, 2] .+ [3.0, missing], [4.0, missing])
956-
@test_broken Core.Compiler.return_type(broadcast, Tuple{typeof(+), Vector{Int},
957-
Vector{Union{Float64, Missing}}}) ==
958-
Vector{<:Union{Float64, Missing}}
959956
@test Core.Compiler.return_type(broadcast, Tuple{typeof(+), Vector{Int},
960957
Vector{Union{Float64, Missing}}}) ==
961-
AbstractVector{<:Union{Float64, Missing}}
958+
Vector{<:Union{Float64, Missing}}
962959
@test isequal([1, 2] + [3.0, missing], [4.0, missing])
963-
@test_broken Core.Compiler.return_type(+, Tuple{Vector{Int},
964-
Vector{Union{Float64, Missing}}}) ==
960+
@test Core.Compiler.return_type(+, Tuple{Vector{Int},
961+
Vector{Union{Float64, Missing}}}) ==
965962
Vector{<:Union{Float64, Missing}}
966963
@test Core.Compiler.return_type(+, Tuple{Vector{Int},
967964
Vector{Union{Float64, Missing}}}) ==
968-
AbstractVector{<:Union{Float64, Missing}}
969-
@test_broken Core.Compiler.return_type(+, Tuple{Vector{Int},
970-
Vector{Union{Float64, Missing}}}) ==
971965
Vector{<:Union{Float64, Missing}}
972966
@test isequal(tuple.([1, 2], [3.0, missing]), [(1, 3.0), (2, missing)])
973-
@test_broken Core.Compiler.return_type(broadcast, Tuple{typeof(tuple), Vector{Int},
974-
Vector{Union{Float64, Missing}}}) ==
975-
Vector{<:Tuple{Int, Any}}
976967
@test Core.Compiler.return_type(broadcast, Tuple{typeof(tuple), Vector{Int},
977968
Vector{Union{Float64, Missing}}}) ==
978-
AbstractVector{<:Tuple{Int, Any}}
969+
Vector{<:Tuple{Int, Any}}
979970
# Check that corner cases do not throw an error
980971
@test isequal(broadcast(x -> x === 1 ? nothing : x, [1, 2, missing]),
981972
[nothing, 2, missing])

test/compiler/inference.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3020,3 +3020,11 @@ end
30203020
# Bare Core.Argument in IR
30213021
@eval f_bare_argument(x) = $(Core.Argument(2))
30223022
@test Base.return_types(f_bare_argument, (Int,))[1] == Int
3023+
3024+
# issue #39611
3025+
Base.return_types((Union{Int,Nothing},)) do x
3026+
if x === nothing || x < 0
3027+
return 0
3028+
end
3029+
x
3030+
end == [Int]

0 commit comments

Comments
 (0)