diff options
Diffstat (limited to 'llvm/unittests')
-rw-r--r-- | llvm/unittests/BinaryFormat/DwarfTest.cpp | 217 | ||||
-rw-r--r-- | llvm/unittests/IR/ConstantFPRangeTest.cpp | 123 | ||||
-rw-r--r-- | llvm/unittests/Support/raw_ostream_test.cpp | 5 |
3 files changed, 309 insertions, 36 deletions
diff --git a/llvm/unittests/BinaryFormat/DwarfTest.cpp b/llvm/unittests/BinaryFormat/DwarfTest.cpp index f4519f6..ba7d591 100644 --- a/llvm/unittests/BinaryFormat/DwarfTest.cpp +++ b/llvm/unittests/BinaryFormat/DwarfTest.cpp @@ -255,41 +255,186 @@ TEST(DwarfTest, lname_SourceLanguageNameString) { #include "llvm/BinaryFormat/Dwarf.def" } -TEST(DWARFDebugInfo, TestLanguageDescription_Versioned) { - // Tests for the llvm::dwarf::LanguageDescription API that - // takes a name *and* a version. - - // Unknown language. - EXPECT_EQ( - llvm::dwarf::LanguageDescription(static_cast<SourceLanguageName>(0)), - "Unknown"); - - EXPECT_EQ( - llvm::dwarf::LanguageDescription(static_cast<SourceLanguageName>(0), 0), - "Unknown"); - - // Test that specifying an invalid version falls back to a valid language name - // regardless. - EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_ObjC, 0), "Objective C"); - EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_Julia, 0), "Julia"); - - // Check some versions. - EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C_plus_plus, 199711), - "C++98"); - EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C_plus_plus, 201402), - "C++14"); - - // Versions round up. - EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C_plus_plus, 201400), - "C++14"); - - // Version 0 for C and C++ is an unversioned name. - EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C, 0), "C (K&R and ISO)"); - EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C_plus_plus, 0), - "ISO C++"); - - // Version 0 for other versioned languages may not be the unversioned name. - EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_Fortran, 0), - "FORTRAN 77"); +struct LanguageDescriptionTestCase { + llvm::dwarf::SourceLanguageName LName; + uint32_t LVersion; + llvm::StringRef ExpectedDescription; +}; + +LanguageDescriptionTestCase LanguageDescriptionTestCases[] = { + {static_cast<SourceLanguageName>(0), 0, "Unknown"}, + {static_cast<SourceLanguageName>(0), 1, "Unknown"}, + {DW_LNAME_Ada, 0, "Ada 83"}, + {DW_LNAME_Ada, 1982, "Ada 83"}, + {DW_LNAME_Ada, 1983, "Ada 83"}, + {DW_LNAME_Ada, 1994, "Ada 95"}, + {DW_LNAME_Ada, 1995, "Ada 95"}, + {DW_LNAME_Ada, 2004, "Ada 2005"}, + {DW_LNAME_Ada, 2005, "Ada 2005"}, + {DW_LNAME_Ada, 2011, "Ada 2012"}, + {DW_LNAME_Ada, 2012, "Ada 2012"}, + {DW_LNAME_Ada, 2013, "ISO Ada"}, + {DW_LNAME_Cobol, 0, "COBOL-74"}, + {DW_LNAME_Cobol, 1973, "COBOL-74"}, + {DW_LNAME_Cobol, 1974, "COBOL-74"}, + {DW_LNAME_Cobol, 1984, "COBOL-85"}, + {DW_LNAME_Cobol, 1985, "COBOL-85"}, + {DW_LNAME_Cobol, 1986, "ISO Cobol"}, + {DW_LNAME_Fortran, 0, "FORTRAN 77"}, + {DW_LNAME_Fortran, 1976, "FORTRAN 77"}, + {DW_LNAME_Fortran, 1977, "FORTRAN 77"}, + {DW_LNAME_Fortran, 1989, "FORTRAN 90"}, + {DW_LNAME_Fortran, 1990, "FORTRAN 90"}, + {DW_LNAME_Fortran, 1994, "Fortran 95"}, + {DW_LNAME_Fortran, 1995, "Fortran 95"}, + {DW_LNAME_Fortran, 2002, "Fortran 2003"}, + {DW_LNAME_Fortran, 2003, "Fortran 2003"}, + {DW_LNAME_Fortran, 2007, "Fortran 2008"}, + {DW_LNAME_Fortran, 2008, "Fortran 2008"}, + {DW_LNAME_Fortran, 2017, "Fortran 2018"}, + {DW_LNAME_Fortran, 2018, "Fortran 2018"}, + {DW_LNAME_Fortran, 2019, "ISO Fortran"}, + {DW_LNAME_C, 0, "C (K&R and ISO)"}, + {DW_LNAME_C, 198911, "C89"}, + {DW_LNAME_C, 198912, "C89"}, + {DW_LNAME_C, 199901, "C99"}, + {DW_LNAME_C, 199902, "C11"}, + {DW_LNAME_C, 201111, "C11"}, + {DW_LNAME_C, 201112, "C11"}, + {DW_LNAME_C, 201201, "C17"}, + {DW_LNAME_C, 201709, "C17"}, + {DW_LNAME_C, 201710, "C17"}, + {DW_LNAME_C, 201711, "C (K&R and ISO)"}, + {DW_LNAME_C_plus_plus, 0, "ISO C++"}, + {DW_LNAME_C_plus_plus, 199710, "C++98"}, + {DW_LNAME_C_plus_plus, 199711, "C++98"}, + {DW_LNAME_C_plus_plus, 199712, "C++03"}, + {DW_LNAME_C_plus_plus, 200310, "C++03"}, + {DW_LNAME_C_plus_plus, 200311, "C++11"}, + {DW_LNAME_C_plus_plus, 201102, "C++11"}, + {DW_LNAME_C_plus_plus, 201103, "C++11"}, + {DW_LNAME_C_plus_plus, 201104, "C++14"}, + {DW_LNAME_C_plus_plus, 201401, "C++14"}, + {DW_LNAME_C_plus_plus, 201402, "C++14"}, + {DW_LNAME_C_plus_plus, 201403, "C++17"}, + {DW_LNAME_C_plus_plus, 201702, "C++17"}, + {DW_LNAME_C_plus_plus, 201703, "C++17"}, + {DW_LNAME_C_plus_plus, 201704, "C++20"}, + {DW_LNAME_C_plus_plus, 202001, "C++20"}, + {DW_LNAME_C_plus_plus, 202002, "C++20"}, + {DW_LNAME_C_plus_plus, 202003, "ISO C++"}, + {DW_LNAME_ObjC_plus_plus, 0, LanguageDescription(DW_LNAME_ObjC_plus_plus)}, + {DW_LNAME_ObjC_plus_plus, 1, LanguageDescription(DW_LNAME_ObjC_plus_plus)}, + {DW_LNAME_ObjC, 0, LanguageDescription(DW_LNAME_ObjC)}, + {DW_LNAME_ObjC, 1, LanguageDescription(DW_LNAME_ObjC)}, + {DW_LNAME_Move, 0, LanguageDescription(DW_LNAME_Move)}, + {DW_LNAME_Move, 1, LanguageDescription(DW_LNAME_Move)}, + {DW_LNAME_SYCL, 0, LanguageDescription(DW_LNAME_SYCL)}, + {DW_LNAME_SYCL, 1, LanguageDescription(DW_LNAME_SYCL)}, + {DW_LNAME_BLISS, 0, LanguageDescription(DW_LNAME_BLISS)}, + {DW_LNAME_BLISS, 1, LanguageDescription(DW_LNAME_BLISS)}, + {DW_LNAME_Crystal, 0, LanguageDescription(DW_LNAME_Crystal)}, + {DW_LNAME_Crystal, 1, LanguageDescription(DW_LNAME_Crystal)}, + {DW_LNAME_D, 0, LanguageDescription(DW_LNAME_D)}, + {DW_LNAME_D, 1, LanguageDescription(DW_LNAME_D)}, + {DW_LNAME_Dylan, 0, LanguageDescription(DW_LNAME_Dylan)}, + {DW_LNAME_Dylan, 1, LanguageDescription(DW_LNAME_Dylan)}, + {DW_LNAME_Go, 0, LanguageDescription(DW_LNAME_Go)}, + {DW_LNAME_Go, 1, LanguageDescription(DW_LNAME_Go)}, + {DW_LNAME_Haskell, 0, LanguageDescription(DW_LNAME_Haskell)}, + {DW_LNAME_Haskell, 1, LanguageDescription(DW_LNAME_Haskell)}, + {DW_LNAME_HLSL, 0, LanguageDescription(DW_LNAME_HLSL)}, + {DW_LNAME_HLSL, 1, LanguageDescription(DW_LNAME_HLSL)}, + {DW_LNAME_Java, 0, LanguageDescription(DW_LNAME_Java)}, + {DW_LNAME_Java, 1, LanguageDescription(DW_LNAME_Java)}, + {DW_LNAME_Julia, 0, LanguageDescription(DW_LNAME_Julia)}, + {DW_LNAME_Julia, 1, LanguageDescription(DW_LNAME_Julia)}, + {DW_LNAME_Kotlin, 0, LanguageDescription(DW_LNAME_Kotlin)}, + {DW_LNAME_Kotlin, 1, LanguageDescription(DW_LNAME_Kotlin)}, + {DW_LNAME_Modula2, 0, LanguageDescription(DW_LNAME_Modula2)}, + {DW_LNAME_Modula2, 1, LanguageDescription(DW_LNAME_Modula2)}, + {DW_LNAME_Modula3, 0, LanguageDescription(DW_LNAME_Modula3)}, + {DW_LNAME_Modula3, 1, LanguageDescription(DW_LNAME_Modula3)}, + {DW_LNAME_OCaml, 0, LanguageDescription(DW_LNAME_OCaml)}, + {DW_LNAME_OCaml, 1, LanguageDescription(DW_LNAME_OCaml)}, + {DW_LNAME_OpenCL_C, 0, LanguageDescription(DW_LNAME_OpenCL_C)}, + {DW_LNAME_OpenCL_C, 1, LanguageDescription(DW_LNAME_OpenCL_C)}, + {DW_LNAME_Pascal, 0, LanguageDescription(DW_LNAME_Pascal)}, + {DW_LNAME_Pascal, 1, LanguageDescription(DW_LNAME_Pascal)}, + {DW_LNAME_PLI, 0, LanguageDescription(DW_LNAME_PLI)}, + {DW_LNAME_PLI, 1, LanguageDescription(DW_LNAME_PLI)}, + {DW_LNAME_Python, 0, LanguageDescription(DW_LNAME_Python)}, + {DW_LNAME_Python, 1, LanguageDescription(DW_LNAME_Python)}, + {DW_LNAME_RenderScript, 0, LanguageDescription(DW_LNAME_RenderScript)}, + {DW_LNAME_RenderScript, 1, LanguageDescription(DW_LNAME_RenderScript)}, + {DW_LNAME_Rust, 0, LanguageDescription(DW_LNAME_Rust)}, + {DW_LNAME_Rust, 1, LanguageDescription(DW_LNAME_Rust)}, + {DW_LNAME_Swift, 0, LanguageDescription(DW_LNAME_Swift)}, + {DW_LNAME_Swift, 1, LanguageDescription(DW_LNAME_Swift)}, + {DW_LNAME_UPC, 0, LanguageDescription(DW_LNAME_UPC)}, + {DW_LNAME_UPC, 1, LanguageDescription(DW_LNAME_UPC)}, + {DW_LNAME_Zig, 0, LanguageDescription(DW_LNAME_Zig)}, + {DW_LNAME_Zig, 1, LanguageDescription(DW_LNAME_Zig)}, + {DW_LNAME_Assembly, 0, LanguageDescription(DW_LNAME_Assembly)}, + {DW_LNAME_Assembly, 1, LanguageDescription(DW_LNAME_Assembly)}, + {DW_LNAME_C_sharp, 0, LanguageDescription(DW_LNAME_C_sharp)}, + {DW_LNAME_C_sharp, 1, LanguageDescription(DW_LNAME_C_sharp)}, + {DW_LNAME_Mojo, 0, LanguageDescription(DW_LNAME_Mojo)}, + {DW_LNAME_Mojo, 1, LanguageDescription(DW_LNAME_Mojo)}, + {DW_LNAME_GLSL, 0, LanguageDescription(DW_LNAME_GLSL)}, + {DW_LNAME_GLSL, 1, LanguageDescription(DW_LNAME_GLSL)}, + {DW_LNAME_GLSL_ES, 0, LanguageDescription(DW_LNAME_GLSL_ES)}, + {DW_LNAME_GLSL_ES, 1, LanguageDescription(DW_LNAME_GLSL_ES)}, + {DW_LNAME_OpenCL_CPP, 0, LanguageDescription(DW_LNAME_OpenCL_CPP)}, + {DW_LNAME_OpenCL_CPP, 1, LanguageDescription(DW_LNAME_OpenCL_CPP)}, + {DW_LNAME_CPP_for_OpenCL, 0, LanguageDescription(DW_LNAME_CPP_for_OpenCL)}, + {DW_LNAME_CPP_for_OpenCL, 1, LanguageDescription(DW_LNAME_CPP_for_OpenCL)}, + {DW_LNAME_Ruby, 0, LanguageDescription(DW_LNAME_Ruby)}, + {DW_LNAME_Ruby, 1, LanguageDescription(DW_LNAME_Ruby)}, + {DW_LNAME_Hylo, 0, LanguageDescription(DW_LNAME_Hylo)}, + {DW_LNAME_Hylo, 1, LanguageDescription(DW_LNAME_Hylo)}, + {DW_LNAME_Metal, 0, LanguageDescription(DW_LNAME_Metal)}, + {DW_LNAME_Metal, 1, LanguageDescription(DW_LNAME_Metal)}}; + +struct LanguageDescriptionTestFixture + : public testing::Test, + public testing::WithParamInterface<LanguageDescriptionTestCase> {}; + +TEST_P(LanguageDescriptionTestFixture, TestLanguageDescription) { + auto [LName, LVersion, ExpectedDescription] = GetParam(); + + // Basic test. + EXPECT_EQ(llvm::dwarf::LanguageDescription(LName, LVersion), + ExpectedDescription); + + // Now do the same test but roundtrip through the DW_LANG_ <-> DW_LNAME_ + // conversion APIs first. + + auto DWLang = llvm::dwarf::toDW_LANG(LName, LVersion); + // Some languages are not 1-to-1 mapped. In which case there's nothing else + // to test. + if (!DWLang) + return; + + std::optional<std::pair<SourceLanguageName, uint32_t>> DWLName = + llvm::dwarf::toDW_LNAME(*DWLang); + + // We are roundtripping, so there definitely should be a mapping back to + // DW_LNAME_. + ASSERT_TRUE(DWLName); + + // There is no official DW_LANG_ code for C++98. So the roundtripping turns it + // into a plain DW_LANG_C_plus_plus. + if (DWLang == DW_LANG_C_plus_plus && LVersion <= 199711) + EXPECT_EQ(llvm::dwarf::LanguageDescription(DWLName->first, DWLName->second), + "ISO C++"); + else + EXPECT_EQ(llvm::dwarf::LanguageDescription(DWLName->first, DWLName->second), + ExpectedDescription); } + +INSTANTIATE_TEST_SUITE_P(LanguageDescriptionTests, + LanguageDescriptionTestFixture, + ::testing::ValuesIn(LanguageDescriptionTestCases)); + } // end namespace diff --git a/llvm/unittests/IR/ConstantFPRangeTest.cpp b/llvm/unittests/IR/ConstantFPRangeTest.cpp index 1436f0f..58a65b9 100644 --- a/llvm/unittests/IR/ConstantFPRangeTest.cpp +++ b/llvm/unittests/IR/ConstantFPRangeTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/ConstantFPRange.h" +#include "llvm/ADT/APFloat.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Operator.h" #include "gtest/gtest.h" @@ -802,4 +803,126 @@ TEST_F(ConstantFPRangeTest, negate) { ConstantFPRange::getNonNaN(APFloat(-2.0), APFloat(3.0))); } +TEST_F(ConstantFPRangeTest, getWithout) { + EXPECT_EQ(Full.getWithoutNaN(), ConstantFPRange::getNonNaN(Sem)); + EXPECT_EQ(NaN.getWithoutNaN(), Empty); + + EXPECT_EQ(NaN.getWithoutInf(), NaN); + EXPECT_EQ(PosInf.getWithoutInf(), Empty); + EXPECT_EQ(NegInf.getWithoutInf(), Empty); + EXPECT_EQ(ConstantFPRange::getNonNaN(Sem).getWithoutInf(), Finite); + EXPECT_EQ(Zero.getWithoutInf(), Zero); + EXPECT_EQ(ConstantFPRange::getNonNaN(APFloat::getInf(Sem, /*Negative=*/true), + APFloat(3.0)) + .getWithoutInf(), + ConstantFPRange::getNonNaN( + APFloat::getLargest(Sem, /*Negative=*/true), APFloat(3.0))); +} + +TEST_F(ConstantFPRangeTest, cast) { + const fltSemantics &F16Sem = APFloat::IEEEhalf(); + const fltSemantics &BF16Sem = APFloat::BFloat(); + const fltSemantics &F32Sem = APFloat::IEEEsingle(); + const fltSemantics &F8NanOnlySem = APFloat::Float8E4M3FN(); + // normal -> normal (exact) + EXPECT_EQ(ConstantFPRange::getNonNaN(APFloat(1.0), APFloat(2.0)).cast(F32Sem), + ConstantFPRange::getNonNaN(APFloat(1.0f), APFloat(2.0f))); + EXPECT_EQ( + ConstantFPRange::getNonNaN(APFloat(-2.0f), APFloat(-1.0f)).cast(Sem), + ConstantFPRange::getNonNaN(APFloat(-2.0), APFloat(-1.0))); + // normal -> normal (inexact) + EXPECT_EQ( + ConstantFPRange::getNonNaN(APFloat(3.141592653589793), + APFloat(6.283185307179586)) + .cast(F32Sem), + ConstantFPRange::getNonNaN(APFloat(3.14159274f), APFloat(6.28318548f))); + // normal -> subnormal + EXPECT_EQ(ConstantFPRange::getNonNaN(APFloat(-5e-8), APFloat(5e-8)) + .cast(F16Sem) + .classify(), + fcSubnormal | fcZero); + // normal -> zero + EXPECT_EQ(ConstantFPRange::getNonNaN( + APFloat::getSmallestNormalized(Sem, /*Negative=*/true), + APFloat::getSmallestNormalized(Sem, /*Negative=*/false)) + .cast(F32Sem) + .classify(), + fcZero); + // normal -> inf + EXPECT_EQ(ConstantFPRange::getNonNaN(APFloat(-65536.0), APFloat(65536.0)) + .cast(F16Sem), + ConstantFPRange::getNonNaN(F16Sem)); + // nan -> qnan + EXPECT_EQ( + ConstantFPRange::getNaNOnly(Sem, /*MayBeQNaN=*/true, /*MayBeSNaN=*/false) + .cast(F32Sem), + ConstantFPRange::getNaNOnly(F32Sem, /*MayBeQNaN=*/true, + /*MayBeSNaN=*/false)); + EXPECT_EQ( + ConstantFPRange::getNaNOnly(Sem, /*MayBeQNaN=*/false, /*MayBeSNaN=*/true) + .cast(F32Sem), + ConstantFPRange::getNaNOnly(F32Sem, /*MayBeQNaN=*/true, + /*MayBeSNaN=*/false)); + EXPECT_EQ( + ConstantFPRange::getNaNOnly(Sem, /*MayBeQNaN=*/true, /*MayBeSNaN=*/true) + .cast(F32Sem), + ConstantFPRange::getNaNOnly(F32Sem, /*MayBeQNaN=*/true, + /*MayBeSNaN=*/false)); + // For BF16 -> F32, signaling bit is still lost. + EXPECT_EQ(ConstantFPRange::getNaNOnly(BF16Sem, /*MayBeQNaN=*/true, + /*MayBeSNaN=*/true) + .cast(F32Sem), + ConstantFPRange::getNaNOnly(F32Sem, /*MayBeQNaN=*/true, + /*MayBeSNaN=*/false)); + // inf -> nan only (return full set for now) + EXPECT_EQ(ConstantFPRange::getNonNaN(APFloat::getInf(Sem, /*Negative=*/true), + APFloat::getInf(Sem, /*Negative=*/false)) + .cast(F8NanOnlySem), + ConstantFPRange::getFull(F8NanOnlySem)); + // other rounding modes + EXPECT_EQ( + ConstantFPRange::getNonNaN(APFloat::getSmallest(Sem, /*Negative=*/true), + APFloat::getSmallest(Sem, /*Negative=*/false)) + .cast(F32Sem, APFloat::rmTowardNegative), + ConstantFPRange::getNonNaN( + APFloat::getSmallest(F32Sem, /*Negative=*/true), + APFloat::getZero(F32Sem, /*Negative=*/false))); + EXPECT_EQ( + ConstantFPRange::getNonNaN(APFloat::getSmallest(Sem, /*Negative=*/true), + APFloat::getSmallest(Sem, /*Negative=*/false)) + .cast(F32Sem, APFloat::rmTowardPositive), + ConstantFPRange::getNonNaN( + APFloat::getZero(F32Sem, /*Negative=*/true), + APFloat::getSmallest(F32Sem, /*Negative=*/false))); + EXPECT_EQ( + ConstantFPRange::getNonNaN( + APFloat::getSmallestNormalized(Sem, /*Negative=*/true), + APFloat::getSmallestNormalized(Sem, /*Negative=*/false)) + .cast(F32Sem, APFloat::rmTowardZero), + ConstantFPRange::getNonNaN(APFloat::getZero(F32Sem, /*Negative=*/true), + APFloat::getZero(F32Sem, /*Negative=*/false))); + + EnumerateValuesInConstantFPRange( + ConstantFPRange::getFull(APFloat::Float8E4M3()), + [&](const APFloat &V) { + bool LosesInfo = false; + + APFloat DoubleV = V; + DoubleV.convert(Sem, APFloat::rmNearestTiesToEven, &LosesInfo); + ConstantFPRange DoubleCR = ConstantFPRange(V).cast(Sem); + EXPECT_TRUE(DoubleCR.contains(DoubleV)) + << "Casting " << V << " to double failed. " << DoubleCR + << " doesn't contain " << DoubleV; + + auto &FP4Sem = APFloat::Float4E2M1FN(); + APFloat FP4V = V; + FP4V.convert(FP4Sem, APFloat::rmNearestTiesToEven, &LosesInfo); + ConstantFPRange FP4CR = ConstantFPRange(V).cast(FP4Sem); + EXPECT_TRUE(FP4CR.contains(FP4V)) + << "Casting " << V << " to FP4E2M1FN failed. " << FP4CR + << " doesn't contain " << FP4V; + }, + /*IgnoreNaNPayload=*/true); +} + } // anonymous namespace diff --git a/llvm/unittests/Support/raw_ostream_test.cpp b/llvm/unittests/Support/raw_ostream_test.cpp index fbeff37..8f9ed41 100644 --- a/llvm/unittests/Support/raw_ostream_test.cpp +++ b/llvm/unittests/Support/raw_ostream_test.cpp @@ -626,6 +626,11 @@ TEST(raw_ostreamTest, writeToDevNull) { EXPECT_TRUE(DevNullIsUsed); } +TEST(raw_ostreamTest, nullStreamZeroBufferSize) { + raw_ostream &NullStream = nulls(); + EXPECT_EQ(NullStream.GetBufferSize(), 0u); +} + TEST(raw_ostreamTest, writeToStdOut) { outs().flush(); testing::internal::CaptureStdout(); |