@@ -2407,11 +2407,8 @@ const _ARGMEM_BUILTINS = Any[
2407
2407
]
2408
2408
2409
2409
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
2415
2412
# join(string.("Intrinsics.", sort(filter(endswith("_fast")∘string, names(Core.Intrinsics)))), ",\n")
2416
2413
Intrinsics. add_float_fast,
2417
2414
Intrinsics. div_float_fast,
@@ -2888,41 +2885,48 @@ function intrinsic_nothrow(f::IntrinsicFunction, argtypes::Vector{Any})
2888
2885
return intrinsic_exct (SimpleInferenceLattice. instance, f, argtypes) === Union{}
2889
2886
end
2890
2887
2888
+ function _is_effect_free_infer (f:: IntrinsicFunction )
2889
+ return ! (f === Intrinsics. pointerset ||
2890
+ f === Intrinsics. atomic_pointerref ||
2891
+ f === Intrinsics. atomic_pointerset ||
2892
+ f === Intrinsics. atomic_pointerswap ||
2893
+ # f === Intrinsics.atomic_pointermodify ||
2894
+ f === Intrinsics. atomic_pointerreplace ||
2895
+ f === Intrinsics. atomic_fence)
2896
+ end
2897
+
2891
2898
# whether `f` is pure for inference
2892
- function is_pure_intrinsic_infer (f:: IntrinsicFunction )
2893
- return ! (f === Intrinsics. pointerref || # this one is volatile
2894
- f === Intrinsics. atomic_pointerref || # this one is volatile
2895
- f === Intrinsics. pointerset || # this one is never effect-free
2896
- f === Intrinsics. atomic_pointerset || # this one is never effect-free
2897
- f === Intrinsics. atomic_pointerswap || # this one is never effect-free
2898
- f === Intrinsics. atomic_pointermodify || # this one is never effect-free
2899
- f === Intrinsics. atomic_pointerreplace || # this one is never effect-free
2900
- f === Intrinsics. llvmcall || # this one is never effect-free
2901
- f === Intrinsics. sqrt_llvm_fast || # this one may differ at runtime (by a few ulps)
2902
- f === Intrinsics. have_fma || # this one depends on the runtime environment
2903
- f === Intrinsics. cglobal) # cglobal lookup answer changes at runtime
2904
- end
2905
-
2906
- # whether `f` is effect free if nothrow
2907
- function intrinsic_effect_free_if_nothrow (@nospecialize f)
2908
- return f === Intrinsics. pointerref ||
2909
- f === Intrinsics. have_fma ||
2910
- is_pure_intrinsic_infer (f)
2899
+ function is_pure_intrinsic_infer (f:: IntrinsicFunction , is_effect_free:: Union{Nothing,Bool} = nothing )
2900
+ if is_effect_free === nothing
2901
+ is_effect_free = _is_effect_free_infer (f)
2902
+ end
2903
+ return is_effect_free && ! (
2904
+ f === Intrinsics. llvmcall || # can do arbitrary things
2905
+ f === Intrinsics. atomic_pointermodify || # can do arbitrary things
2906
+ f === Intrinsics. pointerref || # this one is volatile
2907
+ f === Intrinsics. sqrt_llvm_fast || # this one may differ at runtime (by a few ulps)
2908
+ f === Intrinsics. have_fma || # this one depends on the runtime environment
2909
+ f === Intrinsics. cglobal) # cglobal lookup answer changes at runtime
2911
2910
end
2912
2911
2913
2912
function intrinsic_effects (f:: IntrinsicFunction , argtypes:: Vector{Any} )
2914
2913
if f === Intrinsics. llvmcall
2915
2914
# llvmcall can do arbitrary things
2916
2915
return Effects ()
2916
+ elseif f === atomic_pointermodify
2917
+ # atomic_pointermodify has memory effects, plus any effects from the ModifyOpInfo
2918
+ return Effects ()
2917
2919
end
2918
- if contains_is (_INCONSISTENT_INTRINSICS, f)
2919
- consistent = ALWAYS_FALSE
2920
- else
2920
+ is_effect_free = _is_effect_free_infer (f)
2921
+ effect_free = is_effect_free ? ALWAYS_TRUE : ALWAYS_FALSE
2922
+ if ((is_pure_intrinsic_infer (f, is_effect_free) && ! contains_is (_INCONSISTENT_INTRINSICS, f)) ||
2923
+ f === Intrinsics. pointerset || f === Intrinsics. atomic_pointerset || f === Intrinsics. atomic_fence)
2921
2924
consistent = ALWAYS_TRUE
2925
+ else
2926
+ consistent = ALWAYS_FALSE
2922
2927
end
2923
- effect_free = ! (f === Intrinsics. pointerset) ? ALWAYS_TRUE : ALWAYS_FALSE
2924
2928
nothrow = intrinsic_nothrow (f, argtypes)
2925
- inaccessiblememonly = ALWAYS_TRUE
2929
+ inaccessiblememonly = is_effect_free && ! (f === Intrinsics . pointerref) ? ALWAYS_TRUE : ALWAYS_FALSE
2926
2930
return Effects (EFFECTS_TOTAL; consistent, effect_free, nothrow, inaccessiblememonly)
2927
2931
end
2928
2932
0 commit comments