@@ -1768,6 +1768,12 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1},
1768
1768
return Any
1769
1769
end
1770
1770
if isa (f, IntrinsicFunction)
1771
+ if is_pure_intrinsic_infer (f) && all (a -> isa (a, Const), argtypes)
1772
+ argvals = anymap (a -> a. val, argtypes)
1773
+ try
1774
+ return Const (f (argvals... ))
1775
+ end
1776
+ end
1771
1777
iidx = Int (reinterpret (Int32, f:: IntrinsicFunction )) + 1
1772
1778
if iidx < 0 || iidx > length (t_ifunc)
1773
1779
# invalid intrinsic
@@ -4235,23 +4241,38 @@ const _pure_builtins = Any[tuple, svec, fieldtype, apply_type, ===, isa, typeof,
4235
4241
# known effect-free calls (might not be affect-free)
4236
4242
const _pure_builtins_volatile = Any[getfield, arrayref, isdefined, Core. sizeof]
4237
4243
4238
- function is_pure_intrinsic (f:: IntrinsicFunction )
4244
+ # whether `f` is pure for Inference
4245
+ function is_pure_intrinsic_infer (f:: IntrinsicFunction )
4246
+ return ! (f === Intrinsics. pointerref || # this one is volatile
4247
+ f === Intrinsics. pointerset || # this one is never effect-free
4248
+ f === Intrinsics. llvmcall || # this one is never effect-free
4249
+ f === Intrinsics. arraylen || # this one is volatile
4250
+ f === Intrinsics. sqrt_llvm || # this one may differ at runtime (by a few ulps)
4251
+ f === Intrinsics. cglobal) # cglobal lookup answer changes at runtime
4252
+ end
4253
+
4254
+ # whether `f` is pure for Optimizations
4255
+ function is_pure_intrinsic_optim (f:: IntrinsicFunction )
4239
4256
return ! (f === Intrinsics. pointerref || # this one is volatile
4240
4257
f === Intrinsics. pointerset || # this one is never effect-free
4241
4258
f === Intrinsics. llvmcall || # this one is never effect-free
4242
- f === Intrinsics. checked_sdiv_int ||
4259
+ f === Intrinsics. arraylen || # this one is volatile
4260
+ f === Intrinsics. checked_sdiv_int || # these may throw errors
4243
4261
f === Intrinsics. checked_udiv_int ||
4244
4262
f === Intrinsics. checked_srem_int ||
4245
4263
f === Intrinsics. checked_urem_int ||
4246
- f === Intrinsics. sqrt_llvm ||
4247
4264
f === Intrinsics. cglobal) # cglobal throws an error for symbol-not-found
4248
4265
end
4249
4266
4250
4267
function is_pure_builtin (@nospecialize (f))
4251
- return (contains_is (_pure_builtins, f) ||
4252
- contains_is (_pure_builtins_volatile, f) ||
4253
- (isa (f,IntrinsicFunction) && is_pure_intrinsic (f)) ||
4254
- f === return_type)
4268
+ if isa (f, IntrinsicFunction)
4269
+ return is_pure_intrinsic_optim (f)
4270
+ elseif isa (f, Builtin)
4271
+ return (contains_is (_pure_builtins, f) ||
4272
+ contains_is (_pure_builtins_volatile, f))
4273
+ else
4274
+ return f === return_type
4275
+ end
4255
4276
end
4256
4277
4257
4278
function statement_effect_free (@nospecialize (e), src:: CodeInfo , mod:: Module )
@@ -4592,7 +4613,7 @@ function inlineable(@nospecialize(f), @nospecialize(ft), e::Expr, atypes::Vector
4592
4613
(isbits (val) && Core. sizeof (val) <= MAX_INLINE_CONST_SIZE &&
4593
4614
(contains_is (_pure_builtins, f) ||
4594
4615
(f === getfield && effect_free (e, sv. src, sv. mod, false )) ||
4595
- (isa (f,IntrinsicFunction) && is_pure_intrinsic (f)))))
4616
+ (isa (f, IntrinsicFunction) && is_pure_intrinsic_optim (f)))))
4596
4617
return inline_as_constant (val, argexprs, sv, nothing )
4597
4618
end
4598
4619
end
0 commit comments