Skip to content

Commit 2794485

Browse files
authored
Make remaining float intrinsics require float arguments (JuliaLang#57398)
The `fptrunc`/`fpext` intrinsics were modified in JuliaLang#57160 to throw on non-float arguments. - The arithmetic and math float intrinsics now require all their arguments to be floats - `fptosi`/`fptoui` require their source to be a float - `sitofp`/`uitofp` require their destination type to be a float Also fixes JuliaLang#57384.
1 parent 5f17a11 commit 2794485

File tree

2 files changed

+77
-3
lines changed

2 files changed

+77
-3
lines changed

src/tfuncs.jl

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,6 +2432,43 @@ const _SPECIAL_BUILTINS = Any[
24322432
Core._apply_iterate,
24332433
]
24342434

2435+
# Intrinsics that require all arguments to be floats
2436+
const _FLOAT_INTRINSICS = Any[
2437+
Intrinsics.neg_float,
2438+
Intrinsics.add_float,
2439+
Intrinsics.sub_float,
2440+
Intrinsics.mul_float,
2441+
Intrinsics.div_float,
2442+
Intrinsics.min_float,
2443+
Intrinsics.max_float,
2444+
Intrinsics.fma_float,
2445+
Intrinsics.muladd_float,
2446+
Intrinsics.neg_float_fast,
2447+
Intrinsics.add_float_fast,
2448+
Intrinsics.sub_float_fast,
2449+
Intrinsics.mul_float_fast,
2450+
Intrinsics.div_float_fast,
2451+
Intrinsics.min_float_fast,
2452+
Intrinsics.max_float_fast,
2453+
Intrinsics.eq_float,
2454+
Intrinsics.ne_float,
2455+
Intrinsics.lt_float,
2456+
Intrinsics.le_float,
2457+
Intrinsics.eq_float_fast,
2458+
Intrinsics.ne_float_fast,
2459+
Intrinsics.lt_float_fast,
2460+
Intrinsics.le_float_fast,
2461+
Intrinsics.fpiseq,
2462+
Intrinsics.abs_float,
2463+
Intrinsics.copysign_float,
2464+
Intrinsics.ceil_llvm,
2465+
Intrinsics.floor_llvm,
2466+
Intrinsics.trunc_llvm,
2467+
Intrinsics.rint_llvm,
2468+
Intrinsics.sqrt_llvm,
2469+
Intrinsics.sqrt_llvm_fast
2470+
]
2471+
24352472
# Types compatible with fpext/fptrunc
24362473
const CORE_FLOAT_TYPES = Union{Core.BFloat16, Float16, Float32, Float64}
24372474

@@ -2849,7 +2886,8 @@ function intrinsic_exct(𝕃::AbstractLattice, f::IntrinsicFunction, argtypes::V
28492886
return ErrorException
28502887
end
28512888

2852-
# fpext and fptrunc have further restrictions on the allowed types.
2889+
# fpext, fptrunc, fptoui, fptosi, uitofp, and sitofp have further
2890+
# restrictions on the allowed types.
28532891
if f === Intrinsics.fpext &&
28542892
!(ty <: CORE_FLOAT_TYPES && xty <: CORE_FLOAT_TYPES && Core.sizeof(ty) > Core.sizeof(xty))
28552893
return ErrorException
@@ -2858,6 +2896,12 @@ function intrinsic_exct(𝕃::AbstractLattice, f::IntrinsicFunction, argtypes::V
28582896
!(ty <: CORE_FLOAT_TYPES && xty <: CORE_FLOAT_TYPES && Core.sizeof(ty) < Core.sizeof(xty))
28592897
return ErrorException
28602898
end
2899+
if (f === Intrinsics.fptoui || f === Intrinsics.fptosi) && !(xty <: CORE_FLOAT_TYPES)
2900+
return ErrorException
2901+
end
2902+
if (f === Intrinsics.uitofp || f === Intrinsics.sitofp) && !(ty <: CORE_FLOAT_TYPES)
2903+
return ErrorException
2904+
end
28612905

28622906
return Union{}
28632907
end
@@ -2870,11 +2914,15 @@ function intrinsic_exct(𝕃::AbstractLattice, f::IntrinsicFunction, argtypes::V
28702914
return Union{}
28712915
end
28722916

2873-
# The remaining intrinsics are math/bits/comparison intrinsics. They work on all
2874-
# primitive types of the same type.
2917+
# The remaining intrinsics are math/bits/comparison intrinsics.
2918+
# All the non-floating point intrinsics work on primitive values of the same type.
28752919
isshift = f === shl_int || f === lshr_int || f === ashr_int
28762920
argtype1 = widenconst(argtypes[1])
28772921
isprimitivetype(argtype1) || return ErrorException
2922+
if contains_is(_FLOAT_INTRINSICS, f)
2923+
argtype1 <: CORE_FLOAT_TYPES || return ErrorException
2924+
end
2925+
28782926
for i = 2:length(argtypes)
28792927
argtype = widenconst(argtypes[i])
28802928
if isshift ? !isprimitivetype(argtype) : argtype !== argtype1

test/effects.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,3 +1401,29 @@ end == Compiler.EFFECTS_UNKNOWN
14011401
@test !Compiler.intrinsic_nothrow(Core.Intrinsics.fpext, Any[Type{Float32}, Float64])
14021402
@test !Compiler.intrinsic_nothrow(Core.Intrinsics.fpext, Any[Type{Int32}, Float16])
14031403
@test !Compiler.intrinsic_nothrow(Core.Intrinsics.fpext, Any[Type{Float32}, Int16])
1404+
1405+
# Float intrinsics require float arguments
1406+
@test Base.infer_effects((Int16,)) do x
1407+
return Core.Intrinsics.abs_float(x)
1408+
end |> !Compiler.is_nothrow
1409+
@test Base.infer_effects((Int32, Int32)) do x, y
1410+
return Core.Intrinsics.add_float(x, y)
1411+
end |> !Compiler.is_nothrow
1412+
@test Base.infer_effects((Int32, Int32)) do x, y
1413+
return Core.Intrinsics.add_float(x, y)
1414+
end |> !Compiler.is_nothrow
1415+
@test Base.infer_effects((Int64, Int64, Int64)) do x, y, z
1416+
return Core.Intrinsics.fma_float(x, y, z)
1417+
end |> !Compiler.is_nothrow
1418+
@test Base.infer_effects((Int64,)) do x
1419+
return Core.Intrinsics.fptoui(UInt32, x)
1420+
end |> !Compiler.is_nothrow
1421+
@test Base.infer_effects((Int64,)) do x
1422+
return Core.Intrinsics.fptosi(Int32, x)
1423+
end |> !Compiler.is_nothrow
1424+
@test Base.infer_effects((Int64,)) do x
1425+
return Core.Intrinsics.sitofp(Int64, x)
1426+
end |> !Compiler.is_nothrow
1427+
@test Base.infer_effects((UInt64,)) do x
1428+
return Core.Intrinsics.uitofp(Int64, x)
1429+
end |> !Compiler.is_nothrow

0 commit comments

Comments
 (0)