Skip to content

Commit be4ab9b

Browse files
vtjnashaviatesk
andcommitted
[Compiler] fix intrinsic_effects computation
The atomic operators, in particular, where missing from the list, though many others were also in incorrect lists also. Try to deduplicate the lists slightly. Co-authored-by: Shuhei Kadowaki <aviatesk@gmail.com>
1 parent ce0aae0 commit be4ab9b

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

Compiler/src/tfuncs.jl

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2407,11 +2407,8 @@ const _ARGMEM_BUILTINS = Any[
24072407
]
24082408

24092409
const _INCONSISTENT_INTRINSICS = Any[
2410-
Intrinsics.pointerref, # this one is volatile
2411-
Intrinsics.sqrt_llvm_fast, # this one may differ at runtime (by a few ulps)
2412-
Intrinsics.have_fma, # this one depends on the runtime environment
2413-
Intrinsics.cglobal, # cglobal lookup answer changes at runtime
2414-
# ... and list fastmath intrinsics:
2410+
# all is_pure_intrinsic_infer plus
2411+
# ... all the unsound fastmath functions which should have been in is_pure_intrinsic_infer
24152412
# join(string.("Intrinsics.", sort(filter(endswith("_fast")∘string, names(Core.Intrinsics)))), ",\n")
24162413
Intrinsics.add_float_fast,
24172414
Intrinsics.div_float_fast,
@@ -2936,41 +2933,48 @@ function intrinsic_nothrow(f::IntrinsicFunction, argtypes::Vector{Any})
29362933
return intrinsic_exct(SimpleInferenceLattice.instance, f, argtypes) === Union{}
29372934
end
29382935

2936+
function _is_effect_free_infer(f::IntrinsicFunction)
2937+
return !(f === Intrinsics.pointerset ||
2938+
f === Intrinsics.atomic_pointerref ||
2939+
f === Intrinsics.atomic_pointerset ||
2940+
f === Intrinsics.atomic_pointerswap ||
2941+
# f === Intrinsics.atomic_pointermodify ||
2942+
f === Intrinsics.atomic_pointerreplace ||
2943+
f === Intrinsics.atomic_fence)
2944+
end
2945+
29392946
# whether `f` is pure for inference
2940-
function is_pure_intrinsic_infer(f::IntrinsicFunction)
2941-
return !(f === Intrinsics.pointerref || # this one is volatile
2942-
f === Intrinsics.atomic_pointerref || # this one is volatile
2943-
f === Intrinsics.pointerset || # this one is never effect-free
2944-
f === Intrinsics.atomic_pointerset || # this one is never effect-free
2945-
f === Intrinsics.atomic_pointerswap || # this one is never effect-free
2946-
f === Intrinsics.atomic_pointermodify || # this one is never effect-free
2947-
f === Intrinsics.atomic_pointerreplace || # this one is never effect-free
2948-
f === Intrinsics.llvmcall || # this one is never effect-free
2949-
f === Intrinsics.sqrt_llvm_fast || # this one may differ at runtime (by a few ulps)
2950-
f === Intrinsics.have_fma || # this one depends on the runtime environment
2951-
f === Intrinsics.cglobal) # cglobal lookup answer changes at runtime
2952-
end
2953-
2954-
# whether `f` is effect free if nothrow
2955-
function intrinsic_effect_free_if_nothrow(@nospecialize f)
2956-
return f === Intrinsics.pointerref ||
2957-
f === Intrinsics.have_fma ||
2958-
is_pure_intrinsic_infer(f)
2947+
function is_pure_intrinsic_infer(f::IntrinsicFunction, is_effect_free::Union{Nothing,Bool}=nothing)
2948+
if is_effect_free === nothing
2949+
is_effect_free = _is_effect_free_infer(f)
2950+
end
2951+
return is_effect_free && !(
2952+
f === Intrinsics.llvmcall || # can do arbitrary things
2953+
f === Intrinsics.atomic_pointermodify || # can do arbitrary things
2954+
f === Intrinsics.pointerref || # this one is volatile
2955+
f === Intrinsics.sqrt_llvm_fast || # this one may differ at runtime (by a few ulps)
2956+
f === Intrinsics.have_fma || # this one depends on the runtime environment
2957+
f === Intrinsics.cglobal) # cglobal lookup answer changes at runtime
29592958
end
29602959

29612960
function intrinsic_effects(f::IntrinsicFunction, argtypes::Vector{Any})
29622961
if f === Intrinsics.llvmcall
29632962
# llvmcall can do arbitrary things
29642963
return Effects()
2964+
elseif f === atomic_pointermodify
2965+
# atomic_pointermodify has memory effects, plus any effects from the ModifyOpInfo
2966+
return Effects()
29652967
end
2966-
if contains_is(_INCONSISTENT_INTRINSICS, f)
2967-
consistent = ALWAYS_FALSE
2968-
else
2968+
is_effect_free = _is_effect_free_infer(f)
2969+
effect_free = is_effect_free ? ALWAYS_TRUE : ALWAYS_FALSE
2970+
if ((is_pure_intrinsic_infer(f, is_effect_free) && !contains_is(_INCONSISTENT_INTRINSICS, f)) ||
2971+
f === Intrinsics.pointerset || f === Intrinsics.atomic_pointerset || f === Intrinsics.atomic_fence)
29692972
consistent = ALWAYS_TRUE
2973+
else
2974+
consistent = ALWAYS_FALSE
29702975
end
2971-
effect_free = !(f === Intrinsics.pointerset) ? ALWAYS_TRUE : ALWAYS_FALSE
29722976
nothrow = intrinsic_nothrow(f, argtypes)
2973-
inaccessiblememonly = ALWAYS_TRUE
2977+
inaccessiblememonly = is_effect_free && !(f === Intrinsics.pointerref) ? ALWAYS_TRUE : ALWAYS_FALSE
29742978
return Effects(EFFECTS_TOTAL; consistent, effect_free, nothrow, inaccessiblememonly)
29752979
end
29762980

0 commit comments

Comments
 (0)