From bf23166a6903693d3a13fcbd98e5d0c66c32f3db Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 2 Feb 2024 23:30:01 -0500 Subject: [PATCH] try improving check_top_bit error message Fixes #30247 --- base/boot.jl | 68 +++++++++++++++++++++-------------------- src/common_symbols2.inc | 2 +- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/base/boot.jl b/base/boot.jl index 13bb6bcd7cd4b..f8b9f34fb890c 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -742,12 +742,14 @@ function is_top_bit_set(x::Union{Int8,UInt8}) eq_int(lshr_int(x, 7), trunc_int(typeof(x), 1)) end -#TODO delete this function (but see #48097): +# n.b. This function exists for CUDA to overload to configure error behavior (see #48097) throw_inexacterror(args...) = throw(InexactError(args...)) -function check_top_bit(::Type{To}, x) where {To} +function check_sign_bit(::Type{To}, x) where {To} @inline - is_top_bit_set(x) && throw_inexacterror(:check_top_bit, To, x) + # the top bit is the sign bit of x but "sign bit" sounds better in stacktraces + # n.b. if x is signed, then sizeof(x) === sizeof(To), otherwise sizeof(x) >= sizeof(To) + is_top_bit_set(x) && throw_inexacterror(sizeof(x) === sizeof(To) ? :convert : :trunc, To, x) x end @@ -772,11 +774,11 @@ toInt8(x::Int16) = checked_trunc_sint(Int8, x) toInt8(x::Int32) = checked_trunc_sint(Int8, x) toInt8(x::Int64) = checked_trunc_sint(Int8, x) toInt8(x::Int128) = checked_trunc_sint(Int8, x) -toInt8(x::UInt8) = bitcast(Int8, check_top_bit(Int8, x)) -toInt8(x::UInt16) = checked_trunc_sint(Int8, check_top_bit(Int8, x)) -toInt8(x::UInt32) = checked_trunc_sint(Int8, check_top_bit(Int8, x)) -toInt8(x::UInt64) = checked_trunc_sint(Int8, check_top_bit(Int8, x)) -toInt8(x::UInt128) = checked_trunc_sint(Int8, check_top_bit(Int8, x)) +toInt8(x::UInt8) = bitcast(Int8, check_sign_bit(Int8, x)) +toInt8(x::UInt16) = checked_trunc_sint(Int8, check_sign_bit(Int8, x)) +toInt8(x::UInt32) = checked_trunc_sint(Int8, check_sign_bit(Int8, x)) +toInt8(x::UInt64) = checked_trunc_sint(Int8, check_sign_bit(Int8, x)) +toInt8(x::UInt128) = checked_trunc_sint(Int8, check_sign_bit(Int8, x)) toInt8(x::Bool) = and_int(bitcast(Int8, x), Int8(1)) toInt16(x::Int8) = sext_int(Int16, x) toInt16(x::Int16) = x @@ -784,10 +786,10 @@ toInt16(x::Int32) = checked_trunc_sint(Int16, x) toInt16(x::Int64) = checked_trunc_sint(Int16, x) toInt16(x::Int128) = checked_trunc_sint(Int16, x) toInt16(x::UInt8) = zext_int(Int16, x) -toInt16(x::UInt16) = bitcast(Int16, check_top_bit(Int16, x)) -toInt16(x::UInt32) = checked_trunc_sint(Int16, check_top_bit(Int16, x)) -toInt16(x::UInt64) = checked_trunc_sint(Int16, check_top_bit(Int16, x)) -toInt16(x::UInt128) = checked_trunc_sint(Int16, check_top_bit(Int16, x)) +toInt16(x::UInt16) = bitcast(Int16, check_sign_bit(Int16, x)) +toInt16(x::UInt32) = checked_trunc_sint(Int16, check_sign_bit(Int16, x)) +toInt16(x::UInt64) = checked_trunc_sint(Int16, check_sign_bit(Int16, x)) +toInt16(x::UInt128) = checked_trunc_sint(Int16, check_sign_bit(Int16, x)) toInt16(x::Bool) = and_int(zext_int(Int16, x), Int16(1)) toInt32(x::Int8) = sext_int(Int32, x) toInt32(x::Int16) = sext_int(Int32, x) @@ -796,9 +798,9 @@ toInt32(x::Int64) = checked_trunc_sint(Int32, x) toInt32(x::Int128) = checked_trunc_sint(Int32, x) toInt32(x::UInt8) = zext_int(Int32, x) toInt32(x::UInt16) = zext_int(Int32, x) -toInt32(x::UInt32) = bitcast(Int32, check_top_bit(Int32, x)) -toInt32(x::UInt64) = checked_trunc_sint(Int32, check_top_bit(Int32, x)) -toInt32(x::UInt128) = checked_trunc_sint(Int32, check_top_bit(Int32, x)) +toInt32(x::UInt32) = bitcast(Int32, check_sign_bit(Int32, x)) +toInt32(x::UInt64) = checked_trunc_sint(Int32, check_sign_bit(Int32, x)) +toInt32(x::UInt128) = checked_trunc_sint(Int32, check_sign_bit(Int32, x)) toInt32(x::Bool) = and_int(zext_int(Int32, x), Int32(1)) toInt64(x::Int8) = sext_int(Int64, x) toInt64(x::Int16) = sext_int(Int64, x) @@ -808,8 +810,8 @@ toInt64(x::Int128) = checked_trunc_sint(Int64, x) toInt64(x::UInt8) = zext_int(Int64, x) toInt64(x::UInt16) = zext_int(Int64, x) toInt64(x::UInt32) = zext_int(Int64, x) -toInt64(x::UInt64) = bitcast(Int64, check_top_bit(Int64, x)) -toInt64(x::UInt128) = checked_trunc_sint(Int64, check_top_bit(Int64, x)) +toInt64(x::UInt64) = bitcast(Int64, check_sign_bit(Int64, x)) +toInt64(x::UInt128) = checked_trunc_sint(Int64, check_sign_bit(Int64, x)) toInt64(x::Bool) = and_int(zext_int(Int64, x), Int64(1)) toInt128(x::Int8) = sext_int(Int128, x) toInt128(x::Int16) = sext_int(Int128, x) @@ -820,9 +822,9 @@ toInt128(x::UInt8) = zext_int(Int128, x) toInt128(x::UInt16) = zext_int(Int128, x) toInt128(x::UInt32) = zext_int(Int128, x) toInt128(x::UInt64) = zext_int(Int128, x) -toInt128(x::UInt128) = bitcast(Int128, check_top_bit(Int128, x)) +toInt128(x::UInt128) = bitcast(Int128, check_sign_bit(Int128, x)) toInt128(x::Bool) = and_int(zext_int(Int128, x), Int128(1)) -toUInt8(x::Int8) = bitcast(UInt8, check_top_bit(UInt8, x)) +toUInt8(x::Int8) = bitcast(UInt8, check_sign_bit(UInt8, x)) toUInt8(x::Int16) = checked_trunc_uint(UInt8, x) toUInt8(x::Int32) = checked_trunc_uint(UInt8, x) toUInt8(x::Int64) = checked_trunc_uint(UInt8, x) @@ -833,8 +835,8 @@ toUInt8(x::UInt32) = checked_trunc_uint(UInt8, x) toUInt8(x::UInt64) = checked_trunc_uint(UInt8, x) toUInt8(x::UInt128) = checked_trunc_uint(UInt8, x) toUInt8(x::Bool) = and_int(bitcast(UInt8, x), UInt8(1)) -toUInt16(x::Int8) = sext_int(UInt16, check_top_bit(UInt16, x)) -toUInt16(x::Int16) = bitcast(UInt16, check_top_bit(UInt16, x)) +toUInt16(x::Int8) = sext_int(UInt16, check_sign_bit(UInt16, x)) +toUInt16(x::Int16) = bitcast(UInt16, check_sign_bit(UInt16, x)) toUInt16(x::Int32) = checked_trunc_uint(UInt16, x) toUInt16(x::Int64) = checked_trunc_uint(UInt16, x) toUInt16(x::Int128) = checked_trunc_uint(UInt16, x) @@ -844,9 +846,9 @@ toUInt16(x::UInt32) = checked_trunc_uint(UInt16, x) toUInt16(x::UInt64) = checked_trunc_uint(UInt16, x) toUInt16(x::UInt128) = checked_trunc_uint(UInt16, x) toUInt16(x::Bool) = and_int(zext_int(UInt16, x), UInt16(1)) -toUInt32(x::Int8) = sext_int(UInt32, check_top_bit(UInt32, x)) -toUInt32(x::Int16) = sext_int(UInt32, check_top_bit(UInt32, x)) -toUInt32(x::Int32) = bitcast(UInt32, check_top_bit(UInt32, x)) +toUInt32(x::Int8) = sext_int(UInt32, check_sign_bit(UInt32, x)) +toUInt32(x::Int16) = sext_int(UInt32, check_sign_bit(UInt32, x)) +toUInt32(x::Int32) = bitcast(UInt32, check_sign_bit(UInt32, x)) toUInt32(x::Int64) = checked_trunc_uint(UInt32, x) toUInt32(x::Int128) = checked_trunc_uint(UInt32, x) toUInt32(x::UInt8) = zext_int(UInt32, x) @@ -855,10 +857,10 @@ toUInt32(x::UInt32) = x toUInt32(x::UInt64) = checked_trunc_uint(UInt32, x) toUInt32(x::UInt128) = checked_trunc_uint(UInt32, x) toUInt32(x::Bool) = and_int(zext_int(UInt32, x), UInt32(1)) -toUInt64(x::Int8) = sext_int(UInt64, check_top_bit(UInt64, x)) -toUInt64(x::Int16) = sext_int(UInt64, check_top_bit(UInt64, x)) -toUInt64(x::Int32) = sext_int(UInt64, check_top_bit(UInt64, x)) -toUInt64(x::Int64) = bitcast(UInt64, check_top_bit(UInt64, x)) +toUInt64(x::Int8) = sext_int(UInt64, check_sign_bit(UInt64, x)) +toUInt64(x::Int16) = sext_int(UInt64, check_sign_bit(UInt64, x)) +toUInt64(x::Int32) = sext_int(UInt64, check_sign_bit(UInt64, x)) +toUInt64(x::Int64) = bitcast(UInt64, check_sign_bit(UInt64, x)) toUInt64(x::Int128) = checked_trunc_uint(UInt64, x) toUInt64(x::UInt8) = zext_int(UInt64, x) toUInt64(x::UInt16) = zext_int(UInt64, x) @@ -866,11 +868,11 @@ toUInt64(x::UInt32) = zext_int(UInt64, x) toUInt64(x::UInt64) = x toUInt64(x::UInt128) = checked_trunc_uint(UInt64, x) toUInt64(x::Bool) = and_int(zext_int(UInt64, x), UInt64(1)) -toUInt128(x::Int8) = sext_int(UInt128, check_top_bit(UInt128, x)) -toUInt128(x::Int16) = sext_int(UInt128, check_top_bit(UInt128, x)) -toUInt128(x::Int32) = sext_int(UInt128, check_top_bit(UInt128, x)) -toUInt128(x::Int64) = sext_int(UInt128, check_top_bit(UInt128, x)) -toUInt128(x::Int128) = bitcast(UInt128, check_top_bit(UInt128, x)) +toUInt128(x::Int8) = sext_int(UInt128, check_sign_bit(UInt128, x)) +toUInt128(x::Int16) = sext_int(UInt128, check_sign_bit(UInt128, x)) +toUInt128(x::Int32) = sext_int(UInt128, check_sign_bit(UInt128, x)) +toUInt128(x::Int64) = sext_int(UInt128, check_sign_bit(UInt128, x)) +toUInt128(x::Int128) = bitcast(UInt128, check_sign_bit(UInt128, x)) toUInt128(x::UInt8) = zext_int(UInt128, x) toUInt128(x::UInt16) = zext_int(UInt128, x) toUInt128(x::UInt32) = zext_int(UInt128, x) diff --git a/src/common_symbols2.inc b/src/common_symbols2.inc index a4583fe39f186..ee2a0e2edd9fe 100644 --- a/src/common_symbols2.inc +++ b/src/common_symbols2.inc @@ -8,7 +8,7 @@ jl_symbol("structdiff"), jl_symbol("UnitRange"), jl_symbol("unitrange_last"), jl_symbol("sizeof"), -jl_symbol("check_top_bit"), +jl_symbol("check_sign_bit"), jl_symbol("is_top_bit_set"), jl_symbol("data"), jl_symbol("kwerr"),