Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2188,14 +2188,13 @@ function abstract_eval_value_expr(interp::AbstractInterpreter, e::Expr, vtypes::
end
elseif head === :boundscheck
if isa(sv, InferenceState)
flag = sv.src.ssaflags[sv.currpc]
# If there is no particular @inbounds for this function, then we only taint `noinbounds`,
# which will subsequently taint consistency if this function is called from another
# function that uses `@inbounds`. However, if this :boundscheck is itself within an
# If there is no particular `@inbounds` for this function, then we only taint `:noinbounds`,
# which will subsequently taint `:consistent`-cy if this function is called from another
# function that uses `@inbounds`. However, if this `:boundscheck` is itself within an
# `@inbounds` region, its value depends on `--check-bounds`, so we need to taint
# consistency here also.
# `:consistent`-cy here also.
merge_effects!(interp, sv, Effects(EFFECTS_TOTAL; noinbounds=false,
consistent = (flag & IR_FLAG_INBOUNDS) != 0 ? ALWAYS_FALSE : ALWAYS_TRUE))
consistent = (get_curr_ssaflag(sv) & IR_FLAG_INBOUNDS) != 0 ? ALWAYS_FALSE : ALWAYS_TRUE))
end
rt = Bool
elseif head === :inbounds
Expand Down Expand Up @@ -2512,8 +2511,8 @@ function abstract_eval_phi(interp::AbstractInterpreter, phi::PhiNode, vtypes::Un
end

function stmt_taints_inbounds_consistency(sv::InferenceState)
flag = sv.src.ssaflags[sv.currpc]
return sv.src.propagate_inbounds || (flag & IR_FLAG_INBOUNDS) != 0
sv.src.propagate_inbounds && return true
return (get_curr_ssaflag(sv) & IR_FLAG_INBOUNDS) != 0
end

function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e), vtypes::VarTable, sv::InferenceState)
Expand All @@ -2525,13 +2524,12 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
end
(;rt, effects) = abstract_eval_statement_expr(interp, e, vtypes, sv, nothing)
if !effects.noinbounds
flag = sv.src.ssaflags[sv.currpc]
if !sv.src.propagate_inbounds
# The callee read our inbounds flag, but unless we propagate inbounds,
# we ourselves don't read our parent's inbounds.
effects = Effects(effects; noinbounds=true)
end
if (flag & IR_FLAG_INBOUNDS) != 0
if (get_curr_ssaflag(sv) & IR_FLAG_INBOUNDS) != 0
effects = Effects(effects; consistent=ALWAYS_FALSE)
end
end
Expand Down
4 changes: 2 additions & 2 deletions base/compiler/effects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ following meanings:
This state corresponds to LLVM's `inaccessiblemem_or_argmemonly` function attribute.
- `nonoverlayed::Bool`: indicates that any methods that may be called within this method
are not defined in an [overlayed method table](@ref OverlayMethodTable).
- `noinbounds::Bool`: If set, indicates that this method does not read the parent's :inbounds
state. In particular, it does not have any reached :boundscheck exprs, not propagates inbounds
- `noinbounds::Bool`: If set, indicates that this method does not read the parent's `:inbounds`
state. In particular, it does not have any reached `:boundscheck` exprs, not propagates inbounds
to any children that do.

Note that the representations above are just internal implementation details and thus likely
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/inferencestate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ mutable struct InferenceState

valid_worlds = WorldRange(src.min_world, src.max_world == typemax(UInt) ? get_world_counter() : src.max_world)
bestguess = Bottom
ipo_effects = Effects(EFFECTS_TOTAL)
ipo_effects = EFFECTS_TOTAL

params = InferenceParams(interp)
restrict_abstract_call_sites = isa(linfo.def, Module)
Expand Down
4 changes: 2 additions & 2 deletions base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,8 @@ currently equivalent to the following `setting`s:
must consistently throw given the same argument values.

!!! note
An explict `@inbounds` annotation inside the function will also disable
constant propagation and not be overriden by :foldable.
An explicit `@inbounds` annotation inside the function will also disable
constant folding and not be overriden by `:foldable`.

---
## `:removable`
Expand Down
1 change: 1 addition & 0 deletions test/compiler/effects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ end |> Core.Compiler.is_foldable
end |> Core.Compiler.is_total

# Test that dead `@inbounds` does not taint consistency
# https://github.com/JuliaLang/julia/issues/48243
@test Base.infer_effects() do
false && @inbounds (1,2,3)[1]
return 1
Expand Down