From 10641d4017dce61147b4a470c3de665da30ddd88 Mon Sep 17 00:00:00 2001 From: doe300 Date: Wed, 11 Jul 2018 16:40:15 +0200 Subject: [PATCH] Fix most type conversions, disable GCC ABI change warning See https://github.com/doe300/VC4CL/issues/41 --- src/CMakeLists.txt | 2 +- src/asm/OpCodes.cpp | 12 +++- test/TestArithmetic.cpp | 138 ++++++++++++++++++++++++++++++++++++---- test/TestArithmetic.h | 23 +++++-- 4 files changed, 153 insertions(+), 22 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1ae292ae..f633af61 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,7 +16,7 @@ set(VC4C_ENABLED_WARNINGS -Wall -Wextra -Wold-style-cast -Wno-unused-parameter - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") SET(VC4C_ENABLED_WARNINGS ${VC4C_ENABLED_WARNINGS} -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-shadow -Wno-padded -Wno-shadow-field-in-constructor -Wno-global-constructors -Wno-exit-time-destructors -Wno-missing-prototypes -Wno-gnu-anonymous-struct -Wno-nested-anon-types -Wno-documentation -Wno-unused-command-line-argument -Wno-unused-member-function -Wno-gnu-zero-variadic-macro-arguments -Wno-covered-switch-default -Wno-switch-enum -Wswitch) elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - SET(VC4C_ENABLED_WARNINGS ${VC4C_ENABLED_WARNINGS} -Wdouble-promotion -fdelete-null-pointer-checks -Wnull-dereference -Wuninitialized -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=format -Wsuggest-override -Wconversion -Wzero-as-null-pointer-constant) + SET(VC4C_ENABLED_WARNINGS ${VC4C_ENABLED_WARNINGS} -Wdouble-promotion -fdelete-null-pointer-checks -Wnull-dereference -Wuninitialized -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=format -Wsuggest-override -Wconversion -Wzero-as-null-pointer-constant -Wno-psabi) endif() target_compile_options(${VC4C_LIBRARY_NAME} PRIVATE ${VC4C_ENABLED_WARNINGS}) target_compile_options(${VC4C_PROGRAM_NAME} PRIVATE ${VC4C_ENABLED_WARNINGS}) diff --git a/src/asm/OpCodes.cpp b/src/asm/OpCodes.cpp index e1fbc037..ccdecb2e 100644 --- a/src/asm/OpCodes.cpp +++ b/src/asm/OpCodes.cpp @@ -492,9 +492,15 @@ Optional OpCode::calculate(const Optional& firstOperand, const Opt Value res(ContainerValue(numElements), resultType); for(unsigned char i = 0; i < numElements; ++i) { - auto tmp = calculate( - firstVal->hasType(ValueType::CONTAINER) ? firstVal->container.elements.at(i) : firstVal.value(), - secondVal->hasType(ValueType::CONTAINER) ? secondVal->container.elements.at(i) : secondVal.value()); + Optional tmp = NO_VALUE; + if(numOperands == 1) + tmp = calculate( + firstVal->hasType(ValueType::CONTAINER) ? firstVal->container.elements.at(i) : firstVal.value(), + NO_VALUE); + else + tmp = calculate( + firstVal->hasType(ValueType::CONTAINER) ? firstVal->container.elements.at(i) : firstVal.value(), + secondVal->hasType(ValueType::CONTAINER) ? secondVal->container.elements.at(i) : secondVal.value()); if(!tmp) // result could not be calculated for a single component of the vector, abort return NO_VALUE; diff --git a/test/TestArithmetic.cpp b/test/TestArithmetic.cpp index 4c2ecc0e..26eb786a 100644 --- a/test/TestArithmetic.cpp +++ b/test/TestArithmetic.cpp @@ -10,17 +10,18 @@ #include "VC4C.h" #include "tools.h" +#include #include #include #include -template +template ::min(), T max = std::numeric_limits::max()> static std::array generateInput(bool allowNull) { std::array arr; std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution dis(std::numeric_limits::min(), std::numeric_limits::max()); + std::uniform_int_distribution dis(min, max); for(std::size_t i = 0; i < N; ++i) { @@ -36,13 +37,14 @@ static std::array generateInput(bool allowNull) return arr; } -template +template static std::array generateInput(bool allowNull) { std::array arr; std::random_device rd; std::mt19937 gen(rd()); - std::uniform_real_distribution dis(std::numeric_limits::min(), std::numeric_limits::max()); + std::uniform_real_distribution dis( + static_cast(std::numeric_limits::min()), static_cast(std::numeric_limits::max())); for(std::size_t i = 0; i < N; ++i) { @@ -64,6 +66,13 @@ __kernel void test(__global TYPE* out, const __global TYPE* in0, const __global } )"; +static const std::string SELECTION_OPERATION = R"( +__kernel void test(__global TYPE* out, const __global TYPE* in0, const __global TYPE* in1) { + size_t gid = get_global_id(0); + out[gid] = select(in0[gid], in1[gid], in0[gid]); +} +)"; + static const std::string RELATIONAL_OPERATION = R"( __kernel void test(__global int16* out, const __global TYPE* in0, const __global TYPE* in1) { size_t gid = get_global_id(0); @@ -190,6 +199,12 @@ TestArithmetic::TestArithmetic(const vc4c::Configuration& config) : config(confi TEST_ADD(TestArithmetic::testUnsignedCharLessEquals); TEST_ADD(TestArithmetic::testFloatLessEquals); + TEST_ADD(TestArithmetic::testSignedIntSelection); + TEST_ADD(TestArithmetic::testSignedShortSelection); + TEST_ADD(TestArithmetic::testSignedCharSelection); + TEST_ADD(TestArithmetic::testUnsignedIntSelection); + TEST_ADD(TestArithmetic::testUnsignedShortSelection); + TEST_ADD(TestArithmetic::testUnsignedCharSelection); TEST_ADD(TestArithmetic::testSignedIntAnd); TEST_ADD(TestArithmetic::testSignedShortAnd); TEST_ADD(TestArithmetic::testSignedCharAnd); @@ -209,10 +224,18 @@ TestArithmetic::TestArithmetic(const vc4c::Configuration& config) : config(confi TEST_ADD(TestArithmetic::testUnsignedTruncation); TEST_ADD(TestArithmetic::testSignExtension); TEST_ADD(TestArithmetic::testZeroExtension); - TEST_ADD(TestArithmetic::testSignedToFloat); - TEST_ADD(TestArithmetic::testUnsignedToFloat); - TEST_ADD(TestArithmetic::testFloatToSigned); - TEST_ADD(TestArithmetic::testFloatToUnsigned); + TEST_ADD(TestArithmetic::testSignedIntToFloat); + TEST_ADD(TestArithmetic::testSignedShortToFloat); + TEST_ADD(TestArithmetic::testSignedCharToFloat); + TEST_ADD(TestArithmetic::testUnsignedIntToFloat); + TEST_ADD(TestArithmetic::testUnsignedShortToFloat); + TEST_ADD(TestArithmetic::testUnsignedCharToFloat); + TEST_ADD(TestArithmetic::testFloatToSignedInt); + TEST_ADD(TestArithmetic::testFloatToSignedShort); + TEST_ADD(TestArithmetic::testFloatToSignedChar); + TEST_ADD(TestArithmetic::testFloatToUnsignedInt); + TEST_ADD(TestArithmetic::testFloatToUnsignedShort); + TEST_ADD(TestArithmetic::testFloatToUnsignedChar); } void TestArithmetic::onMismatch(const std::string& expected, const std::string& result) @@ -332,6 +355,25 @@ void testRelationalOperation(vc4c::Configuration& config, const std::stri in0, in1, out, op, options.substr(pos, options.find(' ', pos) - pos), onError); } +template +static void testSelectionOperation(vc4c::Configuration& config, const std::string& options, + const std::function& onError) +{ + std::stringstream code; + compileBuffer(config, code, SELECTION_OPERATION, options); + + auto in0 = generateInput(true); + auto in1 = generateInput(true); + + auto out = runEmulation(code, {in0, in1}); + auto op = [](T a, T b) -> T { + typename std::make_signed::type signedVal; + std::memcpy(&signedVal, &a, sizeof(T)); + return signedVal < 0 ? b : a; + }; + checkBinaryResults(in0, in1, out, op, "select", onError); +} + template static void testConversionOperation(vc4c::Configuration& config, const std::string& options, const std::function& op, const std::function& onError) @@ -352,7 +394,8 @@ static void testConversionOperation(vc4c::Configuration& config, const std::stri std::stringstream code; compileBuffer(config, code, CONVERSION_OPERATION, options); - auto in = generateInput<16 * 12>(true); + // values out of the range of O (the integer type) are implementation-defined + auto in = generateInput<16 * 12, O>(true); auto out = runEmulation(code, {in}); checkUnaryResults(in, out, op, "convert", onError); @@ -719,6 +762,42 @@ void TestArithmetic::testFloatLessEquals() std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); } +void TestArithmetic::testSignedIntSelection() +{ + testSelectionOperation(config, "-DTYPE=int16", + std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testSignedShortSelection() +{ + testSelectionOperation(config, "-DTYPE=short16", + std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testSignedCharSelection() +{ + testSelectionOperation(config, "-DTYPE=char16", + std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testUnsignedIntSelection() +{ + testSelectionOperation(config, "-DTYPE=uint16", + std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testUnsignedShortSelection() +{ + testSelectionOperation(config, "-DTYPE=ushort16", + std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testUnsignedCharSelection() +{ + testSelectionOperation(config, "-DTYPE=uchar16", + std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + void TestArithmetic::testSignedIntAnd() { testRelationalOperation(config, "-DTYPE=int16 -DOP=&&", checkAnd, @@ -849,42 +928,75 @@ void TestArithmetic::testZeroExtension() std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); } -void TestArithmetic::testSignedToFloat() +void TestArithmetic::testSignedIntToFloat() { testConversionOperation(config, "-DIN=int16 -DOUT=float16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testSignedShortToFloat() +{ testConversionOperation(config, "-DIN=short16 -DOUT=float16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testSignedCharToFloat() +{ testConversionOperation(config, "-DIN=char16 -DOUT=float16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); } -void TestArithmetic::testUnsignedToFloat() +void TestArithmetic::testUnsignedIntToFloat() { testConversionOperation(config, "-DIN=uint16 -DOUT=float16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testUnsignedShortToFloat() +{ testConversionOperation(config, "-DIN=ushort16 -DOUT=float16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testUnsignedCharToFloat() +{ testConversionOperation(config, "-DIN=uchar16 -DOUT=float16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); } -void TestArithmetic::testFloatToSigned() +void TestArithmetic::testFloatToSignedInt() { testConversionOperation(config, "-DIN=float16 -DOUT=int16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testFloatToSignedShort() +{ testConversionOperation(config, "-DIN=float16 -DOUT=short16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testFloatToSignedChar() +{ testConversionOperation(config, "-DIN=float16 -DOUT=char16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); } -void TestArithmetic::testFloatToUnsigned() + +void TestArithmetic::testFloatToUnsignedInt() { testConversionOperation(config, "-DIN=float16 -DOUT=uint16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testFloatToUnsignedShort() +{ testConversionOperation(config, "-DIN=float16 -DOUT=ushort16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); +} + +void TestArithmetic::testFloatToUnsignedChar() +{ testConversionOperation(config, "-DIN=float16 -DOUT=uchar16", convert, std::bind(&TestArithmetic::onMismatch, this, std::placeholders::_1, std::placeholders::_2)); } \ No newline at end of file diff --git a/test/TestArithmetic.h b/test/TestArithmetic.h index f6390861..9b4facbb 100644 --- a/test/TestArithmetic.h +++ b/test/TestArithmetic.h @@ -78,6 +78,12 @@ class TestArithmetic : public Test::Suite void testFloatLessEquals(); // logical operators + void testSignedIntSelection(); + void testSignedShortSelection(); + void testSignedCharSelection(); + void testUnsignedIntSelection(); + void testUnsignedShortSelection(); + void testUnsignedCharSelection(); void testSignedIntAnd(); void testSignedShortAnd(); void testSignedCharAnd(); @@ -96,7 +102,6 @@ class TestArithmetic : public Test::Suite void testSignedNot(); void testUnsignedNot(); void testFloatNot(); - void testSelection(); //XXX vector instructions void testExtractElement(); @@ -108,10 +113,18 @@ class TestArithmetic : public Test::Suite void testUnsignedTruncation(); void testSignExtension(); void testZeroExtension(); - void testSignedToFloat(); - void testUnsignedToFloat(); - void testFloatToSigned(); - void testFloatToUnsigned(); + void testSignedIntToFloat(); + void testSignedShortToFloat(); + void testSignedCharToFloat(); + void testUnsignedIntToFloat(); + void testUnsignedShortToFloat(); + void testUnsignedCharToFloat(); + void testFloatToSignedInt(); + void testFloatToSignedShort(); + void testFloatToSignedChar(); + void testFloatToUnsignedInt(); + void testFloatToUnsignedShort(); + void testFloatToUnsignedChar(); //XXX void testVectorBitcastTruncation4To1(); void testVectorBitcastTruncation2To1();