Skip to content

Commit bf773a0

Browse files
committed
Replaces checked_fptosi/checked_fptoui intrinsics with Julia implementations. Fixes #14549.
1 parent 0dcb477 commit bf773a0

File tree

7 files changed

+22
-98
lines changed

7 files changed

+22
-98
lines changed

base/float.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,16 +425,29 @@ for Ti in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UIn
425425
$(Tf(typemin(Ti))-one(Tf)) < x < $(Tf(typemax(Ti))+one(Tf)) || throw(InexactError())
426426
unsafe_trunc($Ti,x)
427427
end
428-
else
428+
@eval function convert(::Type{$Ti}, x::$Tf)
429+
if ($(Tf(typemin(Ti))) <= x <= $(Tf(typemax(Ti)))) && (trunc(x) == x)
430+
return unsafe_trunc($Ti,x)
431+
else
432+
throw(InexactError())
433+
end
434+
end
435+
else #
429436
@eval function trunc(::Type{$Ti},x::$Tf)
430437
$(Tf(typemin(Ti))) <= x < $(Tf(typemax(Ti))) || throw(InexactError())
431438
unsafe_trunc($Ti,x)
432439
end
440+
@eval function convert(::Type{$Ti}, x::$Tf)
441+
if ($(Tf(typemin(Ti))) <= x < $(Tf(typemax(Ti)))) && (trunc(x) == x)
442+
return unsafe_trunc($Ti,x)
443+
else
444+
throw(InexactError())
445+
end
446+
end
433447
end
434448
end
435449
end
436450

437-
438451
@eval begin
439452
issubnormal(x::Float32) = (abs(x) < $(box(Float32,unbox(UInt32,0x00800000)))) & (x!=0)
440453
issubnormal(x::Float64) = (abs(x) < $(box(Float64,unbox(UInt64,0x0010000000000000)))) & (x!=0)

base/int.jl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,6 @@ rem{T<:Integer}(x::T, ::Type{T}) = x
236236
rem(x::Integer, ::Type{Bool}) = ((x&1)!=0)
237237
mod{T<:Integer}(x::Integer, ::Type{T}) = rem(x, T)
238238

239-
convert{Tf<:Union{Float32,Float64}}(T::BitSigned64T, x::Tf) =
240-
box(T,checked_fptosi(T,unbox(Tf,x)))
241-
convert{Tf<:Union{Float32,Float64}}(T::BitUnsigned64T, x::Tf) =
242-
box(T,checked_fptoui(T,unbox(Tf,x)))
243-
244239
convert{Tf<:Union{Float32,Float64}}(T::Union{Type{Int128},Type{UInt128}}, x::Tf) =
245240
(isinteger(x) || throw(InexactError()) ; trunc(T,x))
246241

src/intrinsics.cpp

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -651,80 +651,6 @@ static jl_cgval_t generic_zext(jl_value_t *targ, jl_value_t *x, jl_codectx_t *ct
651651
return mark_julia_type(ans, false, jlto, ctx);
652652
}
653653

654-
static Value *emit_eqfsi(Value *x, Value *y)
655-
{
656-
Value *fy = JL_INT(y);
657-
658-
// using all 64-bit is slightly faster than using mixed sizes
659-
Value *xx = x, *vv = fy;
660-
if (x->getType() == T_float32)
661-
xx = builder.CreateFPExt(xx, T_float64);
662-
if (vv->getType()->getPrimitiveSizeInBits() < 64)
663-
vv = builder.CreateSExt(vv, T_int64);
664-
665-
Value *back = builder.CreateSIToFP(vv, xx->getType());
666-
return builder.CreateAnd
667-
(builder.CreateFCmpOEQ(xx, back),
668-
builder.CreateICmpEQ(vv, builder.CreateFPToSI(back, vv->getType())));
669-
}
670-
671-
static Value *emit_eqfui(Value *x, Value *y)
672-
{
673-
Value *fy = JL_INT(y);
674-
675-
// using all 64-bit is slightly faster than using mixed sizes
676-
Value *xx = x, *vv = fy;
677-
if (x->getType() == T_float32)
678-
xx = builder.CreateFPExt(xx, T_float64);
679-
if (vv->getType()->getPrimitiveSizeInBits() < 64)
680-
vv = builder.CreateZExt(vv, T_int64);
681-
682-
Value *back = builder.CreateUIToFP(vv, xx->getType());
683-
return builder.CreateAnd
684-
(builder.CreateFCmpOEQ(xx, back),
685-
builder.CreateICmpEQ(vv, builder.CreateFPToUI(back, vv->getType())));
686-
}
687-
688-
static jl_cgval_t emit_checked_fptosi(jl_value_t *targ, jl_value_t *x, jl_codectx_t *ctx)
689-
{
690-
jl_value_t *jlto = staticeval_bitstype(targ, "checked_fptosi", ctx);
691-
if (!jlto) return jl_cgval_t();
692-
Type *to = staticeval_bitstype(jlto);
693-
Value *fx = FP(auto_unbox(x, ctx));
694-
if (fx->getType() == T_void) return jl_cgval_t(); // auto_unbox threw an error
695-
Value *ans = builder.CreateFPToSI(fx, to);
696-
if (fx->getType() == T_float32 && to == T_int32) {
697-
raise_exception_unless
698-
(builder.CreateFCmpOEQ(builder.CreateFPExt(fx, T_float64),
699-
builder.CreateSIToFP(ans, T_float64)),
700-
prepare_global(jlinexacterr_var), ctx);
701-
}
702-
else {
703-
raise_exception_unless(emit_eqfsi(fx, ans), prepare_global(jlinexacterr_var), ctx);
704-
}
705-
return mark_julia_type(ans, false, jlto, ctx);
706-
}
707-
708-
static jl_cgval_t emit_checked_fptoui(jl_value_t *targ, jl_value_t *x, jl_codectx_t *ctx)
709-
{
710-
jl_value_t *jlto = staticeval_bitstype(targ, "checked_fptoui", ctx);
711-
if (!jlto) return jl_cgval_t();
712-
Type *to = staticeval_bitstype(jlto);
713-
Value *fx = FP(auto_unbox(x, ctx));
714-
if (fx->getType() == T_void) return jl_cgval_t(); // auto_unbox threw an error
715-
Value *ans = builder.CreateFPToUI(fx, to);
716-
if (fx->getType() == T_float32 && to == T_int32) {
717-
raise_exception_unless
718-
(builder.CreateFCmpOEQ(builder.CreateFPExt(fx, T_float64),
719-
builder.CreateUIToFP(ans, T_float64)),
720-
prepare_global(jlinexacterr_var), ctx);
721-
}
722-
else {
723-
raise_exception_unless(emit_eqfui(fx, ans), prepare_global(jlinexacterr_var), ctx);
724-
}
725-
return mark_julia_type(ans, false, jlto, ctx);
726-
}
727-
728654
static jl_cgval_t emit_runtime_pointerref(jl_value_t *e, jl_value_t *i, jl_codectx_t *ctx)
729655
{
730656
jl_cgval_t parg = emit_expr(e, ctx);
@@ -979,10 +905,6 @@ static jl_cgval_t emit_intrinsic(intrinsic f, jl_value_t **args, size_t nargs,
979905
return generic_sext(args[1], args[2], ctx);
980906
case zext_int:
981907
return generic_zext(args[1], args[2], ctx);
982-
case checked_fptosi:
983-
return emit_checked_fptosi(args[1], args[2], ctx);
984-
case checked_fptoui:
985-
return emit_checked_fptoui(args[1], args[2], ctx);
986908

987909
case uitofp: {
988910
jl_value_t *bt = staticeval_bitstype(args[1], "uitofp", ctx);

src/intrinsics.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@
6868
ADD_I(fptrunc, 2) \
6969
ADD_I(fpext, 2) \
7070
/* checked conversion */ \
71-
ADD_I(checked_fptosi, 2) \
72-
ADD_I(checked_fptoui, 2) \
7371
ADD_I(checked_trunc_sint, 2) \
7472
ADD_I(checked_trunc_uint, 2) \
7573
ADD_I(check_top_bit, 1) \

src/julia_internal.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,6 @@ JL_DLLEXPORT jl_value_t *jl_fpext(jl_value_t *ty, jl_value_t *a);
489489
JL_DLLEXPORT jl_value_t *jl_fptoui_auto(jl_value_t *a);
490490
JL_DLLEXPORT jl_value_t *jl_fptosi_auto(jl_value_t *a);
491491

492-
JL_DLLEXPORT jl_value_t *jl_checked_fptoui(jl_value_t *ty, jl_value_t *a);
493-
JL_DLLEXPORT jl_value_t *jl_checked_fptosi(jl_value_t *ty, jl_value_t *a);
494492
JL_DLLEXPORT jl_value_t *jl_checked_trunc_sint(jl_value_t *ty, jl_value_t *a);
495493
JL_DLLEXPORT jl_value_t *jl_checked_trunc_uint(jl_value_t *ty, jl_value_t *a);
496494

src/runtime_intrinsics.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -824,15 +824,6 @@ static unsigned check_trunc_uint(unsigned isize, unsigned osize, void *pa)
824824
}
825825
cvt_iintrinsic_checked(LLVMTrunc, check_trunc_uint, checked_trunc_uint)
826826

827-
#define checked_fptosi(pr, a) \
828-
if (!LLVMFPtoSI_exact(sizeof(a) * host_char_bit, pa, osize, pr)) \
829-
jl_throw(jl_inexact_exception);
830-
un_fintrinsic_withtype(checked_fptosi, checked_fptosi)
831-
#define checked_fptoui(pr, a) \
832-
if (!LLVMFPtoUI_exact(sizeof(a) * host_char_bit, pa, osize, pr)) \
833-
jl_throw(jl_inexact_exception);
834-
un_fintrinsic_withtype(checked_fptoui, checked_fptoui)
835-
836827
JL_DLLEXPORT jl_value_t *jl_check_top_bit(jl_value_t *a)
837828
{
838829
jl_value_t *ty = jl_typeof(a);

test/numbers.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2447,6 +2447,13 @@ end
24472447
@test_throws InexactError convert(Int16, typemax(UInt64))
24482448
@test_throws InexactError convert(Int, typemax(UInt64))
24492449

2450+
# issue #14549
2451+
for T in (Int8, Int16, UInt8, UInt16)
2452+
for F in (Float32,Float64)
2453+
@test_throws InexactError convert(T, F(200000.0))
2454+
end
2455+
end
2456+
24502457
let x = big(-0.0)
24512458
@test signbit(x) && !signbit(abs(x))
24522459
end

0 commit comments

Comments
 (0)