From 54a28de4a97322fc5c9cc403e870f5f9b8df83ef Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:23:39 +0200 Subject: [PATCH 01/11] Give all complex lambdas an explicit return type --- glslang/MachineIndependent/ParseContextBase.cpp | 2 +- glslang/MachineIndependent/ParseHelper.cpp | 4 ++-- hlsl/hlslParseHelper.cpp | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp index fe2b8e6b..e46684fe 100644 --- a/glslang/MachineIndependent/ParseContextBase.cpp +++ b/glslang/MachineIndependent/ParseContextBase.cpp @@ -253,7 +253,7 @@ const TFunction* TParseContextBase::selectFunction( return viableCandidates.front(); // 4. find best... - auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2){ + auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool { // is call -> can2 better than call -> can1 for any parameter bool hasBetterParam = false; for (int param = 0; param < call.getParamCount(); ++param) { diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 949ba007..2dfb9c72 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -4907,7 +4907,7 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); // can 'from' convert to 'to'? - const auto convertible = [this](const TType& from, const TType& to) { + const auto convertible = [this](const TType& from, const TType& to) -> bool { if (from == to) return true; if (from.isArray() || to.isArray() || ! from.sameElementShape(to)) @@ -4918,7 +4918,7 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu // Is 'to2' a better conversion than 'to1'? // Ties should not be considered as better. // Assumes 'convertible' already said true. - const auto better = [](const TType& from, const TType& to1, const TType& to2) { + const auto better = [](const TType& from, const TType& to1, const TType& to2) -> bool { // 1. exact match if (from == to2) return from != to1; diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 4eda44d7..ca23ca39 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1001,7 +1001,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op const auto getMember = [&](bool flatten, TIntermTyped* node, const TVector& memberVariables, int member, - TOperator op, const TType& memberType) { + TOperator op, const TType& memberType) -> TIntermTyped * { TIntermTyped* subTree; if (flatten) subTree = intermediate.addSymbol(*memberVariables[member]); @@ -2693,7 +2693,7 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi // space unsigned int setNumber; - const auto crackSpace = [&]() { + const auto crackSpace = [&]() -> bool { const int spaceLen = 5; if (spaceDesc->size() < spaceLen + 1) return false; @@ -3889,7 +3889,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); // can 'from' convert to 'to'? - const auto convertible = [this](const TType& from, const TType& to) { + const auto convertible = [this](const TType& from, const TType& to) -> bool { if (from == to) return true; @@ -3916,7 +3916,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu // Is 'to2' a better conversion than 'to1'? // Ties should not be considered as better. // Assumes 'convertible' already said true. - const auto better = [](const TType& from, const TType& to1, const TType& to2) { + const auto better = [](const TType& from, const TType& to1, const TType& to2) -> bool { // exact match is always better than mismatch if (from == to2) return from != to1; @@ -3943,7 +3943,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu // - 32 vs. 64 bit (or width in general) // - bool vs. non bool // - signed vs. not signed - const auto linearize = [](const TBasicType& basicType) { + const auto linearize = [](const TBasicType& basicType) -> int { switch (basicType) { case EbtBool: return 1; case EbtInt: return 10; From 75c3bf68e907d0f6d4ca279724e193addfcdb5f3 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:24:23 +0200 Subject: [PATCH 02/11] Add strtoull wrapper for VS2010, pointing to MS implementation --- glslang/Include/Common.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/glslang/Include/Common.h b/glslang/Include/Common.h index 636645e7..e082356c 100644 --- a/glslang/Include/Common.h +++ b/glslang/Include/Common.h @@ -68,6 +68,10 @@ inline long long int strtoll (const char* str, char** endptr, int base) { return _strtoi64(str, endptr, base); } +inline unsigned long long int strtoull (const char* str, char** endptr, int base) +{ + return _strtoui64(str, endptr, base); +} inline long long int atoll (const char* str) { return strtoll(str, NULL, 10); From ff160f15ef26c3727bc53e240454ee32061232e3 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:24:42 +0200 Subject: [PATCH 03/11] Add #include for std::uint32_t usage --- SPIRV/SPVRemapper.h | 1 + 1 file changed, 1 insertion(+) diff --git a/SPIRV/SPVRemapper.h b/SPIRV/SPVRemapper.h index 43ec1ae7..b3c686aa 100755 --- a/SPIRV/SPVRemapper.h +++ b/SPIRV/SPVRemapper.h @@ -75,6 +75,7 @@ public: #if !defined (use_cpp11) #include +#include namespace spv { class spirvbin_t : public spirvbin_base_t From 31d5d488125f784d0c7a64fb0af6e66e60033935 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:25:52 +0200 Subject: [PATCH 04/11] Change constructor to use ()s instead of {}s --- StandAlone/StandAlone.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 5d30ac2b..cc38f2c8 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -666,11 +666,11 @@ void CompileAndLinkShaderFiles() // they are all getting linked together.) glslang::TWorkItem* workItem; while (Worklist.remove(workItem)) { - ShaderCompUnit compUnit = { + ShaderCompUnit compUnit( FindLanguage(workItem->name), workItem->name, ReadFileData(workItem->name.c_str()) - }; + ); if (! compUnit.text) { usage(); From 033d3ef22ce3b53545098a1904db580d61d41367 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:28:20 +0200 Subject: [PATCH 05/11] Change enum class to plain enum --- SPIRV/SpvBuilder.cpp | 2 +- SPIRV/hex_float.h | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index c19f3683..4703edc3 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -797,7 +797,7 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant) spvutils::HexFloat> fVal(f16); spvutils::HexFloat> f16Val(0); - fVal.castTo(f16Val, spvutils::round_direction::kToZero); + fVal.castTo(f16Val, spvutils::kRoundToZero); unsigned value = f16Val.value().getAsFloat().get_value(); diff --git a/SPIRV/hex_float.h b/SPIRV/hex_float.h index ac7e0027..ea403a77 100644 --- a/SPIRV/hex_float.h +++ b/SPIRV/hex_float.h @@ -226,12 +226,11 @@ struct HexFloatTraits> { static const uint_type exponent_bias = 15; }; -enum class round_direction { - kToZero, - kToNearestEven, - kToPositiveInfinity, - kToNegativeInfinity, - max = kToNegativeInfinity +enum round_direction { + kRoundToZero, + kRoundToNearestEven, + kRoundToPositiveInfinity, + kRoundToNegativeInfinity }; // Template class that houses a floating pointer number. @@ -520,15 +519,15 @@ class HexFloat { // We actually have to narrow the significand here, so we have to follow the // rounding rules. switch (dir) { - case round_direction::kToZero: + case kRoundToZero: break; - case round_direction::kToPositiveInfinity: + case kRoundToPositiveInfinity: round_away_from_zero = !isNegative(); break; - case round_direction::kToNegativeInfinity: + case kRoundToNegativeInfinity: round_away_from_zero = isNegative(); break; - case round_direction::kToNearestEven: + case kRoundToNearestEven: // Have to round down, round bit is 0 if ((first_rounded_bit & significand) == 0) { break; @@ -623,8 +622,8 @@ class HexFloat { } bool round_underflow_up = - isNegative() ? round_dir == round_direction::kToNegativeInfinity - : round_dir == round_direction::kToPositiveInfinity; + isNegative() ? round_dir == kRoundToNegativeInfinity + : round_dir == kRoundToPositiveInfinity; using other_int_type = typename other_T::int_type; // setFromSignUnbiasedExponentAndNormalizedSignificand will // zero out any underflowing value (but retain the sign). @@ -812,7 +811,7 @@ ParseNormalFloat, HexFloatTraits>>( // Then convert to 16-bit float, saturating at infinities, and // rounding toward zero. - float_val.castTo(value, round_direction::kToZero); + float_val.castTo(value, kRoundToZero); // Overflow on 16-bit behaves the same as for 32- and 64-bit: set the // fail bit and set the lowest or highest value. From 1a65fc269c4b50f01400e64140b96377d6b11d95 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:28:54 +0200 Subject: [PATCH 06/11] Add std::isnan and std::isinf wrappers for VS2010 that doesn't have them --- SPIRV/hex_float.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/SPIRV/hex_float.h b/SPIRV/hex_float.h index ea403a77..24a26079 100644 --- a/SPIRV/hex_float.h +++ b/SPIRV/hex_float.h @@ -23,6 +23,19 @@ #include #include +#if defined(_MSC_VER) && _MSC_VER < 1700 +namespace std { +bool isnan(double f) +{ + return ::_isnan(f) != 0; +} +bool isinf(double f) +{ + return ::_finite(f) == 0; +} +} +#endif + #include "bitutils.h" namespace spvutils { From a227d27227e003007fc67b40e9f3c17598dc2846 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:30:27 +0200 Subject: [PATCH 07/11] Explicitly implement default constructors --- SPIRV/hex_float.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SPIRV/hex_float.h b/SPIRV/hex_float.h index 24a26079..3849eeff 100644 --- a/SPIRV/hex_float.h +++ b/SPIRV/hex_float.h @@ -43,7 +43,7 @@ namespace spvutils { class Float16 { public: Float16(uint16_t v) : val(v) {} - Float16() = default; + Float16() {} static bool isNan(const Float16& val) { return ((val.val & 0x7C00) == 0x7C00) && ((val.val & 0x3FF) != 0); } @@ -118,7 +118,7 @@ class FloatProxy { // Since this is to act similar to the normal floats, // do not initialize the data by default. - FloatProxy() = default; + FloatProxy() {} // Intentionally non-explicit. This is a proxy type so // implicit conversions allow us to use it more transparently. From 7cac9e7245c6ce5cdc36f7a9473b994d239a2094 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:31:15 +0200 Subject: [PATCH 08/11] Change "using x = y;" to "typedef y x;" statements --- SPIRV/hex_float.h | 60 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/SPIRV/hex_float.h b/SPIRV/hex_float.h index 3849eeff..4a26ad8c 100644 --- a/SPIRV/hex_float.h +++ b/SPIRV/hex_float.h @@ -69,12 +69,12 @@ class Float16 { // a value is Nan. template struct FloatProxyTraits { - using uint_type = void; + typedef void uint_type; }; template <> struct FloatProxyTraits { - using uint_type = uint32_t; + typedef uint32_t uint_type; static bool isNan(float f) { return std::isnan(f); } // Returns true if the given value is any kind of infinity. static bool isInfinity(float f) { return std::isinf(f); } @@ -86,7 +86,7 @@ struct FloatProxyTraits { template <> struct FloatProxyTraits { - using uint_type = uint64_t; + typedef uint64_t uint_type; static bool isNan(double f) { return std::isnan(f); } // Returns true if the given value is any kind of infinity. static bool isInfinity(double f) { return std::isinf(f); } @@ -98,7 +98,7 @@ struct FloatProxyTraits { template <> struct FloatProxyTraits { - using uint_type = uint16_t; + typedef uint16_t uint_type; static bool isNan(Float16 f) { return Float16::isNan(f); } // Returns true if the given value is any kind of infinity. static bool isInfinity(Float16 f) { return Float16::isInfinity(f); } @@ -114,7 +114,7 @@ struct FloatProxyTraits { template class FloatProxy { public: - using uint_type = typename FloatProxyTraits::uint_type; + typedef typename FloatProxyTraits::uint_type uint_type; // Since this is to act similar to the normal floats, // do not initialize the data by default. @@ -177,13 +177,13 @@ std::istream& operator>>(std::istream& is, FloatProxy& value) { template struct HexFloatTraits { // Integer type that can store this hex-float. - using uint_type = void; + typedef void uint_type; // Signed integer type that can store this hex-float. - using int_type = void; + typedef void int_type; // The numerical type that this HexFloat represents. - using underlying_type = void; + typedef void underlying_type; // The type needed to construct the underlying type. - using native_type = void; + typedef void native_type; // The number of bits that are actually relevant in the uint_type. // This allows us to deal with, for example, 24-bit values in a 32-bit // integer. @@ -201,10 +201,10 @@ struct HexFloatTraits { // 1 sign bit, 8 exponent bits, 23 fractional bits. template <> struct HexFloatTraits> { - using uint_type = uint32_t; - using int_type = int32_t; - using underlying_type = FloatProxy; - using native_type = float; + typedef uint32_t uint_type; + typedef int32_t int_type; + typedef FloatProxy underlying_type; + typedef float native_type; static const uint_type num_used_bits = 32; static const uint_type num_exponent_bits = 8; static const uint_type num_fraction_bits = 23; @@ -215,10 +215,10 @@ struct HexFloatTraits> { // 1 sign bit, 11 exponent bits, 52 fractional bits. template <> struct HexFloatTraits> { - using uint_type = uint64_t; - using int_type = int64_t; - using underlying_type = FloatProxy; - using native_type = double; + typedef uint64_t uint_type; + typedef int64_t int_type; + typedef FloatProxy underlying_type; + typedef double native_type; static const uint_type num_used_bits = 64; static const uint_type num_exponent_bits = 11; static const uint_type num_fraction_bits = 52; @@ -229,10 +229,10 @@ struct HexFloatTraits> { // 1 sign bit, 5 exponent bits, 10 fractional bits. template <> struct HexFloatTraits> { - using uint_type = uint16_t; - using int_type = int16_t; - using underlying_type = uint16_t; - using native_type = uint16_t; + typedef uint16_t uint_type; + typedef int16_t int_type; + typedef uint16_t underlying_type; + typedef uint16_t native_type; static const uint_type num_used_bits = 16; static const uint_type num_exponent_bits = 5; static const uint_type num_fraction_bits = 10; @@ -252,10 +252,10 @@ enum round_direction { template > class HexFloat { public: - using uint_type = typename Traits::uint_type; - using int_type = typename Traits::int_type; - using underlying_type = typename Traits::underlying_type; - using native_type = typename Traits::native_type; + typedef typename Traits::uint_type uint_type; + typedef typename Traits::int_type int_type; + typedef typename Traits::underlying_type underlying_type; + typedef typename Traits::native_type native_type; explicit HexFloat(T f) : value_(f) {} @@ -491,7 +491,7 @@ class HexFloat { template typename other_T::uint_type getRoundedNormalizedSignificand( round_direction dir, bool* carry_bit) { - using other_uint_type = typename other_T::uint_type; + typedef typename other_T::uint_type other_uint_type; static const int_type num_throwaway_bits = static_cast(num_fraction_bits) - static_cast(other_T::num_fraction_bits); @@ -637,7 +637,7 @@ class HexFloat { bool round_underflow_up = isNegative() ? round_dir == kRoundToNegativeInfinity : round_dir == kRoundToPositiveInfinity; - using other_int_type = typename other_T::int_type; + typedef typename other_T::int_type other_int_type; // setFromSignUnbiasedExponentAndNormalizedSignificand will // zero out any underflowing value (but retain the sign). other.setFromSignUnbiasedExponentAndNormalizedSignificand( @@ -676,9 +676,9 @@ inline uint8_t get_nibble_from_character(int character) { // Outputs the given HexFloat to the stream. template std::ostream& operator<<(std::ostream& os, const HexFloat& value) { - using HF = HexFloat; - using uint_type = typename HF::uint_type; - using int_type = typename HF::int_type; + typedef HexFloat HF; + typedef typename HF::uint_type uint_type; + typedef typename HF::int_type int_type; static_assert(HF::num_used_bits != 0, "num_used_bits must be non-zero for a valid float"); From cabba60abfc8a6d8275d939e41c0cb59e9afd694 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:32:37 +0200 Subject: [PATCH 09/11] Change {} constructor brackets to () --- SPIRV/hex_float.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SPIRV/hex_float.h b/SPIRV/hex_float.h index 4a26ad8c..a051b2f5 100644 --- a/SPIRV/hex_float.h +++ b/SPIRV/hex_float.h @@ -757,7 +757,7 @@ inline bool RejectParseDueToLeadingSign(std::istream& is, bool negate_value, if (next_char == '-' || next_char == '+') { // Fail the parse. Emulate standard behaviour by setting the value to // the zero value, and set the fail bit on the stream. - value = HexFloat(typename HexFloat::uint_type{0}); + value = HexFloat(typename HexFloat::uint_type(0)); is.setstate(std::ios_base::failbit); return true; } @@ -789,7 +789,7 @@ inline std::istream& ParseNormalFloat(std::istream& is, bool negate_value, value.set_value(val); // In the failure case, map -0.0 to 0.0. if (is.fail() && value.getUnsignedBits() == 0u) { - value = HexFloat(typename HexFloat::uint_type{0}); + value = HexFloat(typename HexFloat::uint_type(0)); } if (val.isInfinity()) { // Fail the parse. Emulate standard behaviour by setting the value to From 021dbb4cd41d66ec1c36f35139728e4f84b64333 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 19:39:24 +0200 Subject: [PATCH 10/11] Change negatable_left_shift and negatable_right_shift to inline funcs * This avoids an internal compile error on VS2010 possibly related to std::enable_if use. --- SPIRV/hex_float.h | 52 +++++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/SPIRV/hex_float.h b/SPIRV/hex_float.h index a051b2f5..31b9f9ed 100644 --- a/SPIRV/hex_float.h +++ b/SPIRV/hex_float.h @@ -456,33 +456,23 @@ class HexFloat { // constant_number < 0? 0: constant_number // These convert the negative left-shifts into right shifts. - template - struct negatable_left_shift { - static uint_type val(uint_type val) { - return static_cast(val >> -N); - } - }; + template + uint_type negatable_left_shift(int_type N, uint_type val) + { + if(N >= 0) + return val << N; - template - struct negatable_left_shift= 0>::type> { - static uint_type val(uint_type val) { - return static_cast(val << N); - } - }; + return val >> -N; + } - template - struct negatable_right_shift { - static uint_type val(uint_type val) { - return static_cast(val << -N); - } - }; + template + uint_type negatable_right_shift(int_type N, uint_type val) + { + if(N >= 0) + return val >> N; - template - struct negatable_right_shift= 0>::type> { - static uint_type val(uint_type val) { - return static_cast(val >> N); - } - }; + return val << -N; + } // Returns the significand, rounded to fit in a significand in // other_T. This is shifted so that the most significant @@ -499,11 +489,11 @@ class HexFloat { static const uint_type last_significant_bit = (num_throwaway_bits < 0) ? 0 - : negatable_left_shift::val(1u); + : negatable_left_shift(num_throwaway_bits, 1u); static const uint_type first_rounded_bit = (num_throwaway_bits < 1) ? 0 - : negatable_left_shift::val(1u); + : negatable_left_shift(num_throwaway_bits - 1, 1u); static const uint_type throwaway_mask_bits = num_throwaway_bits > 0 ? num_throwaway_bits : 0; @@ -525,7 +515,7 @@ class HexFloat { // do. if ((significand & throwaway_mask) == 0) { return static_cast( - negatable_right_shift::val(significand)); + negatable_right_shift(num_throwaway_bits, significand)); } bool round_away_from_zero = false; @@ -562,11 +552,11 @@ class HexFloat { if (round_away_from_zero) { return static_cast( - negatable_right_shift::val(incrementSignificand( + negatable_right_shift(num_throwaway_bits, incrementSignificand( significand, last_significant_bit, carry_bit))); } else { return static_cast( - negatable_right_shift::val(significand)); + negatable_right_shift(num_throwaway_bits, significand)); } } @@ -620,9 +610,9 @@ class HexFloat { if (is_nan) { typename other_T::uint_type shifted_significand; shifted_significand = static_cast( - negatable_left_shift< + negatable_left_shift( static_cast(other_T::num_fraction_bits) - - static_cast(num_fraction_bits)>::val(significand)); + static_cast(num_fraction_bits), significand)); // We are some sort of Nan. We try to keep the bit-pattern of the Nan // as close as possible. If we had to shift off bits so we are 0, then we From 486d9e44e055c442770dc536a4029bd7e1360dc4 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 13 Oct 2016 20:05:13 +0200 Subject: [PATCH 11/11] Update HexFloat tests to use non-enum class enum values --- gtests/HexFloat.cpp | 149 ++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/gtests/HexFloat.cpp b/gtests/HexFloat.cpp index 248513c4..ddbee1f4 100644 --- a/gtests/HexFloat.cpp +++ b/gtests/HexFloat.cpp @@ -690,10 +690,10 @@ TEST(HexFloatOperationTests, NonRounding) { bool carry_bit = false; spvutils::round_direction rounding[] = { - spvutils::round_direction::kToZero, - spvutils::round_direction::kToNearestEven, - spvutils::round_direction::kToPositiveInfinity, - spvutils::round_direction::kToNegativeInfinity}; + spvutils::kRoundToZero, + spvutils::kRoundToNearestEven, + spvutils::kRoundToPositiveInfinity, + spvutils::kRoundToNegativeInfinity}; // Everything fits, so this should be straight-forward for (spvutils::round_direction round : rounding) { @@ -725,7 +725,6 @@ TEST(HexFloatOperationTests, NonRounding) { } } -using RD = spvutils::round_direction; struct RoundSignificandCase { float source_float; std::pair expected_results; @@ -751,49 +750,49 @@ TEST_P(HexFloatRoundTest, RoundDownToFP16) { INSTANTIATE_TEST_CASE_P(F32ToF16, HexFloatRoundTest, ::testing::ValuesIn(std::vector( { - {float_fractions({0}), std::make_pair(half_bits_set({}), false), RD::kToZero}, - {float_fractions({0}), std::make_pair(half_bits_set({}), false), RD::kToNearestEven}, - {float_fractions({0}), std::make_pair(half_bits_set({}), false), RD::kToPositiveInfinity}, - {float_fractions({0}), std::make_pair(half_bits_set({}), false), RD::kToNegativeInfinity}, - {float_fractions({0, 1}), std::make_pair(half_bits_set({0}), false), RD::kToZero}, + {float_fractions({0}), std::make_pair(half_bits_set({}), false), spvutils::kRoundToZero}, + {float_fractions({0}), std::make_pair(half_bits_set({}), false), spvutils::kRoundToNearestEven}, + {float_fractions({0}), std::make_pair(half_bits_set({}), false), spvutils::kRoundToPositiveInfinity}, + {float_fractions({0}), std::make_pair(half_bits_set({}), false), spvutils::kRoundToNegativeInfinity}, + {float_fractions({0, 1}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero}, - {float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), RD::kToZero}, - {float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0, 9}), false), RD::kToPositiveInfinity}, - {float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), RD::kToNegativeInfinity}, - {float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), RD::kToNearestEven}, + {float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero}, + {float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToPositiveInfinity}, + {float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNegativeInfinity}, + {float_fractions({0, 1, 11}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNearestEven}, - {float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 9}), false), RD::kToZero}, - {float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 8}), false), RD::kToPositiveInfinity}, - {float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNegativeInfinity}, - {float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 8}), false), RD::kToNearestEven}, + {float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToZero}, + {float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 8}), false), spvutils::kRoundToPositiveInfinity}, + {float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNegativeInfinity}, + {float_fractions({0, 1, 10, 11}), std::make_pair(half_bits_set({0, 8}), false), spvutils::kRoundToNearestEven}, - {float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), RD::kToZero}, - {float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), RD::kToPositiveInfinity}, - {float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), RD::kToNegativeInfinity}, - {float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNearestEven}, + {float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero}, + {float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToPositiveInfinity}, + {float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNegativeInfinity}, + {float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNearestEven}, - {-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), RD::kToZero}, - {-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), RD::kToPositiveInfinity}, - {-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNegativeInfinity}, - {-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNearestEven}, + {-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero}, + {-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToPositiveInfinity}, + {-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNegativeInfinity}, + {-float_fractions({0, 1, 11, 12}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNearestEven}, - {float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0}), false), RD::kToZero}, - {float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0, 9}), false), RD::kToPositiveInfinity}, - {float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0}), false), RD::kToNegativeInfinity}, - {float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0, 9}), false), RD::kToNearestEven}, + {float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero}, + {float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToPositiveInfinity}, + {float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNegativeInfinity}, + {float_fractions({0, 1, 11, 22}), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNearestEven}, // Carries - {float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), false), RD::kToZero}, - {float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({}), true), RD::kToPositiveInfinity}, - {float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), false), RD::kToNegativeInfinity}, - {float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({}), true), RD::kToNearestEven}, + {float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), false), spvutils::kRoundToZero}, + {float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({}), true), spvutils::kRoundToPositiveInfinity}, + {float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}), false), spvutils::kRoundToNegativeInfinity}, + {float_fractions({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), std::make_pair(half_bits_set({}), true), spvutils::kRoundToNearestEven}, // Cases where original number was denorm. Note: this should have no effect // the number is pre-normalized. - {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -128)), std::make_pair(half_bits_set({0}), false), RD::kToZero}, - {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -129)), std::make_pair(half_bits_set({0, 9}), false), RD::kToPositiveInfinity}, - {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -131)), std::make_pair(half_bits_set({0}), false), RD::kToNegativeInfinity}, - {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -130)), std::make_pair(half_bits_set({0, 9}), false), RD::kToNearestEven}, + {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -128)), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToZero}, + {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -129)), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToPositiveInfinity}, + {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -131)), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNegativeInfinity}, + {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -130)), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNearestEven}, })),); // clang-format on @@ -810,10 +809,10 @@ TEST_P(HexFloatRoundUpSignificandTest, Widening) { bool carry_bit = false; spvutils::round_direction rounding[] = { - spvutils::round_direction::kToZero, - spvutils::round_direction::kToNearestEven, - spvutils::round_direction::kToPositiveInfinity, - spvutils::round_direction::kToNegativeInfinity}; + spvutils::kRoundToZero, + spvutils::kRoundToNearestEven, + spvutils::kRoundToPositiveInfinity, + spvutils::kRoundToNegativeInfinity}; // Everything fits, so everything should just be bit-shifts. for (spvutils::round_direction round : rounding) { @@ -852,10 +851,10 @@ std::string get_round_text(spvutils::round_direction direction) { return #round_direction switch (direction) { - CASE(spvutils::round_direction::kToZero); - CASE(spvutils::round_direction::kToPositiveInfinity); - CASE(spvutils::round_direction::kToNegativeInfinity); - CASE(spvutils::round_direction::kToNearestEven); + CASE(spvutils::kRoundToZero); + CASE(spvutils::kRoundToPositiveInfinity); + CASE(spvutils::kRoundToNegativeInfinity); + CASE(spvutils::kRoundToNearestEven); } #undef CASE return ""; @@ -884,35 +883,35 @@ INSTANTIATE_TEST_CASE_P(F32ToF16, HexFloatFP32To16Tests, ::testing::ValuesIn(std::vector( { // Exactly representable as half. - {0.f, 0x0, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {-0.f, 0x8000, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {1.0f, 0x3C00, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {-1.0f, 0xBC00, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, + {0.f, 0x0, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {-0.f, 0x8000, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {1.0f, 0x3C00, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {-1.0f, 0xBC00, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, - {float_fractions({0, 1, 10}) , 0x3E01, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {-float_fractions({0, 1, 10}) , 0xBE01, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {static_cast(ldexp(float_fractions({0, 1, 10}), 3)), 0x4A01, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {static_cast(-ldexp(float_fractions({0, 1, 10}), 3)), 0xCA01, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, + {float_fractions({0, 1, 10}) , 0x3E01, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {-float_fractions({0, 1, 10}) , 0xBE01, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {static_cast(ldexp(float_fractions({0, 1, 10}), 3)), 0x4A01, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {static_cast(-ldexp(float_fractions({0, 1, 10}), 3)), 0xCA01, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, // Underflow - {static_cast(ldexp(1.0f, -25)), 0x0, {RD::kToZero, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {static_cast(ldexp(1.0f, -25)), 0x1, {RD::kToPositiveInfinity}}, - {static_cast(-ldexp(1.0f, -25)), 0x8000, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNearestEven}}, - {static_cast(-ldexp(1.0f, -25)), 0x8001, {RD::kToNegativeInfinity}}, - {static_cast(ldexp(1.0f, -24)), 0x1, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, + {static_cast(ldexp(1.0f, -25)), 0x0, {spvutils::kRoundToZero, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {static_cast(ldexp(1.0f, -25)), 0x1, {spvutils::kRoundToPositiveInfinity}}, + {static_cast(-ldexp(1.0f, -25)), 0x8000, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNearestEven}}, + {static_cast(-ldexp(1.0f, -25)), 0x8001, {spvutils::kRoundToNegativeInfinity}}, + {static_cast(ldexp(1.0f, -24)), 0x1, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, // Overflow - {static_cast(ldexp(1.0f, 16)), positive_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {static_cast(ldexp(1.0f, 18)), positive_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {static_cast(ldexp(1.3f, 16)), positive_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {static_cast(-ldexp(1.0f, 16)), negative_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {static_cast(-ldexp(1.0f, 18)), negative_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {static_cast(-ldexp(1.3f, 16)), negative_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, + {static_cast(ldexp(1.0f, 16)), positive_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {static_cast(ldexp(1.0f, 18)), positive_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {static_cast(ldexp(1.3f, 16)), positive_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {static_cast(-ldexp(1.0f, 16)), negative_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {static_cast(-ldexp(1.0f, 18)), negative_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {static_cast(-ldexp(1.3f, 16)), negative_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, // Transfer of Infinities - {std::numeric_limits::infinity(), positive_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, - {-std::numeric_limits::infinity(), negative_infinity, {RD::kToZero, RD::kToPositiveInfinity, RD::kToNegativeInfinity, RD::kToNearestEven}}, + {std::numeric_limits::infinity(), positive_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, + {-std::numeric_limits::infinity(), negative_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, // Nans are below because we cannot test for equality. })),); @@ -929,10 +928,10 @@ TEST_P(HexFloatFP16To32Tests, WideningCasts) { HF16 f(GetParam().source_half); spvutils::round_direction rounding[] = { - spvutils::round_direction::kToZero, - spvutils::round_direction::kToNearestEven, - spvutils::round_direction::kToPositiveInfinity, - spvutils::round_direction::kToNegativeInfinity}; + spvutils::kRoundToZero, + spvutils::kRoundToNearestEven, + spvutils::kRoundToPositiveInfinity, + spvutils::kRoundToNegativeInfinity}; // Everything fits, so everything should just be bit-shifts. for (spvutils::round_direction round : rounding) { @@ -972,10 +971,10 @@ TEST(HexFloatOperationTests, NanTests) { using HF = spvutils::HexFloat>; using HF16 = spvutils::HexFloat>; spvutils::round_direction rounding[] = { - spvutils::round_direction::kToZero, - spvutils::round_direction::kToNearestEven, - spvutils::round_direction::kToPositiveInfinity, - spvutils::round_direction::kToNegativeInfinity}; + spvutils::kRoundToZero, + spvutils::kRoundToNearestEven, + spvutils::kRoundToPositiveInfinity, + spvutils::kRoundToNegativeInfinity}; // Everything fits, so everything should just be bit-shifts. for (spvutils::round_direction round : rounding) {