@@ -2407,11 +2407,8 @@ const _ARGMEM_BUILTINS = Any[
24072407]
24082408
24092409const _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{}
29372934end
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
29592958end
29602959
29612960function 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)
29752979end
29762980
0 commit comments