diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index ca0ab0423038e..ab67a2edc7074 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -444,6 +444,7 @@ static Value *emit_iround(Value *x, bool issigned, jl_codectx_t *ctx) int64_t topbit; Type *intt, *floatt; Value *bits = JL_INT(x); + Value *max, *min; if (bits->getType()->getPrimitiveSizeInBits() == 32) { nmantissa = 23; @@ -451,6 +452,14 @@ static Value *emit_iround(Value *x, bool issigned, jl_codectx_t *ctx) expbits = 0xff; topbit = BIT31; intt = T_int32; floatt = T_float32; + if (issigned) { + max = ConstantFP::get(floatt, 2.1474835e9); + min = ConstantFP::get(floatt, -2.1474836e9); + } + else { + max = ConstantFP::get(floatt, 4.294967e9); + min = ConstantFP::get(floatt, 0.0); + } } else { nmantissa = 52; @@ -458,6 +467,14 @@ static Value *emit_iround(Value *x, bool issigned, jl_codectx_t *ctx) expbits = 0x7ff; topbit = BIT63; intt = T_int64; floatt = T_float64; + if (issigned) { + max = ConstantFP::get(floatt, 9.223372036854775e18); + min = ConstantFP::get(floatt, -9.223372036854776e18); + } + else { + max = ConstantFP::get(floatt, 1.844674407370955e19); + min = ConstantFP::get(floatt, 0.0); + } } // itrunc(x + copysign(0.5,x)) @@ -476,6 +493,9 @@ static Value *emit_iround(Value *x, bool issigned, jl_codectx_t *ctx) builder.CreateBitCast(signedhalf, floatt)); Value *src = builder.CreateSelect(isint, FP(x), sum); + raise_exception_unless(builder.CreateAnd(builder.CreateFCmpOLE(src, max), + builder.CreateFCmpOGE(src, min)), + jlinexacterr_var, ctx); if (issigned) return builder.CreateFPToSI(src, intt); else diff --git a/test/numbers.jl b/test/numbers.jl index 62c10b3274704..a1a949b9132d5 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -1087,6 +1087,23 @@ for x = 2^24-10:2^24+10 @test iceil(y) == i end +@test_fails iround(Inf) +@test_fails iround(NaN) +@test iround(2.5) == 3 +@test iround(-1.9) == -2 +@test_fails iround(Int64, 9.223372036854776e18) +@test iround(Int64, 9.223372036854775e18) == 9223372036854774784 +@test_fails iround(Int64, -9.223372036854778e18) +@test iround(Int64, -9.223372036854776e18) == typemin(Int64) +@test_fails iround(Uint64, 1.8446744073709552e19) +@test iround(Uint64, 1.844674407370955e19) == 0xfffffffffffff800 +@test_fails iround(Int32, 2.1474836f9) +@test iround(Int32, 2.1474835f9) == 2147483520 +@test_fails iround(Int32, -2.147484f9) +@test iround(Int32, -2.1474836f9) == typemin(Int32) +@test_fails iround(Uint32, 4.2949673f9) +@test iround(Uint32, 4.294967f9) == 0xffffff00 + for n = 1:100 m = 1 for (p,k) in factor(n)