Skip to content

Commit

Permalink
[Headers][X86] Add rounding and exception notes to conversions (#83447)
Browse files Browse the repository at this point in the history
Consistently describe rounding/truncating on convert intrinsics. Add
notes where an out-of-range result can raise an exception.
  • Loading branch information
pogo59 committed Mar 19, 2024
1 parent 1d296ec commit a0394f1
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 37 deletions.
31 changes: 23 additions & 8 deletions clang/lib/Headers/avxintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -2201,6 +2201,10 @@ _mm256_cvtpd_ps(__m256d __a)

/// Converts a vector of [8 x float] into a vector of [8 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VCVTPS2DQ </c> instruction.
Expand Down Expand Up @@ -2230,9 +2234,13 @@ _mm256_cvtps_pd(__m128 __a)
return (__m256d)__builtin_convertvector((__v4sf)__a, __v4df);
}

/// Converts a 256-bit vector of [4 x double] into a 128-bit vector of [4
/// x i32], truncating the result by rounding towards zero when it is
/// inexact.
/// Converts a 256-bit vector of [4 x double] into four signed truncated
/// (rounded toward zero) 32-bit integers returned in a 128-bit vector of
/// [4 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand All @@ -2247,9 +2255,12 @@ _mm256_cvttpd_epi32(__m256d __a)
return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) __a);
}

/// Converts a 256-bit vector of [4 x double] into a 128-bit vector of [4
/// x i32]. When a conversion is inexact, the value returned is rounded
/// according to the rounding control bits in the MXCSR register.
/// Converts a 256-bit vector of [4 x double] into a 128-bit vector of
/// [4 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand All @@ -2264,8 +2275,12 @@ _mm256_cvtpd_epi32(__m256d __a)
return (__m128i)__builtin_ia32_cvtpd2dq256((__v4df) __a);
}

/// Converts a vector of [8 x float] into a vector of [8 x i32],
/// truncating the result by rounding towards zero when it is inexact.
/// Converts a vector of [8 x float] into eight signed truncated (rounded
/// toward zero) 32-bit integers returned in a vector of [8 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand Down
62 changes: 48 additions & 14 deletions clang/lib/Headers/emmintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,10 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cvtepi32_pd(__m128i __a) {
/// returned in the lower 64 bits of a 128-bit vector of [4 x i32]. The upper
/// 64 bits of the result vector are set to zero.
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VCVTPD2DQ / CVTPD2DQ </c> instruction.
Expand All @@ -1309,6 +1313,10 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvtpd_epi32(__m128d __a) {
/// Converts the low-order element of a 128-bit vector of [2 x double]
/// into a 32-bit signed integer value.
///
/// If the converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VCVTSD2SI / CVTSD2SI </c> instruction.
Expand Down Expand Up @@ -1394,12 +1402,13 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cvtss_sd(__m128d __a,
}

/// Converts the two double-precision floating-point elements of a
/// 128-bit vector of [2 x double] into two signed 32-bit integer values,
/// returned in the lower 64 bits of a 128-bit vector of [4 x i32].
/// 128-bit vector of [2 x double] into two signed truncated (rounded
/// toward zero) 32-bit integer values, returned in the lower 64 bits
/// of a 128-bit vector of [4 x i32].
///
/// If the result of either conversion is inexact, the result is truncated
/// (rounded towards zero) regardless of the current MXCSR setting. The upper
/// 64 bits of the result vector are set to zero.
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand All @@ -1415,7 +1424,11 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvttpd_epi32(__m128d __a) {
}

/// Converts the low-order element of a [2 x double] vector into a 32-bit
/// signed integer value, truncating the result when it is inexact.
/// signed truncated (rounded toward zero) integer value.
///
/// If the converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand All @@ -1434,6 +1447,10 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_cvttsd_si32(__m128d __a) {
/// 128-bit vector of [2 x double] into two signed 32-bit integer values,
/// returned in a 64-bit vector of [2 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> CVTPD2PI </c> instruction.
Expand All @@ -1446,11 +1463,12 @@ static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvtpd_pi32(__m128d __a) {
}

/// Converts the two double-precision floating-point elements of a
/// 128-bit vector of [2 x double] into two signed 32-bit integer values,
/// returned in a 64-bit vector of [2 x i32].
/// 128-bit vector of [2 x double] into two signed truncated (rounded toward
/// zero) 32-bit integer values, returned in a 64-bit vector of [2 x i32].
///
/// If the result of either conversion is inexact, the result is truncated
/// (rounded towards zero) regardless of the current MXCSR setting.
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand Down Expand Up @@ -3216,7 +3234,11 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cvtsi64_sd(__m128d __a,
}

/// Converts the first (lower) element of a vector of [2 x double] into a
/// 64-bit signed integer value, according to the current rounding mode.
/// 64-bit signed integer value.
///
/// If the converted value does not fit in a 64-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand All @@ -3231,7 +3253,11 @@ static __inline__ long long __DEFAULT_FN_ATTRS _mm_cvtsd_si64(__m128d __a) {
}

/// Converts the first (lower) element of a vector of [2 x double] into a
/// 64-bit signed integer value, truncating the result when it is inexact.
/// 64-bit signed truncated (rounded toward zero) integer value.
///
/// If a converted value does not fit in a 64-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand Down Expand Up @@ -3262,6 +3288,10 @@ static __inline__ __m128 __DEFAULT_FN_ATTRS _mm_cvtepi32_ps(__m128i __a) {

/// Converts a vector of [4 x float] into a vector of [4 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VCVTPS2DQ / CVTPS2DQ </c> instruction.
Expand All @@ -3274,8 +3304,12 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvtps_epi32(__m128 __a) {
return (__m128i)__builtin_ia32_cvtps2dq((__v4sf)__a);
}

/// Converts a vector of [4 x float] into a vector of [4 x i32],
/// truncating the result when it is inexact.
/// Converts a vector of [4 x float] into four signed truncated (rounded toward
/// zero) 32-bit integers, returned in a vector of [4 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand Down
67 changes: 52 additions & 15 deletions clang/lib/Headers/xmmintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,10 @@ _mm_ucomineq_ss(__m128 __a, __m128 __b)
/// Converts a float value contained in the lower 32 bits of a vector of
/// [4 x float] into a 32-bit integer.
///
/// If the converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VCVTSS2SI / CVTSS2SI </c>
Expand All @@ -1351,6 +1355,10 @@ _mm_cvtss_si32(__m128 __a)
/// Converts a float value contained in the lower 32 bits of a vector of
/// [4 x float] into a 32-bit integer.
///
/// If the converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VCVTSS2SI / CVTSS2SI </c>
Expand All @@ -1371,6 +1379,10 @@ _mm_cvt_ss2si(__m128 __a)
/// Converts a float value contained in the lower 32 bits of a vector of
/// [4 x float] into a 64-bit integer.
///
/// If the converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> VCVTSS2SI / CVTSS2SI </c>
Expand All @@ -1391,6 +1403,10 @@ _mm_cvtss_si64(__m128 __a)
/// Converts two low-order float values in a 128-bit vector of
/// [4 x float] into a 64-bit vector of [2 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> CVTPS2PI </c> instruction.
Expand All @@ -1407,6 +1423,10 @@ _mm_cvtps_pi32(__m128 __a)
/// Converts two low-order float values in a 128-bit vector of
/// [4 x float] into a 64-bit vector of [2 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
/// This intrinsic corresponds to the <c> CVTPS2PI </c> instruction.
Expand All @@ -1420,9 +1440,12 @@ _mm_cvt_ps2pi(__m128 __a)
return _mm_cvtps_pi32(__a);
}

/// Converts a float value contained in the lower 32 bits of a vector of
/// [4 x float] into a 32-bit integer, truncating the result when it is
/// inexact.
/// Converts the lower (first) element of a vector of [4 x float] into a signed
/// truncated (rounded toward zero) 32-bit integer.
///
/// If the converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand All @@ -1439,9 +1462,12 @@ _mm_cvttss_si32(__m128 __a)
return __builtin_ia32_cvttss2si((__v4sf)__a);
}

/// Converts a float value contained in the lower 32 bits of a vector of
/// [4 x float] into a 32-bit integer, truncating the result when it is
/// inexact.
/// Converts the lower (first) element of a vector of [4 x float] into a signed
/// truncated (rounded toward zero) 32-bit integer.
///
/// If the converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand All @@ -1459,9 +1485,12 @@ _mm_cvtt_ss2si(__m128 __a)
}

#ifdef __x86_64__
/// Converts a float value contained in the lower 32 bits of a vector of
/// [4 x float] into a 64-bit integer, truncating the result when it is
/// inexact.
/// Converts the lower (first) element of a vector of [4 x float] into a signed
/// truncated (rounded toward zero) 64-bit integer.
///
/// If the converted value does not fit in a 64-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand All @@ -1479,9 +1508,13 @@ _mm_cvttss_si64(__m128 __a)
}
#endif

/// Converts two low-order float values in a 128-bit vector of
/// [4 x float] into a 64-bit vector of [2 x i32], truncating the result
/// when it is inexact.
/// Converts the lower (first) two elements of a 128-bit vector of [4 x float]
/// into two signed truncated (rounded toward zero) 32-bit integers,
/// returned in a 64-bit vector of [2 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand All @@ -1497,9 +1530,13 @@ _mm_cvttps_pi32(__m128 __a)
return (__m64)__builtin_ia32_cvttps2pi((__v4sf)__a);
}

/// Converts two low-order float values in a 128-bit vector of [4 x
/// float] into a 64-bit vector of [2 x i32], truncating the result when it
/// is inexact.
/// Converts the lower (first) two elements of a 128-bit vector of [4 x float]
/// into two signed truncated (rounded toward zero) 64-bit integers,
/// returned in a 64-bit vector of [2 x i32].
///
/// If a converted value does not fit in a 32-bit integer, raises a
/// floating-point invalid exception. If the exception is masked, returns
/// the most negative integer.
///
/// \headerfile <x86intrin.h>
///
Expand Down

0 comments on commit a0394f1

Please sign in to comment.