@@ -1766,6 +1766,12 @@ function builtin_tfunction(@nospecialize(f), argtypes::Array{Any,1},
1766
1766
return Any
1767
1767
end
1768
1768
if isa (f, IntrinsicFunction)
1769
+ if is_pure_intrinsic_infer (f) && all (a -> isa (a, Const), argtypes)
1770
+ argvals = anymap (a -> a. val, argtypes)
1771
+ try
1772
+ return Const (f (argvals... ))
1773
+ end
1774
+ end
1769
1775
iidx = Int (reinterpret (Int32, f:: IntrinsicFunction )) + 1
1770
1776
if iidx < 0 || iidx > length (t_ifunc)
1771
1777
# invalid intrinsic
@@ -2454,6 +2460,11 @@ function abstract_call(@nospecialize(f), fargs::Union{Tuple{},Vector{Any}}, argt
2454
2460
end
2455
2461
return Conditional (a, bty, aty)
2456
2462
end
2463
+ elseif f === (Core. Inference. not_int)
2464
+ aty = argtypes[2 ]
2465
+ if isa (aty, Conditional)
2466
+ return Conditional (aty. var, aty. elsetype, aty. vtype)
2467
+ end
2457
2468
end
2458
2469
end
2459
2470
return isa (rt, TypeVar) ? rt. ub : rt
@@ -4219,23 +4230,38 @@ const _pure_builtins = Any[tuple, svec, fieldtype, apply_type, ===, isa, typeof,
4219
4230
# known effect-free calls (might not be affect-free)
4220
4231
const _pure_builtins_volatile = Any[getfield, arrayref, isdefined, Core. sizeof]
4221
4232
4222
- function is_pure_intrinsic (f:: IntrinsicFunction )
4233
+ # whether `f` is pure for Inference
4234
+ function is_pure_intrinsic_infer (f:: IntrinsicFunction )
4235
+ return ! (f === Intrinsics. pointerref || # this one is volatile
4236
+ f === Intrinsics. pointerset || # this one is never effect-free
4237
+ f === Intrinsics. llvmcall || # this one is never effect-free
4238
+ f === Intrinsics. arraylen || # this one is volatile
4239
+ f === Intrinsics. sqrt_llvm || # this one may differ at runtime (by a few ulps)
4240
+ f === Intrinsics. cglobal) # cglobal lookup answer changes at runtime
4241
+ end
4242
+
4243
+ # whether `f` is pure for Optimizations
4244
+ function is_pure_intrinsic_optim (f:: IntrinsicFunction )
4223
4245
return ! (f === Intrinsics. pointerref || # this one is volatile
4224
4246
f === Intrinsics. pointerset || # this one is never effect-free
4225
4247
f === Intrinsics. llvmcall || # this one is never effect-free
4226
- f === Intrinsics. checked_sdiv_int ||
4248
+ f === Intrinsics. arraylen || # this one is volatile
4249
+ f === Intrinsics. checked_sdiv_int || # these may throw errors
4227
4250
f === Intrinsics. checked_udiv_int ||
4228
4251
f === Intrinsics. checked_srem_int ||
4229
4252
f === Intrinsics. checked_urem_int ||
4230
- f === Intrinsics. sqrt_llvm ||
4231
4253
f === Intrinsics. cglobal) # cglobal throws an error for symbol-not-found
4232
4254
end
4233
4255
4234
4256
function is_pure_builtin (@nospecialize (f))
4235
- return (contains_is (_pure_builtins, f) ||
4236
- contains_is (_pure_builtins_volatile, f) ||
4237
- (isa (f,IntrinsicFunction) && is_pure_intrinsic (f)) ||
4238
- f === return_type)
4257
+ if isa (f, IntrinsicFunction)
4258
+ return is_pure_intrinsic_optim (f)
4259
+ elseif isa (f, Builtin)
4260
+ return (contains_is (_pure_builtins, f) ||
4261
+ contains_is (_pure_builtins_volatile, f))
4262
+ else
4263
+ return f === return_type
4264
+ end
4239
4265
end
4240
4266
4241
4267
function statement_effect_free (@nospecialize (e), src:: CodeInfo , mod:: Module )
@@ -4576,7 +4602,7 @@ function inlineable(@nospecialize(f), @nospecialize(ft), e::Expr, atypes::Vector
4576
4602
(isbits (val) && Core. sizeof (val) <= MAX_INLINE_CONST_SIZE &&
4577
4603
(contains_is (_pure_builtins, f) ||
4578
4604
(f === getfield && effect_free (e, sv. src, sv. mod, false )) ||
4579
- (isa (f,IntrinsicFunction) && is_pure_intrinsic (f)))))
4605
+ (isa (f, IntrinsicFunction) && is_pure_intrinsic_optim (f)))))
4580
4606
return inline_as_constant (val, argexprs, sv, nothing )
4581
4607
end
4582
4608
end
0 commit comments