Importing rustc-1.38.0
diff --git a/src/llvm-project/llvm/unittests/ADT/APFloatTest.cpp b/src/llvm-project/llvm/unittests/ADT/APFloatTest.cpp
index 64053a8..c76347e 100644
--- a/src/llvm-project/llvm/unittests/ADT/APFloatTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/APFloatTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/APFloat.cpp - APFloat unit tests ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -869,6 +868,33 @@
EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble(), "002.05000e+12").convertToDouble());
EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble(), "002.05000e-12").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1e").convertToDouble());
+ EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1e").convertToDouble());
+
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.e").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1.e").convertToDouble());
+ EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1.e").convertToDouble());
+
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble());
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), "+.1e").convertToDouble());
+ EXPECT_EQ(-0.1, APFloat(APFloat::IEEEdouble(), "-.1e").convertToDouble());
+
+ EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "1.1e").convertToDouble());
+ EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "+1.1e").convertToDouble());
+ EXPECT_EQ(-1.1, APFloat(APFloat::IEEEdouble(), "-1.1e").convertToDouble());
+
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e+").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e-").convertToDouble());
+
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble());
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e+").convertToDouble());
+ EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e-").convertToDouble());
+
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e+").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e-").convertToDouble());
+
// These are "carefully selected" to overflow the fast log-base
// calculations in APFloat.cpp
EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "99e99999").isInfinity());
@@ -1166,36 +1192,6 @@
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e"), "Significand has no digits");
}
-TEST(APFloatTest, StringDecimalExponentDeath) {
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1e"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.e"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.1e"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.1e"), "Exponent has no digits");
-
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e+"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e-"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e+"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e-"), "Exponent has no digits");
-
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e+"), "Exponent has no digits");
- EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e-"), "Exponent has no digits");
-}
-
TEST(APFloatTest, StringHexadecimalDeath) {
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x"), "Invalid string");
EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x"), "Invalid string");
diff --git a/src/llvm-project/llvm/unittests/ADT/APIntTest.cpp b/src/llvm-project/llvm/unittests/ADT/APIntTest.cpp
index 8b876f3..4ab79e4 100644
--- a/src/llvm-project/llvm/unittests/ADT/APIntTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/APIntTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/APInt.cpp - APInt unit tests ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -1263,6 +1262,22 @@
EXPECT_EQ(5U, APInt::getBitsNeeded("-10", 10));
EXPECT_EQ(6U, APInt::getBitsNeeded("-19", 10));
EXPECT_EQ(6U, APInt::getBitsNeeded("-20", 10));
+
+ EXPECT_EQ(1U, APInt::getBitsNeeded("-1", 10));
+ EXPECT_EQ(2U, APInt::getBitsNeeded("-2", 10));
+ EXPECT_EQ(3U, APInt::getBitsNeeded("-4", 10));
+ EXPECT_EQ(4U, APInt::getBitsNeeded("-8", 10));
+ EXPECT_EQ(5U, APInt::getBitsNeeded("-16", 10));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("-23", 10));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("-32", 10));
+ EXPECT_EQ(7U, APInt::getBitsNeeded("-64", 10));
+ EXPECT_EQ(8U, APInt::getBitsNeeded("-127", 10));
+ EXPECT_EQ(8U, APInt::getBitsNeeded("-128", 10));
+ EXPECT_EQ(9U, APInt::getBitsNeeded("-255", 10));
+ EXPECT_EQ(9U, APInt::getBitsNeeded("-256", 10));
+ EXPECT_EQ(10U, APInt::getBitsNeeded("-512", 10));
+ EXPECT_EQ(11U, APInt::getBitsNeeded("-1024", 10));
+ EXPECT_EQ(12U, APInt::getBitsNeeded("-1025", 10));
}
TEST(APIntTest, StringBitsNeeded16) {
@@ -2382,6 +2397,42 @@
}
}
+TEST(APIntTest, umul_ov) {
+ const std::pair<uint64_t, uint64_t> Overflows[] = {
+ {0x8000000000000000, 2},
+ {0x5555555555555556, 3},
+ {4294967296, 4294967296},
+ {4294967295, 4294967298},
+ };
+ const std::pair<uint64_t, uint64_t> NonOverflows[] = {
+ {0x7fffffffffffffff, 2},
+ {0x5555555555555555, 3},
+ {4294967295, 4294967297},
+ };
+
+ bool Overflow;
+ for (auto &X : Overflows) {
+ APInt A(64, X.first);
+ APInt B(64, X.second);
+ (void)A.umul_ov(B, Overflow);
+ EXPECT_TRUE(Overflow);
+ }
+ for (auto &X : NonOverflows) {
+ APInt A(64, X.first);
+ APInt B(64, X.second);
+ (void)A.umul_ov(B, Overflow);
+ EXPECT_FALSE(Overflow);
+ }
+
+ for (unsigned Bits = 1; Bits <= 5; ++Bits)
+ for (unsigned A = 0; A != 1u << Bits; ++A)
+ for (unsigned B = 0; B != 1u << Bits; ++B) {
+ APInt C = APInt(Bits, A).umul_ov(APInt(Bits, B), Overflow);
+ APInt D = APInt(2 * Bits, A) * APInt(2 * Bits, B);
+ EXPECT_TRUE(D.getHiBits(Bits).isNullValue() != Overflow);
+ }
+}
+
TEST(APIntTest, SolveQuadraticEquationWrap) {
// Verify that "Solution" is the first non-negative integer that solves
// Ax^2 + Bx + C = "0 or overflow", i.e. that it is a correct solution
@@ -2467,4 +2518,24 @@
Iterate(i);
}
+TEST(APIntTest, MultiplicativeInverseExaustive) {
+ for (unsigned BitWidth = 1; BitWidth <= 16; ++BitWidth) {
+ for (unsigned Value = 0; Value < (1u << BitWidth); ++Value) {
+ APInt V = APInt(BitWidth, Value);
+ APInt MulInv =
+ V.zext(BitWidth + 1)
+ .multiplicativeInverse(APInt::getSignedMinValue(BitWidth + 1))
+ .trunc(BitWidth);
+ APInt One = V * MulInv;
+ if (!V.isNullValue() && V.countTrailingZeros() == 0) {
+ // Multiplicative inverse exists for all odd numbers.
+ EXPECT_TRUE(One.isOneValue());
+ } else {
+ // Multiplicative inverse does not exist for even numbers (and 0).
+ EXPECT_TRUE(MulInv.isNullValue());
+ }
+ }
+ }
+}
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/APSIntTest.cpp b/src/llvm-project/llvm/unittests/ADT/APSIntTest.cpp
index a9b3071..1ad3871 100644
--- a/src/llvm-project/llvm/unittests/ADT/APSIntTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/APSIntTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/APSIntTest.cpp - APSInt unit tests ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -160,4 +159,90 @@
#endif
+TEST(APSIntTest, SignedHighBit) {
+ APSInt False(APInt(1, 0), false);
+ APSInt True(APInt(1, 1), false);
+ APSInt CharMin(APInt(8, 0), false);
+ APSInt CharSmall(APInt(8, 0x13), false);
+ APSInt CharBoundaryUnder(APInt(8, 0x7f), false);
+ APSInt CharBoundaryOver(APInt(8, 0x80), false);
+ APSInt CharLarge(APInt(8, 0xd9), false);
+ APSInt CharMax(APInt(8, 0xff), false);
+
+ EXPECT_FALSE(False.isNegative());
+ EXPECT_TRUE(False.isNonNegative());
+ EXPECT_FALSE(False.isStrictlyPositive());
+
+ EXPECT_TRUE(True.isNegative());
+ EXPECT_FALSE(True.isNonNegative());
+ EXPECT_FALSE(True.isStrictlyPositive());
+
+ EXPECT_FALSE(CharMin.isNegative());
+ EXPECT_TRUE(CharMin.isNonNegative());
+ EXPECT_FALSE(CharMin.isStrictlyPositive());
+
+ EXPECT_FALSE(CharSmall.isNegative());
+ EXPECT_TRUE(CharSmall.isNonNegative());
+ EXPECT_TRUE(CharSmall.isStrictlyPositive());
+
+ EXPECT_FALSE(CharBoundaryUnder.isNegative());
+ EXPECT_TRUE(CharBoundaryUnder.isNonNegative());
+ EXPECT_TRUE(CharBoundaryUnder.isStrictlyPositive());
+
+ EXPECT_TRUE(CharBoundaryOver.isNegative());
+ EXPECT_FALSE(CharBoundaryOver.isNonNegative());
+ EXPECT_FALSE(CharBoundaryOver.isStrictlyPositive());
+
+ EXPECT_TRUE(CharLarge.isNegative());
+ EXPECT_FALSE(CharLarge.isNonNegative());
+ EXPECT_FALSE(CharLarge.isStrictlyPositive());
+
+ EXPECT_TRUE(CharMax.isNegative());
+ EXPECT_FALSE(CharMax.isNonNegative());
+ EXPECT_FALSE(CharMax.isStrictlyPositive());
+}
+
+TEST(APSIntTest, UnsignedHighBit) {
+ APSInt False(APInt(1, 0));
+ APSInt True(APInt(1, 1));
+ APSInt CharMin(APInt(8, 0));
+ APSInt CharSmall(APInt(8, 0x13));
+ APSInt CharBoundaryUnder(APInt(8, 0x7f));
+ APSInt CharBoundaryOver(APInt(8, 0x80));
+ APSInt CharLarge(APInt(8, 0xd9));
+ APSInt CharMax(APInt(8, 0xff));
+
+ EXPECT_FALSE(False.isNegative());
+ EXPECT_TRUE(False.isNonNegative());
+ EXPECT_FALSE(False.isStrictlyPositive());
+
+ EXPECT_FALSE(True.isNegative());
+ EXPECT_TRUE(True.isNonNegative());
+ EXPECT_TRUE(True.isStrictlyPositive());
+
+ EXPECT_FALSE(CharMin.isNegative());
+ EXPECT_TRUE(CharMin.isNonNegative());
+ EXPECT_FALSE(CharMin.isStrictlyPositive());
+
+ EXPECT_FALSE(CharSmall.isNegative());
+ EXPECT_TRUE(CharSmall.isNonNegative());
+ EXPECT_TRUE(CharSmall.isStrictlyPositive());
+
+ EXPECT_FALSE(CharBoundaryUnder.isNegative());
+ EXPECT_TRUE(CharBoundaryUnder.isNonNegative());
+ EXPECT_TRUE(CharBoundaryUnder.isStrictlyPositive());
+
+ EXPECT_FALSE(CharBoundaryOver.isNegative());
+ EXPECT_TRUE(CharBoundaryOver.isNonNegative());
+ EXPECT_TRUE(CharBoundaryOver.isStrictlyPositive());
+
+ EXPECT_FALSE(CharLarge.isNegative());
+ EXPECT_TRUE(CharLarge.isNonNegative());
+ EXPECT_TRUE(CharLarge.isStrictlyPositive());
+
+ EXPECT_FALSE(CharMax.isNegative());
+ EXPECT_TRUE(CharMax.isNonNegative());
+ EXPECT_TRUE(CharMax.isStrictlyPositive());
+}
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/AnyTest.cpp b/src/llvm-project/llvm/unittests/ADT/AnyTest.cpp
index 658f6b6..2ca81bd 100644
--- a/src/llvm-project/llvm/unittests/ADT/AnyTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/AnyTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/AnyTest.cpp - Any tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/ArrayRefTest.cpp b/src/llvm-project/llvm/unittests/ADT/ArrayRefTest.cpp
index e01d212..04b92c0 100644
--- a/src/llvm-project/llvm/unittests/ADT/ArrayRefTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ArrayRefTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/ArrayRefTest.cpp - ArrayRef unit tests -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -34,10 +33,6 @@
// Check that we can't accidentally assign a temporary location to an ArrayRef.
// (Unfortunately we can't make use of the same thing with constructors.)
-//
-// Disable this check under MSVC; even MSVC 2015 isn't inconsistent between
-// std::is_assignable and actually writing such an assignment.
-#if !defined(_MSC_VER)
static_assert(
!std::is_assignable<ArrayRef<int *>&, int *>::value,
"Assigning from single prvalue element");
@@ -50,7 +45,6 @@
static_assert(
!std::is_assignable<ArrayRef<int *>&, std::initializer_list<int *>>::value,
"Assigning from an initializer list");
-#endif
namespace {
@@ -249,4 +243,14 @@
EXPECT_TRUE(AR2.equals(AR2Ref));
}
+TEST(ArrayRefTest, OwningArrayRef) {
+ static const int A1[] = {0, 1};
+ OwningArrayRef<int> A(makeArrayRef(A1));
+ OwningArrayRef<int> B(std::move(A));
+ EXPECT_EQ(A.data(), nullptr);
+}
+
+static_assert(is_trivially_copyable<ArrayRef<int>>::value,
+ "trivially copyable");
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/BitVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/BitVectorTest.cpp
index 84290b3..559dcc5 100644
--- a/src/llvm-project/llvm/unittests/ADT/BitVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/BitVectorTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/BitVectorTest.cpp - BitVector tests --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/BitmaskEnumTest.cpp b/src/llvm-project/llvm/unittests/ADT/BitmaskEnumTest.cpp
index 77635c6..f07e203 100644
--- a/src/llvm-project/llvm/unittests/ADT/BitmaskEnumTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/BitmaskEnumTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/BitmaskEnumTest.cpp - BitmaskEnum unit tests -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp
index 42a07bb..5d034ad 100644
--- a/src/llvm-project/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp
@@ -1,9 +1,8 @@
//=== llvm/unittest/ADT/BreadthFirstIteratorTest.cpp - BFS iterator tests -===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/BumpPtrListTest.cpp b/src/llvm-project/llvm/unittests/ADT/BumpPtrListTest.cpp
index be34a71..ebd0ce2 100644
--- a/src/llvm-project/llvm/unittests/ADT/BumpPtrListTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/BumpPtrListTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/ADT/BumpPtrListTest.cpp - BumpPtrList unit tests ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/CMakeLists.txt b/src/llvm-project/llvm/unittests/ADT/CMakeLists.txt
index 098b6b6..676ce18 100644
--- a/src/llvm-project/llvm/unittests/ADT/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/ADT/CMakeLists.txt
@@ -18,6 +18,7 @@
DenseSetTest.cpp
DepthFirstIteratorTest.cpp
EquivalenceClassesTest.cpp
+ FallibleIteratorTest.cpp
FoldingSet.cpp
FunctionExtrasTest.cpp
FunctionRefTest.cpp
@@ -64,6 +65,7 @@
StringExtrasTest.cpp
StringMapTest.cpp
StringRefTest.cpp
+ StringSetTest.cpp
StringSwitchTest.cpp
TinyPtrVectorTest.cpp
TripleTest.cpp
@@ -71,4 +73,6 @@
VariadicFunctionTest.cpp
)
+target_link_libraries(ADTTests PRIVATE LLVMTestingSupport)
+
add_dependencies(ADTTests intrinsics_gen)
diff --git a/src/llvm-project/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp b/src/llvm-project/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp
index 030fadb..66a67d9 100644
--- a/src/llvm-project/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/DAGDeltaAlgorithmTest.cpp ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/DeltaAlgorithmTest.cpp b/src/llvm-project/llvm/unittests/ADT/DeltaAlgorithmTest.cpp
index 01dc1f3..5e28412 100644
--- a/src/llvm-project/llvm/unittests/ADT/DeltaAlgorithmTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DeltaAlgorithmTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/DeltaAlgorithmTest.cpp ---------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/DenseMapTest.cpp b/src/llvm-project/llvm/unittests/ADT/DenseMapTest.cpp
index ee9c5dd..7e85ce7 100644
--- a/src/llvm-project/llvm/unittests/ADT/DenseMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DenseMapTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/DenseMapMap.cpp - DenseMap unit tests --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -120,17 +119,8 @@
// Lookup tests
EXPECT_FALSE(this->Map.count(this->getKey()));
EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.end());
-#if !defined(_MSC_VER) || defined(__clang__)
EXPECT_EQ(typename TypeParam::mapped_type(),
this->Map.lookup(this->getKey()));
-#else
- // MSVC, at least old versions, cannot parse the typename to disambiguate
- // TypeParam::mapped_type as a type. However, because MSVC doesn't implement
- // two-phase name lookup, it also doesn't require the typename. Deal with
- // this mutual incompatibility through specialized code.
- EXPECT_EQ(TypeParam::mapped_type(),
- this->Map.lookup(this->getKey()));
-#endif
}
// Constant map tests
diff --git a/src/llvm-project/llvm/unittests/ADT/DenseSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/DenseSetTest.cpp
index 7368e2e..e6fe9ca 100644
--- a/src/llvm-project/llvm/unittests/ADT/DenseSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DenseSetTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/DenseSetTest.cpp - DenseSet unit tests --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/DepthFirstIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/DepthFirstIteratorTest.cpp
index 4169cd4..0e3e0e6 100644
--- a/src/llvm-project/llvm/unittests/ADT/DepthFirstIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DepthFirstIteratorTest.cpp
@@ -1,9 +1,8 @@
//=== llvm/unittest/ADT/DepthFirstIteratorTest.cpp - DFS iterator tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/EquivalenceClassesTest.cpp b/src/llvm-project/llvm/unittests/ADT/EquivalenceClassesTest.cpp
index 57d588a..30eab6e 100644
--- a/src/llvm-project/llvm/unittests/ADT/EquivalenceClassesTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/EquivalenceClassesTest.cpp
@@ -1,9 +1,8 @@
//=== llvm/unittest/ADT/EquivalenceClassesTest.cpp - the structure tests --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/FallibleIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/FallibleIteratorTest.cpp
new file mode 100644
index 0000000..d338974
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ADT/FallibleIteratorTest.cpp
@@ -0,0 +1,291 @@
+//===- unittests/ADT/FallibleIteratorTest.cpp - fallible_iterator.h tests -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/fallible_iterator.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "gtest/gtest-spi.h"
+#include "gtest/gtest.h"
+
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+
+using ItemValid = enum { ValidItem, InvalidItem };
+using LinkValid = enum { ValidLink, InvalidLink };
+
+class Item {
+public:
+ Item(ItemValid V) : V(V) {}
+ bool isValid() const { return V == ValidItem; }
+
+private:
+ ItemValid V;
+};
+
+// A utility to mock "bad collections". It supports both invalid items,
+// where the dereference operator may return an Error, and bad links
+// where the inc/dec operations may return an Error.
+// Each element of the mock collection contains a pair of a (possibly broken)
+// item and link.
+using FallibleCollection = std::vector<std::pair<Item, LinkValid>>;
+
+class FallibleCollectionWalker {
+public:
+ FallibleCollectionWalker(FallibleCollection &C, unsigned Idx)
+ : C(C), Idx(Idx) {}
+
+ Item &operator*() { return C[Idx].first; }
+
+ const Item &operator*() const { return C[Idx].first; }
+
+ Error inc() {
+ assert(Idx != C.size() && "Walking off end of (mock) collection");
+ if (C[Idx].second == ValidLink) {
+ ++Idx;
+ return Error::success();
+ }
+ return make_error<StringError>("cant get next object in (mock) collection",
+ inconvertibleErrorCode());
+ }
+
+ Error dec() {
+ assert(Idx != 0 && "Walking off start of (mock) collection");
+ --Idx;
+ if (C[Idx].second == ValidLink)
+ return Error::success();
+ return make_error<StringError>("cant get prev object in (mock) collection",
+ inconvertibleErrorCode());
+ }
+
+ friend bool operator==(const FallibleCollectionWalker &LHS,
+ const FallibleCollectionWalker &RHS) {
+ assert(&LHS.C == &RHS.C && "Comparing iterators across collectionss.");
+ return LHS.Idx == RHS.Idx;
+ }
+
+private:
+ FallibleCollection &C;
+ unsigned Idx;
+};
+
+class FallibleCollectionWalkerWithStructDeref
+ : public FallibleCollectionWalker {
+public:
+ using FallibleCollectionWalker::FallibleCollectionWalker;
+
+ Item *operator->() { return &this->operator*(); }
+
+ const Item *operator->() const { return &this->operator*(); }
+};
+
+class FallibleCollectionWalkerWithFallibleDeref
+ : public FallibleCollectionWalker {
+public:
+ using FallibleCollectionWalker::FallibleCollectionWalker;
+
+ Expected<Item &> operator*() {
+ auto &I = FallibleCollectionWalker::operator*();
+ if (!I.isValid())
+ return make_error<StringError>("bad item", inconvertibleErrorCode());
+ return I;
+ }
+
+ Expected<const Item &> operator*() const {
+ const auto &I = FallibleCollectionWalker::operator*();
+ if (!I.isValid())
+ return make_error<StringError>("bad item", inconvertibleErrorCode());
+ return I;
+ }
+};
+
+TEST(FallibleIteratorTest, BasicSuccess) {
+
+ // Check that a basic use-case involing successful iteration over a
+ // "FallibleCollection" works.
+
+ FallibleCollection C({{ValidItem, ValidLink}, {ValidItem, ValidLink}});
+
+ FallibleCollectionWalker begin(C, 0);
+ FallibleCollectionWalker end(C, 2);
+
+ Error Err = Error::success();
+ for (auto &Elem :
+ make_fallible_range<FallibleCollectionWalker>(begin, end, Err))
+ EXPECT_TRUE(Elem.isValid());
+ cantFail(std::move(Err));
+}
+
+TEST(FallibleIteratorTest, BasicFailure) {
+
+ // Check that a iteration failure (due to the InvalidLink state on element one
+ // of the fallible collection) breaks out of the loop and raises an Error.
+
+ FallibleCollection C({{ValidItem, ValidLink}, {ValidItem, InvalidLink}});
+
+ FallibleCollectionWalker begin(C, 0);
+ FallibleCollectionWalker end(C, 2);
+
+ Error Err = Error::success();
+ for (auto &Elem :
+ make_fallible_range<FallibleCollectionWalker>(begin, end, Err))
+ EXPECT_TRUE(Elem.isValid());
+
+ EXPECT_THAT_ERROR(std::move(Err), Failed()) << "Expected failure value";
+}
+
+TEST(FallibleIteratorTest, NoRedundantErrorCheckOnEarlyExit) {
+
+ // Check that an early return from the loop body does not require a redundant
+ // check of Err.
+
+ FallibleCollection C({{ValidItem, ValidLink}, {ValidItem, ValidLink}});
+
+ FallibleCollectionWalker begin(C, 0);
+ FallibleCollectionWalker end(C, 2);
+
+ Error Err = Error::success();
+ for (auto &Elem :
+ make_fallible_range<FallibleCollectionWalker>(begin, end, Err)) {
+ (void)Elem;
+ return;
+ }
+ // Err not checked, but should be ok because we exit from the loop
+ // body.
+}
+
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(FallibleIteratorTest, RegularLoopExitRequiresErrorCheck) {
+
+ // Check that Err must be checked after a normal (i.e. not early) loop exit
+ // by failing to check and expecting program death (due to the unchecked
+ // error).
+
+ EXPECT_DEATH(
+ {
+ FallibleCollection C({{ValidItem, ValidLink}, {ValidItem, ValidLink}});
+
+ FallibleCollectionWalker begin(C, 0);
+ FallibleCollectionWalker end(C, 2);
+
+ Error Err = Error::success();
+ for (auto &Elem :
+ make_fallible_range<FallibleCollectionWalker>(begin, end, Err))
+ (void)Elem;
+ },
+ "Program aborted due to an unhandled Error:")
+ << "Normal (i.e. not early) loop exit should require an error check";
+}
+#endif
+
+TEST(FallibleIteratorTest, RawIncrementAndDecrementBehavior) {
+
+ // Check the exact behavior of increment / decrement.
+
+ FallibleCollection C({{ValidItem, ValidLink},
+ {ValidItem, InvalidLink},
+ {ValidItem, ValidLink},
+ {ValidItem, InvalidLink}});
+
+ {
+ // One increment from begin succeeds.
+ Error Err = Error::success();
+ auto I = make_fallible_itr(FallibleCollectionWalker(C, 0), Err);
+ ++I;
+ EXPECT_THAT_ERROR(std::move(Err), Succeeded());
+ }
+
+ {
+ // Two increments from begin fail.
+ Error Err = Error::success();
+ auto I = make_fallible_itr(FallibleCollectionWalker(C, 0), Err);
+ ++I;
+ EXPECT_THAT_ERROR(std::move(Err), Succeeded());
+ ++I;
+ EXPECT_THAT_ERROR(std::move(Err), Failed()) << "Expected failure value";
+ }
+
+ {
+ // One decement from element three succeeds.
+ Error Err = Error::success();
+ auto I = make_fallible_itr(FallibleCollectionWalker(C, 3), Err);
+ --I;
+ EXPECT_THAT_ERROR(std::move(Err), Succeeded());
+ }
+
+ {
+ // One decement from element three succeeds.
+ Error Err = Error::success();
+ auto I = make_fallible_itr(FallibleCollectionWalker(C, 3), Err);
+ --I;
+ EXPECT_THAT_ERROR(std::move(Err), Succeeded());
+ --I;
+ EXPECT_THAT_ERROR(std::move(Err), Failed());
+ }
+}
+
+TEST(FallibleIteratorTest, CheckStructDerefOperatorSupport) {
+ // Check that the fallible_iterator wrapper forwards through to the
+ // underlying iterator's structure dereference operator if present.
+
+ FallibleCollection C({{ValidItem, ValidLink},
+ {ValidItem, ValidLink},
+ {InvalidItem, InvalidLink}});
+
+ FallibleCollectionWalkerWithStructDeref begin(C, 0);
+
+ {
+ Error Err = Error::success();
+ auto I = make_fallible_itr(begin, Err);
+ EXPECT_TRUE(I->isValid());
+ cantFail(std::move(Err));
+ }
+
+ {
+ Error Err = Error::success();
+ const auto I = make_fallible_itr(begin, Err);
+ EXPECT_TRUE(I->isValid());
+ cantFail(std::move(Err));
+ }
+}
+
+TEST(FallibleIteratorTest, CheckDerefToExpectedSupport) {
+
+ // Check that the fallible_iterator wrapper forwards value types, in
+ // particular llvm::Expected, correctly.
+
+ FallibleCollection C({{ValidItem, ValidLink},
+ {InvalidItem, ValidLink},
+ {ValidItem, ValidLink}});
+
+ FallibleCollectionWalkerWithFallibleDeref begin(C, 0);
+ FallibleCollectionWalkerWithFallibleDeref end(C, 3);
+
+ Error Err = Error::success();
+ auto I = make_fallible_itr(begin, Err);
+ auto E = make_fallible_end(end);
+
+ Expected<Item> V1 = *I;
+ EXPECT_THAT_ERROR(V1.takeError(), Succeeded());
+ ++I;
+ EXPECT_NE(I, E); // Implicitly check error.
+ Expected<Item> V2 = *I;
+ EXPECT_THAT_ERROR(V2.takeError(), Failed());
+ ++I;
+ EXPECT_NE(I, E); // Implicitly check error.
+ Expected<Item> V3 = *I;
+ EXPECT_THAT_ERROR(V3.takeError(), Succeeded());
+ ++I;
+ EXPECT_EQ(I, E);
+ cantFail(std::move(Err));
+}
+
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/FoldingSet.cpp b/src/llvm-project/llvm/unittests/ADT/FoldingSet.cpp
index f5b1b71..c03353f 100644
--- a/src/llvm-project/llvm/unittests/ADT/FoldingSet.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/FoldingSet.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/FoldingSetTest.cpp -------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ADT/FunctionExtrasTest.cpp b/src/llvm-project/llvm/unittests/ADT/FunctionExtrasTest.cpp
index d85962e..bbbb045 100644
--- a/src/llvm-project/llvm/unittests/ADT/FunctionExtrasTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/FunctionExtrasTest.cpp
@@ -1,9 +1,8 @@
//===- FunctionExtrasTest.cpp - Unit tests for function type erasure ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/FunctionRefTest.cpp b/src/llvm-project/llvm/unittests/ADT/FunctionRefTest.cpp
index b7ef7d7..a599bee 100644
--- a/src/llvm-project/llvm/unittests/ADT/FunctionRefTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/FunctionRefTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/MakeUniqueTest.cpp - make_unique unit tests ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/HashingTest.cpp b/src/llvm-project/llvm/unittests/ADT/HashingTest.cpp
index d96dd7e..66d63d4 100644
--- a/src/llvm-project/llvm/unittests/ADT/HashingTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/HashingTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/HashingTest.cpp ----------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ADT/IListBaseTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListBaseTest.cpp
index 3b8ede8..2983618 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListBaseTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListBaseTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/ADT/IListBaseTest.cpp - ilist_base unit tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/IListIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListIteratorTest.cpp
index 8b2aa62..559e32d 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListIteratorTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/ADT/IListIteratorTest.cpp - ilist_iterator unit tests ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/IListNodeBaseTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListNodeBaseTest.cpp
index 8819ab1..65f85fc 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListNodeBaseTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListNodeBaseTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/ADT/IListNodeBaseTest.cpp - ilist_node_base unit tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/IListNodeTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListNodeTest.cpp
index 51bebc2..cf775eb 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListNodeTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListNodeTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/ADT/IListNodeTest.cpp - ilist_node unit tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/IListSentinelTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListSentinelTest.cpp
index bd60c90..1f4a831 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListSentinelTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListSentinelTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/ADT/IListSentinelTest.cpp - ilist_sentinel unit tests ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/IListTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListTest.cpp
index 0dee4c1..18f6c41 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/ADT/IListTest.cpp - ilist unit tests ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -208,6 +207,12 @@
} // end namespace
namespace llvm {
+// These nodes are stack-allocated for testing purposes, so don't let the ilist
+// own or delete them.
+template <> struct ilist_alloc_traits<NodeWithCallback> {
+ static void deleteNode(NodeWithCallback *) {}
+};
+
template <> struct ilist_callback_traits<NodeWithCallback> {
void addNodeToList(NodeWithCallback *N) { N->IsInList = true; }
void removeNodeFromList(NodeWithCallback *N) { N->IsInList = false; }
@@ -248,6 +253,30 @@
ASSERT_TRUE(N.WasTransferred);
}
+TEST(IListTest, sameListSplice) {
+ NodeWithCallback N1(1);
+ NodeWithCallback N2(2);
+ ASSERT_FALSE(N1.WasTransferred);
+ ASSERT_FALSE(N2.WasTransferred);
+
+ ilist<NodeWithCallback> L1;
+ L1.insert(L1.end(), &N1);
+ L1.insert(L1.end(), &N2);
+ ASSERT_EQ(2u, L1.size());
+ ASSERT_EQ(&N1, &L1.front());
+ ASSERT_FALSE(N1.WasTransferred);
+ ASSERT_FALSE(N2.WasTransferred);
+
+ // Swap the nodes with splice inside the same list. Check that we get the
+ // transfer callback.
+ L1.splice(L1.begin(), L1, std::next(L1.begin()), L1.end());
+ ASSERT_EQ(2u, L1.size());
+ ASSERT_EQ(&N1, &L1.back());
+ ASSERT_EQ(&N2, &L1.front());
+ ASSERT_FALSE(N1.WasTransferred);
+ ASSERT_TRUE(N2.WasTransferred);
+}
+
struct PrivateNode : private ilist_node<PrivateNode> {
friend struct llvm::ilist_detail::NodeAccess;
diff --git a/src/llvm-project/llvm/unittests/ADT/ImmutableListTest.cpp b/src/llvm-project/llvm/unittests/ADT/ImmutableListTest.cpp
index 280cb2e..b0b1e0e 100644
--- a/src/llvm-project/llvm/unittests/ADT/ImmutableListTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ImmutableListTest.cpp
@@ -1,9 +1,8 @@
//===--------- ImmutableListTest.cpp - ImmutableList unit tests --*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. Lee LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -268,4 +267,7 @@
ASSERT_EQ(6, i);
}
+static_assert(is_trivially_copyable<ImmutableList<Wrapper<long>>>::value,
+ "trivially copyable");
+
} // namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/ImmutableMapTest.cpp b/src/llvm-project/llvm/unittests/ADT/ImmutableMapTest.cpp
index 23ca168..fa61816 100644
--- a/src/llvm-project/llvm/unittests/ADT/ImmutableMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ImmutableMapTest.cpp
@@ -1,9 +1,8 @@
//===----------- ImmutableMapTest.cpp - ImmutableMap unit tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/ImmutableSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/ImmutableSetTest.cpp
index 35ac2c1..9fe7a80 100644
--- a/src/llvm-project/llvm/unittests/ADT/ImmutableSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ImmutableSetTest.cpp
@@ -1,9 +1,8 @@
//===----------- ImmutableSetTest.cpp - ImmutableSet unit tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/IntEqClassesTest.cpp b/src/llvm-project/llvm/unittests/ADT/IntEqClassesTest.cpp
index fc908c1..1c15d2c 100644
--- a/src/llvm-project/llvm/unittests/ADT/IntEqClassesTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IntEqClassesTest.cpp
@@ -1,9 +1,8 @@
//===---- ADT/IntEqClassesTest.cpp - IntEqClasses unit tests ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/IntervalMapTest.cpp b/src/llvm-project/llvm/unittests/ADT/IntervalMapTest.cpp
index 513c063..170d152 100644
--- a/src/llvm-project/llvm/unittests/ADT/IntervalMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IntervalMapTest.cpp
@@ -1,9 +1,8 @@
//===---- ADT/IntervalMapTest.cpp - IntervalMap unit tests ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp b/src/llvm-project/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
index 83dc137..c248b04 100644
--- a/src/llvm-project/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/ADT/IntrusiveRefCntPtrTest.cpp ----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/IteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/IteratorTest.cpp
index 902ddfb..f46f109 100644
--- a/src/llvm-project/llvm/unittests/ADT/IteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IteratorTest.cpp
@@ -1,9 +1,8 @@
//===- IteratorTest.cpp - Unit tests for iterator utilities ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/MakeUniqueTest.cpp b/src/llvm-project/llvm/unittests/ADT/MakeUniqueTest.cpp
index 3b4938a..c0c1096 100644
--- a/src/llvm-project/llvm/unittests/ADT/MakeUniqueTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/MakeUniqueTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/MakeUniqueTest.cpp - make_unique unit tests ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/MapVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/MapVectorTest.cpp
index 16e9b5a..b8fdbdd 100644
--- a/src/llvm-project/llvm/unittests/ADT/MapVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/MapVectorTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/ADT/MapVectorTest.cpp - MapVector unit tests ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/MappedIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/MappedIteratorTest.cpp
index d8c48a7..61e45e3 100644
--- a/src/llvm-project/llvm/unittests/ADT/MappedIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/MappedIteratorTest.cpp
@@ -1,9 +1,8 @@
//===------ MappedIteratorTest.cpp - Unit tests for mapped_iterator -------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/OptionalTest.cpp b/src/llvm-project/llvm/unittests/ADT/OptionalTest.cpp
index 20bc9da..1f26c10 100644
--- a/src/llvm-project/llvm/unittests/ADT/OptionalTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/OptionalTest.cpp
@@ -1,17 +1,28 @@
//===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
+#include <array>
+
+
using namespace llvm;
+static_assert(is_trivially_copyable<Optional<int>>::value,
+ "trivially copyable");
+
+static_assert(is_trivially_copyable<Optional<std::array<int, 3>>>::value,
+ "trivially copyable");
+
namespace {
struct NonDefaultConstructible {
@@ -41,6 +52,10 @@
unsigned NonDefaultConstructible::Destructions = 0;
unsigned NonDefaultConstructible::CopyAssignments = 0;
+static_assert(
+ !is_trivially_copyable<Optional<NonDefaultConstructible>>::value,
+ "not trivially copyable");
+
// Test fixture
class OptionalTest : public testing::Test {
};
@@ -199,6 +214,10 @@
};
unsigned MultiArgConstructor::Destructions = 0;
+static_assert(
+ !is_trivially_copyable<Optional<MultiArgConstructor>>::value,
+ "not trivially copyable");
+
TEST_F(OptionalTest, Emplace) {
MultiArgConstructor::ResetCounts();
Optional<MultiArgConstructor> A;
@@ -246,6 +265,9 @@
unsigned MoveOnly::Destructions = 0;
unsigned MoveOnly::MoveAssignments = 0;
+static_assert(!is_trivially_copyable<Optional<MoveOnly>>::value,
+ "not trivially copyable");
+
TEST_F(OptionalTest, MoveOnlyNull) {
MoveOnly::ResetCounts();
Optional<MoveOnly> O;
@@ -347,6 +369,9 @@
unsigned Immovable::Constructions = 0;
unsigned Immovable::Destructions = 0;
+static_assert(!is_trivially_copyable<Optional<Immovable>>::value,
+ "not trivially copyable");
+
TEST_F(OptionalTest, ImmovableEmplace) {
Optional<Immovable> A;
Immovable::ResetCounts();
@@ -518,5 +543,52 @@
CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
}
-} // end anonymous namespace
+struct ComparableAndStreamable {
+ friend bool operator==(ComparableAndStreamable,
+ ComparableAndStreamable) LLVM_ATTRIBUTE_USED {
+ return true;
+ }
+ friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) {
+ return OS << "ComparableAndStreamable";
+ }
+
+ static Optional<ComparableAndStreamable> get() {
+ return ComparableAndStreamable();
+ }
+};
+
+TEST_F(OptionalTest, StreamOperator) {
+ auto to_string = [](Optional<ComparableAndStreamable> O) {
+ SmallString<16> S;
+ raw_svector_ostream OS(S);
+ OS << O;
+ return S;
+ };
+ EXPECT_EQ("ComparableAndStreamable",
+ to_string(ComparableAndStreamable::get()));
+ EXPECT_EQ("None", to_string(None));
+}
+
+struct Comparable {
+ friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED {
+ return true;
+ }
+ static Optional<Comparable> get() { return Comparable(); }
+};
+
+TEST_F(OptionalTest, UseInUnitTests) {
+ // Test that we invoke the streaming operators when pretty-printing values in
+ // EXPECT macros.
+ EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, ComparableAndStreamable::get()),
+ "Expected: llvm::None\n"
+ " Which is: None\n"
+ "To be equal to: ComparableAndStreamable::get()\n"
+ " Which is: ComparableAndStreamable");
+
+ // Test that it is still possible to compare objects which do not have a
+ // custom streaming operator.
+ EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, Comparable::get()), "object");
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/PackedVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/PackedVectorTest.cpp
index 199a670..24df398 100644
--- a/src/llvm-project/llvm/unittests/ADT/PackedVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PackedVectorTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/PackedVectorTest.cpp - PackedVector tests --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/PointerEmbeddedIntTest.cpp b/src/llvm-project/llvm/unittests/ADT/PointerEmbeddedIntTest.cpp
index 695ea12..d24c8b8 100644
--- a/src/llvm-project/llvm/unittests/ADT/PointerEmbeddedIntTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PointerEmbeddedIntTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/PointerEmbeddedIntTest.cpp -----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/PointerIntPairTest.cpp b/src/llvm-project/llvm/unittests/ADT/PointerIntPairTest.cpp
index 985fdba..6b3a4c0 100644
--- a/src/llvm-project/llvm/unittests/ADT/PointerIntPairTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PointerIntPairTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/PointerIntPairTest.cpp - Unit tests --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -62,6 +61,9 @@
Pair2.setPointerAndInt(&s, E::Case3);
EXPECT_EQ(&s, Pair2.getPointer());
EXPECT_EQ(E::Case3, Pair2.getInt());
+
+ static_assert(is_trivially_copyable<PointerIntPair<S *, 2, E>>::value,
+ "trivially copyable");
}
TEST(PointerIntPairTest, DefaultInitialize) {
@@ -97,6 +99,11 @@
EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1,
PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable);
+
+ static_assert(
+ is_trivially_copyable<
+ PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits>>::value,
+ "trivially copyable");
}
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/PointerSumTypeTest.cpp b/src/llvm-project/llvm/unittests/ADT/PointerSumTypeTest.cpp
index a4faea6..fbf59f3 100644
--- a/src/llvm-project/llvm/unittests/ADT/PointerSumTypeTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PointerSumTypeTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/PointerSumTypeTest.cpp ---------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/PointerUnionTest.cpp b/src/llvm-project/llvm/unittests/ADT/PointerUnionTest.cpp
index 360c371..cd6e980 100644
--- a/src/llvm-project/llvm/unittests/ADT/PointerUnionTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PointerUnionTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/PointerUnionTest.cpp - Optional unit tests -------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -69,4 +68,41 @@
EXPECT_EQ(n.get<int *>(), (int *)nullptr);
}
+template<int I> struct alignas(8) Aligned {};
+
+typedef PointerUnion<Aligned<0> *, Aligned<1> *, Aligned<2> *, Aligned<3> *,
+ Aligned<4> *, Aligned<5> *, Aligned<6> *, Aligned<7> *>
+ PU8;
+
+TEST_F(PointerUnionTest, ManyElements) {
+ Aligned<0> a0;
+ Aligned<7> a7;
+
+ PU8 a = &a0;
+ EXPECT_TRUE(a.is<Aligned<0>*>());
+ EXPECT_FALSE(a.is<Aligned<1>*>());
+ EXPECT_FALSE(a.is<Aligned<2>*>());
+ EXPECT_FALSE(a.is<Aligned<3>*>());
+ EXPECT_FALSE(a.is<Aligned<4>*>());
+ EXPECT_FALSE(a.is<Aligned<5>*>());
+ EXPECT_FALSE(a.is<Aligned<6>*>());
+ EXPECT_FALSE(a.is<Aligned<7>*>());
+ EXPECT_EQ(a.dyn_cast<Aligned<0>*>(), &a0);
+ EXPECT_EQ(*a.getAddrOfPtr1(), &a0);
+
+ a = &a7;
+ EXPECT_FALSE(a.is<Aligned<0>*>());
+ EXPECT_FALSE(a.is<Aligned<1>*>());
+ EXPECT_FALSE(a.is<Aligned<2>*>());
+ EXPECT_FALSE(a.is<Aligned<3>*>());
+ EXPECT_FALSE(a.is<Aligned<4>*>());
+ EXPECT_FALSE(a.is<Aligned<5>*>());
+ EXPECT_FALSE(a.is<Aligned<6>*>());
+ EXPECT_TRUE(a.is<Aligned<7>*>());
+ EXPECT_EQ(a.dyn_cast<Aligned<7>*>(), &a7);
+
+ EXPECT_TRUE(a == PU8(&a7));
+ EXPECT_TRUE(a != PU8(&a0));
+}
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/PostOrderIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/PostOrderIteratorTest.cpp
index 20c938e..8e53247 100644
--- a/src/llvm-project/llvm/unittests/ADT/PostOrderIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PostOrderIteratorTest.cpp
@@ -1,9 +1,8 @@
//===- PostOrderIteratorTest.cpp - PostOrderIterator unit tests -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/PostOrderIterator.h"
diff --git a/src/llvm-project/llvm/unittests/ADT/PriorityWorklistTest.cpp b/src/llvm-project/llvm/unittests/ADT/PriorityWorklistTest.cpp
index 040a11f..4dfdd5f 100644
--- a/src/llvm-project/llvm/unittests/ADT/PriorityWorklistTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PriorityWorklistTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/PriorityWorklist.cpp -----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ADT/RangeAdapterTest.cpp b/src/llvm-project/llvm/unittests/ADT/RangeAdapterTest.cpp
index edc1ced..eb18526 100644
--- a/src/llvm-project/llvm/unittests/ADT/RangeAdapterTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/RangeAdapterTest.cpp
@@ -1,9 +1,8 @@
//===- RangeAdapterTest.cpp - Unit tests for range adapters --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/SCCIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/SCCIteratorTest.cpp
index 57a999b..4835095 100644
--- a/src/llvm-project/llvm/unittests/ADT/SCCIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SCCIteratorTest.cpp
@@ -1,9 +1,8 @@
//===----- llvm/unittest/ADT/SCCIteratorTest.cpp - SCCIterator tests ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/STLExtrasTest.cpp b/src/llvm-project/llvm/unittests/ADT/STLExtrasTest.cpp
index e65e71f..8704ddd 100644
--- a/src/llvm-project/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -1,9 +1,8 @@
//===- STLExtrasTest.cpp - Unit tests for STL extras ----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -447,4 +446,37 @@
EXPECT_FALSE(is_splat(V));
}
+TEST(STLExtrasTest, to_address) {
+ int *V1 = new int;
+ EXPECT_EQ(V1, to_address(V1));
+
+ // Check fancy pointer overload for unique_ptr
+ std::unique_ptr<int> V2 = make_unique<int>(0);
+ EXPECT_EQ(V2.get(), to_address(V2));
+
+ V2.reset(V1);
+ EXPECT_EQ(V1, to_address(V2));
+ V2.release();
+
+ // Check fancy pointer overload for shared_ptr
+ std::shared_ptr<int> V3 = std::make_shared<int>(0);
+ std::shared_ptr<int> V4 = V3;
+ EXPECT_EQ(V3.get(), V4.get());
+ EXPECT_EQ(V3.get(), to_address(V3));
+ EXPECT_EQ(V4.get(), to_address(V4));
+
+ V3.reset(V1);
+ EXPECT_EQ(V1, to_address(V3));
+}
+
+TEST(STLExtrasTest, partition_point) {
+ std::vector<int> V = {1, 3, 5, 7, 9};
+
+ // Range version.
+ EXPECT_EQ(V.begin() + 3,
+ partition_point(V, [](unsigned X) { return X < 7; }));
+ EXPECT_EQ(V.begin(), partition_point(V, [](unsigned X) { return X < 1; }));
+ EXPECT_EQ(V.end(), partition_point(V, [](unsigned X) { return X < 50; }));
+}
+
} // namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/ScopeExitTest.cpp b/src/llvm-project/llvm/unittests/ADT/ScopeExitTest.cpp
index ab11dff..1437652 100644
--- a/src/llvm-project/llvm/unittests/ADT/ScopeExitTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ScopeExitTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/ScopeExit.cpp - Scope exit unit tests --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/SequenceTest.cpp b/src/llvm-project/llvm/unittests/ADT/SequenceTest.cpp
index cc82f86..4356bb1 100644
--- a/src/llvm-project/llvm/unittests/ADT/SequenceTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SequenceTest.cpp
@@ -1,9 +1,8 @@
//===- SequenceTest.cpp - Unit tests for a sequence abstraciton -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/SetVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/SetVectorTest.cpp
index b8cac0d..b9fef78 100644
--- a/src/llvm-project/llvm/unittests/ADT/SetVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SetVectorTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/SetVector.cpp ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ADT/SimpleIListTest.cpp b/src/llvm-project/llvm/unittests/ADT/SimpleIListTest.cpp
index a354f33..9b8ffac 100644
--- a/src/llvm-project/llvm/unittests/ADT/SimpleIListTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SimpleIListTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/ADT/SimpleIListTest.cpp - simple_ilist unit tests --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/SmallPtrSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/SmallPtrSetTest.cpp
index 76f9cf7..cff1632 100644
--- a/src/llvm-project/llvm/unittests/ADT/SmallPtrSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SmallPtrSetTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/SmallPtrSetTest.cpp ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ADT/SmallSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/SmallSetTest.cpp
index 3391a5c..8fb78b0 100644
--- a/src/llvm-project/llvm/unittests/ADT/SmallSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SmallSetTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/SmallSetTest.cpp ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ADT/SmallStringTest.cpp b/src/llvm-project/llvm/unittests/ADT/SmallStringTest.cpp
index 995ef8e..6868381 100644
--- a/src/llvm-project/llvm/unittests/ADT/SmallStringTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SmallStringTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/SmallStringTest.cpp ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ADT/SmallVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/SmallVectorTest.cpp
index 9c501bb..dbe4048 100644
--- a/src/llvm-project/llvm/unittests/ADT/SmallVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SmallVectorTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/SmallVectorTest.cpp ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -909,63 +908,69 @@
EmplaceableArg<3> A3(true);
{
SmallVector<Emplaceable, 3> V;
- V.emplace_back();
+ Emplaceable &back = V.emplace_back();
+ EXPECT_TRUE(&back == &V.back());
EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ EXPECT_TRUE(back.State == ES_Emplaced);
+ EXPECT_TRUE(back.A0.State == EAS_Defaulted);
+ EXPECT_TRUE(back.A1.State == EAS_Defaulted);
+ EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+ EXPECT_TRUE(back.A3.State == EAS_Defaulted);
}
{
SmallVector<Emplaceable, 3> V;
- V.emplace_back(std::move(A0));
+ Emplaceable &back = V.emplace_back(std::move(A0));
+ EXPECT_TRUE(&back == &V.back());
EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_RValue);
- EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ EXPECT_TRUE(back.State == ES_Emplaced);
+ EXPECT_TRUE(back.A0.State == EAS_RValue);
+ EXPECT_TRUE(back.A1.State == EAS_Defaulted);
+ EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+ EXPECT_TRUE(back.A3.State == EAS_Defaulted);
}
{
SmallVector<Emplaceable, 3> V;
- V.emplace_back(A0);
+ Emplaceable &back = V.emplace_back(A0);
+ EXPECT_TRUE(&back == &V.back());
EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_LValue);
- EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ EXPECT_TRUE(back.State == ES_Emplaced);
+ EXPECT_TRUE(back.A0.State == EAS_LValue);
+ EXPECT_TRUE(back.A1.State == EAS_Defaulted);
+ EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+ EXPECT_TRUE(back.A3.State == EAS_Defaulted);
}
{
SmallVector<Emplaceable, 3> V;
- V.emplace_back(A0, A1);
+ Emplaceable &back = V.emplace_back(A0, A1);
+ EXPECT_TRUE(&back == &V.back());
EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_LValue);
- EXPECT_TRUE(V.back().A1.State == EAS_LValue);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ EXPECT_TRUE(back.State == ES_Emplaced);
+ EXPECT_TRUE(back.A0.State == EAS_LValue);
+ EXPECT_TRUE(back.A1.State == EAS_LValue);
+ EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+ EXPECT_TRUE(back.A3.State == EAS_Defaulted);
}
{
SmallVector<Emplaceable, 3> V;
- V.emplace_back(std::move(A0), std::move(A1));
+ Emplaceable &back = V.emplace_back(std::move(A0), std::move(A1));
+ EXPECT_TRUE(&back == &V.back());
EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_RValue);
- EXPECT_TRUE(V.back().A1.State == EAS_RValue);
- EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
- EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ EXPECT_TRUE(back.State == ES_Emplaced);
+ EXPECT_TRUE(back.A0.State == EAS_RValue);
+ EXPECT_TRUE(back.A1.State == EAS_RValue);
+ EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+ EXPECT_TRUE(back.A3.State == EAS_Defaulted);
}
{
SmallVector<Emplaceable, 3> V;
- V.emplace_back(std::move(A0), A1, std::move(A2), A3);
+ Emplaceable &back = V.emplace_back(std::move(A0), A1, std::move(A2), A3);
+ EXPECT_TRUE(&back == &V.back());
EXPECT_TRUE(V.size() == 1);
- EXPECT_TRUE(V.back().State == ES_Emplaced);
- EXPECT_TRUE(V.back().A0.State == EAS_RValue);
- EXPECT_TRUE(V.back().A1.State == EAS_LValue);
- EXPECT_TRUE(V.back().A2.State == EAS_RValue);
- EXPECT_TRUE(V.back().A3.State == EAS_LValue);
+ EXPECT_TRUE(back.State == ES_Emplaced);
+ EXPECT_TRUE(back.A0.State == EAS_RValue);
+ EXPECT_TRUE(back.A1.State == EAS_LValue);
+ EXPECT_TRUE(back.A2.State == EAS_RValue);
+ EXPECT_TRUE(back.A3.State == EAS_LValue);
}
{
SmallVector<int, 1> V;
diff --git a/src/llvm-project/llvm/unittests/ADT/SparseBitVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/SparseBitVectorTest.cpp
index 7675dda..db8d58a 100644
--- a/src/llvm-project/llvm/unittests/ADT/SparseBitVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SparseBitVectorTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/SparseBitVectorTest.cpp - SparseBitVector tests --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/SparseMultiSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/SparseMultiSetTest.cpp
index 032990e..54f7bc9 100644
--- a/src/llvm-project/llvm/unittests/ADT/SparseMultiSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SparseMultiSetTest.cpp
@@ -1,9 +1,8 @@
//===------ ADT/SparseSetTest.cpp - SparseSet unit tests - -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/SparseSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/SparseSetTest.cpp
index 4db7a7d..2b065ea 100644
--- a/src/llvm-project/llvm/unittests/ADT/SparseSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SparseSetTest.cpp
@@ -1,9 +1,8 @@
//===------ ADT/SparseSetTest.cpp - SparseSet unit tests - -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/StatisticTest.cpp b/src/llvm-project/llvm/unittests/ADT/StatisticTest.cpp
index 17a5c7f..1b5530f 100644
--- a/src/llvm-project/llvm/unittests/ADT/StatisticTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StatisticTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/StatisticTest.cpp - Statistic unit tests ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/StringExtrasTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringExtrasTest.cpp
index 02a45c3..97c91de 100644
--- a/src/llvm-project/llvm/unittests/ADT/StringExtrasTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StringExtrasTest.cpp
@@ -1,9 +1,8 @@
//===- StringExtrasTest.cpp - Unit tests for String extras ----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/StringMapTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringMapTest.cpp
index a44bbbf..4038d4d 100644
--- a/src/llvm-project/llvm/unittests/ADT/StringMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StringMapTest.cpp
@@ -1,14 +1,12 @@
//===- llvm/unittest/ADT/StringMapMap.cpp - StringMap unit tests ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
#include "gtest/gtest.h"
@@ -285,20 +283,6 @@
EXPECT_EQ(Expected, Keys);
}
-TEST_F(StringMapTest, IterSetKeys) {
- StringSet<> Set;
- Set.insert("A");
- Set.insert("B");
- Set.insert("C");
- Set.insert("D");
-
- auto Keys = to_vector<4>(Set.keys());
- llvm::sort(Keys);
-
- SmallVector<StringRef, 4> Expected = {"A", "B", "C", "D"};
- EXPECT_EQ(Expected, Keys);
-}
-
// Create a non-default constructable value
struct StringMapTestStruct {
StringMapTestStruct(int i) : i(i) {}
diff --git a/src/llvm-project/llvm/unittests/ADT/StringRefTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringRefTest.cpp
index 4087d6c..a45e83c 100644
--- a/src/llvm-project/llvm/unittests/ADT/StringRefTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StringRefTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/StringRefTest.cpp - StringRef unit tests ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -35,10 +34,6 @@
// Check that we can't accidentally assign a temporary std::string to a
// StringRef. (Unfortunately we can't make use of the same thing with
// constructors.)
-//
-// Disable this check under MSVC; even MSVC 2015 isn't consistent between
-// std::is_assignable and actually writing such an assignment.
-#if !defined(_MSC_VER)
static_assert(
!std::is_assignable<StringRef&, std::string>::value,
"Assigning from prvalue std::string");
@@ -57,8 +52,6 @@
static_assert(
std::is_assignable<StringRef&, const char * &>::value,
"Assigning from lvalue C string");
-#endif
-
namespace {
TEST(StringRefTest, Construction) {
@@ -1062,4 +1055,6 @@
EXPECT_EQ(StringRef("Bar"), Strings[1]);
}
+static_assert(is_trivially_copyable<StringRef>::value, "trivially copyable");
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/StringSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringSetTest.cpp
new file mode 100644
index 0000000..17bfa1d
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ADT/StringSetTest.cpp
@@ -0,0 +1,44 @@
+//===- llvm/unittest/ADT/StringSetTest.cpp - StringSet unit tests ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringSet.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace {
+
+// Test fixture
+class StringSetTest : public testing::Test {};
+
+TEST_F(StringSetTest, IterSetKeys) {
+ StringSet<> Set;
+ Set.insert("A");
+ Set.insert("B");
+ Set.insert("C");
+ Set.insert("D");
+
+ auto Keys = to_vector<4>(Set.keys());
+ llvm::sort(Keys);
+
+ SmallVector<StringRef, 4> Expected = {"A", "B", "C", "D"};
+ EXPECT_EQ(Expected, Keys);
+}
+
+TEST_F(StringSetTest, InsertAndCountStringMapEntry) {
+ // Test insert(StringMapEntry) and count(StringMapEntry)
+ // which are required for set_difference(StringSet, StringSet).
+ StringSet<> Set;
+ StringMapEntry<StringRef> *Element = StringMapEntry<StringRef>::Create("A");
+ Set.insert(*Element);
+ size_t Count = Set.count(*Element);
+ size_t Expected = 1;
+ EXPECT_EQ(Expected, Count);
+ Element->Destroy();
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/StringSwitchTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringSwitchTest.cpp
index 62d3a31..2ce6cdc 100644
--- a/src/llvm-project/llvm/unittests/ADT/StringSwitchTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StringSwitchTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/StringSwitchTest.cpp - StringSwitch unit tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/TestGraph.h b/src/llvm-project/llvm/unittests/ADT/TestGraph.h
index 4ddd14c..36d2982 100644
--- a/src/llvm-project/llvm/unittests/ADT/TestGraph.h
+++ b/src/llvm-project/llvm/unittests/ADT/TestGraph.h
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/TestGraph.h - Graph for testing ------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ADT/TinyPtrVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/TinyPtrVectorTest.cpp
index cc14ccc..c8c00d9 100644
--- a/src/llvm-project/llvm/unittests/ADT/TinyPtrVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/TinyPtrVectorTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/TinyPtrVectorTest.cpp ----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ADT/TripleTest.cpp b/src/llvm-project/llvm/unittests/ADT/TripleTest.cpp
index bc7f932..37ebe5d 100644
--- a/src/llvm-project/llvm/unittests/ADT/TripleTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/TripleTest.cpp
@@ -1,9 +1,8 @@
//===----------- Triple.cpp - Triple unit tests ---------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -253,11 +252,11 @@
EXPECT_EQ(Triple::UnknownOS, T.getOS());
EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
- T = Triple("wasm32-unknown-wasi-musl");
+ T = Triple("wasm32-unknown-wasi");
EXPECT_EQ(Triple::wasm32, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::WASI, T.getOS());
- EXPECT_EQ(Triple::Musl, T.getEnvironment());
+ EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
T = Triple("wasm64-unknown-unknown");
EXPECT_EQ(Triple::wasm64, T.getArch());
@@ -265,11 +264,11 @@
EXPECT_EQ(Triple::UnknownOS, T.getOS());
EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
- T = Triple("wasm64-unknown-wasi-musl");
+ T = Triple("wasm64-unknown-wasi");
EXPECT_EQ(Triple::wasm64, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::WASI, T.getOS());
- EXPECT_EQ(Triple::Musl, T.getEnvironment());
+ EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
T = Triple("avr-unknown-unknown");
EXPECT_EQ(Triple::avr, T.getArch());
@@ -553,6 +552,13 @@
EXPECT_EQ(Triple::OpenEmbedded, T.getVendor());
EXPECT_EQ(Triple::Linux, T.getOS());
EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+ EXPECT_TRUE(T.isArch64Bit());
+
+ T = Triple("arm64_32-apple-ios");
+ EXPECT_EQ(Triple::aarch64_32, T.getArch());
+ EXPECT_EQ(Triple::IOS, T.getOS());
+ EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+ EXPECT_TRUE(T.isArch32Bit());
T = Triple("huh");
EXPECT_EQ(Triple::UnknownArch, T.getArch());
@@ -703,6 +709,10 @@
Triple::normalize("i686-linux")); // i686-pc-linux-gnu
EXPECT_EQ("arm-none-unknown-eabi",
Triple::normalize("arm-none-eabi")); // arm-none-eabi
+ EXPECT_EQ("wasm32-unknown-wasi",
+ Triple::normalize("wasm32-wasi")); // wasm32-unknown-wasi
+ EXPECT_EQ("wasm64-unknown-wasi",
+ Triple::normalize("wasm64-wasi")); // wasm64-unknown-wasi
}
TEST(TripleTest, MutateName) {
@@ -866,11 +876,13 @@
EXPECT_FALSE(T.isArch16Bit());
EXPECT_TRUE(T.isArch32Bit());
EXPECT_FALSE(T.isArch64Bit());
+ EXPECT_TRUE(T.isRISCV());
T.setArch(Triple::riscv64);
EXPECT_FALSE(T.isArch16Bit());
EXPECT_FALSE(T.isArch32Bit());
EXPECT_TRUE(T.isArch64Bit());
+ EXPECT_TRUE(T.isRISCV());
}
TEST(TripleTest, BitWidthArchVariants) {
@@ -1227,6 +1239,17 @@
EXPECT_EQ((unsigned)3, Minor);
EXPECT_EQ((unsigned)0, Micro);
EXPECT_TRUE(T.isSimulatorEnvironment());
+ EXPECT_FALSE(T.isMacCatalystEnvironment());
+
+ T = Triple("x86_64-apple-ios13.0-macabi");
+ EXPECT_TRUE(T.isiOS());
+ T.getiOSVersion(Major, Minor, Micro);
+ EXPECT_EQ((unsigned)13, Major);
+ EXPECT_EQ((unsigned)0, Minor);
+ EXPECT_EQ((unsigned)0, Micro);
+ EXPECT_TRUE(T.getEnvironment() == Triple::MacABI);
+ EXPECT_TRUE(T.isMacCatalystEnvironment());
+ EXPECT_FALSE(T.isSimulatorEnvironment());
}
TEST(TripleTest, FileFormat) {
@@ -1247,17 +1270,28 @@
EXPECT_EQ(Triple::Wasm, Triple("wasm32-unknown-unknown").getObjectFormat());
EXPECT_EQ(Triple::Wasm, Triple("wasm64-unknown-unknown").getObjectFormat());
- EXPECT_EQ(Triple::Wasm, Triple("wasm32-unknown-wasi-musl").getObjectFormat());
- EXPECT_EQ(Triple::Wasm, Triple("wasm64-unknown-wasi-musl").getObjectFormat());
+ EXPECT_EQ(Triple::Wasm, Triple("wasm32-wasi").getObjectFormat());
+ EXPECT_EQ(Triple::Wasm, Triple("wasm64-wasi").getObjectFormat());
+ EXPECT_EQ(Triple::Wasm, Triple("wasm32-unknown-wasi").getObjectFormat());
+ EXPECT_EQ(Triple::Wasm, Triple("wasm64-unknown-wasi").getObjectFormat());
EXPECT_EQ(Triple::Wasm,
Triple("wasm32-unknown-unknown-wasm").getObjectFormat());
EXPECT_EQ(Triple::Wasm,
Triple("wasm64-unknown-unknown-wasm").getObjectFormat());
EXPECT_EQ(Triple::Wasm,
- Triple("wasm32-unknown-wasi-musl-wasm").getObjectFormat());
+ Triple("wasm32-wasi-wasm").getObjectFormat());
EXPECT_EQ(Triple::Wasm,
- Triple("wasm64-unknown-wasi-musl-wasm").getObjectFormat());
+ Triple("wasm64-wasi-wasm").getObjectFormat());
+ EXPECT_EQ(Triple::Wasm,
+ Triple("wasm32-unknown-wasi-wasm").getObjectFormat());
+ EXPECT_EQ(Triple::Wasm,
+ Triple("wasm64-unknown-wasi-wasm").getObjectFormat());
+
+ EXPECT_EQ(Triple::XCOFF, Triple("powerpc-ibm-aix").getObjectFormat());
+ EXPECT_EQ(Triple::XCOFF, Triple("powerpc64-ibm-aix").getObjectFormat());
+ EXPECT_EQ(Triple::XCOFF, Triple("powerpc---xcoff").getObjectFormat());
+ EXPECT_EQ(Triple::XCOFF, Triple("powerpc64---xcoff").getObjectFormat());
Triple MSVCNormalized(Triple::normalize("i686-pc-windows-msvc-elf"));
EXPECT_EQ(Triple::ELF, MSVCNormalized.getObjectFormat());
@@ -1277,6 +1311,9 @@
T.setObjectFormat(Triple::MachO);
EXPECT_EQ(Triple::MachO, T.getObjectFormat());
+
+ T.setObjectFormat(Triple::XCOFF);
+ EXPECT_EQ(Triple::XCOFF, T.getObjectFormat());
}
TEST(TripleTest, NormalizeWindows) {
@@ -1321,6 +1358,8 @@
EXPECT_EQ("i686-pc-windows-elf",
Triple::normalize("i686-pc-windows-elf-elf"));
+
+ EXPECT_TRUE(Triple("x86_64-pc-win32").isWindowsMSVCEnvironment());
}
TEST(TripleTest, getARMCPUForArch) {
@@ -1441,6 +1480,10 @@
EXPECT_EQ(Triple::aarch64, T.getArch());
}
{
+ Triple T = Triple("arm64_32");
+ EXPECT_EQ(Triple::aarch64_32, T.getArch());
+ }
+ {
Triple T = Triple("aarch64");
EXPECT_EQ(Triple::aarch64, T.getArch());
}
diff --git a/src/llvm-project/llvm/unittests/ADT/TwineTest.cpp b/src/llvm-project/llvm/unittests/ADT/TwineTest.cpp
index 950eda2..a717036 100644
--- a/src/llvm-project/llvm/unittests/ADT/TwineTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/TwineTest.cpp
@@ -1,9 +1,8 @@
//===- TwineTest.cpp - Twine unit tests -----------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ADT/VariadicFunctionTest.cpp b/src/llvm-project/llvm/unittests/ADT/VariadicFunctionTest.cpp
index 43db648..56cf85a 100644
--- a/src/llvm-project/llvm/unittests/ADT/VariadicFunctionTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/VariadicFunctionTest.cpp
@@ -1,9 +1,8 @@
//===----------- VariadicFunctionTest.cpp - VariadicFunction unit tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/AliasAnalysisTest.cpp b/src/llvm-project/llvm/unittests/Analysis/AliasAnalysisTest.cpp
index 42a4210..80bdcf7 100644
--- a/src/llvm-project/llvm/unittests/Analysis/AliasAnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/AliasAnalysisTest.cpp
@@ -1,9 +1,8 @@
//===--- AliasAnalysisTest.cpp - Mixed TBAA unit tests --------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -86,7 +85,8 @@
bool invalidate(Function &, const PreservedAnalyses &) { return false; }
- AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI) {
CB();
return MayAlias;
}
@@ -167,7 +167,7 @@
// Setup function.
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(C), std::vector<Type *>(), false);
- auto *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ auto *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
auto *BB = BasicBlock::Create(C, "entry", F);
auto IntType = Type::getInt32Ty(C);
auto PtrType = Type::getInt32PtrTy(C);
@@ -175,7 +175,7 @@
auto *Addr = ConstantPointerNull::get(PtrType);
auto *Store1 = new StoreInst(Value, Addr, BB);
- auto *Load1 = new LoadInst(Addr, "load", BB);
+ auto *Load1 = new LoadInst(IntType, Addr, "load", BB);
auto *Add1 = BinaryOperator::CreateAdd(Value, Value, "add", BB);
auto *VAArg1 = new VAArgInst(Addr, PtrType, "vaarg", BB);
auto *CmpXChg1 = new AtomicCmpXchgInst(
diff --git a/src/llvm-project/llvm/unittests/Analysis/AliasSetTrackerTest.cpp b/src/llvm-project/llvm/unittests/Analysis/AliasSetTrackerTest.cpp
index 57d21e2..77a5ac4 100644
--- a/src/llvm-project/llvm/unittests/Analysis/AliasSetTrackerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/AliasSetTrackerTest.cpp
@@ -1,9 +1,8 @@
//=======- AliasSetTrackerTest.cpp - Unit test for the Alias Set Tracker -===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp b/src/llvm-project/llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp
index fc52aff..f69d2d1 100644
--- a/src/llvm-project/llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp
@@ -1,9 +1,8 @@
//===- BasicAliasAnalysisTest.cpp - Unit tests for BasicAA ----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -45,17 +44,19 @@
DominatorTree DT;
AssumptionCache AC;
BasicAAResult BAA;
+ AAQueryInfo AAQI;
TestAnalyses(BasicAATest &Test)
- : DT(*Test.F), AC(*Test.F), BAA(Test.DL, *Test.F, Test.TLI, AC, &DT) {}
+ : DT(*Test.F), AC(*Test.F), BAA(Test.DL, *Test.F, Test.TLI, AC, &DT),
+ AAQI() {}
};
llvm::Optional<TestAnalyses> Analyses;
- BasicAAResult &setupAnalyses() {
+ TestAnalyses &setupAnalyses() {
assert(F);
Analyses.emplace(*this);
- return Analyses->BAA;
+ return Analyses.getValue();
}
public:
@@ -84,15 +85,17 @@
GlobalPtr->setLinkage(GlobalValue::LinkageTypes::InternalLinkage);
GlobalPtr->setInitializer(B.getInt8(0));
- BasicAAResult &BasicAA = setupAnalyses();
+ auto &AllAnalyses = setupAnalyses();
+ BasicAAResult &BasicAA = AllAnalyses.BAA;
+ AAQueryInfo &AAQI = AllAnalyses.AAQI;
ASSERT_EQ(
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::precise(4)),
- MemoryLocation(GlobalPtr, LocationSize::precise(1))),
+ MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
AliasResult::NoAlias);
ASSERT_EQ(
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::upperBound(4)),
- MemoryLocation(GlobalPtr, LocationSize::precise(1))),
+ MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
AliasResult::MayAlias);
}
@@ -109,16 +112,20 @@
Value *ArbitraryI32 = F->arg_begin();
AllocaInst *I8 = B.CreateAlloca(B.getInt8Ty(), B.getInt32(2));
auto *I8AtUncertainOffset =
- cast<GetElementPtrInst>(B.CreateGEP(I8, ArbitraryI32));
+ cast<GetElementPtrInst>(B.CreateGEP(B.getInt8Ty(), I8, ArbitraryI32));
- BasicAAResult &BasicAA = setupAnalyses();
+ auto &AllAnalyses = setupAnalyses();
+ BasicAAResult &BasicAA = AllAnalyses.BAA;
+ AAQueryInfo &AAQI = AllAnalyses.AAQI;
ASSERT_EQ(BasicAA.alias(
MemoryLocation(I8, LocationSize::precise(2)),
- MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1))),
+ MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
+ AAQI),
AliasResult::PartialAlias);
ASSERT_EQ(BasicAA.alias(
MemoryLocation(I8, LocationSize::upperBound(2)),
- MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1))),
+ MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
+ AAQI),
AliasResult::MayAlias);
}
diff --git a/src/llvm-project/llvm/unittests/Analysis/BlockFrequencyInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/BlockFrequencyInfoTest.cpp
index cc05306..2aeba94 100644
--- a/src/llvm-project/llvm/unittests/Analysis/BlockFrequencyInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/BlockFrequencyInfoTest.cpp
@@ -1,13 +1,13 @@
//===- BlockFrequencyInfoTest.cpp - BlockFrequencyInfo unit tests ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/AsmParser/Parser.h"
@@ -91,5 +91,8 @@
EXPECT_EQ(BFI.getBlockFreq(BB3).getFrequency(), BB3Freq);
}
+static_assert(is_trivially_copyable<bfi_detail::BlockMass>::value,
+ "trivially copyable");
+
} // end anonymous namespace
} // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Analysis/BranchProbabilityInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/BranchProbabilityInfoTest.cpp
index 529af5c..0166163 100644
--- a/src/llvm-project/llvm/unittests/Analysis/BranchProbabilityInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/BranchProbabilityInfoTest.cpp
@@ -1,9 +1,8 @@
//===- BranchProbabilityInfoTest.cpp - BranchProbabilityInfo unit tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/CFGTest.cpp b/src/llvm-project/llvm/unittests/Analysis/CFGTest.cpp
index d7f14c3..107bd08 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CFGTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/CFGTest.cpp
@@ -1,13 +1,13 @@
//===- CFGTest.cpp - CFG tests --------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/CFG.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Dominators.h"
@@ -58,24 +58,32 @@
report_fatal_error("@test must have an instruction %A");
if (B == nullptr)
report_fatal_error("@test must have an instruction %B");
+
+ assert(ExclusionSet.empty());
+ for (auto I = F->begin(), E = F->end(); I != E; ++I) {
+ if (I->hasName() && I->getName().startswith("excluded"))
+ ExclusionSet.insert(&*I);
+ }
}
void ExpectPath(bool ExpectedResult) {
static char ID;
class IsPotentiallyReachableTestPass : public FunctionPass {
public:
- IsPotentiallyReachableTestPass(bool ExpectedResult,
- Instruction *A, Instruction *B)
- : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B) {}
+ IsPotentiallyReachableTestPass(bool ExpectedResult, Instruction *A,
+ Instruction *B,
+ SmallPtrSet<BasicBlock *, 4> ExclusionSet)
+ : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B),
+ ExclusionSet(ExclusionSet) {}
- static int initialize() {
- PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass",
- "", &ID, nullptr, true, true);
- PassRegistry::getPassRegistry()->registerPass(*PI, false);
- initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
- initializeDominatorTreeWrapperPassPass(
- *PassRegistry::getPassRegistry());
- return 0;
+ static int initialize() {
+ PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass", "",
+ &ID, nullptr, true, true);
+ PassRegistry::getPassRegistry()->registerPass(*PI, false);
+ initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
+ initializeDominatorTreeWrapperPassPass(
+ *PassRegistry::getPassRegistry());
+ return 0;
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -91,22 +99,26 @@
LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
DominatorTree *DT =
&getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, nullptr),
+ EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, nullptr, nullptr),
ExpectedResult);
- EXPECT_EQ(isPotentiallyReachable(A, B, DT, nullptr), ExpectedResult);
- EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, LI), ExpectedResult);
- EXPECT_EQ(isPotentiallyReachable(A, B, DT, LI), ExpectedResult);
+ EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, DT, nullptr),
+ ExpectedResult);
+ EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, nullptr, LI),
+ ExpectedResult);
+ EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, DT, LI),
+ ExpectedResult);
return false;
}
bool ExpectedResult;
Instruction *A, *B;
+ SmallPtrSet<BasicBlock *, 4> ExclusionSet;
};
static int initialize = IsPotentiallyReachableTestPass::initialize();
(void)initialize;
IsPotentiallyReachableTestPass *P =
- new IsPotentiallyReachableTestPass(ExpectedResult, A, B);
+ new IsPotentiallyReachableTestPass(ExpectedResult, A, B, ExclusionSet);
legacy::PassManager PM;
PM.add(P);
PM.run(*M);
@@ -115,6 +127,7 @@
LLVMContext Context;
std::unique_ptr<Module> M;
Instruction *A, *B;
+ SmallPtrSet<BasicBlock *, 4> ExclusionSet;
};
}
@@ -386,3 +399,109 @@
S[0] = OldBB;
ExpectPath(true);
}
+
+TEST_F(IsPotentiallyReachableTest, UnreachableFromEntryTest) {
+ ParseAssembly("define void @test() {\n"
+ "entry:\n"
+ " %A = bitcast i8 undef to i8\n"
+ " ret void\n"
+ "not.reachable:\n"
+ " %B = bitcast i8 undef to i8\n"
+ " ret void\n"
+ "}");
+ ExpectPath(false);
+}
+
+TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest1) {
+ ParseAssembly("define void @test() {\n"
+ "entry:\n"
+ " ret void\n"
+ "not.reachable.1:\n"
+ " %A = bitcast i8 undef to i8\n"
+ " br label %not.reachable.2\n"
+ "not.reachable.2:\n"
+ " %B = bitcast i8 undef to i8\n"
+ " ret void\n"
+ "}");
+ ExpectPath(true);
+}
+
+TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest2) {
+ ParseAssembly("define void @test() {\n"
+ "entry:\n"
+ " ret void\n"
+ "not.reachable.1:\n"
+ " %B = bitcast i8 undef to i8\n"
+ " br label %not.reachable.2\n"
+ "not.reachable.2:\n"
+ " %A = bitcast i8 undef to i8\n"
+ " ret void\n"
+ "}");
+ ExpectPath(false);
+}
+
+TEST_F(IsPotentiallyReachableTest, SimpleExclusionTest) {
+ ParseAssembly("define void @test() {\n"
+ "entry:\n"
+ " %A = bitcast i8 undef to i8\n"
+ " br label %excluded\n"
+ "excluded:\n"
+ " br label %exit\n"
+ "exit:\n"
+ " %B = bitcast i8 undef to i8\n"
+ " ret void\n"
+ "}");
+ ExpectPath(false);
+}
+
+TEST_F(IsPotentiallyReachableTest, DiamondExcludedTest) {
+ ParseAssembly("declare i1 @switch()\n"
+ "\n"
+ "define void @test() {\n"
+ "entry:\n"
+ " %x = call i1 @switch()\n"
+ " %A = bitcast i8 undef to i8\n"
+ " br i1 %x, label %excluded.1, label %excluded.2\n"
+ "excluded.1:\n"
+ " br label %exit\n"
+ "excluded.2:\n"
+ " br label %exit\n"
+ "exit:\n"
+ " %B = bitcast i8 undef to i8\n"
+ " ret void\n"
+ "}");
+ ExpectPath(false);
+}
+
+TEST_F(IsPotentiallyReachableTest, DiamondOneSideExcludedTest) {
+ ParseAssembly("declare i1 @switch()\n"
+ "\n"
+ "define void @test() {\n"
+ "entry:\n"
+ " %x = call i1 @switch()\n"
+ " %A = bitcast i8 undef to i8\n"
+ " br i1 %x, label %excluded, label %diamond\n"
+ "excluded:\n"
+ " br label %exit\n"
+ "diamond:\n"
+ " br label %exit\n"
+ "exit:\n"
+ " %B = bitcast i8 undef to i8\n"
+ " ret void\n"
+ "}");
+ ExpectPath(true);
+}
+
+TEST_F(IsPotentiallyReachableTest, UnreachableToReachable) {
+ ParseAssembly("define void @test() {\n"
+ "entry:\n"
+ " br label %exit\n"
+ "unreachableblock:\n"
+ " %A = bitcast i8 undef to i8\n"
+ " br label %exit\n"
+ "exit:\n"
+ " %B = bitcast i8 undef to i8\n"
+ " ret void\n"
+ "}");
+ ExpectPath(true);
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp b/src/llvm-project/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
index 60da2bb..f1ed35d 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
@@ -1,9 +1,8 @@
//===- CGSCCPassManagerTest.cpp -------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -1256,26 +1255,30 @@
MPM.run(*M, MAM);
// We run over four SCCs the first time. But then we split an SCC into three.
- // And then we merge those three back into one.
- EXPECT_EQ(4 + 3 + 1, SCCAnalysisRuns);
+ // And then we merge those three back into one. However, this also
+ // invalidates all three SCCs further down in the PO walk.
+ EXPECT_EQ(4 + 3 + 1 + 3, SCCAnalysisRuns);
// The module analysis pass should be run three times.
EXPECT_EQ(3, ModuleAnalysisRuns);
// We run over four SCCs the first time. Then over the two new ones. Then the
// entire module is invalidated causing a full run over all seven. Then we
- // fold three SCCs back to one, and then run over the whole module again.
- EXPECT_EQ(4 + 2 + 7 + 1 + 4, IndirectSCCAnalysisRuns);
- EXPECT_EQ(4 + 2 + 7 + 1 + 4, DoublyIndirectSCCAnalysisRuns);
+ // fold three SCCs back to one, re-compute for it and the two SCCs above it
+ // in the graph, and then run over the whole module again.
+ EXPECT_EQ(4 + 2 + 7 + 1 + 3 + 4, IndirectSCCAnalysisRuns);
+ EXPECT_EQ(4 + 2 + 7 + 1 + 3 + 4, DoublyIndirectSCCAnalysisRuns);
// First we run over all six functions. Then we re-run it over three when we
// split their SCCs. Then we re-run over the whole module. Then we re-run
- // over three functions merged back into a single SCC, and then over the
- // whole module again.
- EXPECT_EQ(6 + 3 + 6 + 3 + 6, FunctionAnalysisRuns);
+ // over three functions merged back into a single SCC, then those three
+ // functions again, the two functions in SCCs above it in the graph, and then
+ // over the whole module again.
+ EXPECT_EQ(6 + 3 + 6 + 3 + 3 + 2 + 6, FunctionAnalysisRuns);
// Re run the function analysis over the entire module, and then re-run it
// over the `(h3, h1, h2)` SCC due to invalidation. Then we re-run it over
// the entire module, then the three functions merged back into a single SCC,
- // and then over the whole module.
- EXPECT_EQ(6 + 3 + 6 + 3 + 6, IndirectFunctionAnalysisRuns);
+ // those three functions again, then the two functions in SCCs above it in
+ // the graph, and then over the whole module.
+ EXPECT_EQ(6 + 3 + 6 + 3 + 3 + 2 + 6, IndirectFunctionAnalysisRuns);
}
}
diff --git a/src/llvm-project/llvm/unittests/Analysis/CMakeLists.txt b/src/llvm-project/llvm/unittests/Analysis/CMakeLists.txt
index 563b48d..a1858d2 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Analysis/CMakeLists.txt
@@ -16,8 +16,9 @@
CFGTest.cpp
CGSCCPassManagerTest.cpp
DivergenceAnalysisTest.cpp
+ DomTreeUpdaterTest.cpp
GlobalsModRefTest.cpp
- ValueLatticeTest.cpp
+ IVDescriptorsTest.cpp
LazyCallGraphTest.cpp
LoopInfoTest.cpp
MemoryBuiltinsTest.cpp
@@ -31,5 +32,7 @@
TargetLibraryInfoTest.cpp
TBAATest.cpp
UnrollAnalyzerTest.cpp
+ ValueLatticeTest.cpp
ValueTrackingTest.cpp
+ VectorUtilsTest.cpp
)
diff --git a/src/llvm-project/llvm/unittests/Analysis/CallGraphTest.cpp b/src/llvm-project/llvm/unittests/Analysis/CallGraphTest.cpp
index 2d4e63f..0060d2c4 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CallGraphTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/CallGraphTest.cpp
@@ -1,9 +1,8 @@
//=======- CallGraphTest.cpp - Unit tests for the CG analysis -------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/CaptureTrackingTest.cpp b/src/llvm-project/llvm/unittests/Analysis/CaptureTrackingTest.cpp
index ee6e010..86a0aa1 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CaptureTrackingTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/CaptureTrackingTest.cpp
@@ -1,9 +1,8 @@
//=======- CaptureTrackingTest.cpp - Unit test for the Capture Tracking ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/DivergenceAnalysisTest.cpp b/src/llvm-project/llvm/unittests/Analysis/DivergenceAnalysisTest.cpp
index 97dbd18..9416e59 100644
--- a/src/llvm-project/llvm/unittests/Analysis/DivergenceAnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/DivergenceAnalysisTest.cpp
@@ -1,9 +1,8 @@
//===- DivergenceAnalysisTest.cpp - DivergenceAnalysis unit tests ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -79,7 +78,7 @@
IntegerType *IntTy = IntegerType::getInt32Ty(Context);
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), {IntTy}, false);
- Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
ReturnInst::Create(Context, nullptr, BB);
diff --git a/src/llvm-project/llvm/unittests/IR/DomTreeUpdaterTest.cpp b/src/llvm-project/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp
similarity index 85%
rename from src/llvm-project/llvm/unittests/IR/DomTreeUpdaterTest.cpp
rename to src/llvm-project/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp
index db2bb80..4a5e2d7 100644
--- a/src/llvm-project/llvm/unittests/IR/DomTreeUpdaterTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp
@@ -1,13 +1,12 @@
-//==- llvm/unittests/IR/DomTreeUpdaterTest.cpp - DomTreeUpdater unit tests ===//
+//===- DomTreeUpdaterTest.cpp - DomTreeUpdater unit tests -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-#include "llvm/IR/DomTreeUpdater.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Constants.h"
@@ -72,8 +71,9 @@
SwitchInst *SI = dyn_cast<SwitchInst>(BB0->getTerminator());
ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst.";
- DTU.insertEdgeRelaxed(BB0, BB0);
- DTU.deleteEdgeRelaxed(BB0, BB0);
+ DTU.applyUpdatesPermissive(
+ {{DominatorTree::Insert, BB0, BB0}, {DominatorTree::Delete, BB0, BB0}});
+ ASSERT_FALSE(DTU.hasPendingUpdates());
// Delete edge bb0 -> bb3 and push the update twice to verify duplicate
// entries are discarded.
@@ -102,13 +102,13 @@
// queued for deletion.
ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
- DTU.applyUpdates(Updates, /*ForceRemoveDuplicates*/ true);
+ DTU.applyUpdatesPermissive(Updates);
ASSERT_FALSE(DTU.hasPendingUpdates());
// Invalid Insert: no edge bb1 -> bb2 after change to bb0.
- DTU.insertEdgeRelaxed(BB1, BB2);
// Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
- DTU.deleteEdgeRelaxed(BB0, BB1);
+ DTU.applyUpdatesPermissive(
+ {{DominatorTree::Insert, BB1, BB2}, {DominatorTree::Delete, BB0, BB1}});
// DTU working with Eager UpdateStrategy does not need to flush.
ASSERT_TRUE(DT.verify());
@@ -183,7 +183,7 @@
EXPECT_EQ(F->begin()->getName(), NewEntry->getName());
EXPECT_TRUE(&F->getEntryBlock() == NewEntry);
- DTU.insertEdgeRelaxed(NewEntry, BB0);
+ DTU.applyUpdates({{DominatorTree::Insert, NewEntry, BB0}});
// Changing the Entry BB requires a full recalculation of DomTree.
DTU.recalculate(*F);
@@ -252,7 +252,7 @@
BasicBlock *BB3 = &*FI++;
// Test discards of self-domination update.
- DTU.deleteEdge(BB0, BB0);
+ DTU.applyUpdatesPermissive({{DominatorTree::Insert, BB0, BB0}});
ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
// Delete edge bb0 -> bb3 and push the update twice to verify duplicate
@@ -275,7 +275,7 @@
// Verify. Updates to DTU must be applied *after* all changes to the CFG
// (including block deletion).
- DTU.applyUpdates(Updates);
+ DTU.applyUpdatesPermissive(Updates);
ASSERT_TRUE(DTU.getDomTree().verify());
// Deletion of a BasicBlock is an immediate event. We remove all uses to the
@@ -359,8 +359,10 @@
// +-> succ
//
// While the final CFG form is functionally identical the updates to
- // DTU are not. In the first case we must have DTU.insertEdge(Pred1, Succ)
- // while in the latter case we must *NOT* have DTU.insertEdge(Pred1, Succ).
+ // DTU are not. In the first case we must have
+ // DTU.applyUpdates({{DominatorTree::Insert, Pred1, Succ}}) while in
+ // the latter case we must *NOT* have
+ // DTU.applyUpdates({{DominatorTree::Insert, Pred1, Succ}}).
// CFG Change: bb0 now only has bb0 -> bb1 and bb0 -> bb3. We are preparing to
// remove bb2.
@@ -380,9 +382,9 @@
BasicBlocks.end());
};
ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(2));
- // Remove bb2 from F. This has to happen before the call to applyUpdates() for
- // DTU to detect there is no longer an edge between bb2 -> bb3. The deleteBB()
- // method converts bb2's TI into "unreachable".
+ // Remove bb2 from F. This has to happen before the call to
+ // applyUpdates() for DTU to detect there is no longer an edge between
+ // bb2 -> bb3. The deleteBB() method converts bb2's TI into "unreachable".
ASSERT_FALSE(isa<UnreachableInst>(BB2->getTerminator()));
EXPECT_FALSE(DTU.isBBPendingDeletion(BB2));
DTU.callbackDeleteBB(BB2, Eraser);
@@ -403,9 +405,9 @@
BranchInst::Create(BB3, BB0);
EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
- // Remove bb1 from F. This has to happen before the call to applyUpdates() for
- // DTU to detect there is no longer an edge between bb1 -> bb3. The deleteBB()
- // method converts bb1's TI into "unreachable".
+ // Remove bb1 from F. This has to happen before the call to
+ // applyUpdates() for DTU to detect there is no longer an edge between
+ // bb1 -> bb3. The deleteBB() method converts bb1's TI into "unreachable".
ASSERT_FALSE(isa<UnreachableInst>(BB1->getTerminator()));
EXPECT_FALSE(DTU.isBBPendingDeletion(BB1));
DTU.callbackDeleteBB(BB1, Eraser);
@@ -413,14 +415,14 @@
ASSERT_TRUE(isa<UnreachableInst>(BB1->getTerminator()));
EXPECT_EQ(BB1->getParent(), F);
- // Update the DTU. In this case we don't call DTU.insertEdge(BB0, BB3) because
- // the edge previously existed at the start of this test when DT was first
- // created.
+ // Update the DTU. In this case we don't submit {DominatorTree::Insert, BB0,
+ // BB3} because the edge previously existed at the start of this test when DT
+ // was first created.
Updates.push_back({DominatorTree::Delete, BB0, BB1});
Updates.push_back({DominatorTree::Delete, BB1, BB3});
// Verify everything.
- DTU.applyUpdates(Updates);
+ DTU.applyUpdatesPermissive(Updates);
ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(2));
DTU.flush();
ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(0));
@@ -468,7 +470,7 @@
BasicBlock *BB2 = &*FI++;
BasicBlock *BB3 = &*FI++;
// Test discards of self-domination update.
- DTU.deleteEdge(BB0, BB0);
+ DTU.applyUpdates({{DominatorTree::Delete, BB0, BB0}});
// Delete edge bb0 -> bb3 and push the update twice to verify duplicate
// entries are discarded.
@@ -505,7 +507,7 @@
// Verify. Updates to DTU must be applied *after* all changes to the CFG
// (including block deletion).
- DTU.applyUpdates(Updates);
+ DTU.applyUpdatesPermissive(Updates);
ASSERT_TRUE(DTU.getDomTree().verify());
ASSERT_TRUE(DTU.hasPendingUpdates());
ASSERT_TRUE(DTU.hasPendingPostDomTreeUpdates());
@@ -559,7 +561,7 @@
// Insert the new edge between new_entry -> bb0. Without this the
// recalculate() call below will not actually recalculate the DT as there
// are no changes pending and no blocks deleted.
- DTU.insertEdge(NewEntry, BB0);
+ DTU.applyUpdates({{DominatorTree::Insert, NewEntry, BB0}});
// Changing the Entry BB requires a full recalculation.
DTU.recalculate(*F);
@@ -644,8 +646,7 @@
SwitchInst *SI = dyn_cast<SwitchInst>(BB0->getTerminator());
ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst.";
- // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
- // entries are discarded.
+ // Delete edge bb0 -> bb3.
std::vector<DominatorTree::UpdateType> Updates;
Updates.reserve(1);
Updates.push_back({DominatorTree::Delete, BB0, BB3});
@@ -690,7 +691,7 @@
++i;
}
- DTU.applyUpdates(Updates);
+ DTU.applyUpdatesPermissive(Updates);
// flush PostDomTree
ASSERT_TRUE(DTU.getPostDomTree().verify());
ASSERT_FALSE(DTU.hasPendingPostDomTreeUpdates());
@@ -725,3 +726,69 @@
DTU.recalculate(*F);
ASSERT_FALSE(DTU.hasPendingDeletedBB());
}
+
+TEST(DomTreeUpdater, LazyUpdateDeduplicationTest) {
+ StringRef FuncName = "f";
+ StringRef ModuleString = R"(
+ define i32 @f() {
+ bb0:
+ br label %bb1
+ bb1:
+ ret i32 1
+ bb2:
+ ret i32 1
+ }
+ )";
+ // Make the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
+ Function *F = M->getFunction(FuncName);
+
+ // Make the DTU.
+ DominatorTree DT(*F);
+ DomTreeUpdater DTU(&DT, nullptr, DomTreeUpdater::UpdateStrategy::Lazy);
+ ASSERT_TRUE(DTU.getDomTree().verify());
+
+ Function::iterator FI = F->begin();
+ BasicBlock *BB0 = &*FI++;
+ BasicBlock *BB1 = &*FI++;
+ BasicBlock *BB2 = &*FI++;
+
+ // CFG Change: remove bb0 -> bb1 and add back bb0 -> bb1.
+ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
+ BB0->getTerminator()->eraseFromParent();
+ BranchInst::Create(BB1, BB0);
+ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
+
+ // Update the DTU and simulate duplicates.
+ DTU.applyUpdatesPermissive({{DominatorTree::Delete, BB0, BB1},
+ {DominatorTree::Delete, BB0, BB1},
+ {DominatorTree::Insert, BB0, BB1},
+ {DominatorTree::Insert, BB0, BB1},
+ {DominatorTree::Insert, BB0, BB1}});
+
+ // The above operations result in a no-op.
+ ASSERT_FALSE(DTU.hasPendingUpdates());
+
+ // Update the DTU. Simulate an invalid update.
+ DTU.applyUpdatesPermissive({{DominatorTree::Delete, BB0, BB1}});
+ ASSERT_FALSE(DTU.hasPendingUpdates());
+
+ // CFG Change: remove bb0 -> bb1.
+ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
+ BB0->getTerminator()->eraseFromParent();
+
+ // Update the DTU and simulate invalid updates.
+ DTU.applyUpdatesPermissive({{DominatorTree::Delete, BB0, BB1},
+ {DominatorTree::Insert, BB0, BB1},
+ {DominatorTree::Delete, BB0, BB1},
+ {DominatorTree::Insert, BB0, BB1},
+ {DominatorTree::Insert, BB0, BB1}});
+ ASSERT_TRUE(DTU.hasPendingUpdates());
+
+ // CFG Change: add bb0 -> bb2.
+ BranchInst::Create(BB2, BB0);
+ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
+ DTU.applyUpdates({{DominatorTree::Insert, BB0, BB2}});
+ ASSERT_TRUE(DTU.getDomTree().verify());
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/GlobalsModRefTest.cpp b/src/llvm-project/llvm/unittests/Analysis/GlobalsModRefTest.cpp
index 323edc2..dfc8e1e 100644
--- a/src/llvm-project/llvm/unittests/Analysis/GlobalsModRefTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/GlobalsModRefTest.cpp
@@ -1,9 +1,8 @@
//===--- GlobalsModRefTest.cpp - Mixed TBAA unit tests --------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/IVDescriptorsTest.cpp b/src/llvm-project/llvm/unittests/Analysis/IVDescriptorsTest.cpp
new file mode 100644
index 0000000..cba45a9
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Analysis/IVDescriptorsTest.cpp
@@ -0,0 +1,100 @@
+//===- IVDescriptorsTest.cpp - IVDescriptors unit tests -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/IVDescriptors.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+/// Build the loop info and scalar evolution for the function and run the Test.
+static void runWithLoopInfoAndSE(
+ Module &M, StringRef FuncName,
+ function_ref<void(Function &F, LoopInfo &LI, ScalarEvolution &SE)> Test) {
+ auto *F = M.getFunction(FuncName);
+ ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
+
+ TargetLibraryInfoImpl TLII;
+ TargetLibraryInfo TLI(TLII);
+ AssumptionCache AC(*F);
+ DominatorTree DT(*F);
+ LoopInfo LI(DT);
+ ScalarEvolution SE(*F, TLI, AC, DT, LI);
+
+ Test(*F, LI, SE);
+}
+
+static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
+ SMDiagnostic Err;
+ std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
+ if (!Mod)
+ Err.print("IVDescriptorsTests", errs());
+ return Mod;
+}
+
+// This tests that IVDescriptors can obtain the induction binary operator for
+// integer induction variables. And hasUnsafeAlgebra() and
+// getUnsafeAlgebraInst() correctly return the expected behavior, i.e. no unsafe
+// algebra.
+TEST(IVDescriptorsTest, LoopWithSingleLatch) {
+ // Parse the module.
+ LLVMContext Context;
+
+ std::unique_ptr<Module> M = parseIR(
+ Context,
+ R"(define void @foo(i32* %A, i32 %ub) {
+entry:
+ br label %for.body
+for.body:
+ %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+ %idxprom = sext i32 %i to i64
+ %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
+ store i32 %i, i32* %arrayidx, align 4
+ %inc = add nsw i32 %i, 1
+ %cmp = icmp slt i32 %inc, %ub
+ br i1 %cmp, label %for.body, label %for.exit
+for.exit:
+ br label %for.end
+for.end:
+ ret void
+})"
+ );
+
+ runWithLoopInfoAndSE(
+ *M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+ Function::iterator FI = F.begin();
+ // First basic block is entry - skip it.
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+ PHINode *Inst_i = dyn_cast<PHINode>(&Header->front());
+ assert(Inst_i->getName() == "i");
+ InductionDescriptor IndDesc;
+ bool IsInductionPHI =
+ InductionDescriptor::isInductionPHI(Inst_i, L, &SE, IndDesc);
+ EXPECT_TRUE(IsInductionPHI);
+ Instruction *Inst_inc = nullptr;
+ BasicBlock::iterator BBI = Header->begin();
+ do {
+ if ((&*BBI)->getName() == "inc")
+ Inst_inc = &*BBI;
+ ++BBI;
+ } while (!Inst_inc);
+ assert(Inst_inc->getName() == "inc");
+ EXPECT_EQ(IndDesc.getInductionBinOp(), Inst_inc);
+ EXPECT_FALSE(IndDesc.hasUnsafeAlgebra());
+ EXPECT_EQ(IndDesc.getUnsafeAlgebraInst(), nullptr);
+ });
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/LazyCallGraphTest.cpp b/src/llvm-project/llvm/unittests/Analysis/LazyCallGraphTest.cpp
index 5e6dd1a..1a7bcc61 100644
--- a/src/llvm-project/llvm/unittests/Analysis/LazyCallGraphTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/LazyCallGraphTest.cpp
@@ -1,9 +1,8 @@
//===- LazyCallGraphTest.cpp - Unit tests for the lazy CG analysis --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -1978,6 +1977,35 @@
EXPECT_TRUE(GRC.isParentOf(FRC));
}
+// Test that a blockaddress that refers to itself creates no new RefSCC
+// connections. https://bugs.llvm.org/show_bug.cgi?id=40722
+TEST(LazyCallGraphTest, HandleBlockAddress2) {
+ LLVMContext Context;
+ std::unique_ptr<Module> M =
+ parseAssembly(Context, "define void @f() {\n"
+ " ret void\n"
+ "}\n"
+ "define void @g(i8** %ptr) {\n"
+ "bb:\n"
+ " store i8* blockaddress(@g, %bb), i8** %ptr\n"
+ " ret void\n"
+ "}\n");
+ LazyCallGraph CG = buildCG(*M);
+
+ CG.buildRefSCCs();
+ auto I = CG.postorder_ref_scc_begin();
+ LazyCallGraph::RefSCC &GRC = *I++;
+ LazyCallGraph::RefSCC &FRC = *I++;
+ EXPECT_EQ(CG.postorder_ref_scc_end(), I);
+
+ LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
+ LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
+ EXPECT_EQ(&FRC, CG.lookupRefSCC(F));
+ EXPECT_EQ(&GRC, CG.lookupRefSCC(G));
+ EXPECT_FALSE(GRC.isParentOf(FRC));
+ EXPECT_FALSE(FRC.isParentOf(GRC));
+}
+
TEST(LazyCallGraphTest, ReplaceNodeFunction) {
LLVMContext Context;
// A graph with several different kinds of edges pointing at a particular
diff --git a/src/llvm-project/llvm/unittests/Analysis/LoopInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/LoopInfoTest.cpp
index 9a59fc8..4f0047f 100644
--- a/src/llvm-project/llvm/unittests/Analysis/LoopInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/LoopInfoTest.cpp
@@ -1,13 +1,16 @@
//===- LoopInfoTest.cpp - LoopInfo unit tests -----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Dominators.h"
#include "llvm/Support/SourceMgr.h"
@@ -27,6 +30,26 @@
Test(*F, LI);
}
+/// Build the loop info and scalar evolution for the function and run the Test.
+static void runWithLoopInfoPlus(
+ Module &M, StringRef FuncName,
+ function_ref<void(Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT)>
+ Test) {
+ auto *F = M.getFunction(FuncName);
+ ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
+
+ TargetLibraryInfoImpl TLII;
+ TargetLibraryInfo TLI(TLII);
+ AssumptionCache AC(*F);
+ DominatorTree DT(*F);
+ LoopInfo LI(DT);
+ ScalarEvolution SE(*F, TLI, AC, DT, LI);
+
+ PostDominatorTree PDT(*F);
+ Test(*F, LI, SE, PDT);
+}
+
static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
const char *ModuleStr) {
SMDiagnostic Err;
@@ -211,3 +234,968 @@
EXPECT_EQ(&L_0_1, ReverseSiblingPreorder[6]);
EXPECT_EQ(&L_0_0, ReverseSiblingPreorder[7]);
}
+
+TEST(LoopInfoTest, CanonicalLoop) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp slt i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp slt i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, LoopWithInverseGuardSuccs) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp sge i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.end, label %for.preheader\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp slt i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, LoopWithSwappedGuardCmp) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp sgt i32 %ub, 0\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp sge i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.exit, label %for.body\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, LoopWithInverseLatchSuccs) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp slt i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp sge i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.exit, label %for.body\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, LoopWithLatchCmpNE) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp slt i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp ne i32 %i, %ub\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, LoopWithGuardCmpSLE) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %ubPlusOne = add i32 %ub, 1\n"
+ " %guardcmp = icmp sle i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp ne i32 %i, %ubPlusOne\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ubPlusOne");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, LoopNonConstantStep) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub, i32 %step) {\n"
+ "entry:\n"
+ " %guardcmp = icmp slt i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = zext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, %step\n"
+ " %cmp = icmp slt i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ EXPECT_EQ(Bounds->getStepValue()->getName(), "step");
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(), Loop::LoopBounds::Direction::Unknown);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, LoopUnsignedBounds) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp ult i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = zext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add i32 %i, 1\n"
+ " %cmp = icmp ult i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_ULT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, DecreasingLoop) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp slt i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ %ub, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = sub nsw i32 %i, 1\n"
+ " %cmp = icmp sgt i32 %inc, 0\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ EXPECT_EQ(Bounds->getInitialIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_EQ(StepValue, nullptr);
+ ConstantInt *FinalIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getFinalIVValue());
+ EXPECT_TRUE(FinalIVValue && FinalIVValue->isZero());
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SGT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Decreasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, CannotFindDirection) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub, i32 %step) {\n"
+ "entry:\n"
+ " %guardcmp = icmp slt i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, %step\n"
+ " %cmp = icmp ne i32 %i, %ub\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(*M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader
+ // - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ EXPECT_EQ(Bounds->getStepValue()->getName(), "step");
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(),
+ ICmpInst::BAD_ICMP_PREDICATE);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Unknown);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, ZextIndVar) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp slt i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %indvars.iv = phi i64 [ 0, %for.preheader ], [ %indvars.iv.next, %for.body ]\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %wide.trip.count = zext i32 %ub to i64\n"
+ " %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count\n"
+ " br i1 %exitcond, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "indvars.iv.next");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "wide.trip.count");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_NE);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "indvars.iv");
+ });
+}
+
+TEST(LoopInfoTest, UnguardedLoop) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp slt i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First basic block is entry - skip it.
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, UnguardedLoopWithControlFlow) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub, i1 %cond) {\n"
+ "entry:\n"
+ " br i1 %cond, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp slt i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, LoopNest) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp slt i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.outer.preheader, label %for.end\n"
+ "for.outer.preheader:\n"
+ " br label %for.outer\n"
+ "for.outer:\n"
+ " %j = phi i32 [ 0, %for.outer.preheader ], [ %inc.outer, %for.outer.latch ]\n"
+ " br i1 %guardcmp, label %for.inner.preheader, label %for.outer.latch\n"
+ "for.inner.preheader:\n"
+ " br label %for.inner\n"
+ "for.inner:\n"
+ " %i = phi i32 [ 0, %for.inner.preheader ], [ %inc, %for.inner ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp slt i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.inner, label %for.inner.exit\n"
+ "for.inner.exit:\n"
+ " br label %for.outer.latch\n"
+ "for.outer.latch:\n"
+ " %inc.outer = add nsw i32 %j, 1\n"
+ " %cmp.outer = icmp slt i32 %inc.outer, %ub\n"
+ " br i1 %cmp.outer, label %for.outer, label %for.outer.exit\n"
+ "for.outer.exit:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.outer.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.outer");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc.outer");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "j");
+
+ // Next two basic blocks are for.outer and for.inner.preheader - skip
+ // them.
+ ++FI;
+ Header = &*(++FI);
+ assert(Header->getName() == "for.inner");
+ L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> InnerBounds = L->getBounds(SE);
+ EXPECT_NE(InnerBounds, None);
+ InitialIVValue =
+ dyn_cast<ConstantInt>(&InnerBounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(InnerBounds->getStepInst().getName(), "inc");
+ StepValue = dyn_cast_or_null<ConstantInt>(InnerBounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(InnerBounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(InnerBounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(InnerBounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ });
+}
+
+TEST(LoopInfoTest, AuxiliaryIV) {
+ const char *ModuleStr =
+ "define void @foo(i32* %A, i32 %ub) {\n"
+ "entry:\n"
+ " %guardcmp = icmp slt i32 0, %ub\n"
+ " br i1 %guardcmp, label %for.preheader, label %for.end\n"
+ "for.preheader:\n"
+ " br label %for.body\n"
+ "for.body:\n"
+ " %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+ " %aux = phi i32 [ 0, %for.preheader ], [ %auxinc, %for.body ]\n"
+ " %loopvariant = phi i32 [ 0, %for.preheader ], [ %loopvariantinc, %for.body ]\n"
+ " %usedoutside = phi i32 [ 0, %for.preheader ], [ %usedoutsideinc, %for.body ]\n"
+ " %mulopcode = phi i32 [ 0, %for.preheader ], [ %mulopcodeinc, %for.body ]\n"
+ " %idxprom = sext i32 %i to i64\n"
+ " %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+ " store i32 %i, i32* %arrayidx, align 4\n"
+ " %mulopcodeinc = mul nsw i32 %mulopcode, 5\n"
+ " %usedoutsideinc = add nsw i32 %usedoutside, 5\n"
+ " %loopvariantinc = add nsw i32 %loopvariant, %i\n"
+ " %auxinc = add nsw i32 %aux, 5\n"
+ " %inc = add nsw i32 %i, 1\n"
+ " %cmp = icmp slt i32 %inc, %ub\n"
+ " br i1 %cmp, label %for.body, label %for.exit\n"
+ "for.exit:\n"
+ " %lcssa = phi i32 [ %usedoutside, %for.body ]\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfoPlus(
+ *M, "foo",
+ [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+ PostDominatorTree &PDT) {
+ Function::iterator FI = F.begin();
+ // First two basic block are entry and for.preheader - skip them.
+ ++FI;
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.body");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+
+ Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+ EXPECT_NE(Bounds, None);
+ ConstantInt *InitialIVValue =
+ dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+ EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+ EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+ ConstantInt *StepValue =
+ dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+ EXPECT_TRUE(StepValue && StepValue->isOne());
+ EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+ EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+ EXPECT_EQ(Bounds->getDirection(),
+ Loop::LoopBounds::Direction::Increasing);
+ EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+ BasicBlock::iterator II = Header->begin();
+ PHINode &Instruction_i = cast<PHINode>(*(II));
+ EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_i, SE));
+ PHINode &Instruction_aux = cast<PHINode>(*(++II));
+ EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_aux, SE));
+ PHINode &Instruction_loopvariant = cast<PHINode>(*(++II));
+ EXPECT_FALSE(
+ L->isAuxiliaryInductionVariable(Instruction_loopvariant, SE));
+ PHINode &Instruction_usedoutside = cast<PHINode>(*(++II));
+ EXPECT_FALSE(
+ L->isAuxiliaryInductionVariable(Instruction_usedoutside, SE));
+ PHINode &Instruction_mulopcode = cast<PHINode>(*(++II));
+ EXPECT_FALSE(
+ L->isAuxiliaryInductionVariable(Instruction_mulopcode, SE));
+ });
+}
+
+// Examine getUniqueExitBlocks/getUniqueNonLatchExitBlocks functions.
+TEST(LoopInfoTest, LoopUniqueExitBlocks) {
+ const char *ModuleStr =
+ "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
+ "define void @foo(i32 %n, i1 %cond) {\n"
+ "entry:\n"
+ " br label %for.cond\n"
+ "for.cond:\n"
+ " %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]\n"
+ " %cmp = icmp slt i32 %i.0, %n\n"
+ " br i1 %cond, label %for.inc, label %for.end1\n"
+ "for.inc:\n"
+ " %inc = add nsw i32 %i.0, 1\n"
+ " br i1 %cmp, label %for.cond, label %for.end2, !llvm.loop !0\n"
+ "for.end1:\n"
+ " br label %for.end\n"
+ "for.end2:\n"
+ " br label %for.end\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n"
+ "!0 = distinct !{!0, !1}\n"
+ "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) {
+ Function::iterator FI = F.begin();
+ // First basic block is entry - skip it.
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.cond");
+ Loop *L = LI.getLoopFor(Header);
+
+ SmallVector<BasicBlock *, 2> Exits;
+ // This loop has 2 unique exits.
+ L->getUniqueExitBlocks(Exits);
+ EXPECT_TRUE(Exits.size() == 2);
+ // And one unique non latch exit.
+ Exits.clear();
+ L->getUniqueNonLatchExitBlocks(Exits);
+ EXPECT_TRUE(Exits.size() == 1);
+ });
+}
+
+// Regression test for getUniqueNonLatchExitBlocks functions.
+// It should detect the exit if it comes from both latch and non-latch blocks.
+TEST(LoopInfoTest, LoopNonLatchUniqueExitBlocks) {
+ const char *ModuleStr =
+ "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
+ "define void @foo(i32 %n, i1 %cond) {\n"
+ "entry:\n"
+ " br label %for.cond\n"
+ "for.cond:\n"
+ " %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]\n"
+ " %cmp = icmp slt i32 %i.0, %n\n"
+ " br i1 %cond, label %for.inc, label %for.end\n"
+ "for.inc:\n"
+ " %inc = add nsw i32 %i.0, 1\n"
+ " br i1 %cmp, label %for.cond, label %for.end, !llvm.loop !0\n"
+ "for.end:\n"
+ " ret void\n"
+ "}\n"
+ "!0 = distinct !{!0, !1}\n"
+ "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n";
+
+ // Parse the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+ runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) {
+ Function::iterator FI = F.begin();
+ // First basic block is entry - skip it.
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.cond");
+ Loop *L = LI.getLoopFor(Header);
+
+ SmallVector<BasicBlock *, 2> Exits;
+ // This loop has 1 unique exit.
+ L->getUniqueExitBlocks(Exits);
+ EXPECT_TRUE(Exits.size() == 1);
+ // And one unique non latch exit.
+ Exits.clear();
+ L->getUniqueNonLatchExitBlocks(Exits);
+ EXPECT_TRUE(Exits.size() == 1);
+ });
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp b/src/llvm-project/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp
index 898ebee..575b7f3 100644
--- a/src/llvm-project/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp
@@ -1,9 +1,8 @@
//===- MemoryBuiltinsTest.cpp - Tests for utilities in MemoryBuiltins.h ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/MemorySSATest.cpp b/src/llvm-project/llvm/unittests/Analysis/MemorySSATest.cpp
index 505e185..bfdf37e 100644
--- a/src/llvm-project/llvm/unittests/Analysis/MemorySSATest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/MemorySSATest.cpp
@@ -1,9 +1,8 @@
//===- MemorySSA.cpp - Unit tests for MemorySSA ---------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/MemorySSA.h"
@@ -93,7 +92,7 @@
MemorySSAUpdater Updater(&MSSA);
// Add the load
B.SetInsertPoint(Merge);
- LoadInst *LoadInst = B.CreateLoad(PointerArg);
+ LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
// MemoryPHI should already exist.
MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
@@ -139,7 +138,7 @@
// Add the load
B.SetInsertPoint(Merge, Merge->begin());
- LoadInst *FirstLoad = B.CreateLoad(PointerArg);
+ LoadInst *FirstLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
// MemoryPHI should not already exist.
MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
@@ -160,14 +159,14 @@
MemoryAccess *LeftStoreAccess = Updater.createMemoryAccessInBB(
LeftStore, nullptr, Left, MemorySSA::Beginning);
Updater.insertDef(cast<MemoryDef>(LeftStoreAccess), false);
- // We don't touch existing loads, so we need to create a new one to get a phi
+
+ // MemoryPHI should exist after adding LeftStore.
+ MP = MSSA.getMemoryAccess(Merge);
+ EXPECT_NE(MP, nullptr);
+
// Add the second load
B.SetInsertPoint(Merge, Merge->begin());
- LoadInst *SecondLoad = B.CreateLoad(PointerArg);
-
- // MemoryPHI should not already exist.
- MP = MSSA.getMemoryAccess(Merge);
- EXPECT_EQ(MP, nullptr);
+ LoadInst *SecondLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
// Create the load memory access
MemoryUse *SecondLoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
@@ -227,13 +226,13 @@
Updater.createMemoryAccessInBB(SI, nullptr, Left, MemorySSA::Beginning);
Updater.insertDef(cast<MemoryDef>(StoreAccess));
+ // MemoryPHI should be created when inserting the def
+ MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
+ EXPECT_NE(MP, nullptr);
+
// Add the load
B.SetInsertPoint(Merge, Merge->begin());
- LoadInst *LoadInst = B.CreateLoad(PointerArg);
-
- // MemoryPHI should not already exist.
- MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
- EXPECT_EQ(MP, nullptr);
+ LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
// Create the load memory acccess
MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
@@ -263,7 +262,7 @@
// Load in left block
B.SetInsertPoint(Left, Left->begin());
- LoadInst *LoadInst1 = B.CreateLoad(PointerArg);
+ LoadInst *LoadInst1 = B.CreateLoad(B.getInt8Ty(), PointerArg);
// Store in merge block
B.SetInsertPoint(Merge, Merge->begin());
B.CreateStore(B.getInt8(16), PointerArg);
@@ -311,7 +310,7 @@
BranchInst::Create(Merge, Left);
BranchInst::Create(Merge, Right);
B.SetInsertPoint(Merge);
- B.CreateLoad(PointerArg);
+ B.CreateLoad(B.getInt8Ty(), PointerArg);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
MemorySSAUpdater Updater(&MSSA);
@@ -347,7 +346,7 @@
BranchInst::Create(Merge, Left);
BranchInst::Create(Merge, Right);
B.SetInsertPoint(Merge);
- auto *MergeLoad = B.CreateLoad(PointerArg);
+ auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
MemorySSAUpdater Updater(&MSSA);
@@ -393,7 +392,7 @@
BranchInst::Create(Merge, Left);
BranchInst::Create(Merge, Right);
B.SetInsertPoint(Merge);
- auto *MergeLoad = B.CreateLoad(PointerArg);
+ auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
MemorySSAUpdater Updater(&MSSA);
@@ -437,7 +436,7 @@
BranchInst::Create(Merge, Left);
BranchInst::Create(Merge, Right);
B.SetInsertPoint(Merge);
- auto *MergeLoad = B.CreateLoad(PointerArg);
+ auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
MemorySSAUpdater Updater(&MSSA);
@@ -491,7 +490,7 @@
BranchInst::Create(Merge, Left);
BranchInst::Create(Merge, Right);
B.SetInsertPoint(Merge);
- LoadInst *LoadInst = B.CreateLoad(PointerArg);
+ LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
@@ -536,7 +535,7 @@
BranchInst::Create(Merge, Left);
BranchInst::Create(Merge, Right);
B.SetInsertPoint(Merge);
- LoadInst *LoadInst = B.CreateLoad(PointerArg);
+ LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
@@ -632,7 +631,7 @@
Type *Int8 = Type::getInt8Ty(C);
Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
Instruction *SI = B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
- Instruction *LI = B.CreateLoad(Alloca);
+ Instruction *LI = B.CreateLoad(Int8, Alloca);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
@@ -716,12 +715,12 @@
B.SetInsertPoint(IfThen);
Instruction *FirstStore = B.CreateStore(Zero, AllocA);
B.CreateStore(Zero, AllocB);
- Instruction *ALoad0 = B.CreateLoad(AllocA, "");
+ Instruction *ALoad0 = B.CreateLoad(Int8, AllocA, "");
Instruction *BStore = B.CreateStore(Zero, AllocB);
// Due to use optimization/etc. we make a store to A, which is removed after
// we build MSSA. This helps keep the test case simple-ish.
Instruction *KillStore = B.CreateStore(Zero, AllocA);
- Instruction *ALoad = B.CreateLoad(AllocA, "");
+ Instruction *ALoad = B.CreateLoad(Int8, AllocA, "");
B.CreateBr(IfEnd);
B.SetInsertPoint(IfEnd);
@@ -772,7 +771,7 @@
Value *AllocA = B.CreateAlloca(Int8, One, "");
Instruction *Store = B.CreateStore(One, AllocA);
- Instruction *Load = B.CreateLoad(AllocA);
+ Instruction *Load = B.CreateLoad(Int8, AllocA);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
@@ -801,7 +800,7 @@
Instruction *SIA = B.CreateStore(ConstantInt::get(Int8, 0), AllocaA);
Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
Instruction *SIB = B.CreateStore(ConstantInt::get(Int8, 0), AllocaB);
- Instruction *LIA = B.CreateLoad(AllocaA);
+ Instruction *LIA = B.CreateLoad(Int8, AllocaA);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
@@ -835,11 +834,11 @@
StoreInst *StoreA0 = B.CreateStore(ConstantInt::get(Int8, 0), A);
StoreInst *StoreB = B.CreateStore(ConstantInt::get(Int8, 0), B_);
- LoadInst *LoadB = B.CreateLoad(B_);
+ LoadInst *LoadB = B.CreateLoad(Int8, B_);
StoreInst *StoreA1 = B.CreateStore(ConstantInt::get(Int8, 4), A);
StoreInst *StoreC = B.CreateStore(ConstantInt::get(Int8, 4), C);
StoreInst *StoreA2 = B.CreateStore(ConstantInt::get(Int8, 4), A);
- LoadInst *LoadC = B.CreateLoad(C);
+ LoadInst *LoadC = B.CreateLoad(Int8, C);
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
@@ -903,7 +902,7 @@
MemorySSA &MSSA = *Analyses->MSSA;
MemorySSAUpdater Updater(&MSSA);
// Create the load memory acccess
- LoadInst *LoadInst = B.CreateLoad(FirstArg);
+ LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), FirstArg);
MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
LoadInst, nullptr, AfterLoopBB, MemorySSA::Beginning));
Updater.insertUse(LoadAccess);
@@ -1011,15 +1010,15 @@
B.CreateStore(ConstantInt::get(Int8, 1), AllocaB);
// Check load from LOE
- LoadInst *LA1 = B.CreateLoad(AllocaA, "");
+ LoadInst *LA1 = B.CreateLoad(Int8, AllocaA, "");
// Check load alias cached for second load
- LoadInst *LA2 = B.CreateLoad(AllocaA, "");
+ LoadInst *LA2 = B.CreateLoad(Int8, AllocaA, "");
B.CreateStore(ConstantInt::get(Int8, 1), AllocaA);
// Check load from store/def
- LoadInst *LA3 = B.CreateLoad(AllocaA, "");
+ LoadInst *LA3 = B.CreateLoad(Int8, AllocaA, "");
// Check load alias cached for second load
- LoadInst *LA4 = B.CreateLoad(AllocaA, "");
+ LoadInst *LA4 = B.CreateLoad(Int8, AllocaA, "");
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
@@ -1104,13 +1103,13 @@
Argument *PointerA = &*ArgIt;
Argument *PointerB = &*(++ArgIt);
B.CreateStore(ConstantInt::get(Int8, 1), PointerB);
- LoadInst *LA1 = B.CreateLoad(PointerA, "");
+ LoadInst *LA1 = B.CreateLoad(Int8, PointerA, "");
B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
- LoadInst *LB1 = B.CreateLoad(PointerB, "");
+ LoadInst *LB1 = B.CreateLoad(Int8, PointerB, "");
B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
- LoadInst *LA2 = B.CreateLoad(PointerA, "");
+ LoadInst *LA2 = B.CreateLoad(Int8, PointerA, "");
B.CreateStore(ConstantInt::get(Int8, 0), PointerB);
- LoadInst *LB2 = B.CreateLoad(PointerB, "");
+ LoadInst *LB2 = B.CreateLoad(Int8, PointerB, "");
setupAnalyses();
MemorySSA &MSSA = *Analyses->MSSA;
@@ -1228,7 +1227,7 @@
B.SetInsertPoint(Entry);
Value *Foo = &*F->arg_begin();
- Value *Bar = B.CreateGEP(Foo, B.getInt64(1), "bar");
+ Value *Bar = B.CreateGEP(B.getInt8Ty(), Foo, B.getInt64(1), "bar");
B.CreateStore(B.getInt8(0), Foo);
B.CreateStore(B.getInt8(0), Bar);
diff --git a/src/llvm-project/llvm/unittests/Analysis/OrderedBasicBlockTest.cpp b/src/llvm-project/llvm/unittests/Analysis/OrderedBasicBlockTest.cpp
index b8b9ff0..4cccb38 100644
--- a/src/llvm-project/llvm/unittests/Analysis/OrderedBasicBlockTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/OrderedBasicBlockTest.cpp
@@ -1,9 +1,8 @@
//===- OrderedBasicBlockTest.cpp - OrderedBasicBlock unit tests -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/OrderedInstructionsTest.cpp b/src/llvm-project/llvm/unittests/Analysis/OrderedInstructionsTest.cpp
index dc1b25b..473fe7f 100644
--- a/src/llvm-project/llvm/unittests/Analysis/OrderedInstructionsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/OrderedInstructionsTest.cpp
@@ -1,9 +1,8 @@
//===- OrderedInstructions.cpp - Unit tests for OrderedInstructions ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -26,7 +25,7 @@
IRBuilder<> B(Ctx);
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Ctx), {B.getInt8PtrTy()}, false);
- Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
// Create the function as follow and check for dominance relation.
//
@@ -45,13 +44,13 @@
BasicBlock *BBX = BasicBlock::Create(Ctx, "bbx", F);
B.SetInsertPoint(BBX);
Argument *PointerArg = &*F->arg_begin();
- LoadInst *LoadInstX = B.CreateLoad(PointerArg);
- LoadInst *LoadInstY = B.CreateLoad(PointerArg);
+ LoadInst *LoadInstX = B.CreateLoad(B.getInt8Ty(), PointerArg);
+ LoadInst *LoadInstY = B.CreateLoad(B.getInt8Ty(), PointerArg);
// Create BBY with 1 load.
BasicBlock *BBY = BasicBlock::Create(Ctx, "bby", F);
B.SetInsertPoint(BBY);
- LoadInst *LoadInstZ = B.CreateLoad(PointerArg);
+ LoadInst *LoadInstZ = B.CreateLoad(B.getInt8Ty(), PointerArg);
B.CreateRet(LoadInstZ);
std::unique_ptr<DominatorTree> DT(new DominatorTree(*F));
OrderedInstructions OI(&*DT);
diff --git a/src/llvm-project/llvm/unittests/Analysis/PhiValuesTest.cpp b/src/llvm-project/llvm/unittests/Analysis/PhiValuesTest.cpp
index 303b0df..82c0233 100644
--- a/src/llvm-project/llvm/unittests/Analysis/PhiValuesTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/PhiValuesTest.cpp
@@ -1,9 +1,8 @@
//===- PhiValuesTest.cpp - PhiValues unit tests ---------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -27,7 +26,8 @@
Type *I32PtrTy = Type::getInt32PtrTy(C);
// Create a function with phis that do not have other phis as incoming values
- Function *F = cast<Function>(M.getOrInsertFunction("f", FunctionType::get(VoidTy, false)));
+ Function *F = Function::Create(FunctionType::get(VoidTy, false),
+ Function::ExternalLinkage, "f", M);
BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
BasicBlock *If = BasicBlock::Create(C, "if", F);
@@ -37,10 +37,10 @@
BranchInst::Create(Then, If);
BranchInst::Create(Then, Else);
- Value *Val1 = new LoadInst(UndefValue::get(I32PtrTy), "val1", Entry);
- Value *Val2 = new LoadInst(UndefValue::get(I32PtrTy), "val2", Entry);
- Value *Val3 = new LoadInst(UndefValue::get(I32PtrTy), "val3", Entry);
- Value *Val4 = new LoadInst(UndefValue::get(I32PtrTy), "val4", Entry);
+ Value *Val1 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val1", Entry);
+ Value *Val2 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val2", Entry);
+ Value *Val3 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val3", Entry);
+ Value *Val4 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val4", Entry);
PHINode *Phi1 = PHINode::Create(I32Ty, 2, "phi1", Then);
Phi1->addIncoming(Val1, If);
@@ -93,7 +93,8 @@
Type *I32PtrTy = Type::getInt32PtrTy(C);
// Create a function with a phi that has another phi as an incoming value
- Function *F = cast<Function>(M.getOrInsertFunction("f", FunctionType::get(VoidTy, false)));
+ Function *F = Function::Create(FunctionType::get(VoidTy, false),
+ Function::ExternalLinkage, "f", M);
BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
BasicBlock *If1 = BasicBlock::Create(C, "if1", F);
@@ -109,10 +110,10 @@
BranchInst::Create(End, If2);
BranchInst::Create(End, Else2);
- Value *Val1 = new LoadInst(UndefValue::get(I32PtrTy), "val1", Entry);
- Value *Val2 = new LoadInst(UndefValue::get(I32PtrTy), "val2", Entry);
- Value *Val3 = new LoadInst(UndefValue::get(I32PtrTy), "val3", Entry);
- Value *Val4 = new LoadInst(UndefValue::get(I32PtrTy), "val4", Entry);
+ Value *Val1 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val1", Entry);
+ Value *Val2 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val2", Entry);
+ Value *Val3 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val3", Entry);
+ Value *Val4 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val4", Entry);
PHINode *Phi1 = PHINode::Create(I32Ty, 2, "phi1", Then);
Phi1->addIncoming(Val1, If1);
diff --git a/src/llvm-project/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
index 95d8426..002901d 100644
--- a/src/llvm-project/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
@@ -1,9 +1,8 @@
//===- ProfileSummaryInfoTest.cpp - ProfileSummaryInfo unit tests ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/src/llvm-project/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 3da0614bb..fb8f668 100644
--- a/src/llvm-project/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1,9 +1,8 @@
//===- ScalarEvolutionsTest.cpp - ScalarEvolution unit tests --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -64,7 +63,7 @@
TEST_F(ScalarEvolutionsTest, SCEVUnknownRAUW) {
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
std::vector<Type *>(), false);
- Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
ReturnInst::Create(Context, nullptr, BB);
@@ -113,7 +112,7 @@
TEST_F(ScalarEvolutionsTest, SimplifiedPHI) {
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
std::vector<Type *>(), false);
- Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
@@ -147,7 +146,7 @@
auto *I32PtrTy = Type::getInt32PtrTy(Context);
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
- Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
@@ -330,7 +329,7 @@
TEST_F(ScalarEvolutionsTest, CompareSCEVComplexity) {
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
- Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
BasicBlock *LoopBB = BasicBlock::Create(Context, "bb1", F);
BranchInst::Create(LoopBB, EntryBB);
@@ -400,7 +399,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), {IntPtrTy, IntPtrTy}, false);
- Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
Value *X = &*F->arg_begin();
@@ -408,9 +407,11 @@
const int ValueDepth = 10;
for (int i = 0; i < ValueDepth; i++) {
- X = new LoadInst(new IntToPtrInst(X, IntPtrPtrTy, "", EntryBB), "",
+ X = new LoadInst(IntPtrTy, new IntToPtrInst(X, IntPtrPtrTy, "", EntryBB),
+ "",
/*isVolatile*/ false, EntryBB);
- Y = new LoadInst(new IntToPtrInst(Y, IntPtrPtrTy, "", EntryBB), "",
+ Y = new LoadInst(IntPtrTy, new IntToPtrInst(Y, IntPtrPtrTy, "", EntryBB),
+ "",
/*isVolatile*/ false, EntryBB);
}
@@ -436,7 +437,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), ArgTys, false);
- Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
Argument *A1 = &*F->arg_begin();
Argument *A2 = &*(std::next(F->arg_begin()));
@@ -670,7 +671,7 @@
// ret void
// }
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), {}, false);
- Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
BasicBlock *CondBB = BasicBlock::Create(Context, "for.cond", F);
@@ -749,7 +750,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
- Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
Argument *Arg = &*F->arg_begin();
@@ -772,7 +773,8 @@
Phi->addIncoming(Add, L);
Builder.SetInsertPoint(Post);
- Value *GepBase = Builder.CreateGEP(Arg, ConstantInt::get(T_int64, 1));
+ Value *GepBase =
+ Builder.CreateGEP(T_int64, Arg, ConstantInt::get(T_int64, 1));
Instruction *Ret = Builder.CreateRetVoid();
ScalarEvolution SE = buildSE(*F);
@@ -822,7 +824,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
- Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
BasicBlock *Top = BasicBlock::Create(Context, "top", F);
BasicBlock *LPh = BasicBlock::Create(Context, "L.ph", F);
@@ -920,7 +922,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
- Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
Argument *Arg = &*F->arg_begin();
@@ -980,7 +982,8 @@
// ix.
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
- Function *F = cast<Function>(M.getOrInsertFunction("addrecphitest", FTy));
+ Function *F =
+ Function::Create(FTy, Function::ExternalLinkage, "addrecphitest", M);
/*
Create IR:
@@ -1036,7 +1039,8 @@
SmallVector<Type *, 1> Types;
Types.push_back(Int32Ty);
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
- Function *F = cast<Function>(M.getOrInsertFunction("addrecphitest", FTy));
+ Function *F =
+ Function::Create(FTy, Function::ExternalLinkage, "addrecphitest", M);
/*
Create IR:
@@ -1090,7 +1094,7 @@
SmallVector<Type *, 1> Types;
Types.push_back(ArgTy);
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
- Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
ReturnInst::Create(Context, nullptr, BB);
@@ -1146,7 +1150,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
- Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
BasicBlock *Top = BasicBlock::Create(Context, "top", F);
BasicBlock *LPh = BasicBlock::Create(Context, "L.ph", F);
@@ -1207,7 +1211,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
- Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
Argument *Arg = &*F->arg_begin();
ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
@@ -1259,7 +1263,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
- Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
Argument *Arg = &*F->arg_begin();
ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
@@ -1309,7 +1313,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
- Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
Argument *Arg = &*F->arg_begin();
ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
@@ -1360,7 +1364,7 @@
FunctionType *FTy =
FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
- Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
Argument *Arg = &*F->arg_begin();
ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
@@ -1390,5 +1394,289 @@
EXPECT_FALSE(I->hasNoSignedWrap());
}
+// Check logic of SCEV expression size computation.
+TEST_F(ScalarEvolutionsTest, SCEVComputeExpressionSize) {
+ /*
+ * Create the following code:
+ * void func(i64 %a, i64 %b)
+ * entry:
+ * %s1 = add i64 %a, 1
+ * %s2 = udiv i64 %s1, %b
+ * br label %exit
+ * exit:
+ * ret
+ */
+
+ // Create a module.
+ Module M("SCEVComputeExpressionSize", Context);
+
+ Type *T_int64 = Type::getInt64Ty(Context);
+
+ FunctionType *FTy =
+ FunctionType::get(Type::getVoidTy(Context), { T_int64, T_int64 }, false);
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
+ Argument *A = &*F->arg_begin();
+ Argument *B = &*std::next(F->arg_begin());
+ ConstantInt *C = ConstantInt::get(Context, APInt(64, 1));
+
+ BasicBlock *Entry = BasicBlock::Create(Context, "entry", F);
+ BasicBlock *Exit = BasicBlock::Create(Context, "exit", F);
+
+ IRBuilder<> Builder(Entry);
+ auto *S1 = cast<Instruction>(Builder.CreateAdd(A, C, "s1"));
+ auto *S2 = cast<Instruction>(Builder.CreateUDiv(S1, B, "s2"));
+ Builder.CreateBr(Exit);
+
+ Builder.SetInsertPoint(Exit);
+ Builder.CreateRetVoid();
+
+ ScalarEvolution SE = buildSE(*F);
+ // Get S2 first to move it to cache.
+ const SCEV *AS = SE.getSCEV(A);
+ const SCEV *BS = SE.getSCEV(B);
+ const SCEV *CS = SE.getSCEV(C);
+ const SCEV *S1S = SE.getSCEV(S1);
+ const SCEV *S2S = SE.getSCEV(S2);
+ EXPECT_EQ(AS->getExpressionSize(), 1u);
+ EXPECT_EQ(BS->getExpressionSize(), 1u);
+ EXPECT_EQ(CS->getExpressionSize(), 1u);
+ EXPECT_EQ(S1S->getExpressionSize(), 3u);
+ EXPECT_EQ(S2S->getExpressionSize(), 5u);
+}
+
+TEST_F(ScalarEvolutionsTest, SCEVExpandInsertCanonicalIV) {
+ LLVMContext C;
+ SMDiagnostic Err;
+
+ // Expand the addrec produced by GetAddRec into a loop without a canonical IV.
+ // SCEVExpander will insert one.
+ auto TestNoCanonicalIV = [&](
+ std::function<const SCEV *(ScalarEvolution & SE, Loop * L)> GetAddRec) {
+ std::unique_ptr<Module> M =
+ parseAssemblyString("define i32 @test(i32 %limit) { "
+ "entry: "
+ " br label %loop "
+ "loop: "
+ " %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ] "
+ " %i.inc = add nsw i32 %i, 1 "
+ " %cont = icmp slt i32 %i.inc, %limit "
+ " br i1 %cont, label %loop, label %exit "
+ "exit: "
+ " ret i32 %i.inc "
+ "}",
+ Err, C);
+
+ assert(M && "Could not parse module?");
+ assert(!verifyModule(*M) && "Must have been well formed!");
+
+ runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+ auto &I = GetInstByName(F, "i");
+ auto *Loop = LI.getLoopFor(I.getParent());
+ EXPECT_FALSE(Loop->getCanonicalInductionVariable());
+
+ auto *AR = GetAddRec(SE, Loop);
+ unsigned ExpectedCanonicalIVWidth = SE.getTypeSizeInBits(AR->getType());
+
+ SCEVExpander Exp(SE, M->getDataLayout(), "expander");
+ auto *InsertAt = I.getNextNode();
+ Exp.expandCodeFor(AR, nullptr, InsertAt);
+ PHINode *CanonicalIV = Loop->getCanonicalInductionVariable();
+ unsigned CanonicalIVBitWidth =
+ cast<IntegerType>(CanonicalIV->getType())->getBitWidth();
+ EXPECT_EQ(CanonicalIVBitWidth, ExpectedCanonicalIVWidth);
+ });
+ };
+
+ // Expand the addrec produced by GetAddRec into a loop with a canonical IV
+ // which is narrower than addrec type.
+ // SCEVExpander will insert a canonical IV of a wider type to expand the
+ // addrec.
+ auto TestNarrowCanonicalIV = [&](
+ std::function<const SCEV *(ScalarEvolution & SE, Loop * L)> GetAddRec) {
+ std::unique_ptr<Module> M = parseAssemblyString(
+ "define i32 @test(i32 %limit) { "
+ "entry: "
+ " br label %loop "
+ "loop: "
+ " %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ] "
+ " %canonical.iv = phi i8 [ 0, %entry ], [ %canonical.iv.inc, %loop ] "
+ " %i.inc = add nsw i32 %i, 1 "
+ " %canonical.iv.inc = add i8 %canonical.iv, 1 "
+ " %cont = icmp slt i32 %i.inc, %limit "
+ " br i1 %cont, label %loop, label %exit "
+ "exit: "
+ " ret i32 %i.inc "
+ "}",
+ Err, C);
+
+ assert(M && "Could not parse module?");
+ assert(!verifyModule(*M) && "Must have been well formed!");
+
+ runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+ auto &I = GetInstByName(F, "i");
+
+ auto *LoopHeaderBB = I.getParent();
+ auto *Loop = LI.getLoopFor(LoopHeaderBB);
+ PHINode *CanonicalIV = Loop->getCanonicalInductionVariable();
+ EXPECT_EQ(CanonicalIV, &GetInstByName(F, "canonical.iv"));
+
+ auto *AR = GetAddRec(SE, Loop);
+
+ unsigned ExpectedCanonicalIVWidth = SE.getTypeSizeInBits(AR->getType());
+ unsigned CanonicalIVBitWidth =
+ cast<IntegerType>(CanonicalIV->getType())->getBitWidth();
+ EXPECT_LT(CanonicalIVBitWidth, ExpectedCanonicalIVWidth);
+
+ SCEVExpander Exp(SE, M->getDataLayout(), "expander");
+ auto *InsertAt = I.getNextNode();
+ Exp.expandCodeFor(AR, nullptr, InsertAt);
+
+ // Loop over all of the PHI nodes, looking for the new canonical indvar.
+ PHINode *NewCanonicalIV = nullptr;
+ for (BasicBlock::iterator i = LoopHeaderBB->begin(); isa<PHINode>(i);
+ ++i) {
+ PHINode *PN = cast<PHINode>(i);
+ if (PN == &I || PN == CanonicalIV)
+ continue;
+ // We expect that the only PHI added is the new canonical IV
+ EXPECT_FALSE(NewCanonicalIV);
+ NewCanonicalIV = PN;
+ }
+
+ // Check that NewCanonicalIV is a canonical IV, i.e {0,+,1}
+ BasicBlock *Incoming = nullptr, *Backedge = nullptr;
+ EXPECT_TRUE(Loop->getIncomingAndBackEdge(Incoming, Backedge));
+ auto *Start = NewCanonicalIV->getIncomingValueForBlock(Incoming);
+ EXPECT_TRUE(isa<ConstantInt>(Start));
+ EXPECT_TRUE(dyn_cast<ConstantInt>(Start)->isZero());
+ auto *Next = NewCanonicalIV->getIncomingValueForBlock(Backedge);
+ EXPECT_TRUE(isa<BinaryOperator>(Next));
+ auto *NextBinOp = dyn_cast<BinaryOperator>(Next);
+ EXPECT_EQ(NextBinOp->getOpcode(), Instruction::Add);
+ EXPECT_EQ(NextBinOp->getOperand(0), NewCanonicalIV);
+ auto *Step = NextBinOp->getOperand(1);
+ EXPECT_TRUE(isa<ConstantInt>(Step));
+ EXPECT_TRUE(dyn_cast<ConstantInt>(Step)->isOne());
+
+ unsigned NewCanonicalIVBitWidth =
+ cast<IntegerType>(NewCanonicalIV->getType())->getBitWidth();
+ EXPECT_EQ(NewCanonicalIVBitWidth, ExpectedCanonicalIVWidth);
+ });
+ };
+
+ // Expand the addrec produced by GetAddRec into a loop with a canonical IV
+ // of addrec width.
+ // To expand the addrec SCEVExpander should use the existing canonical IV.
+ auto TestMatchingCanonicalIV = [&](
+ std::function<const SCEV *(ScalarEvolution & SE, Loop * L)> GetAddRec,
+ unsigned ARBitWidth) {
+ auto ARBitWidthTypeStr = "i" + std::to_string(ARBitWidth);
+ std::unique_ptr<Module> M = parseAssemblyString(
+ "define i32 @test(i32 %limit) { "
+ "entry: "
+ " br label %loop "
+ "loop: "
+ " %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ] "
+ " %canonical.iv = phi " + ARBitWidthTypeStr +
+ " [ 0, %entry ], [ %canonical.iv.inc, %loop ] "
+ " %i.inc = add nsw i32 %i, 1 "
+ " %canonical.iv.inc = add " + ARBitWidthTypeStr +
+ " %canonical.iv, 1 "
+ " %cont = icmp slt i32 %i.inc, %limit "
+ " br i1 %cont, label %loop, label %exit "
+ "exit: "
+ " ret i32 %i.inc "
+ "}",
+ Err, C);
+
+ assert(M && "Could not parse module?");
+ assert(!verifyModule(*M) && "Must have been well formed!");
+
+ runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+ auto &I = GetInstByName(F, "i");
+ auto &CanonicalIV = GetInstByName(F, "canonical.iv");
+
+ auto *LoopHeaderBB = I.getParent();
+ auto *Loop = LI.getLoopFor(LoopHeaderBB);
+ EXPECT_EQ(&CanonicalIV, Loop->getCanonicalInductionVariable());
+ unsigned CanonicalIVBitWidth =
+ cast<IntegerType>(CanonicalIV.getType())->getBitWidth();
+
+ auto *AR = GetAddRec(SE, Loop);
+ EXPECT_EQ(ARBitWidth, SE.getTypeSizeInBits(AR->getType()));
+ EXPECT_EQ(CanonicalIVBitWidth, ARBitWidth);
+
+ SCEVExpander Exp(SE, M->getDataLayout(), "expander");
+ auto *InsertAt = I.getNextNode();
+ Exp.expandCodeFor(AR, nullptr, InsertAt);
+
+ // Loop over all of the PHI nodes, looking if a new canonical indvar was
+ // introduced.
+ PHINode *NewCanonicalIV = nullptr;
+ for (BasicBlock::iterator i = LoopHeaderBB->begin(); isa<PHINode>(i);
+ ++i) {
+ PHINode *PN = cast<PHINode>(i);
+ if (PN == &I || PN == &CanonicalIV)
+ continue;
+ NewCanonicalIV = PN;
+ }
+ EXPECT_FALSE(NewCanonicalIV);
+ });
+ };
+
+ unsigned ARBitWidth = 16;
+ Type *ARType = IntegerType::get(C, ARBitWidth);
+
+ // Expand {5,+,1}
+ auto GetAR2 = [&](ScalarEvolution &SE, Loop *L) -> const SCEV * {
+ return SE.getAddRecExpr(SE.getConstant(APInt(ARBitWidth, 5)),
+ SE.getOne(ARType), L, SCEV::FlagAnyWrap);
+ };
+ TestNoCanonicalIV(GetAR2);
+ TestNarrowCanonicalIV(GetAR2);
+ TestMatchingCanonicalIV(GetAR2, ARBitWidth);
+}
+
+TEST_F(ScalarEvolutionsTest, SCEVExpanderShlNSW) {
+
+ auto checkOneCase = [this](std::string &&str) {
+ LLVMContext C;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseAssemblyString(str, Err, C);
+
+ assert(M && "Could not parse module?");
+ assert(!verifyModule(*M) && "Must have been well formed!");
+
+ Function *F = M->getFunction("f");
+ ASSERT_NE(F, nullptr) << "Could not find function 'f'";
+
+ BasicBlock &Entry = F->getEntryBlock();
+ LoadInst *Load = cast<LoadInst>(&Entry.front());
+ BinaryOperator *And = cast<BinaryOperator>(*Load->user_begin());
+
+ ScalarEvolution SE = buildSE(*F);
+ const SCEV *AndSCEV = SE.getSCEV(And);
+ EXPECT_TRUE(isa<SCEVMulExpr>(AndSCEV));
+ EXPECT_TRUE(cast<SCEVMulExpr>(AndSCEV)->hasNoSignedWrap());
+
+ SCEVExpander Exp(SE, M->getDataLayout(), "expander");
+ auto *I = cast<Instruction>(Exp.expandCodeFor(AndSCEV, nullptr, And));
+ EXPECT_EQ(I->getOpcode(), Instruction::Shl);
+ EXPECT_FALSE(I->hasNoSignedWrap());
+ };
+
+ checkOneCase("define void @f(i16* %arrayidx) { "
+ " %1 = load i16, i16* %arrayidx "
+ " %2 = and i16 %1, -32768 "
+ " ret void "
+ "} ");
+
+ checkOneCase("define void @f(i8* %arrayidx) { "
+ " %1 = load i8, i8* %arrayidx "
+ " %2 = and i8 %1, -128 "
+ " ret void "
+ "} ");
+}
+
} // end anonymous namespace
} // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Analysis/SparsePropagation.cpp b/src/llvm-project/llvm/unittests/Analysis/SparsePropagation.cpp
index 298b140..bab14a2 100644
--- a/src/llvm-project/llvm/unittests/Analysis/SparsePropagation.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/SparsePropagation.cpp
@@ -1,9 +1,8 @@
//===- SparsePropagation.cpp - Unit tests for the generic solver ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -382,7 +381,7 @@
BasicBlock *Else = BasicBlock::Create(Context, "else", F);
F->arg_begin()->setName("cond");
Builder.SetInsertPoint(If);
- LoadInst *Cond = Builder.CreateLoad(F->arg_begin());
+ LoadInst *Cond = Builder.CreateLoad(Type::getInt1Ty(Context), F->arg_begin());
Builder.CreateCondBr(Cond, Then, Else);
Builder.SetInsertPoint(Then);
Builder.CreateRet(Builder.getInt64(1));
@@ -422,7 +421,7 @@
BasicBlock *Else = BasicBlock::Create(Context, "else", F);
F->arg_begin()->setName("cond");
Builder.SetInsertPoint(If);
- LoadInst *Cond = Builder.CreateLoad(F->arg_begin());
+ LoadInst *Cond = Builder.CreateLoad(Type::getInt1Ty(Context), F->arg_begin());
Builder.CreateCondBr(Cond, Then, Else);
Builder.SetInsertPoint(Then);
Builder.CreateRet(Builder.getInt64(0));
diff --git a/src/llvm-project/llvm/unittests/Analysis/TBAATest.cpp b/src/llvm-project/llvm/unittests/Analysis/TBAATest.cpp
index f3f05d8..5a71c74 100644
--- a/src/llvm-project/llvm/unittests/Analysis/TBAATest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/TBAATest.cpp
@@ -1,9 +1,8 @@
//===--- TBAATest.cpp - Mixed TBAA unit tests -----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -34,7 +33,7 @@
static StoreInst *getFunctionWithSingleStore(Module *M, StringRef Name) {
auto &C = M->getContext();
FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), {});
- auto *F = cast<Function>(M->getOrInsertFunction(Name, FTy));
+ auto *F = Function::Create(FTy, Function::ExternalLinkage, Name, M);
auto *BB = BasicBlock::Create(C, "entry", F);
auto *IntType = Type::getInt32Ty(C);
auto *PtrType = Type::getInt32PtrTy(C);
diff --git a/src/llvm-project/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
index 482d9d8..00b1e94 100644
--- a/src/llvm-project/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -1,9 +1,8 @@
//===--- TargetLibraryInfoTest.cpp - TLI/LibFunc unit tests ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -68,7 +67,7 @@
for (unsigned FI = 0; FI != LibFunc::NumLibFuncs; ++FI) {
LibFunc LF = (LibFunc)FI;
auto *F = cast<Function>(
- M->getOrInsertFunction(TLI.getName(LF), InvalidFTy));
+ M->getOrInsertFunction(TLI.getName(LF), InvalidFTy).getCallee());
EXPECT_FALSE(isLibFunc(F, LF));
}
}
@@ -314,6 +313,8 @@
"declare i8* @strtok(i8*, i8*)\n"
"declare i8* @strtok_r(i8*, i8*, i8**)\n"
"declare i64 @strtol(i8*, i8**, i32)\n"
+ "declare i64 @strlcat(i8*, i8**, i64)\n"
+ "declare i64 @strlcpy(i8*, i8**, i64)\n"
"declare x86_fp80 @strtold(i8*, i8**)\n"
"declare i64 @strtoll(i8*, i8**, i32)\n"
"declare i64 @strtoul(i8*, i8**, i32)\n"
@@ -468,6 +469,15 @@
"declare i8* @__stpncpy_chk(i8*, i8*, i64, i64)\n"
"declare i8* @__strcpy_chk(i8*, i8*, i64)\n"
"declare i8* @__strncpy_chk(i8*, i8*, i64, i64)\n"
+ "declare i8* @__memccpy_chk(i8*, i8*, i32, i64)\n"
+ "declare i32 @__snprintf_chk(i8*, i64, i32, i64, i8*, ...)\n"
+ "declare i32 @__sprintf_chk(i8*, i32, i64, i8*, ...)\n"
+ "declare i8* @__strcat_chk(i8*, i8*, i64)\n"
+ "declare i64 @__strlcat_chk(i8*, i8*, i64, i64)\n"
+ "declare i8* @__strncat_chk(i8*, i8*, i64, i64)\n"
+ "declare i64 @__strlcpy_chk(i8*, i8*, i64, i64)\n"
+ "declare i32 @__vsnprintf_chk(i8*, i64, i32, i64, i8*, %struct*)\n"
+ "declare i32 @__vsprintf_chk(i8*, i32, i64, i8*, %struct*)\n"
"declare i8* @memalign(i64, i64)\n"
"declare i8* @mempcpy(i8*, i8*, i64)\n"
@@ -495,6 +505,11 @@
"declare i32 @iprintf(i8*, ...)\n"
"declare i32 @siprintf(i8*, i8*, ...)\n"
+ // __small_printf variants have the same prototype as the non-'i' versions.
+ "declare i32 @__small_fprintf(%struct*, i8*, ...)\n"
+ "declare i32 @__small_printf(i8*, ...)\n"
+ "declare i32 @__small_sprintf(i8*, i8*, ...)\n"
+
"declare i32 @htonl(i32)\n"
"declare i16 @htons(i16)\n"
"declare i32 @ntohl(i32)\n"
diff --git a/src/llvm-project/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp b/src/llvm-project/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp
index 937e69f..dfa4267 100644
--- a/src/llvm-project/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp
@@ -1,9 +1,8 @@
//===- UnrollAnalyzerTest.cpp - UnrollAnalyzer unit tests -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/ValueLatticeTest.cpp b/src/llvm-project/llvm/unittests/Analysis/ValueLatticeTest.cpp
index b0b3797..844254e 100644
--- a/src/llvm-project/llvm/unittests/Analysis/ValueLatticeTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/ValueLatticeTest.cpp
@@ -1,9 +1,8 @@
//===- ValueLatticeTest.cpp - ScalarEvolution unit tests --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Analysis/ValueTrackingTest.cpp b/src/llvm-project/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 5b36d63..96b41d9 100644
--- a/src/llvm-project/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -1,9 +1,8 @@
//===- ValueTrackingTest.cpp - ValueTracking tests ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -14,8 +13,8 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/KnownBits.h"
+#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -24,21 +23,26 @@
class ValueTrackingTest : public testing::Test {
protected:
- void parseAssembly(const char *Assembly) {
+ std::unique_ptr<Module> parseModule(StringRef Assembly) {
SMDiagnostic Error;
- M = parseAssemblyString(Assembly, Error, Context);
+ std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
std::string errMsg;
raw_string_ostream os(errMsg);
Error.print("", os);
+ EXPECT_TRUE(M) << os.str();
- // A failure here means that the test itself is buggy.
- if (!M)
- report_fatal_error(os.str());
+ return M;
+ }
+
+ void parseAssembly(StringRef Assembly) {
+ M = parseModule(Assembly);
+ ASSERT_TRUE(M);
Function *F = M->getFunction("test");
- if (F == nullptr)
- report_fatal_error("Test must have a function named @test");
+ ASSERT_TRUE(F) << "Test must have a function @test";
+ if (!F)
+ return;
A = nullptr;
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
@@ -47,13 +51,12 @@
A = &*I;
}
}
- if (A == nullptr)
- report_fatal_error("@test must have an instruction %A");
+ ASSERT_TRUE(A) << "@test must have an instruction %A";
}
LLVMContext Context;
std::unique_ptr<Module> M;
- Instruction *A;
+ Instruction *A = nullptr;
};
class MatchSelectPatternTest : public ValueTrackingTest {
@@ -465,6 +468,7 @@
"declare void @nounwind_argmemonly(i32*) nounwind argmemonly "
"declare void @throws_but_readonly(i32*) readonly "
"declare void @throws_but_argmemonly(i32*) argmemonly "
+ "declare void @nounwind_willreturn(i32*) nounwind willreturn"
" "
"declare void @unknown(i32*) "
" "
@@ -477,6 +481,7 @@
" call void @unknown(i32* %p) nounwind argmemonly "
" call void @unknown(i32* %p) readonly "
" call void @unknown(i32* %p) argmemonly "
+ " call void @nounwind_willreturn(i32* %p)"
" ret void "
"} ";
@@ -498,6 +503,7 @@
true, // call void @unknown(i32* %p) nounwind argmemonly
false, // call void @unknown(i32* %p) readonly
false, // call void @unknown(i32* %p) argmemonly
+ true, // call void @nounwind_willreturn(i32* %p)
false, // ret void
};
@@ -616,3 +622,327 @@
"declare i16 @llvm.fshl.i16(i16, i16, i16)\n");
expectKnownBits(/*zero*/ 15u, /*one*/ 3840u);
}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatLeadingOnes) {
+ // uadd.sat(1111...1, ........)
+ // = 1111....
+ parseAssembly(
+ "define i8 @test(i8 %a, i8 %b) {\n"
+ " %aa = or i8 %a, 241\n"
+ " %A = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %b)\n"
+ " ret i8 %A\n"
+ "}\n"
+ "declare i8 @llvm.uadd.sat.i8(i8, i8)\n");
+ expectKnownBits(/*zero*/ 0u, /*one*/ 240u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatOnesPreserved) {
+ // uadd.sat(00...011, .1...110)
+ // = .......1
+ parseAssembly(
+ "define i8 @test(i8 %a, i8 %b) {\n"
+ " %aa = or i8 %a, 3\n"
+ " %aaa = and i8 %aa, 59\n"
+ " %bb = or i8 %b, 70\n"
+ " %bbb = and i8 %bb, 254\n"
+ " %A = call i8 @llvm.uadd.sat.i8(i8 %aaa, i8 %bbb)\n"
+ " ret i8 %A\n"
+ "}\n"
+ "declare i8 @llvm.uadd.sat.i8(i8, i8)\n");
+ expectKnownBits(/*zero*/ 0u, /*one*/ 1u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatLHSLeadingZeros) {
+ // usub.sat(0000...0, ........)
+ // = 0000....
+ parseAssembly(
+ "define i8 @test(i8 %a, i8 %b) {\n"
+ " %aa = and i8 %a, 14\n"
+ " %A = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %b)\n"
+ " ret i8 %A\n"
+ "}\n"
+ "declare i8 @llvm.usub.sat.i8(i8, i8)\n");
+ expectKnownBits(/*zero*/ 240u, /*one*/ 0u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatRHSLeadingOnes) {
+ // usub.sat(........, 1111...1)
+ // = 0000....
+ parseAssembly(
+ "define i8 @test(i8 %a, i8 %b) {\n"
+ " %bb = or i8 %a, 241\n"
+ " %A = call i8 @llvm.usub.sat.i8(i8 %a, i8 %bb)\n"
+ " ret i8 %A\n"
+ "}\n"
+ "declare i8 @llvm.usub.sat.i8(i8, i8)\n");
+ expectKnownBits(/*zero*/ 240u, /*one*/ 0u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatZerosPreserved) {
+ // usub.sat(11...011, .1...110)
+ // = ......0.
+ parseAssembly(
+ "define i8 @test(i8 %a, i8 %b) {\n"
+ " %aa = or i8 %a, 195\n"
+ " %aaa = and i8 %aa, 251\n"
+ " %bb = or i8 %b, 70\n"
+ " %bbb = and i8 %bb, 254\n"
+ " %A = call i8 @llvm.usub.sat.i8(i8 %aaa, i8 %bbb)\n"
+ " ret i8 %A\n"
+ "}\n"
+ "declare i8 @llvm.usub.sat.i8(i8, i8)\n");
+ expectKnownBits(/*zero*/ 2u, /*one*/ 0u);
+}
+
+class IsBytewiseValueTest : public ValueTrackingTest,
+ public ::testing::WithParamInterface<
+ std::pair<const char *, const char *>> {
+protected:
+};
+
+const std::pair<const char *, const char *> IsBytewiseValueTests[] = {
+ {
+ "i8 0",
+ "i48* null",
+ },
+ {
+ "i8 undef",
+ "i48* undef",
+ },
+ {
+ "i8 0",
+ "i8 zeroinitializer",
+ },
+ {
+ "i8 0",
+ "i8 0",
+ },
+ {
+ "i8 -86",
+ "i8 -86",
+ },
+ {
+ "i8 -1",
+ "i8 -1",
+ },
+ {
+ "i8 undef",
+ "i16 undef",
+ },
+ {
+ "i8 0",
+ "i16 0",
+ },
+ {
+ "",
+ "i16 7",
+ },
+ {
+ "i8 -86",
+ "i16 -21846",
+ },
+ {
+ "i8 -1",
+ "i16 -1",
+ },
+ {
+ "i8 0",
+ "i48 0",
+ },
+ {
+ "i8 -1",
+ "i48 -1",
+ },
+ {
+ "i8 0",
+ "i49 0",
+ },
+ {
+ "",
+ "i49 -1",
+ },
+ {
+ "i8 0",
+ "half 0xH0000",
+ },
+ {
+ "i8 -85",
+ "half 0xHABAB",
+ },
+ {
+ "i8 0",
+ "float 0.0",
+ },
+ {
+ "i8 -1",
+ "float 0xFFFFFFFFE0000000",
+ },
+ {
+ "i8 0",
+ "double 0.0",
+ },
+ {
+ "i8 -15",
+ "double 0xF1F1F1F1F1F1F1F1",
+ },
+ {
+ "i8 undef",
+ "i16* undef",
+ },
+ {
+ "i8 0",
+ "i16* inttoptr (i64 0 to i16*)",
+ },
+ {
+ "i8 -1",
+ "i16* inttoptr (i64 -1 to i16*)",
+ },
+ {
+ "i8 -86",
+ "i16* inttoptr (i64 -6148914691236517206 to i16*)",
+ },
+ {
+ "",
+ "i16* inttoptr (i48 -1 to i16*)",
+ },
+ {
+ "i8 -1",
+ "i16* inttoptr (i96 -1 to i16*)",
+ },
+ {
+ "i8 undef",
+ "[0 x i8] zeroinitializer",
+ },
+ {
+ "i8 undef",
+ "[0 x i8] undef",
+ },
+ {
+ "i8 undef",
+ "[5 x [0 x i8]] zeroinitializer",
+ },
+ {
+ "i8 undef",
+ "[5 x [0 x i8]] undef",
+ },
+ {
+ "i8 0",
+ "[6 x i8] zeroinitializer",
+ },
+ {
+ "i8 undef",
+ "[6 x i8] undef",
+ },
+ {
+ "i8 1",
+ "[5 x i8] [i8 1, i8 1, i8 1, i8 1, i8 1]",
+ },
+ {
+ "",
+ "[5 x i64] [i64 1, i64 1, i64 1, i64 1, i64 1]",
+ },
+ {
+ "i8 -1",
+ "[5 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]",
+ },
+ {
+ "",
+ "[4 x i8] [i8 1, i8 2, i8 1, i8 1]",
+ },
+ {
+ "i8 1",
+ "[4 x i8] [i8 1, i8 undef, i8 1, i8 1]",
+ },
+ {
+ "i8 0",
+ "<6 x i8> zeroinitializer",
+ },
+ {
+ "i8 undef",
+ "<6 x i8> undef",
+ },
+ {
+ "i8 1",
+ "<5 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1>",
+ },
+ {
+ "",
+ "<5 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1>",
+ },
+ {
+ "i8 -1",
+ "<5 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>",
+ },
+ {
+ "",
+ "<4 x i8> <i8 1, i8 1, i8 2, i8 1>",
+ },
+ {
+ "i8 5",
+ "<2 x i8> < i8 5, i8 undef >",
+ },
+ {
+ "i8 0",
+ "[2 x [2 x i16]] zeroinitializer",
+ },
+ {
+ "i8 undef",
+ "[2 x [2 x i16]] undef",
+ },
+ {
+ "i8 -86",
+ "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], "
+ "[2 x i16] [i16 -21846, i16 -21846]]",
+ },
+ {
+ "",
+ "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], "
+ "[2 x i16] [i16 -21836, i16 -21846]]",
+ },
+ {
+ "i8 undef",
+ "{ } zeroinitializer",
+ },
+ {
+ "i8 undef",
+ "{ } undef",
+ },
+ {
+ "i8 undef",
+ "{ {}, {} } zeroinitializer",
+ },
+ {
+ "i8 undef",
+ "{ {}, {} } undef",
+ },
+ {
+ "i8 0",
+ "{i8, i64, i16*} zeroinitializer",
+ },
+ {
+ "i8 undef",
+ "{i8, i64, i16*} undef",
+ },
+ {
+ "i8 -86",
+ "{i8, i64, i16*} {i8 -86, i64 -6148914691236517206, i16* undef}",
+ },
+ {
+ "",
+ "{i8, i64, i16*} {i8 86, i64 -6148914691236517206, i16* undef}",
+ },
+};
+
+INSTANTIATE_TEST_CASE_P(IsBytewiseValueParamTests, IsBytewiseValueTest,
+ ::testing::ValuesIn(IsBytewiseValueTests),);
+
+TEST_P(IsBytewiseValueTest, IsBytewiseValue) {
+ auto M = parseModule(std::string("@test = global ") + GetParam().second);
+ GlobalVariable *GV = dyn_cast<GlobalVariable>(M->getNamedValue("test"));
+ Value *Actual = isBytewiseValue(GV->getInitializer(), M->getDataLayout());
+ std::string Buff;
+ raw_string_ostream S(Buff);
+ if (Actual)
+ S << *Actual;
+ EXPECT_EQ(GetParam().first, S.str());
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/VectorUtilsTest.cpp b/src/llvm-project/llvm/unittests/Analysis/VectorUtilsTest.cpp
new file mode 100644
index 0000000..a33fdb5
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Analysis/VectorUtilsTest.cpp
@@ -0,0 +1,281 @@
+//===- VectorUtilsTest.cpp - VectorUtils tests ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/VectorUtils.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/NoFolder.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/KnownBits.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class VectorUtilsTest : public testing::Test {
+protected:
+ void parseAssembly(const char *Assembly) {
+ SMDiagnostic Error;
+ M = parseAssemblyString(Assembly, Error, Context);
+
+ std::string errMsg;
+ raw_string_ostream os(errMsg);
+ Error.print("", os);
+
+ // A failure here means that the test itself is buggy.
+ if (!M)
+ report_fatal_error(os.str());
+
+ Function *F = M->getFunction("test");
+ if (F == nullptr)
+ report_fatal_error("Test must have a function named @test");
+
+ A = nullptr;
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
+ if (I->hasName()) {
+ if (I->getName() == "A")
+ A = &*I;
+ }
+ }
+ if (A == nullptr)
+ report_fatal_error("@test must have an instruction %A");
+ }
+
+ LLVMContext Context;
+ std::unique_ptr<Module> M;
+ Instruction *A;
+};
+
+struct BasicTest : public testing::Test {
+ LLVMContext Ctx;
+ std::unique_ptr<Module> M;
+ Function *F;
+ BasicBlock *BB;
+ IRBuilder<NoFolder> IRB;
+
+ BasicTest()
+ : M(new Module("VectorUtils", Ctx)),
+ F(Function::Create(
+ FunctionType::get(Type::getVoidTy(Ctx), /* IsVarArg */ false),
+ Function::ExternalLinkage, "f", M.get())),
+ BB(BasicBlock::Create(Ctx, "entry", F)), IRB(BB) {}
+};
+
+
+} // namespace
+
+TEST_F(BasicTest, isSplat) {
+ Value *UndefVec = UndefValue::get(VectorType::get(IRB.getInt8Ty(), 4));
+ EXPECT_TRUE(isSplatValue(UndefVec));
+
+ Constant *UndefScalar = UndefValue::get(IRB.getInt8Ty());
+ EXPECT_FALSE(isSplatValue(UndefScalar));
+
+ Constant *ScalarC = IRB.getInt8(42);
+ EXPECT_FALSE(isSplatValue(ScalarC));
+
+ Constant *OtherScalarC = IRB.getInt8(-42);
+ Constant *NonSplatC = ConstantVector::get({ScalarC, OtherScalarC});
+ EXPECT_FALSE(isSplatValue(NonSplatC));
+
+ Value *SplatC = IRB.CreateVectorSplat(5, ScalarC);
+ EXPECT_TRUE(isSplatValue(SplatC));
+
+ // FIXME: Constant splat analysis does not allow undef elements.
+ Constant *SplatWithUndefC = ConstantVector::get({ScalarC, UndefScalar});
+ EXPECT_FALSE(isSplatValue(SplatWithUndefC));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_00) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i8> %x) {\n"
+ " %A = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> zeroinitializer\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_11) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i8> %x) {\n"
+ " %A = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_01) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i8> %x) {\n"
+ " %A = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 0, i32 1>\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_FALSE(isSplatValue(A));
+}
+
+// FIXME: Constant (mask) splat analysis does not allow undef elements.
+
+TEST_F(VectorUtilsTest, isSplatValue_0u) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i8> %x) {\n"
+ " %A = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 0, i32 undef>\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Binop) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i8> %x) {\n"
+ " %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+ " %v1 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %A = udiv <2 x i8> %v0, %v1\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Binop_ConstantOp0) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i8> %x) {\n"
+ " %v1 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %A = ashr <2 x i8> <i8 42, i8 42>, %v1\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Binop_Not_Op0) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i8> %x) {\n"
+ " %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 0>\n"
+ " %v1 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %A = add <2 x i8> %v0, %v1\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Binop_Not_Op1) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i8> %x) {\n"
+ " %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %v1 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 0, i32 1>\n"
+ " %A = shl <2 x i8> %v0, %v1\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+ " %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %v1 = shufflevector <2 x i8> %y, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+ " %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %A = select <2 x i1> %v0, <2 x i8> %v1, <2 x i8> %v2\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select_ConstantOp) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+ " %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %A = select <2 x i1> %v0, <2 x i8> <i8 42, i8 42>, <2 x i8> %v2\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select_NotCond) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+ " %v1 = shufflevector <2 x i8> %y, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+ " %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %A = select <2 x i1> %x, <2 x i8> %v1, <2 x i8> %v2\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select_NotOp1) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+ " %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %A = select <2 x i1> %v0, <2 x i8> %y, <2 x i8> %v2\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select_NotOp2) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+ " %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %v1 = shufflevector <2 x i8> %y, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+ " %A = select <2 x i1> %v0, <2 x i8> %v1, <2 x i8> %z\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_SelectBinop) {
+ parseAssembly(
+ "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+ " %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %v1 = shufflevector <2 x i8> %y, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+ " %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " %bo = xor <2 x i8> %v1, %v2\n"
+ " %A = select <2 x i1> %v0, <2 x i8> %bo, <2 x i8> %v2\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, getSplatValueElt0) {
+ parseAssembly(
+ "define <2 x i8> @test(i8 %x) {\n"
+ " %ins = insertelement <2 x i8> undef, i8 %x, i32 0\n"
+ " %A = shufflevector <2 x i8> %ins, <2 x i8> undef, <2 x i32> zeroinitializer\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_EQ(getSplatValue(A)->getName(), "x");
+}
+
+TEST_F(VectorUtilsTest, getSplatValueEltMismatch) {
+ parseAssembly(
+ "define <2 x i8> @test(i8 %x) {\n"
+ " %ins = insertelement <2 x i8> undef, i8 %x, i32 1\n"
+ " %A = shufflevector <2 x i8> %ins, <2 x i8> undef, <2 x i32> zeroinitializer\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_EQ(getSplatValue(A), nullptr);
+}
+
+// TODO: This is a splat, but we don't recognize it.
+
+TEST_F(VectorUtilsTest, getSplatValueElt1) {
+ parseAssembly(
+ "define <2 x i8> @test(i8 %x) {\n"
+ " %ins = insertelement <2 x i8> undef, i8 %x, i32 1\n"
+ " %A = shufflevector <2 x i8> %ins, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+ " ret <2 x i8> %A\n"
+ "}\n");
+ EXPECT_EQ(getSplatValue(A), nullptr);
+}
diff --git a/src/llvm-project/llvm/unittests/AsmParser/AsmParserTest.cpp b/src/llvm-project/llvm/unittests/AsmParser/AsmParserTest.cpp
index ddbedd0..d5f734d 100644
--- a/src/llvm-project/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/src/llvm-project/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/AsmParser/AsmParserTest.cpp - asm parser unittests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/CMakeLists.txt b/src/llvm-project/llvm/unittests/BinaryFormat/CMakeLists.txt
index 82d76ec..c058402 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/CMakeLists.txt
@@ -5,8 +5,8 @@
add_llvm_unittest(BinaryFormatTests
DwarfTest.cpp
MachOTest.cpp
+ MsgPackDocumentTest.cpp
MsgPackReaderTest.cpp
- MsgPackTypesTest.cpp
MsgPackWriterTest.cpp
TestFileMagic.cpp
)
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/DwarfTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/DwarfTest.cpp
index 08a731f..5509689 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/DwarfTest.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/DwarfTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/BinaryFormat/DwarfTest.cpp - Dwarf support tests ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MachOTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MachOTest.cpp
index da8e9e8..5acffc4 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/MachOTest.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/MachOTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/BinaryFormat/MachOTest.cpp - MachO support tests ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackDocumentTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackDocumentTest.cpp
new file mode 100644
index 0000000..00b1579
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackDocumentTest.cpp
@@ -0,0 +1,168 @@
+//===- MsgPackDocumentTest.cpp --------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/MsgPackDocument.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace msgpack;
+
+TEST(MsgPackDocument, TestReadInt) {
+ Document Doc;
+ bool Ok = Doc.readFromBlob(StringRef("\xd0\x00", 2), /*Multi=*/false);
+ ASSERT_TRUE(Ok);
+ ASSERT_EQ(Doc.getRoot().getKind(), Type::Int);
+ ASSERT_EQ(Doc.getRoot().getInt(), 0);
+}
+
+TEST(MsgPackDocument, TestReadArray) {
+ Document Doc;
+ bool Ok = Doc.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
+ ASSERT_TRUE(Ok);
+ ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
+ auto A = Doc.getRoot().getArray();
+ ASSERT_EQ(A.size(), 2u);
+ auto SI = A[0];
+ ASSERT_EQ(SI.getKind(), Type::Int);
+ ASSERT_EQ(SI.getInt(), 1);
+ auto SN = A[1];
+ ASSERT_EQ(SN.getKind(), Type::Nil);
+}
+
+TEST(MsgPackDocument, TestReadMap) {
+ Document Doc;
+ bool Ok = Doc.readFromBlob(StringRef("\x82\xa3"
+ "foo"
+ "\xd0\x01\xa3"
+ "bar"
+ "\xd0\x02"),
+ /*Multi=*/false);
+ ASSERT_TRUE(Ok);
+ ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
+ auto M = Doc.getRoot().getMap();
+ ASSERT_EQ(M.size(), 2u);
+ auto FooS = M["foo"];
+ ASSERT_EQ(FooS.getKind(), Type::Int);
+ ASSERT_EQ(FooS.getInt(), 1);
+ auto BarS = M["bar"];
+ ASSERT_EQ(BarS.getKind(), Type::Int);
+ ASSERT_EQ(BarS.getInt(), 2);
+}
+
+TEST(MsgPackDocument, TestWriteInt) {
+ Document Doc;
+ Doc.getRoot() = Doc.getNode(int64_t(1));
+ std::string Buffer;
+ Doc.writeToBlob(Buffer);
+ ASSERT_EQ(Buffer, "\x01");
+}
+
+TEST(MsgPackDocument, TestWriteArray) {
+ Document Doc;
+ auto A = Doc.getRoot().getArray(/*Convert=*/true);
+ A.push_back(Doc.getNode(int64_t(1)));
+ A.push_back(Doc.getNode());
+ std::string Buffer;
+ Doc.writeToBlob(Buffer);
+ ASSERT_EQ(Buffer, "\x92\x01\xc0");
+}
+
+TEST(MsgPackDocument, TestWriteMap) {
+ Document Doc;
+ auto M = Doc.getRoot().getMap(/*Convert=*/true);
+ M["foo"] = Doc.getNode(int64_t(1));
+ M["bar"] = Doc.getNode(int64_t(2));
+ std::string Buffer;
+ Doc.writeToBlob(Buffer);
+ ASSERT_EQ(Buffer, "\x82\xa3"
+ "bar"
+ "\x02\xa3"
+ "foo"
+ "\x01");
+}
+
+TEST(MsgPackDocument, TestOutputYAMLArray) {
+ Document Doc;
+ auto A = Doc.getRoot().getArray(/*Convert=*/true);
+ A.push_back(Doc.getNode(int64_t(1)));
+ A.push_back(Doc.getNode(int64_t(2)));
+ std::string Buffer;
+ raw_string_ostream OStream(Buffer);
+ Doc.toYAML(OStream);
+ ASSERT_EQ(OStream.str(), "---\n- 1\n- 2\n...\n");
+}
+
+TEST(MsgPackDocument, TestInputYAMLArray) {
+ Document Doc;
+ bool Ok = Doc.fromYAML("---\n- !int 0x1\n- !str 2\n...\n");
+ ASSERT_TRUE(Ok);
+ ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
+ auto A = Doc.getRoot().getArray();
+ ASSERT_EQ(A.size(), 2u);
+ auto SI = A[0];
+ ASSERT_EQ(SI.getKind(), Type::UInt);
+ ASSERT_EQ(SI.getUInt(), 1u);
+ auto SS = A[1];
+ ASSERT_EQ(SS.getKind(), Type::String);
+ ASSERT_EQ(SS.getString(), "2");
+}
+
+TEST(MsgPackDocument, TestOutputYAMLMap) {
+ Document Doc;
+ auto M = Doc.getRoot().getMap(/*Convert=*/true);
+ M["foo"] = Doc.getNode(int64_t(1));
+ M["bar"] = Doc.getNode(uint64_t(2));
+ auto N = Doc.getMapNode();
+ M["qux"] = N;
+ N["baz"] = Doc.getNode(true);
+ std::string Buffer;
+ raw_string_ostream OStream(Buffer);
+ Doc.toYAML(OStream);
+ ASSERT_EQ(OStream.str(), "---\n"
+ "bar: 2\n"
+ "foo: 1\n"
+ "qux:\n"
+ " baz: true\n"
+ "...\n");
+}
+
+TEST(MsgPackDocument, TestOutputYAMLMapHex) {
+ Document Doc;
+ Doc.setHexMode();
+ auto M = Doc.getRoot().getMap(/*Convert=*/true);
+ M["foo"] = Doc.getNode(int64_t(1));
+ M["bar"] = Doc.getNode(uint64_t(2));
+ auto N = Doc.getMapNode();
+ M["qux"] = N;
+ N["baz"] = Doc.getNode(true);
+ std::string Buffer;
+ raw_string_ostream OStream(Buffer);
+ Doc.toYAML(OStream);
+ ASSERT_EQ(OStream.str(), "---\n"
+ "bar: 0x2\n"
+ "foo: 1\n"
+ "qux:\n"
+ " baz: true\n"
+ "...\n");
+}
+
+TEST(MsgPackDocument, TestInputYAMLMap) {
+ Document Doc;
+ bool Ok = Doc.fromYAML("---\nfoo: !int 0x1\nbaz: !str 2\n...\n");
+ ASSERT_TRUE(Ok);
+ ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
+ auto M = Doc.getRoot().getMap();
+ ASSERT_EQ(M.size(), 2u);
+ auto SI = M["foo"];
+ ASSERT_EQ(SI.getKind(), Type::UInt);
+ ASSERT_EQ(SI.getUInt(), 1u);
+ auto SS = M["baz"];
+ ASSERT_EQ(SS.getKind(), Type::String);
+ ASSERT_EQ(SS.getString(), "2");
+}
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackReaderTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackReaderTest.cpp
index e3c1bbb..06ae8b0 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackReaderTest.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackReaderTest.cpp
@@ -1,9 +1,8 @@
//===- MsgPackReaderTest.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackTypesTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackTypesTest.cpp
deleted file mode 100644
index 87bb6fa..0000000
--- a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackTypesTest.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-//===- MsgPackTypesTest.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/BinaryFormat/MsgPackTypes.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-using namespace msgpack;
-
-TEST(MsgPackTypes, TestReadInt) {
- Reader MPReader(StringRef("\xd0\x00", 2));
- auto OptNodeOrErr = Node::read(MPReader);
- ASSERT_TRUE(static_cast<bool>(OptNodeOrErr));
- ASSERT_TRUE(*OptNodeOrErr);
- auto *S = dyn_cast<ScalarNode>((*OptNodeOrErr)->get());
- ASSERT_TRUE(S);
- ASSERT_EQ(S->getScalarKind(), ScalarNode::SK_Int);
- ASSERT_EQ(S->getInt(), 0);
-}
-
-TEST(MsgPackTypes, TestReadArray) {
- Reader MPReader(StringRef("\x92\xd0\x01\xc0"));
- auto OptNodeOrErr = Node::read(MPReader);
- ASSERT_TRUE(static_cast<bool>(OptNodeOrErr));
- ASSERT_TRUE(*OptNodeOrErr);
- auto *A = dyn_cast<ArrayNode>((*OptNodeOrErr)->get());
- ASSERT_TRUE(A);
- ASSERT_EQ(A->size(), 2u);
- auto *SI = dyn_cast<ScalarNode>((*A)[0].get());
- ASSERT_TRUE(SI);
- ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_Int);
- ASSERT_EQ(SI->getInt(), 1);
- auto *SN = dyn_cast<ScalarNode>((*A)[1].get());
- ASSERT_TRUE(SN);
- ASSERT_EQ(SN->getScalarKind(), ScalarNode::SK_Nil);
-}
-
-TEST(MsgPackTypes, TestReadMap) {
- Reader MPReader(StringRef("\x82\xa3"
- "foo"
- "\xd0\x01\xa3"
- "bar"
- "\xd0\x02"));
- auto OptNodeOrErr = Node::read(MPReader);
- ASSERT_TRUE(static_cast<bool>(OptNodeOrErr));
- ASSERT_TRUE(*OptNodeOrErr);
- auto *A = dyn_cast<MapNode>((*OptNodeOrErr)->get());
- ASSERT_TRUE(A);
- ASSERT_EQ(A->size(), 2u);
- auto *FooS = dyn_cast<ScalarNode>((*A)["foo"].get());
- ASSERT_TRUE(FooS);
- ASSERT_EQ(FooS->getScalarKind(), ScalarNode::SK_Int);
- ASSERT_EQ(FooS->getInt(), 1);
- auto *BarS = dyn_cast<ScalarNode>((*A)["bar"].get());
- ASSERT_TRUE(BarS);
- ASSERT_EQ(BarS->getScalarKind(), ScalarNode::SK_Int);
- ASSERT_EQ(BarS->getInt(), 2);
-}
-
-TEST(MsgPackTypes, TestWriteInt) {
- std::string Buffer;
- raw_string_ostream OStream(Buffer);
- Writer MPWriter(OStream);
- ScalarNode I(int64_t(1));
- I.write(MPWriter);
- ASSERT_EQ(OStream.str(), "\x01");
-}
-
-TEST(MsgPackTypes, TestWriteArray) {
- std::string Buffer;
- raw_string_ostream OStream(Buffer);
- Writer MPWriter(OStream);
- ArrayNode A;
- A.push_back(std::make_shared<ScalarNode>(int64_t(1)));
- A.push_back(std::make_shared<ScalarNode>());
- A.write(MPWriter);
- ASSERT_EQ(OStream.str(), "\x92\x01\xc0");
-}
-
-TEST(MsgPackTypes, TestWriteMap) {
- std::string Buffer;
- raw_string_ostream OStream(Buffer);
- Writer MPWriter(OStream);
- MapNode M;
- M["foo"] = std::make_shared<ScalarNode>(int64_t(1));
- M["bar"] = std::make_shared<ScalarNode>(int64_t(2));
- M.write(MPWriter);
- ASSERT_EQ(OStream.str(), "\x82\xa3"
- "foo"
- "\x01\xa3"
- "bar"
- "\x02");
-}
-
-TEST(MsgPackTypes, TestOutputYAMLArray) {
- std::string Buffer;
- raw_string_ostream OStream(Buffer);
- yaml::Output yout(OStream);
- ArrayNode A;
- A.push_back(std::make_shared<ScalarNode>(int64_t(1)));
- A.push_back(std::make_shared<ScalarNode>(int64_t(2)));
- yout << A;
- ASSERT_EQ(OStream.str(), "---\n- !int 1\n- !int 2\n...\n");
-}
-
-TEST(MsgPackTypes, TestInputYAMLArray) {
- NodePtr RootNode;
- yaml::Input yin("---\n- !int 1\n- !str 2\n...\n");
- yin >> RootNode;
- auto *A = dyn_cast<ArrayNode>(RootNode.get());
- ASSERT_TRUE(A);
- ASSERT_EQ(A->size(), 2u);
- auto *SI = dyn_cast<ScalarNode>((*A)[0].get());
- ASSERT_TRUE(SI);
- ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_UInt);
- ASSERT_EQ(SI->getUInt(), 1u);
- auto *SS = dyn_cast<ScalarNode>((*A)[1].get());
- ASSERT_TRUE(SS);
- ASSERT_EQ(SS->getScalarKind(), ScalarNode::SK_String);
- ASSERT_EQ(SS->getString(), "2");
-}
-
-TEST(MsgPackTypes, TestOutputYAMLMap) {
- std::string Buffer;
- raw_string_ostream OStream(Buffer);
- yaml::Output yout(OStream);
- MapNode M;
- M["foo"] = std::make_shared<ScalarNode>(int64_t(1));
- M["bar"] = std::make_shared<ScalarNode>(uint64_t(2));
- auto N = std::make_shared<MapNode>();
- (*N)["baz"] = std::make_shared<ScalarNode>(true);
- M["qux"] = std::move(N);
- yout << M;
- ASSERT_EQ(OStream.str(), "---\nfoo: !int 1\nbar: "
- "!int 2\nqux: \n baz: "
- "!bool true\n...\n");
-}
-
-TEST(MsgPackTypes, TestInputYAMLMap) {
- NodePtr RootNode;
- yaml::Input yin("---\nfoo: !int 1\nbaz: !str 2\n...\n");
- yin >> RootNode;
- auto *M = dyn_cast<MapNode>(RootNode.get());
- ASSERT_TRUE(M);
- ASSERT_EQ(M->size(), 2u);
- auto *SI = dyn_cast<ScalarNode>((*M)["foo"].get());
- ASSERT_TRUE(SI);
- ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_UInt);
- ASSERT_EQ(SI->getUInt(), 1u);
- auto *SS = dyn_cast<ScalarNode>((*M)["baz"].get());
- ASSERT_TRUE(SS);
- ASSERT_EQ(SS->getScalarKind(), ScalarNode::SK_String);
- ASSERT_EQ(SS->getString(), "2");
-}
-
-// Test that the document is parsed into a tree of shared_ptr where each node
-// can have multiple owners.
-TEST(MsgPackTypes, TestInputShared) {
- yaml::Input yin("---\nfoo:\n bar: !int 1\n...\n");
- NodePtr InnerMap;
- NodePtr IntNode;
- {
- {
- {
- NodePtr RootNode;
- yin >> RootNode;
- auto *M = dyn_cast<MapNode>(RootNode.get());
- ASSERT_TRUE(M);
- ASSERT_EQ(M->size(), 1u);
- InnerMap = (*M)["foo"];
- }
- auto *N = dyn_cast<MapNode>(InnerMap.get());
- ASSERT_TRUE(N);
- ASSERT_EQ(N->size(), 1u);
- IntNode = (*N)["bar"];
- }
- auto *S = dyn_cast<ScalarNode>(IntNode.get());
- ASSERT_TRUE(S);
- ASSERT_EQ(S->getScalarKind(), ScalarNode::SK_UInt);
- ASSERT_EQ(S->getUInt(), 1u);
- }
-}
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp
index ecca3ee..3a5ba9a 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp
@@ -1,9 +1,8 @@
//===- MsgPackWriterTest.cpp ------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/TestFileMagic.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/TestFileMagic.cpp
index 5f132ba..22c26df 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/TestFileMagic.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/TestFileMagic.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/BinaryFormat/TestFileMagic.cpp - File magic tests ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp b/src/llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp
index 3b46007..e803677 100644
--- a/src/llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp
+++ b/src/llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Bitcode/CMakeLists.txt b/src/llvm-project/llvm/unittests/Bitcode/CMakeLists.txt
index 4d06f80..7e9d1bc 100644
--- a/src/llvm-project/llvm/unittests/Bitcode/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Bitcode/CMakeLists.txt
@@ -8,6 +8,4 @@
add_llvm_unittest(BitcodeTests
BitReaderTest.cpp
- BitstreamReaderTest.cpp
- BitstreamWriterTest.cpp
)
diff --git a/src/llvm-project/llvm/unittests/Bitcode/BitstreamReaderTest.cpp b/src/llvm-project/llvm/unittests/Bitstream/BitstreamReaderTest.cpp
similarity index 71%
rename from src/llvm-project/llvm/unittests/Bitcode/BitstreamReaderTest.cpp
rename to src/llvm-project/llvm/unittests/Bitstream/BitstreamReaderTest.cpp
index e7535f3..f58af22 100644
--- a/src/llvm-project/llvm/unittests/Bitcode/BitstreamReaderTest.cpp
+++ b/src/llvm-project/llvm/unittests/Bitstream/BitstreamReaderTest.cpp
@@ -1,15 +1,14 @@
//===- BitstreamReaderTest.cpp - Tests for BitstreamReader ----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitstream/BitstreamWriter.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -23,15 +22,17 @@
BitstreamCursor Cursor(Bytes);
EXPECT_FALSE(Cursor.AtEndOfStream());
- (void)Cursor.Read(8);
+ Expected<SimpleBitstreamCursor::word_t> MaybeRead = Cursor.Read(8);
+ EXPECT_TRUE((bool)MaybeRead);
EXPECT_FALSE(Cursor.AtEndOfStream());
- (void)Cursor.Read(24);
+ MaybeRead = Cursor.Read(24);
+ EXPECT_TRUE((bool)MaybeRead);
EXPECT_TRUE(Cursor.AtEndOfStream());
- Cursor.JumpToBit(0);
+ EXPECT_FALSE(Cursor.JumpToBit(0));
EXPECT_FALSE(Cursor.AtEndOfStream());
- Cursor.JumpToBit(32);
+ EXPECT_FALSE(Cursor.JumpToBit(32));
EXPECT_TRUE(Cursor.AtEndOfStream());
}
@@ -41,7 +42,7 @@
};
BitstreamCursor Cursor(Bytes);
- Cursor.JumpToBit(32);
+ EXPECT_FALSE(Cursor.JumpToBit(32));
EXPECT_TRUE(Cursor.AtEndOfStream());
}
@@ -57,7 +58,8 @@
for (unsigned I = 0, E = 32; I != E; ++I) {
EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
- (void)Cursor.Read(1);
+ Expected<SimpleBitstreamCursor::word_t> MaybeRead = Cursor.Read(1);
+ EXPECT_TRUE((bool)MaybeRead);
}
EXPECT_EQ(4u, Cursor.getCurrentByteNo());
}
@@ -117,24 +119,33 @@
// Header. Included in test so that we can run llvm-bcanalyzer to debug
// when there are problems.
- ASSERT_EQ(Magic, Stream.Read(32));
+ Expected<SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(32);
+ ASSERT_TRUE((bool)MaybeRead);
+ ASSERT_EQ(Magic, MaybeRead.get());
// Block.
- BitstreamEntry Entry =
+ Expected<BitstreamEntry> MaybeEntry =
Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
+ ASSERT_TRUE((bool)MaybeEntry);
+ BitstreamEntry Entry = MaybeEntry.get();
ASSERT_EQ(BitstreamEntry::SubBlock, Entry.Kind);
ASSERT_EQ(BlockID, Entry.ID);
ASSERT_FALSE(Stream.EnterSubBlock(BlockID));
// Abbreviation.
- Entry = Stream.advance();
+ MaybeEntry = Stream.advance();
+ ASSERT_TRUE((bool)MaybeEntry);
+ Entry = MaybeEntry.get();
ASSERT_EQ(BitstreamEntry::Record, Entry.Kind);
ASSERT_EQ(AbbrevID, Entry.ID);
// Record.
StringRef BlobOut;
SmallVector<uint64_t, 1> Record;
- ASSERT_EQ(RecordID, Stream.readRecord(Entry.ID, Record, &BlobOut));
+ Expected<unsigned> MaybeRecord =
+ Stream.readRecord(Entry.ID, Record, &BlobOut);
+ ASSERT_TRUE((bool)MaybeRecord);
+ ASSERT_EQ(RecordID, MaybeRecord.get());
EXPECT_TRUE(Record.empty());
EXPECT_EQ(BlobIn, BlobOut);
}
@@ -144,8 +155,13 @@
uint8_t Bytes[] = {8, 7, 6, 5, 4, 3, 2, 1};
for (unsigned I = 1; I != 8; ++I) {
SimpleBitstreamCursor Cursor(ArrayRef<uint8_t>(Bytes, I));
- EXPECT_EQ(8ull, Cursor.Read(8));
+ Expected<SimpleBitstreamCursor::word_t> MaybeRead = Cursor.Read(8);
+ ASSERT_TRUE((bool)MaybeRead);
+ EXPECT_EQ(8ull, MaybeRead.get());
}
}
+static_assert(is_trivially_copyable<BitCodeAbbrevOp>::value,
+ "trivially copyable");
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Bitcode/BitstreamWriterTest.cpp b/src/llvm-project/llvm/unittests/Bitstream/BitstreamWriterTest.cpp
similarity index 83%
rename from src/llvm-project/llvm/unittests/Bitcode/BitstreamWriterTest.cpp
rename to src/llvm-project/llvm/unittests/Bitstream/BitstreamWriterTest.cpp
index 79143c8..993c5aa 100644
--- a/src/llvm-project/llvm/unittests/Bitcode/BitstreamWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/Bitstream/BitstreamWriterTest.cpp
@@ -1,13 +1,12 @@
//===- BitstreamWriterTest.cpp - Tests for BitstreamWriter ----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitstream/BitstreamWriter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "gtest/gtest.h"
diff --git a/src/llvm-project/llvm/unittests/Bitstream/CMakeLists.txt b/src/llvm-project/llvm/unittests/Bitstream/CMakeLists.txt
new file mode 100644
index 0000000..a620034
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Bitstream/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(LLVM_LINK_COMPONENTS
+ BitstreamReader
+ )
+
+add_llvm_unittest(BitstreamTests
+ BitstreamReaderTest.cpp
+ BitstreamWriterTest.cpp
+ )
diff --git a/src/llvm-project/llvm/unittests/CMakeLists.txt b/src/llvm-project/llvm/unittests/CMakeLists.txt
index 459e89d..6bb2fb8 100644
--- a/src/llvm-project/llvm/unittests/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/CMakeLists.txt
@@ -13,6 +13,7 @@
add_subdirectory(AsmParser)
add_subdirectory(BinaryFormat)
add_subdirectory(Bitcode)
+add_subdirectory(Bitstream)
add_subdirectory(CodeGen)
add_subdirectory(DebugInfo)
add_subdirectory(Demangle)
@@ -26,7 +27,7 @@
add_subdirectory(Object)
add_subdirectory(ObjectYAML)
add_subdirectory(Option)
-add_subdirectory(OptRemarks)
+add_subdirectory(Remarks)
add_subdirectory(Passes)
add_subdirectory(ProfileData)
add_subdirectory(Support)
diff --git a/src/llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
index e25249e..3ac32ae 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/CodeGen/AArch64SelectionDAGTest.cpp -------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -158,4 +157,46 @@
false);
}
+// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
+TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
+ if (!TM)
+ return;
+ SDLoc Loc;
+ auto IntVT = EVT::getIntegerVT(Context, 8);
+ auto UnknownOp = DAG->getRegister(0, IntVT);
+ auto Mask = DAG->getConstant(0x8A, Loc, IntVT);
+ auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
+ auto N1 = DAG->getConstant(0x55, Loc, IntVT);
+ auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1);
+ // N0 = ?000?0?0
+ // N1 = 01010101
+ // =>
+ // Known.One = 01010101 (0x55)
+ // Known.Zero = 00100000 (0x20)
+ KnownBits Known = DAG->computeKnownBits(Op);
+ EXPECT_EQ(Known.Zero, APInt(8, 0x20));
+ EXPECT_EQ(Known.One, APInt(8, 0x55));
+}
+
+// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
+TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
+ if (!TM)
+ return;
+ SDLoc Loc;
+ auto IntVT = EVT::getIntegerVT(Context, 8);
+ auto N0 = DAG->getConstant(0x55, Loc, IntVT);
+ auto UnknownOp = DAG->getRegister(0, IntVT);
+ auto Mask = DAG->getConstant(0x2e, Loc, IntVT);
+ auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
+ auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
+ // N0 = 01010101
+ // N1 = 00?0???0
+ // =>
+ // Known.One = 00000001 (0x1)
+ // Known.Zero = 10000000 (0x80)
+ KnownBits Known = DAG->computeKnownBits(Op);
+ EXPECT_EQ(Known.Zero, APInt(8, 0x80));
+ EXPECT_EQ(Known.One, APInt(8, 0x1));
+}
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/CMakeLists.txt b/src/llvm-project/llvm/unittests/CodeGen/CMakeLists.txt
index 5ef8c2a..706a65b 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/CodeGen/CMakeLists.txt
@@ -19,6 +19,8 @@
MachineInstrTest.cpp
MachineOperandTest.cpp
ScalableVectorMVTsTest.cpp
+ TypeTraitsTest.cpp
+ TargetOptionsTest.cpp
)
add_subdirectory(GlobalISel)
diff --git a/src/llvm-project/llvm/unittests/CodeGen/DIEHashTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/DIEHashTest.cpp
index c82876b..649e132 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/DIEHashTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/DIEHashTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/CodeGen/DIEHashTest.cpp ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt
index 32bbd56..2ffec27 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt
@@ -10,8 +10,10 @@
)
add_llvm_unittest(GlobalISelTests
- LegalizerInfoTest.cpp
- PatternMatchTest.cpp
- LegalizerHelperTest.cpp
- CSETest.cpp
- )
+ CSETest.cpp
+ LegalizerHelperTest.cpp
+ LegalizerInfoTest.cpp
+ MachineIRBuilderTest.cpp
+ GISelMITest.cpp
+ PatternMatchTest.cpp
+ )
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
index c6bbd8b..f2f755b 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
@@ -1,9 +1,8 @@
//===- CSETest.cpp -----------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -22,43 +21,56 @@
auto MIBInput1 = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[1]});
auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
GISelCSEInfo CSEInfo;
- CSEInfo.setCSEConfig(make_unique<CSEConfig>());
+ CSEInfo.setCSEConfig(make_unique<CSEConfigFull>());
CSEInfo.analyze(*MF);
B.setCSEInfo(&CSEInfo);
CSEMIRBuilder CSEB(B.getState());
+
CSEB.setInsertPt(*EntryMBB, EntryMBB->begin());
unsigned AddReg = MRI->createGenericVirtualRegister(s16);
auto MIBAddCopy =
CSEB.buildInstr(TargetOpcode::G_ADD, {AddReg}, {MIBInput, MIBInput});
- ASSERT_EQ(MIBAddCopy->getOpcode(), TargetOpcode::COPY);
+ EXPECT_EQ(MIBAddCopy->getOpcode(), TargetOpcode::COPY);
auto MIBAdd2 =
CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
- ASSERT_TRUE(&*MIBAdd == &*MIBAdd2);
+ EXPECT_TRUE(&*MIBAdd == &*MIBAdd2);
auto MIBAdd4 =
CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
- ASSERT_TRUE(&*MIBAdd == &*MIBAdd4);
+ EXPECT_TRUE(&*MIBAdd == &*MIBAdd4);
auto MIBAdd5 =
CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput1});
- ASSERT_TRUE(&*MIBAdd != &*MIBAdd5);
+ EXPECT_TRUE(&*MIBAdd != &*MIBAdd5);
// Try building G_CONSTANTS.
auto MIBCst = CSEB.buildConstant(s32, 0);
auto MIBCst1 = CSEB.buildConstant(s32, 0);
- ASSERT_TRUE(&*MIBCst == &*MIBCst1);
+ EXPECT_TRUE(&*MIBCst == &*MIBCst1);
// Try the CFing of BinaryOps.
auto MIBCF1 = CSEB.buildInstr(TargetOpcode::G_ADD, {s32}, {MIBCst, MIBCst});
- ASSERT_TRUE(&*MIBCF1 == &*MIBCst);
+ EXPECT_TRUE(&*MIBCF1 == &*MIBCst);
// Try out building FCONSTANTs.
auto MIBFP0 = CSEB.buildFConstant(s32, 1.0);
auto MIBFP0_1 = CSEB.buildFConstant(s32, 1.0);
- ASSERT_TRUE(&*MIBFP0 == &*MIBFP0_1);
+ EXPECT_TRUE(&*MIBFP0 == &*MIBFP0_1);
CSEInfo.print();
+ // Make sure buildConstant with a vector type doesn't crash, and the elements
+ // CSE.
+ auto Splat0 = CSEB.buildConstant(LLT::vector(2, s32), 0);
+ EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, Splat0->getOpcode());
+ EXPECT_EQ(Splat0->getOperand(1).getReg(), Splat0->getOperand(2).getReg());
+ EXPECT_EQ(&*MIBCst, MRI->getVRegDef(Splat0->getOperand(1).getReg()));
+
+ auto FSplat = CSEB.buildFConstant(LLT::vector(2, s32), 1.0);
+ EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, FSplat->getOpcode());
+ EXPECT_EQ(FSplat->getOperand(1).getReg(), FSplat->getOperand(2).getReg());
+ EXPECT_EQ(&*MIBFP0, MRI->getVRegDef(FSplat->getOperand(1).getReg()));
+
// Check G_UNMERGE_VALUES
auto MIBUnmerge = CSEB.buildUnmerge({s32, s32}, Copies[0]);
auto MIBUnmerge2 = CSEB.buildUnmerge({s32, s32}, Copies[0]);
- ASSERT_TRUE(&*MIBUnmerge == &*MIBUnmerge2);
+ EXPECT_TRUE(&*MIBUnmerge == &*MIBUnmerge2);
}
TEST_F(GISelMITest, TestCSEConstantConfig) {
@@ -78,10 +90,10 @@
auto MIBAdd1 =
CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
// We should CSE constants only. Adds should not be CSEd.
- ASSERT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY);
- ASSERT_TRUE(&*MIBAdd1 != &*MIBAdd);
+ EXPECT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY);
+ EXPECT_TRUE(&*MIBAdd1 != &*MIBAdd);
// We should CSE constant.
auto MIBZeroTmp = CSEB.buildConstant(s16, 0);
- ASSERT_TRUE(&*MIBZero == &*MIBZeroTmp);
+ EXPECT_TRUE(&*MIBZero == &*MIBZeroTmp);
}
} // namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp
new file mode 100644
index 0000000..0558c41
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp
@@ -0,0 +1,30 @@
+//===------------------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "GISelMITest.h"
+
+namespace llvm {
+std::ostream &
+operator<<(std::ostream &OS, const LLT Ty) {
+ std::string Repr;
+ raw_string_ostream SS{Repr};
+ Ty.print(SS);
+ OS << SS.str();
+ return OS;
+}
+
+std::ostream &
+operator<<(std::ostream &OS, const MachineFunction &MF) {
+ std::string Repr;
+ raw_string_ostream SS{Repr};
+ MF.print(SS);
+ OS << SS.str();
+ return OS;
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
index 91b8e81..0e18ac8 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
@@ -1,10 +1,8 @@
-//===- GISelMITest.h
-//-----------------------------------------------===//
+//===- GISelMITest.h --------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_UNITTEST_CODEGEN_GLOBALISEL_GISELMI_H
@@ -45,6 +43,15 @@
initializeCodeGen(*Registry);
}
+// Define a printers to help debugging when things go wrong.
+namespace llvm {
+std::ostream &
+operator<<(std::ostream &OS, const LLT Ty);
+
+std::ostream &
+operator<<(std::ostream &OS, const MachineFunction &MF);
+}
+
/// Create a TargetMachine. As we lack a dedicated always available target for
/// unittests, we go for "AArch64".
static std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
@@ -117,7 +124,7 @@
return MF;
}
-static void collectCopies(SmallVectorImpl<unsigned> &Copies,
+static void collectCopies(SmallVectorImpl<Register> &Copies,
MachineFunction *MF) {
for (auto &MBB : *MF)
for (MachineInstr &MI : MBB) {
@@ -145,7 +152,7 @@
MachineFunction *MF;
std::pair<std::unique_ptr<Module>, std::unique_ptr<MachineModuleInfo>>
ModuleMMIPair;
- SmallVector<unsigned, 4> Copies;
+ SmallVector<Register, 4> Copies;
MachineBasicBlock *EntryMBB;
MachineIRBuilder B;
MachineRegisterInfo *MRI;
@@ -188,7 +195,9 @@
SMLoc());
Regex PrefixRE = FC.buildCheckPrefixRegex();
std::vector<FileCheckString> CheckStrings;
- FC.ReadCheckFile(SM, CheckFileText, PrefixRE, CheckStrings);
+ if (FC.ReadCheckFile(SM, CheckFileText, PrefixRE, CheckStrings))
+ return false;
+
auto OutBuffer = OutputBuf->getBuffer();
SM.AddNewSourceBuffer(std::move(OutputBuf), SMLoc());
return FC.CheckInput(SM, OutBuffer, CheckStrings);
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
index 9764a0b..2776f75 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
@@ -1,15 +1,18 @@
//===- LegalizerHelperTest.cpp
//-----------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "GISelMITest.h"
+using namespace LegalizeActions;
+using namespace LegalizeMutations;
+using namespace LegalityPredicates;
+
namespace {
class DummyGISelObserver : public GISelChangeObserver {
@@ -27,8 +30,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(
- A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s64}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s64, s64}});
+ });
// Build Instr
auto MIBCTTZ =
B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
@@ -36,7 +40,7 @@
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
// Perform Legalization
- ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
+ EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -48,7 +52,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTTZ expansion in terms of CTLZ
@@ -57,8 +61,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(A,
- { getActionDefinitionsBuilder(G_CTLZ).legalFor({s64}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTLZ).legalFor({{s64, s64}});
+ });
// Build Instr
auto MIBCTTZ =
B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
@@ -66,7 +71,7 @@
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
// Perform Legalization
- ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
+ EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -80,7 +85,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTTZ expansion in terms of CTPOP
@@ -89,15 +94,16 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(
- A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s64}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTPOP).legalFor({{s64, s64}});
+ });
// Build
auto MIBCTTZ =
B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
+ EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -109,7 +115,72 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+// CTPOP widening.
+TEST_F(GISelMITest, WidenBitCountingCTPOP1) {
+ if (!TM)
+ return;
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});
+ });
+
+ // Build
+ // Trunc it to s8.
+ LLT s8{LLT::scalar(8)};
+ LLT s16{LLT::scalar(16)};
+ auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+ auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s16}, {MIBTrunc});
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.widenScalar(*MIBCTPOP, 1, s16));
+
+ auto CheckStr = R"(
+ CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
+ CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
+ CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
+ CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[CTPOP]]:_(s16)
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+// Test a strange case where the result is wider than the source
+TEST_F(GISelMITest, WidenBitCountingCTPOP2) {
+ if (!TM)
+ return;
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTPOP).legalFor({{s32, s16}});
+ });
+
+ // Build
+ // Trunc it to s8.
+ LLT s8{LLT::scalar(8)};
+ LLT s16{LLT::scalar(16)};
+ LLT s32{LLT::scalar(32)};
+ auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+ auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s32}, {MIBTrunc});
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.widenScalar(*MIBCTPOP, 1, s16));
+
+ auto CheckStr = R"(
+ CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
+ CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
+ CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
+ CHECK: [[COPY:%[0-9]+]]:_(s32) = G_ZEXT [[CTPOP]]:_(s16)
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTTZ_ZERO_UNDEF expansion in terms of CTTZ
@@ -118,15 +189,16 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(A,
- { getActionDefinitionsBuilder(G_CTTZ).legalFor({s64}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTTZ).legalFor({{s64, s64}});
+ });
// Build
auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF,
{LLT::scalar(64)}, {Copies[0]});
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
+ EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -134,7 +206,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTLZ expansion in terms of CTLZ_ZERO_UNDEF
@@ -143,15 +215,16 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(
- A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s64}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s64, s64}});
+ });
// Build
auto MIBCTLZ =
B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]});
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
+ EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -163,7 +236,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall
@@ -172,15 +245,16 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(
- A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({s64}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({{s64, s64}});
+ });
// Build
auto MIBCTLZ =
B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]});
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
+ EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -192,7 +266,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTLZ expansion
@@ -201,8 +275,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(A,
- { getActionDefinitionsBuilder(G_CTPOP).legalFor({s8}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTPOP).legalFor({{s8, s8}});
+ });
// Build
// Trunc it to s8.
LLT s8{LLT::scalar(8)};
@@ -211,7 +286,7 @@
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
+ EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -231,7 +306,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTLZ widening.
@@ -240,8 +315,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(A,
- { getActionDefinitionsBuilder(G_CTLZ).legalFor({s16}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTLZ).legalFor({{s16, s16}});
+ });
// Build
// Trunc it to s8.
LLT s8{LLT::scalar(8)};
@@ -251,7 +327,7 @@
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ, 0, s16) ==
+ EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ, 1, s16) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -264,7 +340,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTLZ_ZERO_UNDEF widening.
@@ -273,8 +349,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(
- A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s16}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s16, s16}});
+ });
// Build
// Trunc it to s8.
LLT s8{LLT::scalar(8)};
@@ -285,7 +362,7 @@
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 0, s16) ==
+ EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 1, s16) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -298,7 +375,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTPOP widening.
@@ -307,8 +384,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(
- A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s16}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});
+ });
// Build
// Trunc it to s8.
LLT s8{LLT::scalar(8)};
@@ -318,7 +396,7 @@
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.widenScalar(*MIBCTPOP, 0, s16) ==
+ EXPECT_TRUE(Helper.widenScalar(*MIBCTPOP, 1, s16) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -329,7 +407,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTTZ_ZERO_UNDEF widening.
@@ -338,8 +416,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(
- A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s16}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s16, s16}});
+ });
// Build
// Trunc it to s8.
LLT s8{LLT::scalar(8)};
@@ -350,7 +429,7 @@
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 0, s16) ==
+ EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 1, s16) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -361,7 +440,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// CTTZ widening.
@@ -370,8 +449,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(A,
- { getActionDefinitionsBuilder(G_CTTZ).legalFor({s16}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_CTTZ).legalFor({{s16, s16}});
+ });
// Build
// Trunc it to s8.
LLT s8{LLT::scalar(8)};
@@ -381,7 +461,7 @@
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ, 0, s16) ==
+ EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ, 1, s16) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -394,7 +474,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// UADDO widening.
TEST_F(GISelMITest, WidenUADDO) {
@@ -402,8 +482,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(A,
- { getActionDefinitionsBuilder(G_ADD).legalFor({s16}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});
+ });
// Build
// Trunc it to s8.
LLT s8{LLT::scalar(8)};
@@ -415,7 +496,7 @@
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
+ EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -430,7 +511,7 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
// USUBO widening.
@@ -439,8 +520,9 @@
return;
// Declare your legalization info
- DefineLegalizerInfo(A,
- { getActionDefinitionsBuilder(G_SUB).legalFor({s16}); });
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}});
+ });
// Build
// Trunc it to s8.
LLT s8{LLT::scalar(8)};
@@ -452,7 +534,7 @@
AInfo Info(MF->getSubtarget());
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, Info, Observer, B);
- ASSERT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==
+ EXPECT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==
LegalizerHelper::LegalizeResult::Legalized);
auto CheckStr = R"(
@@ -467,6 +549,460 @@
)";
// Check
- ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, FewerElementsAnd) {
+ if (!TM)
+ return;
+
+ const LLT V2S32 = LLT::vector(2, 32);
+ const LLT V5S32 = LLT::vector(5, 32);
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_AND)
+ .legalFor({s32});
+ });
+
+ auto Op0 = B.buildUndef(V5S32);
+ auto Op1 = B.buildUndef(V5S32);
+ auto And = B.buildAnd(V5S32, Op0, Op1);
+
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ EXPECT_TRUE(Helper.fewerElementsVector(*And, 0, V2S32) ==
+ LegalizerHelper::LegalizeResult::Legalized);
+
+ auto CheckStr = R"(
+ CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+ CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+ CHECK: [[IMP_DEF2:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+ CHECK: [[EXTRACT0:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[IMP_DEF0]]:_(<5 x s32>), 0
+ CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[IMP_DEF1]]:_(<5 x s32>), 0
+ CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[EXTRACT0]]:_, [[EXTRACT1]]:_
+ CHECK: [[INSERT0:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[IMP_DEF2]]:_, [[AND0]]:_(<2 x s32>), 0
+
+ CHECK: [[EXTRACT2:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[IMP_DEF0]]:_(<5 x s32>), 64
+ CHECK: [[EXTRACT3:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[IMP_DEF1]]:_(<5 x s32>), 64
+ CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[EXTRACT2]]:_, [[EXTRACT3]]:_
+ CHECK: [[INSERT1:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT0]]:_, [[AND1]]:_(<2 x s32>), 64
+
+ CHECK: [[EXTRACT4:%[0-9]+]]:_(s32) = G_EXTRACT [[IMP_DEF0]]:_(<5 x s32>), 128
+ CHECK: [[EXTRACT5:%[0-9]+]]:_(s32) = G_EXTRACT [[IMP_DEF1]]:_(<5 x s32>), 128
+ CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[EXTRACT4]]:_, [[EXTRACT5]]:_
+ CHECK: [[INSERT2:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT1]]:_, [[AND2]]:_(s32), 128
+ )";
+
+ // Check
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, MoreElementsAnd) {
+ if (!TM)
+ return;
+
+ LLT s32 = LLT::scalar(32);
+ LLT v2s32 = LLT::vector(2, 32);
+ LLT v6s32 = LLT::vector(6, 32);
+
+ LegalizerInfo LI;
+ LI.getActionDefinitionsBuilder(TargetOpcode::G_AND)
+ .legalFor({v6s32})
+ .clampMinNumElements(0, s32, 6);
+ LI.computeTables();
+
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, LI, Observer, B);
+
+ B.setInsertPt(*EntryMBB, EntryMBB->end());
+
+ auto Val0 = B.buildBitcast(v2s32, Copies[0]);
+ auto Val1 = B.buildBitcast(v2s32, Copies[1]);
+
+ auto And = B.buildAnd(v2s32, Val0, Val1);
+
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.moreElementsVector(*And, 0, v6s32));
+
+ auto CheckStr = R"(
+ CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
+ CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
+ CHECK: [[IMP_DEF0:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
+ CHECK: [[CONCAT0:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>)
+ CHECK: [[IMP_DEF1:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
+ CHECK: [[CONCAT1:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>)
+ CHECK: [[AND:%[0-9]+]]:_(<6 x s32>) = G_AND [[CONCAT0]]:_, [[CONCAT1]]:_
+ CHECK: (<2 x s32>) = G_EXTRACT [[AND]]:_(<6 x s32>), 0
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, FewerElementsPhi) {
+ if (!TM)
+ return;
+
+ LLT s1 = LLT::scalar(1);
+ LLT s32 = LLT::scalar(32);
+ LLT s64 = LLT::scalar(64);
+ LLT v2s32 = LLT::vector(2, 32);
+ LLT v5s32 = LLT::vector(5, 32);
+
+ LegalizerInfo LI;
+ LI.getActionDefinitionsBuilder(TargetOpcode::G_PHI)
+ .legalFor({v2s32})
+ .clampMinNumElements(0, s32, 2);
+ LI.computeTables();
+
+ LLT PhiTy = v5s32;
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, LI, Observer, B);
+ B.setMBB(*EntryMBB);
+
+ MachineBasicBlock *MidMBB = MF->CreateMachineBasicBlock();
+ MachineBasicBlock *EndMBB = MF->CreateMachineBasicBlock();
+ MF->insert(MF->end(), MidMBB);
+ MF->insert(MF->end(), EndMBB);
+
+ EntryMBB->addSuccessor(MidMBB);
+ EntryMBB->addSuccessor(EndMBB);
+ MidMBB->addSuccessor(EndMBB);
+
+ auto InitVal = B.buildUndef(PhiTy);
+ auto InitOtherVal = B.buildConstant(s64, 999);
+
+ auto ICmp = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);
+ B.buildBrCond(ICmp.getReg(0), *MidMBB);
+ B.buildBr(*EndMBB);
+
+
+ B.setMBB(*MidMBB);
+ auto MidVal = B.buildUndef(PhiTy);
+ auto MidOtherVal = B.buildConstant(s64, 345);
+ B.buildBr(*EndMBB);
+
+ B.setMBB(*EndMBB);
+ auto Phi = B.buildInstr(TargetOpcode::G_PHI)
+ .addDef(MRI->createGenericVirtualRegister(PhiTy))
+ .addUse(InitVal.getReg(0))
+ .addMBB(EntryMBB)
+ .addUse(MidVal.getReg(0))
+ .addMBB(MidMBB);
+
+ // Insert another irrelevant phi to make sure the rebuild is inserted after
+ // it.
+ B.buildInstr(TargetOpcode::G_PHI)
+ .addDef(MRI->createGenericVirtualRegister(s64))
+ .addUse(InitOtherVal.getReg(0))
+ .addMBB(EntryMBB)
+ .addUse(MidOtherVal.getReg(0))
+ .addMBB(MidMBB);
+
+ // Add some use instruction after the phis.
+ B.buildAnd(PhiTy, Phi.getReg(0), Phi.getReg(0));
+
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.fewerElementsVector(*Phi, 0, v2s32));
+
+ auto CheckStr = R"(
+ CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+ CHECK: [[EXTRACT0:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 0
+ CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 64
+ CHECK: [[EXTRACT2:%[0-9]+]]:_(s32) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 128
+ CHECK: G_BRCOND
+
+ CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+ CHECK: [[EXTRACT3:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 0
+ CHECK: [[EXTRACT4:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 64
+ CHECK: [[EXTRACT5:%[0-9]+]]:_(s32) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 128
+ CHECK: G_BR
+
+ CHECK: [[PHI0:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT0]]:_(<2 x s32>), %bb.0, [[EXTRACT3]]:_(<2 x s32>), %bb.1
+ CHECK: [[PHI1:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT1]]:_(<2 x s32>), %bb.0, [[EXTRACT4]]:_(<2 x s32>), %bb.1
+ CHECK: [[PHI2:%[0-9]+]]:_(s32) = G_PHI [[EXTRACT2]]:_(s32), %bb.0, [[EXTRACT5]]:_(s32), %bb.1
+
+ CHECK: [[OTHER_PHI:%[0-9]+]]:_(s64) = G_PHI
+ CHECK: [[REBUILD_VAL_IMPDEF:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+ CHECK: [[INSERT0:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[REBUILD_VAL_IMPDEF]]:_, [[PHI0]]:_(<2 x s32>), 0
+ CHECK: [[INSERT1:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT0]]:_, [[PHI1]]:_(<2 x s32>), 64
+ CHECK: [[INSERT2:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT1]]:_, [[PHI2]]:_(s32), 128
+ CHECK: [[USE_OP:%[0-9]+]]:_(<5 x s32>) = G_AND [[INSERT2]]:_, [[INSERT2]]:_
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+// FNEG expansion in terms of FSUB
+TEST_F(GISelMITest, LowerFNEG) {
+ if (!TM)
+ return;
+
+ // Declare your legalization info
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_FSUB).legalFor({s64});
+ });
+
+ // Build Instr. Make sure FMF are preserved.
+ auto FAdd =
+ B.buildInstr(TargetOpcode::G_FADD, {LLT::scalar(64)}, {Copies[0], Copies[1]},
+ MachineInstr::MIFlag::FmNsz);
+
+ // Should not propagate the flags of src instruction.
+ auto FNeg0 =
+ B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {FAdd.getReg(0)},
+ {MachineInstr::MIFlag::FmArcp});
+
+ // Preserve the one flag.
+ auto FNeg1 =
+ B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {Copies[0]},
+ MachineInstr::MIFlag::FmNoInfs);
+
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ // Perform Legalization
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*FNeg0, 0, LLT::scalar(64)));
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*FNeg1, 0, LLT::scalar(64)));
+
+ auto CheckStr = R"(
+ CHECK: [[FADD:%[0-9]+]]:_(s64) = nsz G_FADD %0:_, %1:_
+ CHECK: [[CONST0:%[0-9]+]]:_(s64) = G_FCONSTANT double -0.000000e+00
+ CHECK: [[FSUB0:%[0-9]+]]:_(s64) = arcp G_FSUB [[CONST0]]:_, [[FADD]]:_
+ CHECK: [[CONST1:%[0-9]+]]:_(s64) = G_FCONSTANT double -0.000000e+00
+ CHECK: [[FSUB1:%[0-9]+]]:_(s64) = ninf G_FSUB [[CONST1]]:_, %0:_
+ )";
+
+ // Check
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, LowerMinMax) {
+ if (!TM)
+ return;
+
+ LLT s64 = LLT::scalar(64);
+ LLT v2s32 = LLT::vector(2, 32);
+
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
+ .lowerFor({s64, LLT::vector(2, s32)});
+ });
+
+ auto SMin = B.buildSMin(s64, Copies[0], Copies[1]);
+ auto SMax = B.buildSMax(s64, Copies[0], Copies[1]);
+ auto UMin = B.buildUMin(s64, Copies[0], Copies[1]);
+ auto UMax = B.buildUMax(s64, Copies[0], Copies[1]);
+
+ auto VecVal0 = B.buildBitcast(v2s32, Copies[0]);
+ auto VecVal1 = B.buildBitcast(v2s32, Copies[1]);
+
+ auto SMinV = B.buildSMin(v2s32, VecVal0, VecVal1);
+ auto SMaxV = B.buildSMax(v2s32, VecVal0, VecVal1);
+ auto UMinV = B.buildUMin(v2s32, VecVal0, VecVal1);
+ auto UMaxV = B.buildUMax(v2s32, VecVal0, VecVal1);
+
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*SMin, 0, s64));
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*SMax, 0, s64));
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*UMin, 0, s64));
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*UMax, 0, s64));
+
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*SMinV, 0, v2s32));
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*SMaxV, 0, v2s32));
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*UMinV, 0, v2s32));
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.lower(*UMaxV, 0, v2s32));
+
+ auto CheckStr = R"(
+ CHECK: [[CMP0:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), %0:_(s64), %1:_
+ CHECK: [[SMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP0]]:_(s1), %0:_, %1:_
+
+ CHECK: [[CMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), %0:_(s64), %1:_
+ CHECK: [[SMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP1]]:_(s1), %0:_, %1:_
+
+ CHECK: [[CMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), %0:_(s64), %1:_
+ CHECK: [[UMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP2]]:_(s1), %0:_, %1:_
+
+ CHECK: [[CMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), %0:_(s64), %1:_
+ CHECK: [[UMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP3]]:_(s1), %0:_, %1:_
+
+ CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %0:_(s64)
+ CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %1:_(s64)
+
+ CHECK: [[VCMP0:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(slt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
+ CHECK: [[SMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP0]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
+
+ CHECK: [[VCMP1:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(sgt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
+ CHECK: [[SMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP1]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
+
+ CHECK: [[VCMP2:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
+ CHECK: [[UMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP2]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
+
+ CHECK: [[VCMP3:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ugt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
+ CHECK: [[UMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP3]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, WidenScalarBuildVector) {
+ if (!TM)
+ return;
+
+ LLT S32 = LLT::scalar(32);
+ LLT S16 = LLT::scalar(16);
+ LLT V2S16 = LLT::vector(2, S16);
+ LLT V2S32 = LLT::vector(2, S32);
+
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
+ .lowerFor({s64, LLT::vector(2, s32)});
+ });
+
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ B.setInsertPt(*EntryMBB, EntryMBB->end());
+
+ Register Constant0 = B.buildConstant(S16, 1).getReg(0);
+ Register Constant1 = B.buildConstant(S16, 2).getReg(0);
+ auto BV0 = B.buildBuildVector(V2S16, {Constant0, Constant1});
+ auto BV1 = B.buildBuildVector(V2S16, {Constant0, Constant1});
+
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.widenScalar(*BV0, 0, V2S32));
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.widenScalar(*BV1, 1, S32));
+
+ auto CheckStr = R"(
+ CHECK: [[K0:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
+ CHECK-NEXT: [[K1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
+ CHECK-NEXT: [[EXT_K0_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
+ CHECK-NEXT: [[EXT_K1_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
+ CHECK-NEXT: [[BV0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[EXT_K0_0]]:_(s32), [[EXT_K1_0]]:_(s32)
+ CHECK-NEXT: [[BV0_TRUNC:%[0-9]+]]:_(<2 x s16>) = G_TRUNC [[BV0]]
+
+ CHECK: [[EXT_K0_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
+ CHECK-NEXT: [[EXT_K1_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
+
+ CHECK-NEXT: [[BV1:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR_TRUNC [[EXT_K0_1]]:_(s32), [[EXT_K1_1]]:_(s32)
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, LowerMergeValues) {
+ if (!TM)
+ return;
+
+ const LLT S32 = LLT::scalar(32);
+ const LLT S24 = LLT::scalar(24);
+ const LLT S21 = LLT::scalar(21);
+ const LLT S16 = LLT::scalar(16);
+ const LLT S9 = LLT::scalar(9);
+ const LLT S8 = LLT::scalar(8);
+ const LLT S3 = LLT::scalar(3);
+
+ DefineLegalizerInfo(A, {
+ getActionDefinitionsBuilder(G_UNMERGE_VALUES)
+ .widenScalarIf(typeIs(1, LLT::scalar(3)), changeTo(1, LLT::scalar(9)));
+ });
+
+ AInfo Info(MF->getSubtarget());
+ DummyGISelObserver Observer;
+ LegalizerHelper Helper(*MF, Info, Observer, B);
+ B.setInsertPt(*EntryMBB, EntryMBB->end());
+
+ // 24 = 3 3 3 3 3 3 3 3
+ // => 9
+ //
+ // This can do 3 merges, but need an extra implicit_def.
+ SmallVector<Register, 8> Merge0Ops;
+ for (int I = 0; I != 8; ++I)
+ Merge0Ops.push_back(B.buildConstant(S3, I).getReg(0));
+
+ auto Merge0 = B.buildMerge(S24, Merge0Ops);
+
+ // 21 = 3 3 3 3 3 3 3
+ // => 9, 2 extra implicit_def needed
+ //
+ SmallVector<Register, 8> Merge1Ops;
+ for (int I = 0; I != 7; ++I)
+ Merge1Ops.push_back(B.buildConstant(S3, I).getReg(0));
+
+ auto Merge1 = B.buildMerge(S21, Merge1Ops);
+
+ SmallVector<Register, 8> Merge2Ops;
+ for (int I = 0; I != 2; ++I)
+ Merge2Ops.push_back(B.buildConstant(S8, I).getReg(0));
+
+ auto Merge2 = B.buildMerge(S16, Merge2Ops);
+
+
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.widenScalar(*Merge0, 1, S9));
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.widenScalar(*Merge1, 1, S9));
+
+ // Request a source size greater than the original destination size.
+ EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+ Helper.widenScalar(*Merge2, 1, S32));
+
+ auto CheckStr = R"(
+ CHECK: [[K0:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
+ CHECK-NEXT: [[K1:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
+ CHECK-NEXT: [[K2:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
+ CHECK-NEXT: [[K3:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
+ CHECK-NEXT: [[K4:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
+ CHECK-NEXT: [[K5:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
+ CHECK-NEXT: [[K6:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
+ CHECK-NEXT: [[K7:%[0-9]+]]:_(s3) = G_CONSTANT i3 -1
+ CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
+ CHECK-NEXT: [[MERGE0:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K0]]:_(s3), [[K1]]:_(s3), [[K2]]:_(s3)
+ CHECK-NEXT: [[MERGE1:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K3]]:_(s3), [[K4]]:_(s3), [[K5]]:_(s3)
+ CHECK-NEXT: [[MERGE2:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K6]]:_(s3), [[K7]]:_(s3), [[IMPDEF0]]:_(s3)
+ CHECK-NEXT: [[MERGE3:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE0]]:_(s9), [[MERGE1]]:_(s9), [[MERGE2]]:_(s9)
+ CHECK-NEXT: (s24) = G_TRUNC [[MERGE3]]:_(s27)
+
+
+ CHECK: [[K8:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
+ CHECK-NEXT: [[K9:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
+ CHECK-NEXT: [[K10:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
+ CHECK-NEXT: [[K11:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
+ CHECK-NEXT: [[K12:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
+ CHECK-NEXT: [[K13:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
+ CHECK-NEXT: [[K14:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
+ CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
+ CHECK-NEXT: [[MERGE4:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K8]]:_(s3), [[K9]]:_(s3), [[K10]]:_(s3)
+ CHECK-NEXT: [[MERGE5:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K11]]:_(s3), [[K12]]:_(s3), [[K13]]:_(s3)
+ CHECK-NEXT: [[MERGE6:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K14]]:_(s3), [[IMPDEF1]]:_(s3), [[IMPDEF1]]:_(s3)
+ CHECK-NEXT: [[MERGE7:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE4]]:_(s9), [[MERGE5]]:_(s9), [[MERGE6]]:_(s9)
+ CHECK-NEXT: (s21) = G_TRUNC [[MERGE7]]:_(s27)
+
+
+ CHECK: [[K15:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
+ CHECK-NEXT: [[K16:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
+ CHECK-NEXT: [[ZEXT_K15:[0-9]+]]:_(s32) = G_ZEXT [[K15]]:_(s8)
+ CHECK-NEXT: [[ZEXT_K16:[0-9]+]]:_(s32) = G_ZEXT [[K16]]:_(s8)
+ [[K16:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ZEXT_K16]]:_, [[K16]]:_(s32)
+ [[OR:%[0-9]+]]:_(s32) = G_OR [[ZEXT_K16]]:_, [[SHL]]:_
+ (s16) = G_TRUNC [[OR]]:_(s32)
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
}
} // namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
index 42371e6..b342143 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
@@ -1,14 +1,14 @@
//===- llvm/unittest/CodeGen/GlobalISel/LegalizerInfoTest.cpp -------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
+#include "GISelMITest.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -34,12 +34,9 @@
return OS;
}
-std::ostream &
-operator<<(std::ostream &OS, const llvm::LLT Ty) {
- std::string Repr;
- raw_string_ostream SS{Repr};
- Ty.print(SS);
- OS << SS.str();
+std::ostream &operator<<(std::ostream &OS, const llvm::LegalizeActionStep Ty) {
+ OS << "LegalizeActionStep(" << Ty.Action << ", " << Ty.TypeIdx << ", "
+ << Ty.NewType << ')';
return OS;
}
}
@@ -62,28 +59,28 @@
for (unsigned opcode : {G_ADD, G_SUB}) {
// Check we infer the correct types and actually do what we're told.
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(8)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(8)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(16)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(16)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(32)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(32)}}),
LegalizeActionStep(Legal, 0, LLT{}));
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(64)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(64)}}),
LegalizeActionStep(Legal, 0, LLT{}));
// Make sure the default for over-sized types applies.
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(128)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(128)}}),
LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64)));
// Make sure we also handle unusual sizes
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(1)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(1)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(31)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(31)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(33)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(33)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(64)));
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(63)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(63)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(64)));
- ASSERT_EQ(L.getAction({opcode, {LLT::scalar(65)}}),
+ EXPECT_EQ(L.getAction({opcode, {LLT::scalar(65)}}),
LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64)));
}
}
@@ -108,18 +105,18 @@
// Check we infer the correct types and actually do what we're told for some
// simple cases.
- ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 8)}}),
+ EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(8, 8)}}),
LegalizeActionStep(Legal, 0, LLT{}));
- ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 7)}}),
+ EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(8, 7)}}),
LegalizeActionStep(WidenScalar, 0, LLT::vector(8, 8)));
- ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(2, 8)}}),
+ EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(2, 8)}}),
LegalizeActionStep(MoreElements, 0, LLT::vector(8, 8)));
- ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 32)}}),
+ EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(8, 32)}}),
LegalizeActionStep(FewerElements, 0, LLT::vector(4, 32)));
// Check a few non-power-of-2 sizes:
- ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(3, 3)}}),
+ EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(3, 3)}}),
LegalizeActionStep(WidenScalar, 0, LLT::vector(3, 8)));
- ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(3, 8)}}),
+ EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(3, 8)}}),
LegalizeActionStep(MoreElements, 0, LLT::vector(8, 8)));
}
@@ -139,14 +136,14 @@
L.computeTables();
// Check we infer the correct types and actually do what we're told.
- ASSERT_EQ(L.getAction({G_PTRTOINT, {s64, p0}}),
+ EXPECT_EQ(L.getAction({G_PTRTOINT, {s64, p0}}),
LegalizeActionStep(Legal, 0, LLT{}));
// Make sure we also handle unusual sizes
- ASSERT_EQ(
+ EXPECT_EQ(
L.getAction({G_PTRTOINT, {LLT::scalar(65), s64}}),
LegalizeActionStep(NarrowScalar, 0, s64));
- ASSERT_EQ(
+ EXPECT_EQ(
L.getAction({G_PTRTOINT, {s64, LLT::pointer(0, 32)}}),
LegalizeActionStep(Unsupported, 1, LLT::pointer(0, 32)));
}
@@ -164,9 +161,9 @@
L.computeTables();
- ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(16)}}),
+ EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(16)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
- ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(32)}}),
+ EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(32)}}),
LegalizeActionStep(Lower, 0, LLT::scalar(32)));
}
@@ -182,20 +179,229 @@
// Check we infer the correct types and actually do what we're told.
for (unsigned Size : {1, 8, 16, 32}) {
- ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(Size)}}),
+ EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(Size)}}),
LegalizeActionStep(Legal, 0, LLT{}));
}
- ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(2)}}),
+ EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(2)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(8)));
- ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(7)}}),
+ EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(7)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(8)));
- ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(9)}}),
+ EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(9)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(16)));
- ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(17)}}),
+ EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(17)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
- ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(31)}}),
+ EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(31)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
- ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(33)}}),
+ EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(33)}}),
LegalizeActionStep(Unsupported, 0, LLT::scalar(33)));
}
}
+
+#define EXPECT_ACTION(Action, Index, Type, Query) \
+ do { \
+ auto A = LI.getAction(Query); \
+ EXPECT_EQ(LegalizeActionStep(Action, Index, Type), A) << A; \
+ } while (0)
+
+TEST(LegalizerInfoTest, RuleSets) {
+ using namespace TargetOpcode;
+
+ const LLT s5 = LLT::scalar(5);
+ const LLT s8 = LLT::scalar(8);
+ const LLT s16 = LLT::scalar(16);
+ const LLT s32 = LLT::scalar(32);
+ const LLT s33 = LLT::scalar(33);
+ const LLT s64 = LLT::scalar(64);
+
+ const LLT v2s5 = LLT::vector(2, 5);
+ const LLT v2s8 = LLT::vector(2, 8);
+ const LLT v2s16 = LLT::vector(2, 16);
+ const LLT v2s32 = LLT::vector(2, 32);
+ const LLT v3s32 = LLT::vector(3, 32);
+ const LLT v4s32 = LLT::vector(4, 32);
+ const LLT v2s33 = LLT::vector(2, 33);
+ const LLT v2s64 = LLT::vector(2, 64);
+
+ const LLT p0 = LLT::pointer(0, 32);
+ const LLT v3p0 = LLT::vector(3, p0);
+ const LLT v4p0 = LLT::vector(4, p0);
+
+ {
+ LegalizerInfo LI;
+
+ LI.getActionDefinitionsBuilder(G_IMPLICIT_DEF)
+ .legalFor({v4s32, v4p0})
+ .moreElementsToNextPow2(0);
+ LI.computeTables();
+
+ EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {s32}));
+ EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {v2s32}));
+ EXPECT_ACTION(MoreElements, 0, v4p0, LegalityQuery(G_IMPLICIT_DEF, {v3p0}));
+ EXPECT_ACTION(MoreElements, 0, v4s32, LegalityQuery(G_IMPLICIT_DEF, {v3s32}));
+ }
+
+ // Test minScalarOrElt
+ {
+ LegalizerInfo LI;
+ LI.getActionDefinitionsBuilder(G_OR)
+ .legalFor({s32})
+ .minScalarOrElt(0, s32);
+ LI.computeTables();
+
+ EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16}));
+ EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_OR, {v2s16}));
+ }
+
+ // Test maxScalarOrELt
+ {
+ LegalizerInfo LI;
+ LI.getActionDefinitionsBuilder(G_AND)
+ .legalFor({s16})
+ .maxScalarOrElt(0, s16);
+ LI.computeTables();
+
+ EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32}));
+ EXPECT_ACTION(NarrowScalar, 0, v2s16, LegalityQuery(G_AND, {v2s32}));
+ }
+
+ // Test clampScalarOrElt
+ {
+ LegalizerInfo LI;
+ LI.getActionDefinitionsBuilder(G_XOR)
+ .legalFor({s16})
+ .clampScalarOrElt(0, s16, s32);
+ LI.computeTables();
+
+ EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64}));
+ EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8}));
+
+ // Make sure the number of elements is preserved.
+ EXPECT_ACTION(NarrowScalar, 0, v2s32, LegalityQuery(G_XOR, {v2s64}));
+ EXPECT_ACTION(WidenScalar, 0, v2s16, LegalityQuery(G_XOR, {v2s8}));
+ }
+
+ // Test minScalar
+ {
+ LegalizerInfo LI;
+ LI.getActionDefinitionsBuilder(G_OR)
+ .legalFor({s32})
+ .minScalar(0, s32);
+ LI.computeTables();
+
+ // Only handle scalars, ignore vectors.
+ EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16}));
+ EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_OR, {v2s16}));
+ }
+
+ // Test maxScalar
+ {
+ LegalizerInfo LI;
+ LI.getActionDefinitionsBuilder(G_AND)
+ .legalFor({s16})
+ .maxScalar(0, s16);
+ LI.computeTables();
+
+ // Only handle scalars, ignore vectors.
+ EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32}));
+ EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s32}));
+ }
+
+ // Test clampScalar
+ {
+ LegalizerInfo LI;
+
+ LI.getActionDefinitionsBuilder(G_XOR)
+ .legalFor({s16})
+ .clampScalar(0, s16, s32);
+ LI.computeTables();
+
+ EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64}));
+ EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8}));
+
+ // Only handle scalars, ignore vectors.
+ EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s64}));
+ EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s8}));
+ }
+
+ // Test widenScalarOrEltToNextPow2
+ {
+ LegalizerInfo LI;
+
+ LI.getActionDefinitionsBuilder(G_AND)
+ .legalFor({s32})
+ .widenScalarOrEltToNextPow2(0, 32);
+ LI.computeTables();
+
+ // Handle scalars and vectors
+ EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5}));
+ EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_AND, {v2s5}));
+ EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33}));
+ EXPECT_ACTION(WidenScalar, 0, v2s64, LegalityQuery(G_AND, {v2s33}));
+ }
+
+ // Test widenScalarToNextPow2
+ {
+ LegalizerInfo LI;
+
+ LI.getActionDefinitionsBuilder(G_AND)
+ .legalFor({s32})
+ .widenScalarToNextPow2(0, 32);
+ LI.computeTables();
+
+ EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5}));
+ EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33}));
+
+ // Do nothing for vectors.
+ EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s5}));
+ EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s33}));
+ }
+}
+
+TEST(LegalizerInfoTest, MMOAlignment) {
+ using namespace TargetOpcode;
+
+ const LLT s32 = LLT::scalar(32);
+ const LLT p0 = LLT::pointer(0, 64);
+
+ {
+ LegalizerInfo LI;
+ LI.getActionDefinitionsBuilder(G_LOAD)
+ .legalForTypesWithMemDesc({{s32, p0, 32, 32}});
+
+ LI.computeTables();
+
+ EXPECT_ACTION(Legal, 0, LLT(),
+ LegalityQuery(G_LOAD, {s32, p0},
+ LegalityQuery::MemDesc{
+ 32, 32, AtomicOrdering::NotAtomic}));
+ EXPECT_ACTION(Unsupported, 0, LLT(),
+ LegalityQuery(G_LOAD, {s32, p0},
+ LegalityQuery::MemDesc{
+ 32, 16, AtomicOrdering::NotAtomic }));
+ EXPECT_ACTION(Unsupported, 0, LLT(),
+ LegalityQuery(G_LOAD, {s32, p0},
+ LegalityQuery::MemDesc{
+ 32, 8, AtomicOrdering::NotAtomic}));
+ }
+
+ // Test that the maximum supported alignment value isn't truncated
+ {
+ // Maximum IR defined alignment in bytes.
+ const uint64_t MaxAlignment = UINT64_C(1) << 29;
+ const uint64_t MaxAlignInBits = 8 * MaxAlignment;
+ LegalizerInfo LI;
+ LI.getActionDefinitionsBuilder(G_LOAD)
+ .legalForTypesWithMemDesc({{s32, p0, 32, MaxAlignInBits}});
+
+ LI.computeTables();
+
+ EXPECT_ACTION(Legal, 0, LLT(),
+ LegalityQuery(G_LOAD, {s32, p0},
+ LegalityQuery::MemDesc{32,
+ MaxAlignInBits, AtomicOrdering::NotAtomic}));
+ EXPECT_ACTION(Unsupported, 0, LLT(),
+ LegalityQuery(G_LOAD, {s32, p0},
+ LegalityQuery::MemDesc{
+ 32, 8, AtomicOrdering::NotAtomic }));
+ }
+}
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
new file mode 100644
index 0000000..f6d8112
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
@@ -0,0 +1,280 @@
+//===- MachineIRBuilderTest.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "GISelMITest.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+
+TEST_F(GISelMITest, TestBuildConstantFConstant) {
+ if (!TM)
+ return;
+
+ B.buildConstant(LLT::scalar(32), 42);
+ B.buildFConstant(LLT::scalar(32), 1.0);
+
+ B.buildConstant(LLT::vector(2, 32), 99);
+ B.buildFConstant(LLT::vector(2, 32), 2.0);
+
+ // Test APFloat overload.
+ APFloat KVal(APFloat::IEEEdouble(), "4.0");
+ B.buildFConstant(LLT::scalar(64), KVal);
+
+ auto CheckStr = R"(
+ CHECK: [[CONST0:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+ CHECK: [[FCONST0:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+00
+ CHECK: [[CONST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 99
+ CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[CONST1]]:_(s32), [[CONST1]]:_(s32)
+ CHECK: [[FCONST1:%[0-9]+]]:_(s32) = G_FCONSTANT float 2.000000e+00
+ CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FCONST1]]:_(s32), [[FCONST1]]:_(s32)
+ CHECK: [[FCONST2:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+
+TEST_F(GISelMITest, TestBuildConstantFConstantDeath) {
+ if (!TM)
+ return;
+
+ LLVMContext &Ctx = MF->getFunction().getContext();
+ APInt APV32(32, 12345);
+
+ // Test APInt version breaks
+ EXPECT_DEATH(B.buildConstant(LLT::scalar(16), APV32),
+ "creating constant with the wrong size");
+ EXPECT_DEATH(B.buildConstant(LLT::vector(2, 16), APV32),
+ "creating constant with the wrong size");
+
+ // Test ConstantInt version breaks
+ ConstantInt *CI = ConstantInt::get(Ctx, APV32);
+ EXPECT_DEATH(B.buildConstant(LLT::scalar(16), *CI),
+ "creating constant with the wrong size");
+ EXPECT_DEATH(B.buildConstant(LLT::vector(2, 16), *CI),
+ "creating constant with the wrong size");
+
+ APFloat DoubleVal(APFloat::IEEEdouble());
+ ConstantFP *CF = ConstantFP::get(Ctx, DoubleVal);
+ EXPECT_DEATH(B.buildFConstant(LLT::scalar(16), *CF),
+ "creating fconstant with the wrong size");
+ EXPECT_DEATH(B.buildFConstant(LLT::vector(2, 16), *CF),
+ "creating fconstant with the wrong size");
+}
+
+#endif
+#endif
+
+TEST_F(GISelMITest, DstOpSrcOp) {
+ if (!TM)
+ return;
+
+ SmallVector<Register, 4> Copies;
+ collectCopies(Copies, MF);
+
+ LLT s64 = LLT::scalar(64);
+ auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
+
+ // Test SrcOp and DstOp can be constructed directly from MachineOperand by
+ // copying the instruction
+ B.buildAdd(MIBAdd->getOperand(0), MIBAdd->getOperand(1), MIBAdd->getOperand(2));
+
+
+ auto CheckStr = R"(
+ ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY0]]:_, [[COPY1]]:_
+ ; CHECK: [[ADD]]:_(s64) = G_ADD [[COPY0]]:_, [[COPY1]]:_
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildUnmerge) {
+ if (!TM)
+ return;
+
+ SmallVector<Register, 4> Copies;
+ collectCopies(Copies, MF);
+ B.buildUnmerge(LLT::scalar(32), Copies[0]);
+ B.buildUnmerge(LLT::scalar(16), Copies[1]);
+
+ auto CheckStr = R"(
+ ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK: [[UNMERGE32_0:%[0-9]+]]:_(s32), [[UNMERGE32_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY0]]
+ ; CHECK: [[UNMERGE16_0:%[0-9]+]]:_(s16), [[UNMERGE16_1:%[0-9]+]]:_(s16), [[UNMERGE16_2:%[0-9]+]]:_(s16), [[UNMERGE16_3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY1]]
+
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, TestBuildFPInsts) {
+ if (!TM)
+ return;
+
+ SmallVector<Register, 4> Copies;
+ collectCopies(Copies, MF);
+
+ LLT S64 = LLT::scalar(64);
+
+ B.buildFAdd(S64, Copies[0], Copies[1]);
+ B.buildFSub(S64, Copies[0], Copies[1]);
+ B.buildFMA(S64, Copies[0], Copies[1], Copies[2]);
+ B.buildFNeg(S64, Copies[0]);
+ B.buildFAbs(S64, Copies[0]);
+ B.buildFCopysign(S64, Copies[0], Copies[1]);
+
+ auto CheckStr = R"(
+ ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2
+ ; CHECK: [[FADD:%[0-9]+]]:_(s64) = G_FADD [[COPY0]]:_, [[COPY1]]:_
+ ; CHECK: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[COPY0]]:_, [[COPY1]]:_
+ ; CHECK: [[FMA:%[0-9]+]]:_(s64) = G_FMA [[COPY0]]:_, [[COPY1]]:_, [[COPY2]]:_
+ ; CHECK: [[FNEG:%[0-9]+]]:_(s64) = G_FNEG [[COPY0]]:_
+ ; CHECK: [[FABS:%[0-9]+]]:_(s64) = G_FABS [[COPY0]]:_
+ ; CHECK: [[FCOPYSIGN:%[0-9]+]]:_(s64) = G_FCOPYSIGN [[COPY0]]:_, [[COPY1]]:_
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildIntrinsic) {
+ if (!TM)
+ return;
+
+ LLT S64 = LLT::scalar(64);
+ SmallVector<Register, 4> Copies;
+ collectCopies(Copies, MF);
+
+ // Make sure DstOp version works. sqrt is just a placeholder intrinsic.
+ B.buildIntrinsic(Intrinsic::sqrt, {S64}, false)
+ .addUse(Copies[0]);
+
+ // Make sure register version works
+ SmallVector<Register, 1> Results;
+ Results.push_back(MRI->createGenericVirtualRegister(S64));
+ B.buildIntrinsic(Intrinsic::sqrt, Results, false)
+ .addUse(Copies[1]);
+
+ auto CheckStr = R"(
+ ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK: [[SQRT0:%[0-9]+]]:_(s64) = G_INTRINSIC intrinsic(@llvm.sqrt), [[COPY0]]:_
+ ; CHECK: [[SQRT1:%[0-9]+]]:_(s64) = G_INTRINSIC intrinsic(@llvm.sqrt), [[COPY1]]:_
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildXor) {
+ if (!TM)
+ return;
+
+ LLT S64 = LLT::scalar(64);
+ LLT S128 = LLT::scalar(128);
+ SmallVector<Register, 4> Copies;
+ collectCopies(Copies, MF);
+ B.buildXor(S64, Copies[0], Copies[1]);
+ B.buildNot(S64, Copies[0]);
+
+ // Make sure this works with > 64-bit types
+ auto Merge = B.buildMerge(S128, {Copies[0], Copies[1]});
+ B.buildNot(S128, Merge);
+ auto CheckStr = R"(
+ ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK: [[XOR0:%[0-9]+]]:_(s64) = G_XOR [[COPY0]]:_, [[COPY1]]:_
+ ; CHECK: [[NEGONE64:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+ ; CHECK: [[XOR1:%[0-9]+]]:_(s64) = G_XOR [[COPY0]]:_, [[NEGONE64]]:_
+ ; CHECK: [[MERGE:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY0]]:_(s64), [[COPY1]]:_(s64)
+ ; CHECK: [[NEGONE128:%[0-9]+]]:_(s128) = G_CONSTANT i128 -1
+ ; CHECK: [[XOR2:%[0-9]+]]:_(s128) = G_XOR [[MERGE]]:_, [[NEGONE128]]:_
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildBitCounts) {
+ if (!TM)
+ return;
+
+ LLT S32 = LLT::scalar(32);
+ SmallVector<Register, 4> Copies;
+ collectCopies(Copies, MF);
+
+ B.buildCTPOP(S32, Copies[0]);
+ B.buildCTLZ(S32, Copies[0]);
+ B.buildCTLZ_ZERO_UNDEF(S32, Copies[1]);
+ B.buildCTTZ(S32, Copies[0]);
+ B.buildCTTZ_ZERO_UNDEF(S32, Copies[1]);
+
+ auto CheckStr = R"(
+ ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK: [[CTPOP:%[0-9]+]]:_(s32) = G_CTPOP [[COPY0]]:_
+ ; CHECK: [[CTLZ0:%[0-9]+]]:_(s32) = G_CTLZ [[COPY0]]:_
+ ; CHECK: [[CTLZ_UNDEF0:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[COPY1]]:_
+ ; CHECK: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[COPY0]]:_
+ ; CHECK: [[CTTZ_UNDEF0:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[COPY1]]:_
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildCasts) {
+ if (!TM)
+ return;
+
+ LLT S32 = LLT::scalar(32);
+ SmallVector<Register, 4> Copies;
+ collectCopies(Copies, MF);
+
+ B.buildUITOFP(S32, Copies[0]);
+ B.buildSITOFP(S32, Copies[0]);
+ B.buildFPTOUI(S32, Copies[0]);
+ B.buildFPTOSI(S32, Copies[0]);
+
+ auto CheckStr = R"(
+ ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: [[UITOFP:%[0-9]+]]:_(s32) = G_UITOFP [[COPY0]]:_
+ ; CHECK: [[SITOFP:%[0-9]+]]:_(s32) = G_SITOFP [[COPY0]]:_
+ ; CHECK: [[FPTOUI:%[0-9]+]]:_(s32) = G_FPTOUI [[COPY0]]:_
+ ; CHECK: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY0]]:_
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildMinMax) {
+ if (!TM)
+ return;
+
+ LLT S64 = LLT::scalar(64);
+ SmallVector<Register, 4> Copies;
+ collectCopies(Copies, MF);
+
+ B.buildSMin(S64, Copies[0], Copies[1]);
+ B.buildSMax(S64, Copies[0], Copies[1]);
+ B.buildUMin(S64, Copies[0], Copies[1]);
+ B.buildUMax(S64, Copies[0], Copies[1]);
+
+ auto CheckStr = R"(
+ ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+ ; CHECK: [[SMIN0:%[0-9]+]]:_(s64) = G_SMIN [[COPY0]]:_, [[COPY1]]:_
+ ; CHECK: [[SMAX0:%[0-9]+]]:_(s64) = G_SMAX [[COPY0]]:_, [[COPY1]]:_
+ ; CHECK: [[UMIN0:%[0-9]+]]:_(s64) = G_UMIN [[COPY0]]:_, [[COPY1]]:_
+ ; CHECK: [[UMAX0:%[0-9]+]]:_(s64) = G_UMAX [[COPY0]]:_, [[COPY1]]:_
+ )";
+
+ EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
index 466a2dd..7ba7918 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
@@ -1,9 +1,8 @@
//===- PatternMatchTest.cpp -----------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -112,7 +111,7 @@
return MF;
}
-static void collectCopies(SmallVectorImpl<unsigned> &Copies,
+static void collectCopies(SmallVectorImpl<Register> &Copies,
MachineFunction *MF) {
for (auto &MBB : *MF)
for (MachineInstr &MI : MBB) {
@@ -129,7 +128,7 @@
auto ModuleMMIPair = createDummyModule(Context, *TM, "");
MachineFunction *MF =
getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
- SmallVector<unsigned, 4> Copies;
+ SmallVector<Register, 4> Copies;
collectCopies(Copies, MF);
MachineBasicBlock *EntryMBB = &*MF->begin();
MachineIRBuilder B(*MF);
@@ -138,8 +137,8 @@
auto MIBCst = B.buildConstant(LLT::scalar(64), 42);
int64_t Cst;
bool match = mi_match(MIBCst->getOperand(0).getReg(), MRI, m_ICst(Cst));
- ASSERT_TRUE(match);
- ASSERT_EQ(Cst, 42);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Cst, 42);
}
TEST(PatternMatchInstr, MatchBinaryOp) {
@@ -150,7 +149,7 @@
auto ModuleMMIPair = createDummyModule(Context, *TM, "");
MachineFunction *MF =
getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
- SmallVector<unsigned, 4> Copies;
+ SmallVector<Register, 4> Copies;
collectCopies(Copies, MF);
MachineBasicBlock *EntryMBB = &*MF->begin();
MachineIRBuilder B(*MF);
@@ -161,13 +160,13 @@
// Test case for no bind.
bool match =
mi_match(MIBAdd->getOperand(0).getReg(), MRI, m_GAdd(m_Reg(), m_Reg()));
- ASSERT_TRUE(match);
- unsigned Src0, Src1, Src2;
+ EXPECT_TRUE(match);
+ Register Src0, Src1, Src2;
match = mi_match(MIBAdd->getOperand(0).getReg(), MRI,
m_GAdd(m_Reg(Src0), m_Reg(Src1)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
- ASSERT_EQ(Src1, Copies[1]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
+ EXPECT_EQ(Src1, Copies[1]);
// Build MUL(ADD %0, %1), %2
auto MIBMul = B.buildMul(s64, MIBAdd, Copies[2]);
@@ -175,17 +174,17 @@
// Try to match MUL.
match = mi_match(MIBMul->getOperand(0).getReg(), MRI,
m_GMul(m_Reg(Src0), m_Reg(Src1)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, MIBAdd->getOperand(0).getReg());
- ASSERT_EQ(Src1, Copies[2]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, MIBAdd->getOperand(0).getReg());
+ EXPECT_EQ(Src1, Copies[2]);
// Try to match MUL(ADD)
match = mi_match(MIBMul->getOperand(0).getReg(), MRI,
m_GMul(m_GAdd(m_Reg(Src0), m_Reg(Src1)), m_Reg(Src2)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
- ASSERT_EQ(Src1, Copies[1]);
- ASSERT_EQ(Src2, Copies[2]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
+ EXPECT_EQ(Src1, Copies[1]);
+ EXPECT_EQ(Src2, Copies[2]);
// Test Commutativity.
auto MIBMul2 = B.buildMul(s64, Copies[0], B.buildConstant(s64, 42));
@@ -194,50 +193,50 @@
int64_t Cst;
match = mi_match(MIBMul2->getOperand(0).getReg(), MRI,
m_GMul(m_ICst(Cst), m_Reg(Src0)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Cst, 42);
- ASSERT_EQ(Src0, Copies[0]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Cst, 42);
+ EXPECT_EQ(Src0, Copies[0]);
// Make sure commutative doesn't work with something like SUB.
auto MIBSub = B.buildSub(s64, Copies[0], B.buildConstant(s64, 42));
match = mi_match(MIBSub->getOperand(0).getReg(), MRI,
m_GSub(m_ICst(Cst), m_Reg(Src0)));
- ASSERT_FALSE(match);
+ EXPECT_FALSE(match);
auto MIBFMul = B.buildInstr(TargetOpcode::G_FMUL, {s64},
{Copies[0], B.buildConstant(s64, 42)});
// Match and test commutativity for FMUL.
match = mi_match(MIBFMul->getOperand(0).getReg(), MRI,
m_GFMul(m_ICst(Cst), m_Reg(Src0)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Cst, 42);
- ASSERT_EQ(Src0, Copies[0]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Cst, 42);
+ EXPECT_EQ(Src0, Copies[0]);
// FSUB
auto MIBFSub = B.buildInstr(TargetOpcode::G_FSUB, {s64},
{Copies[0], B.buildConstant(s64, 42)});
match = mi_match(MIBFSub->getOperand(0).getReg(), MRI,
m_GFSub(m_Reg(Src0), m_Reg()));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
// Build AND %0, %1
auto MIBAnd = B.buildAnd(s64, Copies[0], Copies[1]);
// Try to match AND.
match = mi_match(MIBAnd->getOperand(0).getReg(), MRI,
m_GAnd(m_Reg(Src0), m_Reg(Src1)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
- ASSERT_EQ(Src1, Copies[1]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
+ EXPECT_EQ(Src1, Copies[1]);
// Build OR %0, %1
auto MIBOr = B.buildOr(s64, Copies[0], Copies[1]);
// Try to match OR.
match = mi_match(MIBOr->getOperand(0).getReg(), MRI,
m_GOr(m_Reg(Src0), m_Reg(Src1)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
- ASSERT_EQ(Src1, Copies[1]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
+ EXPECT_EQ(Src1, Copies[1]);
// Try to use the FoldableInstructionsBuilder to build binary ops.
ConstantFoldingMIRBuilder CFB(B.getState());
@@ -246,15 +245,15 @@
CFB.buildAdd(s32, CFB.buildConstant(s32, 0), CFB.buildConstant(s32, 1));
// This should be a constant now.
match = mi_match(MIBCAdd->getOperand(0).getReg(), MRI, m_ICst(Cst));
- ASSERT_TRUE(match);
- ASSERT_EQ(Cst, 1);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Cst, 1);
auto MIBCAdd1 =
CFB.buildInstr(TargetOpcode::G_ADD, {s32},
{CFB.buildConstant(s32, 0), CFB.buildConstant(s32, 1)});
// This should be a constant now.
match = mi_match(MIBCAdd1->getOperand(0).getReg(), MRI, m_ICst(Cst));
- ASSERT_TRUE(match);
- ASSERT_EQ(Cst, 1);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Cst, 1);
// Try one of the other constructors of MachineIRBuilder to make sure it's
// compatible.
@@ -265,8 +264,8 @@
{CFB1.buildConstant(s32, 1), CFB1.buildConstant(s32, 1)});
// This should be a constant now.
match = mi_match(MIBCSub->getOperand(0).getReg(), MRI, m_ICst(Cst));
- ASSERT_TRUE(match);
- ASSERT_EQ(Cst, 0);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Cst, 0);
}
TEST(PatternMatchInstr, MatchFPUnaryOp) {
@@ -277,7 +276,7 @@
auto ModuleMMIPair = createDummyModule(Context, *TM, "");
MachineFunction *MF =
getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
- SmallVector<unsigned, 4> Copies;
+ SmallVector<Register, 4> Copies;
collectCopies(Copies, MF);
MachineBasicBlock *EntryMBB = &*MF->begin();
MachineIRBuilder B(*MF);
@@ -291,53 +290,53 @@
// Match G_FABS.
auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, {s32}, {Copy0s32});
bool match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg()));
- ASSERT_TRUE(match);
+ EXPECT_TRUE(match);
- unsigned Src;
+ Register Src;
auto MIBFNeg = B.buildInstr(TargetOpcode::G_FNEG, {s32}, {Copy0s32});
match = mi_match(MIBFNeg->getOperand(0).getReg(), MRI, m_GFNeg(m_Reg(Src)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src, Copy0s32->getOperand(0).getReg());
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src, Copy0s32->getOperand(0).getReg());
match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg(Src)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src, Copy0s32->getOperand(0).getReg());
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src, Copy0s32->getOperand(0).getReg());
// Build and match FConstant.
auto MIBFCst = B.buildFConstant(s32, .5);
const ConstantFP *TmpFP{};
match = mi_match(MIBFCst->getOperand(0).getReg(), MRI, m_GFCst(TmpFP));
- ASSERT_TRUE(match);
- ASSERT_TRUE(TmpFP);
+ EXPECT_TRUE(match);
+ EXPECT_TRUE(TmpFP);
APFloat APF((float).5);
auto *CFP = ConstantFP::get(Context, APF);
- ASSERT_EQ(CFP, TmpFP);
+ EXPECT_EQ(CFP, TmpFP);
// Build double float.
LLT s64 = LLT::scalar(64);
auto MIBFCst64 = B.buildFConstant(s64, .5);
const ConstantFP *TmpFP64{};
match = mi_match(MIBFCst64->getOperand(0).getReg(), MRI, m_GFCst(TmpFP64));
- ASSERT_TRUE(match);
- ASSERT_TRUE(TmpFP64);
+ EXPECT_TRUE(match);
+ EXPECT_TRUE(TmpFP64);
APFloat APF64(.5);
auto CFP64 = ConstantFP::get(Context, APF64);
- ASSERT_EQ(CFP64, TmpFP64);
- ASSERT_NE(TmpFP64, TmpFP);
+ EXPECT_EQ(CFP64, TmpFP64);
+ EXPECT_NE(TmpFP64, TmpFP);
// Build half float.
LLT s16 = LLT::scalar(16);
auto MIBFCst16 = B.buildFConstant(s16, .5);
const ConstantFP *TmpFP16{};
match = mi_match(MIBFCst16->getOperand(0).getReg(), MRI, m_GFCst(TmpFP16));
- ASSERT_TRUE(match);
- ASSERT_TRUE(TmpFP16);
+ EXPECT_TRUE(match);
+ EXPECT_TRUE(TmpFP16);
bool Ignored;
APFloat APF16(.5);
APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
auto CFP16 = ConstantFP::get(Context, APF16);
- ASSERT_EQ(TmpFP16, CFP16);
- ASSERT_NE(TmpFP16, TmpFP);
+ EXPECT_EQ(TmpFP16, CFP16);
+ EXPECT_NE(TmpFP16, TmpFP);
}
TEST(PatternMatchInstr, MatchExtendsTrunc) {
@@ -348,7 +347,7 @@
auto ModuleMMIPair = createDummyModule(Context, *TM, "");
MachineFunction *MF =
getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
- SmallVector<unsigned, 4> Copies;
+ SmallVector<Register, 4> Copies;
collectCopies(Copies, MF);
MachineBasicBlock *EntryMBB = &*MF->begin();
MachineIRBuilder B(*MF);
@@ -361,39 +360,39 @@
auto MIBAExt = B.buildAnyExt(s64, MIBTrunc);
auto MIBZExt = B.buildZExt(s64, MIBTrunc);
auto MIBSExt = B.buildSExt(s64, MIBTrunc);
- unsigned Src0;
+ Register Src0;
bool match =
mi_match(MIBTrunc->getOperand(0).getReg(), MRI, m_GTrunc(m_Reg(Src0)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
match =
mi_match(MIBAExt->getOperand(0).getReg(), MRI, m_GAnyExt(m_Reg(Src0)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
match = mi_match(MIBSExt->getOperand(0).getReg(), MRI, m_GSExt(m_Reg(Src0)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
match = mi_match(MIBZExt->getOperand(0).getReg(), MRI, m_GZExt(m_Reg(Src0)));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
// Match ext(trunc src)
match = mi_match(MIBAExt->getOperand(0).getReg(), MRI,
m_GAnyExt(m_GTrunc(m_Reg(Src0))));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
match = mi_match(MIBSExt->getOperand(0).getReg(), MRI,
m_GSExt(m_GTrunc(m_Reg(Src0))));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
match = mi_match(MIBZExt->getOperand(0).getReg(), MRI,
m_GZExt(m_GTrunc(m_Reg(Src0))));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
}
TEST(PatternMatchInstr, MatchSpecificType) {
@@ -404,7 +403,7 @@
auto ModuleMMIPair = createDummyModule(Context, *TM, "");
MachineFunction *MF =
getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
- SmallVector<unsigned, 4> Copies;
+ SmallVector<Register, 4> Copies;
collectCopies(Copies, MF);
MachineBasicBlock *EntryMBB = &*MF->begin();
MachineIRBuilder B(*MF);
@@ -415,32 +414,32 @@
LLT s64 = LLT::scalar(64);
LLT s32 = LLT::scalar(32);
auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
- ASSERT_FALSE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
+ EXPECT_FALSE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
m_GAdd(m_SpecificType(s32), m_Reg())));
- ASSERT_TRUE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
+ EXPECT_TRUE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
m_GAdd(m_SpecificType(s64), m_Reg())));
// Try to match the destination type of a bitcast.
LLT v2s32 = LLT::vector(2, 32);
auto MIBCast = B.buildCast(v2s32, Copies[0]);
- ASSERT_TRUE(
+ EXPECT_TRUE(
mi_match(MIBCast->getOperand(0).getReg(), MRI, m_GBitcast(m_Reg())));
- ASSERT_TRUE(
+ EXPECT_TRUE(
mi_match(MIBCast->getOperand(0).getReg(), MRI, m_SpecificType(v2s32)));
- ASSERT_TRUE(
+ EXPECT_TRUE(
mi_match(MIBCast->getOperand(1).getReg(), MRI, m_SpecificType(s64)));
// Build a PTRToInt and INTTOPTR and match and test them.
LLT PtrTy = LLT::pointer(0, 64);
auto MIBIntToPtr = B.buildCast(PtrTy, Copies[0]);
auto MIBPtrToInt = B.buildCast(s64, MIBIntToPtr);
- unsigned Src0;
+ Register Src0;
// match the ptrtoint(inttoptr reg)
bool match = mi_match(MIBPtrToInt->getOperand(0).getReg(), MRI,
m_GPtrToInt(m_GIntToPtr(m_Reg(Src0))));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
}
TEST(PatternMatchInstr, MatchCombinators) {
@@ -451,7 +450,7 @@
auto ModuleMMIPair = createDummyModule(Context, *TM, "");
MachineFunction *MF =
getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
- SmallVector<unsigned, 4> Copies;
+ SmallVector<Register, 4> Copies;
collectCopies(Copies, MF);
MachineBasicBlock *EntryMBB = &*MF->begin();
MachineIRBuilder B(*MF);
@@ -460,30 +459,55 @@
LLT s64 = LLT::scalar(64);
LLT s32 = LLT::scalar(32);
auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
- unsigned Src0, Src1;
+ Register Src0, Src1;
bool match =
mi_match(MIBAdd->getOperand(0).getReg(), MRI,
m_all_of(m_SpecificType(s64), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
- ASSERT_EQ(Src1, Copies[1]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
+ EXPECT_EQ(Src1, Copies[1]);
// Check for s32 (which should fail).
match =
mi_match(MIBAdd->getOperand(0).getReg(), MRI,
m_all_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
- ASSERT_FALSE(match);
+ EXPECT_FALSE(match);
match =
mi_match(MIBAdd->getOperand(0).getReg(), MRI,
m_any_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
- ASSERT_TRUE(match);
- ASSERT_EQ(Src0, Copies[0]);
- ASSERT_EQ(Src1, Copies[1]);
+ EXPECT_TRUE(match);
+ EXPECT_EQ(Src0, Copies[0]);
+ EXPECT_EQ(Src1, Copies[1]);
// Match a case where none of the predicates hold true.
match = mi_match(
MIBAdd->getOperand(0).getReg(), MRI,
m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg())));
- ASSERT_FALSE(match);
+ EXPECT_FALSE(match);
+}
+
+TEST(PatternMatchInstr, MatchMiscellaneous) {
+ LLVMContext Context;
+ std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
+ if (!TM)
+ return;
+ auto ModuleMMIPair = createDummyModule(Context, *TM, "");
+ MachineFunction *MF =
+ getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
+ SmallVector<Register, 4> Copies;
+ collectCopies(Copies, MF);
+ MachineBasicBlock *EntryMBB = &*MF->begin();
+ MachineIRBuilder B(*MF);
+ MachineRegisterInfo &MRI = MF->getRegInfo();
+ B.setInsertPt(*EntryMBB, EntryMBB->end());
+ LLT s64 = LLT::scalar(64);
+ auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
+ // Make multiple uses of this add.
+ B.buildCast(LLT::pointer(0, 32), MIBAdd);
+ B.buildCast(LLT::pointer(1, 32), MIBAdd);
+ bool match = mi_match(MIBAdd.getReg(0), MRI, m_GAdd(m_Reg(), m_Reg()));
+ EXPECT_TRUE(match);
+ match = mi_match(MIBAdd.getReg(0), MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())));
+ EXPECT_FALSE(match);
}
} // namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
index a4765d9..bf4277d 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/CodeGen/GlobalISel/LowLevelTypeTest.cpp --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -16,18 +15,6 @@
using namespace llvm;
-// Define a pretty printer to help debugging when things go wrong.
-namespace llvm {
-std::ostream &
-operator<<(std::ostream &OS, const llvm::LLT Ty) {
- std::string Repr;
- raw_string_ostream SS{Repr};
- Ty.print(SS);
- OS << SS.str();
- return OS;
-}
-}
-
namespace {
TEST(LowLevelTypeTest, Scalar) {
@@ -104,41 +91,118 @@
}
}
+TEST(LowLevelTypeTest, ScalarOrVector) {
+ // Test version with number of bits for scalar type.
+ EXPECT_EQ(LLT::scalar(32), LLT::scalarOrVector(1, 32));
+ EXPECT_EQ(LLT::vector(2, 32), LLT::scalarOrVector(2, 32));
+
+ // Test version with LLT for scalar type.
+ EXPECT_EQ(LLT::scalar(32), LLT::scalarOrVector(1, LLT::scalar(32)));
+ EXPECT_EQ(LLT::vector(2, 32), LLT::scalarOrVector(2, LLT::scalar(32)));
+
+ // Test with pointer elements.
+ EXPECT_EQ(LLT::pointer(1, 32), LLT::scalarOrVector(1, LLT::pointer(1, 32)));
+ EXPECT_EQ(LLT::vector(2, LLT::pointer(1, 32)),
+ LLT::scalarOrVector(2, LLT::pointer(1, 32)));
+}
+
+TEST(LowLevelTypeTest, ChangeElementType) {
+ const LLT P0 = LLT::pointer(0, 32);
+ const LLT P1 = LLT::pointer(1, 64);
+
+ const LLT S32 = LLT::scalar(32);
+ const LLT S64 = LLT::scalar(64);
+
+ const LLT V2S32 = LLT::vector(2, 32);
+ const LLT V2S64 = LLT::vector(2, 64);
+
+ const LLT V2P0 = LLT::vector(2, P0);
+ const LLT V2P1 = LLT::vector(2, P1);
+
+ EXPECT_EQ(S64, S32.changeElementType(S64));
+ EXPECT_EQ(S32, S32.changeElementType(S32));
+
+ EXPECT_EQ(S32, S64.changeElementSize(32));
+ EXPECT_EQ(S32, S32.changeElementSize(32));
+
+ EXPECT_EQ(V2S64, V2S32.changeElementType(S64));
+ EXPECT_EQ(V2S32, V2S64.changeElementType(S32));
+
+ EXPECT_EQ(V2S64, V2S32.changeElementSize(64));
+ EXPECT_EQ(V2S32, V2S64.changeElementSize(32));
+
+ EXPECT_EQ(P0, S32.changeElementType(P0));
+ EXPECT_EQ(S32, P0.changeElementType(S32));
+
+ EXPECT_EQ(V2P1, V2P0.changeElementType(P1));
+ EXPECT_EQ(V2S32, V2P0.changeElementType(S32));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+
+// Invalid to directly change the element size for pointers.
+TEST(LowLevelTypeTest, ChangeElementTypeDeath) {
+ const LLT P0 = LLT::pointer(0, 32);
+ const LLT V2P0 = LLT::vector(2, P0);
+
+ EXPECT_DEATH(P0.changeElementSize(64),
+ "invalid to directly change element size for pointers");
+ EXPECT_DEATH(V2P0.changeElementSize(64),
+ "invalid to directly change element size for pointers");
+
+ // Make sure this still fails even without a change in size.
+ EXPECT_DEATH(P0.changeElementSize(32),
+ "invalid to directly change element size for pointers");
+ EXPECT_DEATH(V2P0.changeElementSize(32),
+ "invalid to directly change element size for pointers");
+}
+
+#endif
+#endif
+
TEST(LowLevelTypeTest, Pointer) {
LLVMContext C;
- DataLayout DL("");
+ DataLayout DL("p64:64:64-p127:512:512:512-p16777215:65528:8");
- for (unsigned AS : {0U, 1U, 127U, 0xffffU}) {
- const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
- const LLT VTy = LLT::vector(4, Ty);
+ for (unsigned AS : {0U, 1U, 127U, 0xffffU,
+ static_cast<unsigned>(maxUIntN(23)),
+ static_cast<unsigned>(maxUIntN(24))}) {
+ for (unsigned NumElts : {2, 3, 4, 256, 65535}) {
+ const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
+ const LLT VTy = LLT::vector(NumElts, Ty);
- // Test kind.
- ASSERT_TRUE(Ty.isValid());
- ASSERT_TRUE(Ty.isPointer());
+ // Test kind.
+ ASSERT_TRUE(Ty.isValid());
+ ASSERT_TRUE(Ty.isPointer());
- ASSERT_FALSE(Ty.isScalar());
- ASSERT_FALSE(Ty.isVector());
+ ASSERT_FALSE(Ty.isScalar());
+ ASSERT_FALSE(Ty.isVector());
- ASSERT_TRUE(VTy.isValid());
- ASSERT_TRUE(VTy.isVector());
- ASSERT_TRUE(VTy.getElementType().isPointer());
+ ASSERT_TRUE(VTy.isValid());
+ ASSERT_TRUE(VTy.isVector());
+ ASSERT_TRUE(VTy.getElementType().isPointer());
- // Test addressspace.
- EXPECT_EQ(AS, Ty.getAddressSpace());
- EXPECT_EQ(AS, VTy.getElementType().getAddressSpace());
+ EXPECT_EQ(Ty, VTy.getElementType());
+ EXPECT_EQ(Ty.getSizeInBits(), VTy.getScalarSizeInBits());
- // Test equality operators.
- EXPECT_TRUE(Ty == Ty);
- EXPECT_FALSE(Ty != Ty);
- EXPECT_TRUE(VTy == VTy);
- EXPECT_FALSE(VTy != VTy);
+ // Test address space.
+ EXPECT_EQ(AS, Ty.getAddressSpace());
+ EXPECT_EQ(AS, VTy.getElementType().getAddressSpace());
- // Test Type->LLT conversion.
- Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
- EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
- Type *IRVTy =
- VectorType::get(PointerType::get(IntegerType::get(C, 8), AS), 4);
- EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL));
+ // Test equality operators.
+ EXPECT_TRUE(Ty == Ty);
+ EXPECT_FALSE(Ty != Ty);
+ EXPECT_TRUE(VTy == VTy);
+ EXPECT_FALSE(VTy != VTy);
+
+ // Test Type->LLT conversion.
+ Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
+ EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
+ Type *IRVTy =
+ VectorType::get(PointerType::get(IntegerType::get(C, 8), AS), NumElts);
+ EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL));
+ }
}
}
diff --git a/src/llvm-project/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp
index 63365ab..5ce0983 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp
@@ -1,9 +1,8 @@
//===- MachineInstrBundleIteratorTest.cpp ---------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp
index 73d3d25..67d0c59 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp
@@ -1,12 +1,12 @@
//===- MachineInstrTest.cpp -----------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -44,11 +44,63 @@
bool hasFP(const MachineFunction &MF) const override { return false; }
};
+static TargetRegisterClass *const BogusRegisterClasses[] = {nullptr};
+
+class BogusRegisterInfo : public TargetRegisterInfo {
+public:
+ BogusRegisterInfo()
+ : TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses,
+ nullptr, nullptr, LaneBitmask(~0u), nullptr) {
+ InitMCRegisterInfo(nullptr, 0, 0, 0, nullptr, 0, nullptr, 0, nullptr,
+ nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr);
+ }
+
+ const MCPhysReg *
+ getCalleeSavedRegs(const MachineFunction *MF) const override {
+ return nullptr;
+ }
+ ArrayRef<const uint32_t *> getRegMasks() const override { return None; }
+ ArrayRef<const char *> getRegMaskNames() const override { return None; }
+ BitVector getReservedRegs(const MachineFunction &MF) const override {
+ return BitVector();
+ }
+ const RegClassWeight &
+ getRegClassWeight(const TargetRegisterClass *RC) const override {
+ static RegClassWeight Bogus{1, 16};
+ return Bogus;
+ }
+ unsigned getRegUnitWeight(unsigned RegUnit) const override { return 1; }
+ unsigned getNumRegPressureSets() const override { return 0; }
+ const char *getRegPressureSetName(unsigned Idx) const override {
+ return "bogus";
+ }
+ unsigned getRegPressureSetLimit(const MachineFunction &MF,
+ unsigned Idx) const override {
+ return 0;
+ }
+ const int *
+ getRegClassPressureSets(const TargetRegisterClass *RC) const override {
+ static const int Bogus[] = {0, -1};
+ return &Bogus[0];
+ }
+ const int *getRegUnitPressureSets(unsigned RegUnit) const override {
+ static const int Bogus[] = {0, -1};
+ return &Bogus[0];
+ }
+
+ Register getFrameRegister(const MachineFunction &MF) const override {
+ return 0;
+ }
+ void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
+ unsigned FIOperandNum,
+ RegScavenger *RS = nullptr) const override {}
+};
+
class BogusSubtarget : public TargetSubtargetInfo {
public:
BogusSubtarget(TargetMachine &TM)
: TargetSubtargetInfo(Triple(""), "", "", {}, {}, nullptr, nullptr,
- nullptr, nullptr, nullptr, nullptr, nullptr),
+ nullptr, nullptr, nullptr, nullptr),
FL(), TL(TM) {}
~BogusSubtarget() override {}
@@ -58,8 +110,11 @@
const TargetInstrInfo *getInstrInfo() const override { return &TII; }
+ const TargetRegisterInfo *getRegisterInfo() const override { return &TRI; }
+
private:
BogusFrameLowering FL;
+ BogusRegisterInfo TRI;
BogusTargetLowering TL;
TargetInstrInfo TII;
};
@@ -266,11 +321,46 @@
std::string str;
raw_string_ostream OS(str);
- MI->print(OS);
+ MI->print(OS, /*IsStandalone*/true, /*SkipOpers*/false, /*SkipDebugLoc*/false,
+ /*AddNewLine*/false);
ASSERT_TRUE(
StringRef(OS.str()).startswith("$noreg = UNKNOWN debug-location "));
ASSERT_TRUE(
StringRef(OS.str()).endswith("filename:1:5"));
}
+TEST(MachineInstrSpan, DistanceBegin) {
+ auto MF = createMachineFunction();
+ auto MBB = MF->CreateMachineBasicBlock();
+
+ MCInstrDesc MCID = {0, 0, 0, 0, 0, 0,
+ 0, nullptr, nullptr, nullptr, 0, nullptr};
+
+ auto MII = MBB->begin();
+ MachineInstrSpan MIS(MII, MBB);
+ ASSERT_TRUE(MIS.empty());
+
+ auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
+ MBB->insert(MII, MI);
+ ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
+}
+
+TEST(MachineInstrSpan, DistanceEnd) {
+ auto MF = createMachineFunction();
+ auto MBB = MF->CreateMachineBasicBlock();
+
+ MCInstrDesc MCID = {0, 0, 0, 0, 0, 0,
+ 0, nullptr, nullptr, nullptr, 0, nullptr};
+
+ auto MII = MBB->end();
+ MachineInstrSpan MIS(MII, MBB);
+ ASSERT_TRUE(MIS.empty());
+
+ auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
+ MBB->insert(MII, MI);
+ ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
+}
+
+static_assert(is_trivially_copyable<MCOperand>::value, "trivially copyable");
+
} // end namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/MachineOperandTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/MachineOperandTest.cpp
index 53ec5ae..faa471f 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/MachineOperandTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/MachineOperandTest.cpp
@@ -1,9 +1,8 @@
//===- MachineOperandTest.cpp ---------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -399,4 +398,14 @@
ASSERT_TRUE(OS.str() == "intpred(eq)");
}
+TEST(MachineOperandTest, HashValue) {
+ char SymName1[] = "test";
+ char SymName2[] = "test";
+ MachineOperand MO1 = MachineOperand::CreateES(SymName1);
+ MachineOperand MO2 = MachineOperand::CreateES(SymName2);
+ ASSERT_NE(SymName1, SymName2);
+ ASSERT_EQ(hash_value(MO1), hash_value(MO2));
+ ASSERT_TRUE(MO1.isIdenticalTo(MO2));
+}
+
} // end namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp
index 20b3fb1..3dd3bec 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp
@@ -1,9 +1,8 @@
//===-------- llvm/unittest/CodeGen/ScalableVectorMVTsTest.cpp ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/CodeGen/TargetOptionsTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/TargetOptionsTest.cpp
new file mode 100644
index 0000000..6b4d3ed
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/CodeGen/TargetOptionsTest.cpp
@@ -0,0 +1,76 @@
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace llvm {
+ void initializeTestPassPass(PassRegistry &);
+}
+
+namespace {
+
+void initLLVM() {
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+ InitializeAllAsmPrinters();
+ InitializeAllAsmParsers();
+
+ PassRegistry *Registry = PassRegistry::getPassRegistry();
+ initializeCore(*Registry);
+ initializeCodeGen(*Registry);
+}
+
+/// Create a TargetMachine. We need a target that doesn't have IPRA enabled by
+/// default. That turns out to be all targets at the moment, so just use X86.
+std::unique_ptr<TargetMachine> createTargetMachine(bool EnableIPRA) {
+ Triple TargetTriple("x86_64--");
+ std::string Error;
+ const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
+ if (!T)
+ return nullptr;
+
+ TargetOptions Options;
+ Options.EnableIPRA = EnableIPRA;
+ return std::unique_ptr<TargetMachine>(T->createTargetMachine(
+ "X86", "", "", Options, None, None, CodeGenOpt::Aggressive));
+}
+
+typedef std::function<void(bool)> TargetOptionsTest;
+
+static void targetOptionsTest(bool EnableIPRA) {
+ std::unique_ptr<TargetMachine> TM = createTargetMachine(EnableIPRA);
+ // This test is designed for the X86 backend; stop if it is not available.
+ if (!TM)
+ return;
+ legacy::PassManager PM;
+ LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get());
+
+ TargetPassConfig *TPC = LLVMTM->createPassConfig(PM);
+ (void)TPC;
+
+ ASSERT_TRUE(TM->Options.EnableIPRA == EnableIPRA);
+
+ delete TPC;
+}
+
+} // End of anonymous namespace.
+
+TEST(TargetOptionsTest, IPRASetToOff) {
+ targetOptionsTest(false);
+}
+
+TEST(TargetOptionsTest, IPRASetToOn) {
+ targetOptionsTest(true);
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ initLLVM();
+ return RUN_ALL_TESTS();
+}
diff --git a/src/llvm-project/llvm/unittests/CodeGen/TypeTraitsTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/TypeTraitsTest.cpp
new file mode 100644
index 0000000..840375b
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/CodeGen/TypeTraitsTest.cpp
@@ -0,0 +1,25 @@
+//===- llvm/unittest/CodeGen/TypeTraitsTest.cpp --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/RegisterPressure.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+#if __has_feature(is_trivially_copyable) || (defined(__GNUC__) && __GNUC__ >= 5)
+static_assert(is_trivially_copyable<PressureChange>::value, "trivially copyable");
+static_assert(is_trivially_copyable<SDep>::value, "trivially copyable");
+static_assert(is_trivially_copyable<SDValue>::value, "trivially copyable");
+static_assert(is_trivially_copyable<SlotIndex>::value, "trivially copyable");
+static_assert(is_trivially_copyable<IdentifyingPassPtr>::value, "trivially copyable");
+#endif
+
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/CMakeLists.txt b/src/llvm-project/llvm/unittests/DebugInfo/CMakeLists.txt
index 579fdb2..0a0a114 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/DebugInfo/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(CodeView)
add_subdirectory(DWARF)
+add_subdirectory(GSYM)
add_subdirectory(MSF)
add_subdirectory(PDB)
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
index c84eae32..ff01ef7 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/DebugInfo/CodeView/RandomAccessVisitorTest.cpp -------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -43,8 +42,6 @@
}
inline bool operator==(const CVType &R1, const CVType &R2) {
- if (R1.Type != R2.Type)
- return false;
if (R1.RecordData != R2.RecordData)
return false;
return true;
@@ -108,7 +105,7 @@
GlobalState->Records.push_back(AR);
GlobalState->Indices.push_back(Builder.writeLeafType(AR));
- CVType Type(TypeLeafKind::LF_ARRAY, Builder.records().back());
+ CVType Type(Builder.records().back());
GlobalState->TypeVector.push_back(Type);
GlobalState->AllOffsets.push_back(
@@ -370,11 +367,10 @@
TypeIndex IndexOne = Builder.writeLeafType(Modifier);
// set up a type stream that refers to the above two serialized records.
- std::vector<CVType> TypeArray;
- TypeArray.push_back(
- CVType(static_cast<TypeLeafKind>(Class.Kind), Builder.records()[0]));
- TypeArray.push_back(
- CVType(static_cast<TypeLeafKind>(Modifier.Kind), Builder.records()[1]));
+ std::vector<CVType> TypeArray = {
+ {Builder.records()[0]},
+ {Builder.records()[1]},
+ };
BinaryItemStream<CVType> ItemStream(llvm::support::little);
ItemStream.setItems(TypeArray);
VarStreamArray<CVType> TypeStream(ItemStream);
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeHashingTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeHashingTest.cpp
index 5b9dadf..8b9dc7a 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeHashingTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeHashingTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/DebugInfo/CodeView/TypeHashingTest.cpp ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
index 1b89160..d011db9 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
index ffbde2d..e2631af 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/DebugInfo/DWARFDebugInfoTest.cpp ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -42,7 +41,7 @@
template <uint16_t Version, class AddrType, class RefAddrType>
void TestAllForms() {
- Triple Triple = getHostTripleForAddrSize(sizeof(AddrType));
+ Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
if (!isConfigurationSupported(Triple))
return;
@@ -456,7 +455,7 @@
}
template <uint16_t Version, class AddrType> void TestChildren() {
- Triple Triple = getHostTripleForAddrSize(sizeof(AddrType));
+ Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
if (!isConfigurationSupported(Triple))
return;
@@ -586,7 +585,7 @@
}
template <uint16_t Version, class AddrType> void TestReferences() {
- Triple Triple = getHostTripleForAddrSize(sizeof(AddrType));
+ Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
if (!isConfigurationSupported(Triple))
return;
@@ -836,7 +835,7 @@
}
template <uint16_t Version, class AddrType> void TestAddresses() {
- Triple Triple = getHostTripleForAddrSize(sizeof(AddrType));
+ Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
if (!isConfigurationSupported(Triple))
return;
@@ -1008,7 +1007,7 @@
}
TEST(DWARFDebugInfo, TestStringOffsets) {
- Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+ Triple Triple = getNormalizedDefaultTargetTriple();
if (!isConfigurationSupported(Triple))
return;
@@ -1072,7 +1071,7 @@
}
TEST(DWARFDebugInfo, TestEmptyStringOffsets) {
- Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+ Triple Triple = getNormalizedDefaultTargetTriple();
if (!isConfigurationSupported(Triple))
return;
@@ -1101,7 +1100,7 @@
}
TEST(DWARFDebugInfo, TestRelations) {
- Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+ Triple Triple = getNormalizedDefaultTargetTriple();
if (!isConfigurationSupported(Triple))
return;
@@ -1288,7 +1287,7 @@
}
TEST(DWARFDebugInfo, TestChildIterators) {
- Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+ Triple Triple = getNormalizedDefaultTargetTriple();
if (!isConfigurationSupported(Triple))
return;
@@ -1402,7 +1401,7 @@
}
TEST(DWARFDebugInfo, TestAttributeIterators) {
- Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+ Triple Triple = getNormalizedDefaultTargetTriple();
if (!isConfigurationSupported(Triple))
return;
@@ -1464,7 +1463,7 @@
}
TEST(DWARFDebugInfo, TestFindRecurse) {
- Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+ Triple Triple = getNormalizedDefaultTargetTriple();
if (!isConfigurationSupported(Triple))
return;
@@ -1556,134 +1555,129 @@
TEST(DWARFDebugInfo, TestDwarfToFunctions) {
// Test all of the dwarf::toXXX functions that take a
// Optional<DWARFFormValue> and extract the values from it.
- DWARFFormValue FormVal;
uint64_t InvalidU64 = 0xBADBADBADBADBADB;
int64_t InvalidS64 = 0xBADBADBADBADBADB;
+
// First test that we don't get valid values back when using an optional with
// no value.
- Optional<DWARFFormValue> FormValOpt;
- EXPECT_FALSE(toString(FormValOpt).hasValue());
- EXPECT_FALSE(toUnsigned(FormValOpt).hasValue());
- EXPECT_FALSE(toReference(FormValOpt).hasValue());
- EXPECT_FALSE(toSigned(FormValOpt).hasValue());
- EXPECT_FALSE(toAddress(FormValOpt).hasValue());
- EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
- EXPECT_FALSE(toBlock(FormValOpt).hasValue());
- EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
- EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidS64));
+ Optional<DWARFFormValue> FormValOpt1 = DWARFFormValue();
+ EXPECT_FALSE(toString(FormValOpt1).hasValue());
+ EXPECT_FALSE(toUnsigned(FormValOpt1).hasValue());
+ EXPECT_FALSE(toReference(FormValOpt1).hasValue());
+ EXPECT_FALSE(toSigned(FormValOpt1).hasValue());
+ EXPECT_FALSE(toAddress(FormValOpt1).hasValue());
+ EXPECT_FALSE(toSectionOffset(FormValOpt1).hasValue());
+ EXPECT_FALSE(toBlock(FormValOpt1).hasValue());
+ EXPECT_EQ(nullptr, toString(FormValOpt1, nullptr));
+ EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt1, InvalidU64));
+ EXPECT_EQ(InvalidU64, toReference(FormValOpt1, InvalidU64));
+ EXPECT_EQ(InvalidU64, toAddress(FormValOpt1, InvalidU64));
+ EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt1, InvalidU64));
+ EXPECT_EQ(InvalidS64, toSigned(FormValOpt1, InvalidS64));
// Test successful and unsuccessful address decoding.
uint64_t Address = 0x100000000ULL;
- FormVal.setForm(DW_FORM_addr);
- FormVal.setUValue(Address);
- FormValOpt = FormVal;
+ Optional<DWARFFormValue> FormValOpt2 =
+ DWARFFormValue::createFromUValue(DW_FORM_addr, Address);
- EXPECT_FALSE(toString(FormValOpt).hasValue());
- EXPECT_FALSE(toUnsigned(FormValOpt).hasValue());
- EXPECT_FALSE(toReference(FormValOpt).hasValue());
- EXPECT_FALSE(toSigned(FormValOpt).hasValue());
- EXPECT_TRUE(toAddress(FormValOpt).hasValue());
- EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
- EXPECT_FALSE(toBlock(FormValOpt).hasValue());
- EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
- EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
- EXPECT_EQ(Address, toAddress(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidU64));
+ EXPECT_FALSE(toString(FormValOpt2).hasValue());
+ EXPECT_FALSE(toUnsigned(FormValOpt2).hasValue());
+ EXPECT_FALSE(toReference(FormValOpt2).hasValue());
+ EXPECT_FALSE(toSigned(FormValOpt2).hasValue());
+ EXPECT_TRUE(toAddress(FormValOpt2).hasValue());
+ EXPECT_FALSE(toSectionOffset(FormValOpt2).hasValue());
+ EXPECT_FALSE(toBlock(FormValOpt2).hasValue());
+ EXPECT_EQ(nullptr, toString(FormValOpt2, nullptr));
+ EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt2, InvalidU64));
+ EXPECT_EQ(InvalidU64, toReference(FormValOpt2, InvalidU64));
+ EXPECT_EQ(Address, toAddress(FormValOpt2, InvalidU64));
+ EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt2, InvalidU64));
+ EXPECT_EQ(InvalidS64, toSigned(FormValOpt2, InvalidU64));
// Test successful and unsuccessful unsigned constant decoding.
uint64_t UData8 = 0x1020304050607080ULL;
- FormVal.setForm(DW_FORM_udata);
- FormVal.setUValue(UData8);
- FormValOpt = FormVal;
+ Optional<DWARFFormValue> FormValOpt3 =
+ DWARFFormValue::createFromUValue(DW_FORM_udata, UData8);
- EXPECT_FALSE(toString(FormValOpt).hasValue());
- EXPECT_TRUE(toUnsigned(FormValOpt).hasValue());
- EXPECT_FALSE(toReference(FormValOpt).hasValue());
- EXPECT_TRUE(toSigned(FormValOpt).hasValue());
- EXPECT_FALSE(toAddress(FormValOpt).hasValue());
- EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
- EXPECT_FALSE(toBlock(FormValOpt).hasValue());
- EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
- EXPECT_EQ(UData8, toUnsigned(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
- EXPECT_EQ((int64_t)UData8, toSigned(FormValOpt, InvalidU64));
+ EXPECT_FALSE(toString(FormValOpt3).hasValue());
+ EXPECT_TRUE(toUnsigned(FormValOpt3).hasValue());
+ EXPECT_FALSE(toReference(FormValOpt3).hasValue());
+ EXPECT_TRUE(toSigned(FormValOpt3).hasValue());
+ EXPECT_FALSE(toAddress(FormValOpt3).hasValue());
+ EXPECT_FALSE(toSectionOffset(FormValOpt3).hasValue());
+ EXPECT_FALSE(toBlock(FormValOpt3).hasValue());
+ EXPECT_EQ(nullptr, toString(FormValOpt3, nullptr));
+ EXPECT_EQ(UData8, toUnsigned(FormValOpt3, InvalidU64));
+ EXPECT_EQ(InvalidU64, toReference(FormValOpt3, InvalidU64));
+ EXPECT_EQ(InvalidU64, toAddress(FormValOpt3, InvalidU64));
+ EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt3, InvalidU64));
+ EXPECT_EQ((int64_t)UData8, toSigned(FormValOpt3, InvalidU64));
// Test successful and unsuccessful reference decoding.
uint32_t RefData = 0x11223344U;
- FormVal.setForm(DW_FORM_ref_addr);
- FormVal.setUValue(RefData);
- FormValOpt = FormVal;
+ Optional<DWARFFormValue> FormValOpt4 =
+ DWARFFormValue::createFromUValue(DW_FORM_ref_addr, RefData);
- EXPECT_FALSE(toString(FormValOpt).hasValue());
- EXPECT_FALSE(toUnsigned(FormValOpt).hasValue());
- EXPECT_TRUE(toReference(FormValOpt).hasValue());
- EXPECT_FALSE(toSigned(FormValOpt).hasValue());
- EXPECT_FALSE(toAddress(FormValOpt).hasValue());
- EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
- EXPECT_FALSE(toBlock(FormValOpt).hasValue());
- EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
- EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64));
- EXPECT_EQ(RefData, toReference(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidU64));
+ EXPECT_FALSE(toString(FormValOpt4).hasValue());
+ EXPECT_FALSE(toUnsigned(FormValOpt4).hasValue());
+ EXPECT_TRUE(toReference(FormValOpt4).hasValue());
+ EXPECT_FALSE(toSigned(FormValOpt4).hasValue());
+ EXPECT_FALSE(toAddress(FormValOpt4).hasValue());
+ EXPECT_FALSE(toSectionOffset(FormValOpt4).hasValue());
+ EXPECT_FALSE(toBlock(FormValOpt4).hasValue());
+ EXPECT_EQ(nullptr, toString(FormValOpt4, nullptr));
+ EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt4, InvalidU64));
+ EXPECT_EQ(RefData, toReference(FormValOpt4, InvalidU64));
+ EXPECT_EQ(InvalidU64, toAddress(FormValOpt4, InvalidU64));
+ EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt4, InvalidU64));
+ EXPECT_EQ(InvalidS64, toSigned(FormValOpt4, InvalidU64));
// Test successful and unsuccessful signed constant decoding.
int64_t SData8 = 0x1020304050607080ULL;
- FormVal.setForm(DW_FORM_udata);
- FormVal.setSValue(SData8);
- FormValOpt = FormVal;
+ Optional<DWARFFormValue> FormValOpt5 =
+ DWARFFormValue::createFromSValue(DW_FORM_udata, SData8);
- EXPECT_FALSE(toString(FormValOpt).hasValue());
- EXPECT_TRUE(toUnsigned(FormValOpt).hasValue());
- EXPECT_FALSE(toReference(FormValOpt).hasValue());
- EXPECT_TRUE(toSigned(FormValOpt).hasValue());
- EXPECT_FALSE(toAddress(FormValOpt).hasValue());
- EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
- EXPECT_FALSE(toBlock(FormValOpt).hasValue());
- EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
- EXPECT_EQ((uint64_t)SData8, toUnsigned(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
- EXPECT_EQ(SData8, toSigned(FormValOpt, InvalidU64));
+ EXPECT_FALSE(toString(FormValOpt5).hasValue());
+ EXPECT_TRUE(toUnsigned(FormValOpt5).hasValue());
+ EXPECT_FALSE(toReference(FormValOpt5).hasValue());
+ EXPECT_TRUE(toSigned(FormValOpt5).hasValue());
+ EXPECT_FALSE(toAddress(FormValOpt5).hasValue());
+ EXPECT_FALSE(toSectionOffset(FormValOpt5).hasValue());
+ EXPECT_FALSE(toBlock(FormValOpt5).hasValue());
+ EXPECT_EQ(nullptr, toString(FormValOpt5, nullptr));
+ EXPECT_EQ((uint64_t)SData8, toUnsigned(FormValOpt5, InvalidU64));
+ EXPECT_EQ(InvalidU64, toReference(FormValOpt5, InvalidU64));
+ EXPECT_EQ(InvalidU64, toAddress(FormValOpt5, InvalidU64));
+ EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt5, InvalidU64));
+ EXPECT_EQ(SData8, toSigned(FormValOpt5, InvalidU64));
// Test successful and unsuccessful block decoding.
uint8_t Data[] = { 2, 3, 4 };
ArrayRef<uint8_t> Array(Data);
- FormVal.setForm(DW_FORM_block1);
- FormVal.setBlockValue(Array);
- FormValOpt = FormVal;
+ Optional<DWARFFormValue> FormValOpt6 =
+ DWARFFormValue::createFromBlockValue(DW_FORM_block1, Array);
- EXPECT_FALSE(toString(FormValOpt).hasValue());
- EXPECT_FALSE(toUnsigned(FormValOpt).hasValue());
- EXPECT_FALSE(toReference(FormValOpt).hasValue());
- EXPECT_FALSE(toSigned(FormValOpt).hasValue());
- EXPECT_FALSE(toAddress(FormValOpt).hasValue());
- EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
- auto BlockOpt = toBlock(FormValOpt);
+ EXPECT_FALSE(toString(FormValOpt6).hasValue());
+ EXPECT_FALSE(toUnsigned(FormValOpt6).hasValue());
+ EXPECT_FALSE(toReference(FormValOpt6).hasValue());
+ EXPECT_FALSE(toSigned(FormValOpt6).hasValue());
+ EXPECT_FALSE(toAddress(FormValOpt6).hasValue());
+ EXPECT_FALSE(toSectionOffset(FormValOpt6).hasValue());
+ auto BlockOpt = toBlock(FormValOpt6);
EXPECT_TRUE(BlockOpt.hasValue());
EXPECT_EQ(*BlockOpt, Array);
- EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
- EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
- EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidU64));
+ EXPECT_EQ(nullptr, toString(FormValOpt6, nullptr));
+ EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt6, InvalidU64));
+ EXPECT_EQ(InvalidU64, toReference(FormValOpt6, InvalidU64));
+ EXPECT_EQ(InvalidU64, toAddress(FormValOpt6, InvalidU64));
+ EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt6, InvalidU64));
+ EXPECT_EQ(InvalidS64, toSigned(FormValOpt6, InvalidU64));
// Test
}
TEST(DWARFDebugInfo, TestFindAttrs) {
- Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+ Triple Triple = getNormalizedDefaultTargetTriple();
if (!isConfigurationSupported(Triple))
return;
@@ -1746,7 +1740,7 @@
}
TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) {
- Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+ Triple Triple = getNormalizedDefaultTargetTriple();
if (!isConfigurationSupported(Triple))
return;
@@ -2989,72 +2983,34 @@
VerifySuccess(*DwarfContext);
}
-TEST(DWARFDebugInfo, TestDwarfRangesContains) {
- DWARFAddressRange R(0x10, 0x20);
-
- //----------------------------------------------------------------------
- // Test ranges that start before R...
- //----------------------------------------------------------------------
- // Other range ends before start of R
- ASSERT_FALSE(R.contains({0x0f, 0x10}));
- // Other range end address is start of a R
- ASSERT_FALSE(R.contains({0x0f, 0x11}));
- // Other range end address is at and of R
- ASSERT_FALSE(R.contains({0x0f, 0x20}));
- // Other range end address is past end of R
- ASSERT_FALSE(R.contains({0x0f, 0x40}));
-
- //----------------------------------------------------------------------
- // Test ranges that start at R's start address
- //----------------------------------------------------------------------
- // Ensure empty ranges matches
- ASSERT_TRUE(R.contains({0x10, 0x10}));
- // 1 byte of Range
- ASSERT_TRUE(R.contains({0x10, 0x11}));
- // same as Range
- ASSERT_TRUE(R.contains({0x10, 0x20}));
- // 1 byte past Range
- ASSERT_FALSE(R.contains({0x10, 0x21}));
-
- //----------------------------------------------------------------------
- // Test ranges that start inside Range
- //----------------------------------------------------------------------
- // empty in range
- ASSERT_TRUE(R.contains({0x11, 0x11}));
- // all in Range
- ASSERT_TRUE(R.contains({0x11, 0x1f}));
- // ends at end of Range
- ASSERT_TRUE(R.contains({0x11, 0x20}));
- // ends past Range
- ASSERT_FALSE(R.contains({0x11, 0x21}));
-
- //----------------------------------------------------------------------
- // Test ranges that start at last bytes of Range
- //----------------------------------------------------------------------
- // ends at end of Range
- ASSERT_TRUE(R.contains({0x1f, 0x20}));
- // ends past Range
- ASSERT_FALSE(R.contains({0x1f, 0x21}));
-
- //----------------------------------------------------------------------
- // Test ranges that start after Range
- //----------------------------------------------------------------------
- // empty considered in Range
- ASSERT_TRUE(R.contains({0x20, 0x20}));
- // valid past Range
- ASSERT_FALSE(R.contains({0x20, 0x21}));
-}
-
TEST(DWARFDebugInfo, TestDWARFDieRangeInfoContains) {
- DWARFVerifier::DieRangeInfo Ranges({{0x10, 0x20}, {0x30, 0x40}});
+ DWARFVerifier::DieRangeInfo Empty;
+ ASSERT_TRUE(Empty.contains(Empty));
+ DWARFVerifier::DieRangeInfo Ranges(
+ {{0x10, 0x20}, {0x30, 0x40}, {0x40, 0x50}});
+
+ ASSERT_TRUE(Ranges.contains(Empty));
ASSERT_FALSE(Ranges.contains({{{0x0f, 0x10}}}));
- ASSERT_FALSE(Ranges.contains({{{0x20, 0x30}}}));
- ASSERT_FALSE(Ranges.contains({{{0x40, 0x41}}}));
+ ASSERT_FALSE(Ranges.contains({{{0x0f, 0x20}}}));
+ ASSERT_FALSE(Ranges.contains({{{0x0f, 0x21}}}));
+
+ // Test ranges that start at R's start address
+ ASSERT_TRUE(Ranges.contains({{{0x10, 0x10}}}));
+ ASSERT_TRUE(Ranges.contains({{{0x10, 0x11}}}));
ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}}}));
+ ASSERT_FALSE(Ranges.contains({{{0x10, 0x21}}}));
+
ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}}}));
+
+ // Test ranges that start at last bytes of Range
ASSERT_TRUE(Ranges.contains({{{0x1f, 0x20}}}));
- ASSERT_TRUE(Ranges.contains({{{0x30, 0x40}}}));
+ ASSERT_FALSE(Ranges.contains({{{0x1f, 0x21}}}));
+
+ // Test ranges that start after Range
+ ASSERT_TRUE(Ranges.contains({{{0x20, 0x20}}}));
+ ASSERT_FALSE(Ranges.contains({{{0x20, 0x21}}}));
+
ASSERT_TRUE(Ranges.contains({{{0x31, 0x32}}}));
ASSERT_TRUE(Ranges.contains({{{0x3f, 0x40}}}));
ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}, {0x30, 0x40}}}));
@@ -3067,7 +3023,10 @@
{0x31, 0x32},
{0x32, 0x33}}}));
ASSERT_FALSE(Ranges.contains(
- {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x41}}}));
+ {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x51}}}));
+ ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}, {0x30, 0x50}}}));
+ ASSERT_FALSE(Ranges.contains({{{0x30, 0x51}}}));
+ ASSERT_FALSE(Ranges.contains({{{0x50, 0x51}}}));
}
namespace {
@@ -3194,6 +3153,9 @@
AssertRangesIntersect(Ranges, {{0x3f, 0x40}});
// Test range that starts at end of second range
AssertRangesDontIntersect(Ranges, {{0x40, 0x41}});
+
+ AssertRangesDontIntersect(Ranges, {{0x20, 0x21}, {0x2f, 0x30}});
+ AssertRangesIntersect(Ranges, {{0x20, 0x21}, {0x2f, 0x31}});
}
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
index 03586ca..ce7c252 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
@@ -1,9 +1,8 @@
//===- DWARFDebugLineTest.cpp ---------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -38,7 +37,7 @@
}
bool setupGenerator(uint16_t Version = 4) {
- Triple T = getHostTripleForAddrSize(8);
+ Triple T = getDefaultTargetTripleForAddrSize(8);
if (!isConfigurationSupported(T))
return false;
auto ExpectedGenerator = Generator::create(T, Version);
@@ -51,8 +50,9 @@
Context = createContext();
assert(Context != nullptr && "test state is not valid");
const DWARFObject &Obj = Context->getDWARFObj();
- LineData = DWARFDataExtractor(Obj, Obj.getLineSection(),
- sys::IsLittleEndianHost, 8);
+ LineData = DWARFDataExtractor(
+ Obj, Obj.getLineSection(),
+ getDefaultTargetTripleForAddrSize(8).isLittleEndian(), 8);
}
std::unique_ptr<DWARFContext> createContext() {
@@ -291,13 +291,13 @@
return;
LineTable < = Gen->addLineTable();
- LT.setCustomPrologue({{0xffffff00, LineTable::Long}});
+ LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});
generate();
checkGetOrParseLineTableEmitsError(
"parsing line table prologue at offset 0x00000000 unsupported reserved "
- "unit length found of value 0xffffff00");
+ "unit length found of value 0xfffffff0");
}
TEST_F(DebugLineBasicFixture, ErrorForLowVersion) {
@@ -532,7 +532,7 @@
return;
LineTable < = Gen->addLineTable();
- LT.setCustomPrologue({{0xffffff00, LineTable::Long}});
+ LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});
Gen->addLineTable();
generate();
@@ -544,7 +544,7 @@
EXPECT_FALSE(Recoverable);
checkError("parsing line table prologue at offset 0x00000000 unsupported "
- "reserved unit length found of value 0xffffff00",
+ "reserved unit length found of value 0xfffffff0",
std::move(Unrecoverable));
}
@@ -553,7 +553,7 @@
return;
LineTable < = Gen->addLineTable();
- LT.setCustomPrologue({{0xffffff00, LineTable::Long}});
+ LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});
Gen->addLineTable();
generate();
@@ -564,7 +564,7 @@
EXPECT_TRUE(Parser.done());
checkError("parsing line table prologue at offset 0x00000000 unsupported "
- "reserved unit length found of value 0xffffff00",
+ "reserved unit length found of value 0xfffffff0",
std::move(Unrecoverable));
}
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
index 582b580..c40db07 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/DebugInfo/DWARFFormValueTest.cpp ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
index 9732766..468eaa2 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
@@ -1,9 +1,8 @@
//===--- unittests/DebugInfo/DWARF/DwarfGenerator.cpp -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -184,11 +183,11 @@
P.LineRange = 14;
P.OpcodeBase = 13;
P.StandardOpcodeLengths = {0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1};
- P.IncludeDirectories.push_back(DWARFFormValue(DW_FORM_string));
- P.IncludeDirectories.back().setPValue("a dir");
+ P.IncludeDirectories.push_back(
+ DWARFFormValue::createFromPValue(DW_FORM_string, "a dir"));
P.FileNames.push_back(DWARFDebugLine::FileNameEntry());
- P.FileNames.back().Name.setPValue("a file");
- P.FileNames.back().Name.setForm(DW_FORM_string);
+ P.FileNames.back().Name =
+ DWARFFormValue::createFromPValue(DW_FORM_string, "a file");
return P;
}
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h
index 40ecaa9..2f95e29 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h
@@ -1,9 +1,8 @@
//===--- unittests/DebugInfo/DWARF/DwarfGenerator.h -------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.cpp
index ef43c13..249cfb4 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.cpp
@@ -1,15 +1,15 @@
//===--- unittests/DebugInfo/DWARF/DwarfUtils.cpp ---------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "DwarfUtils.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
@@ -26,9 +26,20 @@
}
}
-Triple llvm::dwarf::utils::getHostTripleForAddrSize(uint8_t AddrSize) {
- Triple T(Triple::normalize(LLVM_HOST_TRIPLE));
+Triple llvm::dwarf::utils::getNormalizedDefaultTargetTriple() {
+ Triple T(Triple::normalize(sys::getDefaultTargetTriple()));
+ return T;
+}
+
+Triple llvm::dwarf::utils::getDefaultTargetTripleForAddrSize(uint8_t AddrSize) {
+ Triple T = getNormalizedDefaultTargetTriple();
+
+ assert((AddrSize == 4 || AddrSize == 8) &&
+ "Only 32-bit/64-bit address size variants are supported");
+
+ // If a 32-bit/64-bit address size was specified, try to convert the triple
+ // if it is for the wrong variant.
if (AddrSize == 8 && T.isArch32Bit())
return T.get64BitArchVariant();
if (AddrSize == 4 && T.isArch64Bit())
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.h b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.h
index 3d80456..036071e 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.h
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.h
@@ -1,9 +1,8 @@
//===--- unittests/DebugInfo/DWARF/DwarfUtils.h -----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -19,7 +18,8 @@
namespace dwarf {
namespace utils {
-Triple getHostTripleForAddrSize(uint8_t AddrSize);
+Triple getDefaultTargetTripleForAddrSize(uint8_t AddrSize);
+Triple getNormalizedDefaultTargetTriple();
bool isConfigurationSupported(Triple &T);
} // end namespace utils
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/GSYM/CMakeLists.txt b/src/llvm-project/llvm/unittests/DebugInfo/GSYM/CMakeLists.txt
new file mode 100644
index 0000000..fb9d5e5
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/DebugInfo/GSYM/CMakeLists.txt
@@ -0,0 +1,10 @@
+set(LLVM_LINK_COMPONENTS
+ DebugInfoGSYM
+ Support
+ )
+
+add_llvm_unittest(DebugInfoGSYMTests
+ GSYMTest.cpp
+ )
+
+target_link_libraries(DebugInfoGSYMTests PRIVATE LLVMTestingSupport)
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
new file mode 100644
index 0000000..dc34691
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
@@ -0,0 +1,381 @@
+//===- llvm/unittest/DebugInfo/GSYMTest.cpp -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/DebugInfo/GSYM/FileEntry.h"
+#include "llvm/DebugInfo/GSYM/FunctionInfo.h"
+#include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include "llvm/DebugInfo/GSYM/Range.h"
+#include "llvm/DebugInfo/GSYM/StringTable.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "gtest/gtest.h"
+#include <string>
+
+using namespace llvm;
+using namespace gsym;
+
+TEST(GSYMTest, TestFileEntry) {
+ // Make sure default constructed GSYM FileEntry has zeroes in the
+ // directory and basename string table indexes.
+ FileEntry empty1;
+ FileEntry empty2;
+ EXPECT_EQ(empty1.Dir, 0u);
+ EXPECT_EQ(empty1.Base, 0u);
+ // Verify equality operator works
+ FileEntry a1(10, 30);
+ FileEntry a2(10, 30);
+ FileEntry b(10, 40);
+ EXPECT_EQ(empty1, empty2);
+ EXPECT_EQ(a1, a2);
+ EXPECT_NE(a1, b);
+ EXPECT_NE(a1, empty1);
+ // Test we can use llvm::gsym::FileEntry in llvm::DenseMap.
+ DenseMap<FileEntry, uint32_t> EntryToIndex;
+ constexpr uint32_t Index1 = 1;
+ constexpr uint32_t Index2 = 1;
+ auto R = EntryToIndex.insert(std::make_pair(a1, Index1));
+ EXPECT_TRUE(R.second);
+ EXPECT_EQ(R.first->second, Index1);
+ R = EntryToIndex.insert(std::make_pair(a1, Index1));
+ EXPECT_FALSE(R.second);
+ EXPECT_EQ(R.first->second, Index1);
+ R = EntryToIndex.insert(std::make_pair(b, Index2));
+ EXPECT_TRUE(R.second);
+ EXPECT_EQ(R.first->second, Index2);
+ R = EntryToIndex.insert(std::make_pair(a1, Index2));
+ EXPECT_FALSE(R.second);
+ EXPECT_EQ(R.first->second, Index2);
+}
+
+TEST(GSYMTest, TestFunctionInfo) {
+ // Test GSYM FunctionInfo structs and functionality.
+ FunctionInfo invalid;
+ EXPECT_FALSE(invalid.isValid());
+ EXPECT_FALSE(invalid.hasRichInfo());
+ const uint64_t StartAddr = 0x1000;
+ const uint64_t EndAddr = 0x1100;
+ const uint64_t Size = EndAddr - StartAddr;
+ const uint32_t NameOffset = 30;
+ FunctionInfo FI(StartAddr, Size, NameOffset);
+ EXPECT_TRUE(FI.isValid());
+ EXPECT_FALSE(FI.hasRichInfo());
+ EXPECT_EQ(FI.startAddress(), StartAddr);
+ EXPECT_EQ(FI.endAddress(), EndAddr);
+ EXPECT_EQ(FI.size(), Size);
+ const uint32_t FileIdx = 1;
+ const uint32_t Line = 12;
+ FI.Lines.push_back(LineEntry(StartAddr, FileIdx, Line));
+ EXPECT_TRUE(FI.hasRichInfo());
+ FI.clear();
+ EXPECT_FALSE(FI.isValid());
+ EXPECT_FALSE(FI.hasRichInfo());
+
+ FunctionInfo A1(0x1000, 0x100, NameOffset);
+ FunctionInfo A2(0x1000, 0x100, NameOffset);
+ FunctionInfo B;
+ // Check == operator
+ EXPECT_EQ(A1, A2);
+ // Make sure things are not equal if they only differ by start address.
+ B = A2;
+ B.setStartAddress(0x2000);
+ EXPECT_NE(B, A2);
+ // Make sure things are not equal if they only differ by size.
+ B = A2;
+ B.setSize(0x101);
+ EXPECT_NE(B, A2);
+ // Make sure things are not equal if they only differ by name.
+ B = A2;
+ B.Name = 60;
+ EXPECT_NE(B, A2);
+ // Check < operator.
+ // Check less than where address differs.
+ B = A2;
+ B.setStartAddress(A2.startAddress() + 0x1000);
+ EXPECT_LT(A1, B);
+
+ // We use the < operator to take a variety of different FunctionInfo
+ // structs from a variety of sources: symtab, debug info, runtime info
+ // and we sort them and want the sorting to allow us to quickly get the
+ // best version of a function info.
+ FunctionInfo FISymtab(StartAddr, Size, NameOffset);
+ FunctionInfo FIWithLines(StartAddr, Size, NameOffset);
+ FIWithLines.Lines.push_back(LineEntry(StartAddr, FileIdx, Line));
+ // Test that a FunctionInfo with just a name and size is less than one
+ // that has name, size and any number of line table entries
+ EXPECT_LT(FISymtab, FIWithLines);
+
+ FunctionInfo FIWithLinesAndInline = FIWithLines;
+ FIWithLinesAndInline.Inline.Ranges.insert(
+ AddressRange(StartAddr, StartAddr + 0x10));
+ // Test that a FunctionInfo with name, size, and line entries is less than
+ // the same one with valid inline info
+ EXPECT_LT(FIWithLines, FIWithLinesAndInline);
+
+ // Test if we have an entry with lines and one with more lines for the same
+ // range, the ones with more lines is greater than the one with less.
+ FunctionInfo FIWithMoreLines = FIWithLines;
+ FIWithMoreLines.Lines.push_back(LineEntry(StartAddr, FileIdx, Line + 5));
+ EXPECT_LT(FIWithLines, FIWithMoreLines);
+
+ // Test that if we have the same number of lines we compare the line entries
+ // in the FunctionInfo.Lines vector.
+ FunctionInfo FIWithLinesWithHigherAddress = FIWithLines;
+ FIWithLinesWithHigherAddress.Lines[0].Addr += 0x10;
+ EXPECT_LT(FIWithLines, FIWithLinesWithHigherAddress);
+}
+
+TEST(GSYMTest, TestInlineInfo) {
+ // Test InlineInfo structs.
+ InlineInfo II;
+ EXPECT_FALSE(II.isValid());
+ II.Ranges.insert(AddressRange(0x1000, 0x2000));
+ // Make sure InlineInfo in valid with just an address range since
+ // top level InlineInfo objects have ranges with no name, call file
+ // or call line
+ EXPECT_TRUE(II.isValid());
+ // Make sure InlineInfo isn't after being cleared.
+ II.clear();
+ EXPECT_FALSE(II.isValid());
+
+ // Create an InlineInfo that contains the following data. The
+ // indentation of the address range indicates the parent child
+ // relationships of the InlineInfo objects:
+ //
+ // Variable Range and values
+ // =========== ====================================================
+ // Root [0x100-0x200) (no name, file, or line)
+ // Inline1 [0x150-0x160) Name = 1, File = 1, Line = 11
+ // Inline1Sub1 [0x152-0x155) Name = 2, File = 2, Line = 22
+ // Inline1Sub2 [0x157-0x158) Name = 3, File = 3, Line = 33
+ InlineInfo Root;
+ Root.Ranges.insert(AddressRange(0x100, 0x200));
+ InlineInfo Inline1;
+ Inline1.Ranges.insert(AddressRange(0x150, 0x160));
+ Inline1.Name = 1;
+ Inline1.CallFile = 1;
+ Inline1.CallLine = 11;
+ InlineInfo Inline1Sub1;
+ Inline1Sub1.Ranges.insert(AddressRange(0x152, 0x155));
+ Inline1Sub1.Name = 2;
+ Inline1Sub1.CallFile = 2;
+ Inline1Sub1.CallLine = 22;
+ InlineInfo Inline1Sub2;
+ Inline1Sub2.Ranges.insert(AddressRange(0x157, 0x158));
+ Inline1Sub2.Name = 3;
+ Inline1Sub2.CallFile = 3;
+ Inline1Sub2.CallLine = 33;
+ Inline1.Children.push_back(Inline1Sub1);
+ Inline1.Children.push_back(Inline1Sub2);
+ Root.Children.push_back(Inline1);
+
+ // Make sure an address that is out of range won't match
+ EXPECT_FALSE(Root.getInlineStack(0x50));
+
+ // Verify that we get no inline stacks for addresses out of [0x100-0x200)
+ EXPECT_FALSE(Root.getInlineStack(Root.Ranges[0].Start - 1));
+ EXPECT_FALSE(Root.getInlineStack(Root.Ranges[0].End));
+
+ // Verify we get no inline stack entries for addresses that are in
+ // [0x100-0x200) but not in [0x150-0x160)
+ EXPECT_FALSE(Root.getInlineStack(Inline1.Ranges[0].Start - 1));
+ EXPECT_FALSE(Root.getInlineStack(Inline1.Ranges[0].End));
+
+ // Verify we get one inline stack entry for addresses that are in
+ // [[0x150-0x160)) but not in [0x152-0x155) or [0x157-0x158)
+ auto InlineInfos = Root.getInlineStack(Inline1.Ranges[0].Start);
+ ASSERT_TRUE(InlineInfos);
+ ASSERT_EQ(InlineInfos->size(), 1u);
+ ASSERT_EQ(*InlineInfos->at(0), Inline1);
+ InlineInfos = Root.getInlineStack(Inline1.Ranges[0].End - 1);
+ EXPECT_TRUE(InlineInfos);
+ ASSERT_EQ(InlineInfos->size(), 1u);
+ ASSERT_EQ(*InlineInfos->at(0), Inline1);
+
+ // Verify we get two inline stack entries for addresses that are in
+ // [0x152-0x155)
+ InlineInfos = Root.getInlineStack(Inline1Sub1.Ranges[0].Start);
+ EXPECT_TRUE(InlineInfos);
+ ASSERT_EQ(InlineInfos->size(), 2u);
+ ASSERT_EQ(*InlineInfos->at(0), Inline1Sub1);
+ ASSERT_EQ(*InlineInfos->at(1), Inline1);
+ InlineInfos = Root.getInlineStack(Inline1Sub1.Ranges[0].End - 1);
+ EXPECT_TRUE(InlineInfos);
+ ASSERT_EQ(InlineInfos->size(), 2u);
+ ASSERT_EQ(*InlineInfos->at(0), Inline1Sub1);
+ ASSERT_EQ(*InlineInfos->at(1), Inline1);
+
+ // Verify we get two inline stack entries for addresses that are in
+ // [0x157-0x158)
+ InlineInfos = Root.getInlineStack(Inline1Sub2.Ranges[0].Start);
+ EXPECT_TRUE(InlineInfos);
+ ASSERT_EQ(InlineInfos->size(), 2u);
+ ASSERT_EQ(*InlineInfos->at(0), Inline1Sub2);
+ ASSERT_EQ(*InlineInfos->at(1), Inline1);
+ InlineInfos = Root.getInlineStack(Inline1Sub2.Ranges[0].End - 1);
+ EXPECT_TRUE(InlineInfos);
+ ASSERT_EQ(InlineInfos->size(), 2u);
+ ASSERT_EQ(*InlineInfos->at(0), Inline1Sub2);
+ ASSERT_EQ(*InlineInfos->at(1), Inline1);
+}
+
+TEST(GSYMTest, TestLineEntry) {
+ // test llvm::gsym::LineEntry structs.
+ const uint64_t ValidAddr = 0x1000;
+ const uint64_t InvalidFileIdx = 0;
+ const uint32_t ValidFileIdx = 1;
+ const uint32_t ValidLine = 5;
+
+ LineEntry Invalid;
+ EXPECT_FALSE(Invalid.isValid());
+ // Make sure that an entry is invalid if it has a bad file index.
+ LineEntry BadFile(ValidAddr, InvalidFileIdx, ValidLine);
+ EXPECT_FALSE(BadFile.isValid());
+ // Test operators
+ LineEntry E1(ValidAddr, ValidFileIdx, ValidLine);
+ LineEntry E2(ValidAddr, ValidFileIdx, ValidLine);
+ LineEntry DifferentAddr(ValidAddr + 1, ValidFileIdx, ValidLine);
+ LineEntry DifferentFile(ValidAddr, ValidFileIdx + 1, ValidLine);
+ LineEntry DifferentLine(ValidAddr, ValidFileIdx, ValidLine + 1);
+ EXPECT_TRUE(E1.isValid());
+ EXPECT_EQ(E1, E2);
+ EXPECT_NE(E1, DifferentAddr);
+ EXPECT_NE(E1, DifferentFile);
+ EXPECT_NE(E1, DifferentLine);
+ EXPECT_LT(E1, DifferentAddr);
+}
+
+TEST(GSYMTest, TestRanges) {
+ // test llvm::gsym::AddressRange.
+ const uint64_t StartAddr = 0x1000;
+ const uint64_t EndAddr = 0x2000;
+ // Verify constructor and API to ensure it takes start and end address.
+ const AddressRange Range(StartAddr, EndAddr);
+ EXPECT_EQ(Range.size(), EndAddr - StartAddr);
+
+ // Verify llvm::gsym::AddressRange::contains().
+ EXPECT_FALSE(Range.contains(0));
+ EXPECT_FALSE(Range.contains(StartAddr - 1));
+ EXPECT_TRUE(Range.contains(StartAddr));
+ EXPECT_TRUE(Range.contains(EndAddr - 1));
+ EXPECT_FALSE(Range.contains(EndAddr));
+ EXPECT_FALSE(Range.contains(UINT64_MAX));
+
+ const AddressRange RangeSame(StartAddr, EndAddr);
+ const AddressRange RangeDifferentStart(StartAddr + 1, EndAddr);
+ const AddressRange RangeDifferentEnd(StartAddr, EndAddr + 1);
+ const AddressRange RangeDifferentStartEnd(StartAddr + 1, EndAddr + 1);
+ // Test == and != with values that are the same
+ EXPECT_EQ(Range, RangeSame);
+ EXPECT_FALSE(Range != RangeSame);
+ // Test == and != with values that are the different
+ EXPECT_NE(Range, RangeDifferentStart);
+ EXPECT_NE(Range, RangeDifferentEnd);
+ EXPECT_NE(Range, RangeDifferentStartEnd);
+ EXPECT_FALSE(Range == RangeDifferentStart);
+ EXPECT_FALSE(Range == RangeDifferentEnd);
+ EXPECT_FALSE(Range == RangeDifferentStartEnd);
+
+ // Test "bool operator<(const AddressRange &, const AddressRange &)".
+ EXPECT_FALSE(Range < RangeSame);
+ EXPECT_FALSE(RangeSame < Range);
+ EXPECT_LT(Range, RangeDifferentStart);
+ EXPECT_LT(Range, RangeDifferentEnd);
+ EXPECT_LT(Range, RangeDifferentStartEnd);
+ // Test "bool operator<(const AddressRange &, uint64_t)"
+ EXPECT_LT(Range.Start, StartAddr + 1);
+ // Test "bool operator<(uint64_t, const AddressRange &)"
+ EXPECT_LT(StartAddr - 1, Range.Start);
+
+ // Verify llvm::gsym::AddressRange::isContiguousWith() and
+ // llvm::gsym::AddressRange::intersects().
+ const AddressRange EndsBeforeRangeStart(0, StartAddr - 1);
+ const AddressRange EndsAtRangeStart(0, StartAddr);
+ const AddressRange OverlapsRangeStart(StartAddr - 1, StartAddr + 1);
+ const AddressRange InsideRange(StartAddr + 1, EndAddr - 1);
+ const AddressRange OverlapsRangeEnd(EndAddr - 1, EndAddr + 1);
+ const AddressRange StartsAtRangeEnd(EndAddr, EndAddr + 0x100);
+ const AddressRange StartsAfterRangeEnd(EndAddr + 1, EndAddr + 0x100);
+
+ EXPECT_FALSE(Range.intersects(EndsBeforeRangeStart));
+ EXPECT_FALSE(Range.intersects(EndsAtRangeStart));
+ EXPECT_TRUE(Range.intersects(OverlapsRangeStart));
+ EXPECT_TRUE(Range.intersects(InsideRange));
+ EXPECT_TRUE(Range.intersects(OverlapsRangeEnd));
+ EXPECT_FALSE(Range.intersects(StartsAtRangeEnd));
+ EXPECT_FALSE(Range.intersects(StartsAfterRangeEnd));
+
+ // Test the functions that maintain GSYM address ranges:
+ // "bool AddressRange::contains(uint64_t Addr) const;"
+ // "void AddressRanges::insert(const AddressRange &R);"
+ AddressRanges Ranges;
+ Ranges.insert(AddressRange(0x1000, 0x2000));
+ Ranges.insert(AddressRange(0x2000, 0x3000));
+ Ranges.insert(AddressRange(0x4000, 0x5000));
+
+ EXPECT_FALSE(Ranges.contains(0));
+ EXPECT_FALSE(Ranges.contains(0x1000 - 1));
+ EXPECT_TRUE(Ranges.contains(0x1000));
+ EXPECT_TRUE(Ranges.contains(0x2000));
+ EXPECT_TRUE(Ranges.contains(0x4000));
+ EXPECT_TRUE(Ranges.contains(0x2000 - 1));
+ EXPECT_TRUE(Ranges.contains(0x3000 - 1));
+ EXPECT_FALSE(Ranges.contains(0x3000 + 1));
+ EXPECT_TRUE(Ranges.contains(0x5000 - 1));
+ EXPECT_FALSE(Ranges.contains(0x5000 + 1));
+ EXPECT_FALSE(Ranges.contains(UINT64_MAX));
+
+ // Verify that intersecting ranges get combined
+ Ranges.clear();
+ Ranges.insert(AddressRange(0x1100, 0x1F00));
+ // Verify a wholy contained range that is added doesn't do anything.
+ Ranges.insert(AddressRange(0x1500, 0x1F00));
+ EXPECT_EQ(Ranges.size(), 1u);
+ EXPECT_EQ(Ranges[0], AddressRange(0x1100, 0x1F00));
+
+ // Verify a range that starts before and intersects gets combined.
+ Ranges.insert(AddressRange(0x1000, Ranges[0].Start + 1));
+ EXPECT_EQ(Ranges.size(), 1u);
+ EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x1F00));
+
+ // Verify a range that starts inside and extends ranges gets combined.
+ Ranges.insert(AddressRange(Ranges[0].End - 1, 0x2000));
+ EXPECT_EQ(Ranges.size(), 1u);
+ EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
+
+ // Verify that adjacent ranges don't get combined
+ Ranges.insert(AddressRange(0x2000, 0x3000));
+ EXPECT_EQ(Ranges.size(), 2u);
+ EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
+ EXPECT_EQ(Ranges[1], AddressRange(0x2000, 0x3000));
+ // Verify if we add an address range that intersects two ranges
+ // that they get combined
+ Ranges.insert(AddressRange(Ranges[0].End - 1, Ranges[1].Start + 1));
+ EXPECT_EQ(Ranges.size(), 1u);
+ EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x3000));
+
+ Ranges.insert(AddressRange(0x3000, 0x4000));
+ Ranges.insert(AddressRange(0x4000, 0x5000));
+ Ranges.insert(AddressRange(0x2000, 0x4500));
+ EXPECT_EQ(Ranges.size(), 1u);
+ EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x5000));
+}
+
+TEST(GSYMTest, TestStringTable) {
+ StringTable StrTab(StringRef("\0Hello\0World\0", 13));
+ // Test extracting strings from a string table.
+ EXPECT_EQ(StrTab.getString(0), "");
+ EXPECT_EQ(StrTab.getString(1), "Hello");
+ EXPECT_EQ(StrTab.getString(7), "World");
+ EXPECT_EQ(StrTab.getString(8), "orld");
+ // Test pointing to last NULL terminator gets empty string.
+ EXPECT_EQ(StrTab.getString(12), "");
+ // Test pointing to past end gets empty string.
+ EXPECT_EQ(StrTab.getString(13), "");
+}
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp
index 1624795..f327fef 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp
@@ -1,9 +1,8 @@
//===- MSFBuilderTest.cpp Tests manipulation of MSF stream metadata ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFCommonTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFCommonTest.cpp
index ee9ac75..68d0875 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFCommonTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFCommonTest.cpp
@@ -1,9 +1,8 @@
//===- MSFBuilderTest.cpp Tests manipulation of MSF stream metadata ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp
index 639536e..bc12721 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/DebugInfo/MSF/MappedBlockStreamTest.cpp --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/PDB/HashTableTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/PDB/HashTableTest.cpp
index 301b215..5f0695b 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/PDB/HashTableTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/PDB/HashTableTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/DebugInfo/PDB/HashTableTest.cpp ----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -28,27 +27,35 @@
namespace {
-class HashTableInternals : public HashTable<uint32_t> {
+struct IdentityHashTraits {
+ uint32_t hashLookupKey(uint32_t N) const { return N; }
+ uint32_t storageKeyToLookupKey(uint32_t N) const { return N; }
+ uint32_t lookupKeyToStorageKey(uint32_t N) { return N; }
+};
+
+template <class T = uint32_t>
+class HashTableInternals : public HashTable<T> {
public:
- using HashTable::Buckets;
- using HashTable::Present;
- using HashTable::Deleted;
+ using HashTable<T>::Buckets;
+ using HashTable<T>::Present;
+ using HashTable<T>::Deleted;
};
}
TEST(HashTableTest, TestSimple) {
- HashTableInternals Table;
+ HashTableInternals<> Table;
EXPECT_EQ(0u, Table.size());
EXPECT_GT(Table.capacity(), 0u);
- Table.set_as(3u, 7);
+ IdentityHashTraits Traits;
+ Table.set_as(3u, 7, Traits);
EXPECT_EQ(1u, Table.size());
- ASSERT_NE(Table.end(), Table.find_as(3u));
- EXPECT_EQ(7u, Table.get(3u));
+ ASSERT_NE(Table.end(), Table.find_as(3u, Traits));
+ EXPECT_EQ(7u, Table.get(3u, Traits));
}
TEST(HashTableTest, TestCollision) {
- HashTableInternals Table;
+ HashTableInternals<> Table;
EXPECT_EQ(0u, Table.size());
EXPECT_GT(Table.capacity(), 0u);
@@ -58,33 +65,35 @@
uint32_t N1 = Table.capacity() + 1;
uint32_t N2 = 2 * N1;
- Table.set_as(N1, 7);
- Table.set_as(N2, 12);
+ IdentityHashTraits Traits;
+ Table.set_as(N1, 7, Traits);
+ Table.set_as(N2, 12, Traits);
EXPECT_EQ(2u, Table.size());
- ASSERT_NE(Table.end(), Table.find_as(N1));
- ASSERT_NE(Table.end(), Table.find_as(N2));
+ ASSERT_NE(Table.end(), Table.find_as(N1, Traits));
+ ASSERT_NE(Table.end(), Table.find_as(N2, Traits));
- EXPECT_EQ(7u, Table.get(N1));
- EXPECT_EQ(12u, Table.get(N2));
+ EXPECT_EQ(7u, Table.get(N1, Traits));
+ EXPECT_EQ(12u, Table.get(N2, Traits));
}
TEST(HashTableTest, TestRemove) {
- HashTableInternals Table;
+ HashTableInternals<> Table;
EXPECT_EQ(0u, Table.size());
EXPECT_GT(Table.capacity(), 0u);
- Table.set_as(1u, 2);
- Table.set_as(3u, 4);
+ IdentityHashTraits Traits;
+ Table.set_as(1u, 2, Traits);
+ Table.set_as(3u, 4, Traits);
EXPECT_EQ(2u, Table.size());
- ASSERT_NE(Table.end(), Table.find_as(1u));
- ASSERT_NE(Table.end(), Table.find_as(3u));
+ ASSERT_NE(Table.end(), Table.find_as(1u, Traits));
+ ASSERT_NE(Table.end(), Table.find_as(3u, Traits));
- EXPECT_EQ(2u, Table.get(1u));
- EXPECT_EQ(4u, Table.get(3u));
+ EXPECT_EQ(2u, Table.get(1u, Traits));
+ EXPECT_EQ(4u, Table.get(3u, Traits));
}
TEST(HashTableTest, TestCollisionAfterMultipleProbes) {
- HashTableInternals Table;
+ HashTableInternals<> Table;
EXPECT_EQ(0u, Table.size());
EXPECT_GT(Table.capacity(), 0u);
@@ -95,17 +104,18 @@
uint32_t N2 = N1 + 1;
uint32_t N3 = 2 * N1;
- Table.set_as(N1, 7);
- Table.set_as(N2, 11);
- Table.set_as(N3, 13);
+ IdentityHashTraits Traits;
+ Table.set_as(N1, 7, Traits);
+ Table.set_as(N2, 11, Traits);
+ Table.set_as(N3, 13, Traits);
EXPECT_EQ(3u, Table.size());
- ASSERT_NE(Table.end(), Table.find_as(N1));
- ASSERT_NE(Table.end(), Table.find_as(N2));
- ASSERT_NE(Table.end(), Table.find_as(N3));
+ ASSERT_NE(Table.end(), Table.find_as(N1, Traits));
+ ASSERT_NE(Table.end(), Table.find_as(N2, Traits));
+ ASSERT_NE(Table.end(), Table.find_as(N3, Traits));
- EXPECT_EQ(7u, Table.get(N1));
- EXPECT_EQ(11u, Table.get(N2));
- EXPECT_EQ(13u, Table.get(N3));
+ EXPECT_EQ(7u, Table.get(N1, Traits));
+ EXPECT_EQ(11u, Table.get(N2, Traits));
+ EXPECT_EQ(13u, Table.get(N3, Traits));
}
TEST(HashTableTest, Grow) {
@@ -113,24 +123,26 @@
// guaranteed to trigger a grow. Then verify that the size is the same, the
// capacity is larger, and all the original items are still in the table.
- HashTableInternals Table;
+ HashTableInternals<> Table;
+ IdentityHashTraits Traits;
uint32_t OldCapacity = Table.capacity();
for (uint32_t I = 0; I < OldCapacity; ++I) {
- Table.set_as(OldCapacity + I * 2 + 1, I * 2 + 3);
+ Table.set_as(OldCapacity + I * 2 + 1, I * 2 + 3, Traits);
}
EXPECT_EQ(OldCapacity, Table.size());
EXPECT_GT(Table.capacity(), OldCapacity);
for (uint32_t I = 0; I < OldCapacity; ++I) {
- ASSERT_NE(Table.end(), Table.find_as(OldCapacity + I * 2 + 1));
- EXPECT_EQ(I * 2 + 3, Table.get(OldCapacity + I * 2 + 1));
+ ASSERT_NE(Table.end(), Table.find_as(OldCapacity + I * 2 + 1, Traits));
+ EXPECT_EQ(I * 2 + 3, Table.get(OldCapacity + I * 2 + 1, Traits));
}
}
TEST(HashTableTest, Serialization) {
- HashTableInternals Table;
+ HashTableInternals<> Table;
+ IdentityHashTraits Traits;
uint32_t Cap = Table.capacity();
for (uint32_t I = 0; I < Cap; ++I) {
- Table.set_as(Cap + I * 2 + 1, I * 2 + 3);
+ Table.set_as(Cap + I * 2 + 1, I * 2 + 3, Traits);
}
std::vector<uint8_t> Buffer(Table.calculateSerializedLength());
@@ -140,7 +152,7 @@
// We should have written precisely the number of bytes we calculated earlier.
EXPECT_EQ(Buffer.size(), Writer.getOffset());
- HashTableInternals Table2;
+ HashTableInternals<> Table2;
BinaryStreamReader Reader(Stream);
EXPECT_THAT_ERROR(Table2.load(Reader), Succeeded());
// We should have read precisely the number of bytes we calculated earlier.
@@ -193,20 +205,19 @@
} while (std::next_permutation(Streams.begin(), Streams.end()));
}
-namespace {
struct FooBar {
uint32_t X;
uint32_t Y;
+
+ bool operator==(const FooBar &RHS) const {
+ return X == RHS.X && Y == RHS.Y;
+ }
};
-} // namespace
-
-namespace llvm {
-namespace pdb {
-template <> struct PdbHashTraits<FooBar> {
+struct FooBarHashTraits {
std::vector<char> Buffer;
- PdbHashTraits() { Buffer.push_back(0); }
+ FooBarHashTraits() { Buffer.push_back(0); }
uint32_t hashLookupKey(StringRef S) const {
return llvm::pdb::hashStringV1(S);
@@ -226,17 +237,16 @@
return N;
}
};
-} // namespace pdb
-} // namespace llvm
TEST(HashTableTest, NonTrivialValueType) {
- HashTable<FooBar> Table;
+ HashTableInternals<FooBar> Table;
+ FooBarHashTraits Traits;
uint32_t Cap = Table.capacity();
for (uint32_t I = 0; I < Cap; ++I) {
FooBar F;
F.X = I;
F.Y = I + 1;
- Table.set_as(utostr(I), F);
+ Table.set_as(utostr(I), F, Traits);
}
std::vector<uint8_t> Buffer(Table.calculateSerializedLength());
@@ -246,7 +256,7 @@
// We should have written precisely the number of bytes we calculated earlier.
EXPECT_EQ(Buffer.size(), Writer.getOffset());
- HashTable<FooBar> Table2;
+ HashTableInternals<FooBar> Table2;
BinaryStreamReader Reader(Stream);
EXPECT_THAT_ERROR(Table2.load(Reader), Succeeded());
// We should have read precisely the number of bytes we calculated earlier.
@@ -254,7 +264,7 @@
EXPECT_EQ(Table.size(), Table2.size());
EXPECT_EQ(Table.capacity(), Table2.capacity());
- // EXPECT_EQ(Table.Buckets, Table2.Buckets);
- // EXPECT_EQ(Table.Present, Table2.Present);
- // EXPECT_EQ(Table.Deleted, Table2.Deleted);
+ EXPECT_EQ(Table.Buckets, Table2.Buckets);
+ EXPECT_EQ(Table.Present, Table2.Present);
+ EXPECT_EQ(Table.Deleted, Table2.Deleted);
}
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp
index 15afea6..91c7db4 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp
@@ -1,9 +1,8 @@
//===- NativeSymbolReuseTest.cpp ------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/PDB/PDBApiTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/PDB/PDBApiTest.cpp
index 007ea90..766f54d 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/PDB/PDBApiTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/PDB/PDBApiTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/DebugInfo/PDB/PDBApiTest.cpp -------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
index bf08ab2..2f7c061 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
@@ -1,9 +1,8 @@
//===- StringTableBuilderTest.cpp -----------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -20,11 +19,7 @@
using namespace llvm::pdb;
using namespace llvm::support;
-namespace {
-class StringTableBuilderTest : public ::testing::Test {};
-}
-
-TEST_F(StringTableBuilderTest, Simple) {
+TEST(StringTableBuilderTest, Simple) {
// Create /names table contents.
PDBStringTableBuilder Builder;
@@ -79,3 +74,21 @@
EXPECT_THAT_EXPECTED(Table.getIDForString("bazz"), HasValue(BazzID));
EXPECT_THAT_EXPECTED(Table.getIDForString("barr"), HasValue(BarrID));
}
+
+TEST(StringTableHashTraitsTest, Simple) {
+ PDBStringTableBuilder Builder;
+
+ // Create more than 64kiB of dummy entries.
+ for (int i = 0; i < 320; ++i) {
+ std::string aaaaa = std::string(220, 'a') + std::to_string(i);
+ Builder.insert(aaaaa);
+ }
+
+ std::string S = "foo.natvis";
+ uint32_t Pos = Builder.insert(S);
+
+ EXPECT_GT(Pos, 0xFFFFu);
+
+ StringTableHashTraits Traits(Builder);
+ EXPECT_LE(Traits.hashLookupKey(S), 0xFFFFu);
+}
diff --git a/src/llvm-project/llvm/unittests/Demangle/CMakeLists.txt b/src/llvm-project/llvm/unittests/Demangle/CMakeLists.txt
index 954f3d0..c6291bb 100644
--- a/src/llvm-project/llvm/unittests/Demangle/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Demangle/CMakeLists.txt
@@ -4,6 +4,7 @@
)
add_llvm_unittest(DemangleTests
+ DemangleTest.cpp
ItaniumDemangleTest.cpp
PartialDemangleTest.cpp
)
diff --git a/src/llvm-project/llvm/unittests/Demangle/DemangleTest.cpp b/src/llvm-project/llvm/unittests/Demangle/DemangleTest.cpp
new file mode 100644
index 0000000..cb70a72
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Demangle/DemangleTest.cpp
@@ -0,0 +1,24 @@
+//===-- DemangleTest.cpp --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Demangle/Demangle.h"
+#include "gmock/gmock.h"
+
+using namespace llvm;
+
+TEST(Demangle, demangleTest) {
+ EXPECT_EQ(demangle("_"), "_");
+ EXPECT_EQ(demangle("_Z3fooi"), "foo(int)");
+ EXPECT_EQ(demangle("__Z3fooi"), "foo(int)");
+ EXPECT_EQ(demangle("___Z3fooi_block_invoke"),
+ "invocation function for block in foo(int)");
+ EXPECT_EQ(demangle("____Z3fooi_block_invoke"),
+ "invocation function for block in foo(int)");
+ EXPECT_EQ(demangle("?foo@@YAXH@Z"), "void __cdecl foo(int)");
+ EXPECT_EQ(demangle("foo"), "foo");
+}
diff --git a/src/llvm-project/llvm/unittests/Demangle/ItaniumDemangleTest.cpp b/src/llvm-project/llvm/unittests/Demangle/ItaniumDemangleTest.cpp
index abb690c..11bb784 100644
--- a/src/llvm-project/llvm/unittests/Demangle/ItaniumDemangleTest.cpp
+++ b/src/llvm-project/llvm/unittests/Demangle/ItaniumDemangleTest.cpp
@@ -1,9 +1,8 @@
//===------------------ ItaniumDemangleTest.cpp ---------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Demangle/PartialDemangleTest.cpp b/src/llvm-project/llvm/unittests/Demangle/PartialDemangleTest.cpp
index 8bb4a3a..0379d83 100644
--- a/src/llvm-project/llvm/unittests/Demangle/PartialDemangleTest.cpp
+++ b/src/llvm-project/llvm/unittests/Demangle/PartialDemangleTest.cpp
@@ -1,9 +1,8 @@
//===----------------------- PartialDemangleTest.cpp ----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/CMakeLists.txt b/src/llvm-project/llvm/unittests/ExecutionEngine/CMakeLists.txt
index 302de99..1bf2105 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/CMakeLists.txt
@@ -12,6 +12,7 @@
ExecutionEngineTest.cpp
)
+add_subdirectory(JITLink)
add_subdirectory(Orc)
# Include MCJIT tests only if native arch is a built JIT target.
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/ExecutionEngineTest.cpp
index ec5fab6..77b1085 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/ExecutionEngineTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/ExecutionEngineTest.cpp
@@ -1,9 +1,8 @@
//===- ExecutionEngineTest.cpp - Unit tests for ExecutionEngine -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt
new file mode 100644
index 0000000..9f9ffbb
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt
@@ -0,0 +1,18 @@
+set(LLVM_LINK_COMPONENTS
+ ${LLVM_TARGETS_TO_BUILD}
+ JITLink
+ MC
+ MCDisassembler
+ MCParser
+ Object
+ RuntimeDyld
+ Support
+ Target
+ )
+
+add_llvm_unittest(JITLinkTests
+ JITLinkTestCommon.cpp
+ MachO_x86_64_Tests.cpp
+ )
+
+target_link_libraries(JITLinkTests PRIVATE LLVMTestingSupport)
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.cpp
new file mode 100644
index 0000000..b0c6d5b
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.cpp
@@ -0,0 +1,251 @@
+//===------- JITLinkTestCommon.cpp - Common code for JITLink tests --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "JITLinkTestCommon.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
+#include "llvm/Support/TargetSelect.h"
+
+using namespace llvm::jitlink;
+namespace llvm {
+
+Expected<std::unique_ptr<JITLinkTestCommon::TestResources>>
+JITLinkTestCommon::TestResources::Create(StringRef AsmSrc, StringRef TripleStr,
+ bool PIC, bool LargeCodeModel,
+ MCTargetOptions Options) {
+ Error Err = Error::success();
+ auto R = std::unique_ptr<TestResources>(new TestResources(
+ AsmSrc, TripleStr, PIC, LargeCodeModel, std::move(Options), Err));
+ if (Err)
+ return std::move(Err);
+ return std::move(R);
+}
+
+MemoryBufferRef
+JITLinkTestCommon::TestResources::getTestObjectBufferRef() const {
+ return MemoryBufferRef(StringRef(ObjBuffer.data(), ObjBuffer.size()),
+ "Test object");
+}
+
+JITLinkTestCommon::TestResources::TestResources(StringRef AsmSrc,
+ StringRef TripleStr, bool PIC,
+ bool LargeCodeModel,
+ MCTargetOptions Options,
+ Error &Err)
+ : ObjStream(ObjBuffer), Options(std::move(Options)) {
+ ErrorAsOutParameter _(&Err);
+ Triple TT(Triple::normalize(TripleStr));
+ if (auto Err2 = initializeTripleSpecifics(TT)) {
+ Err = std::move(Err2);
+ return;
+ }
+ initializeTestSpecifics(AsmSrc, TT, PIC, LargeCodeModel);
+}
+
+Error JITLinkTestCommon::TestResources::initializeTripleSpecifics(Triple &TT) {
+ std::string ErrorMsg;
+ TheTarget = TargetRegistry::lookupTarget("", TT, ErrorMsg);
+
+ if (!TheTarget)
+ return make_error<StringError>(ErrorMsg, inconvertibleErrorCode());
+
+ MRI.reset(TheTarget->createMCRegInfo(TT.getTriple()));
+ if (!MRI)
+ report_fatal_error("Could not build MCRegisterInfo for triple");
+
+ MAI.reset(TheTarget->createMCAsmInfo(*MRI, TT.getTriple()));
+ if (!MAI)
+ report_fatal_error("Could not build MCAsmInfo for triple");
+
+ MCII.reset(TheTarget->createMCInstrInfo());
+ if (!MCII)
+ report_fatal_error("Could not build MCInstrInfo for triple");
+
+ STI.reset(TheTarget->createMCSubtargetInfo(TT.getTriple(), "", ""));
+ if (!STI)
+ report_fatal_error("Could not build MCSubtargetInfo for triple");
+
+ DisCtx = llvm::make_unique<MCContext>(MAI.get(), MRI.get(), nullptr);
+ Dis.reset(TheTarget->createMCDisassembler(*STI, *DisCtx));
+
+ if (!Dis)
+ report_fatal_error("Could not build MCDisassembler");
+
+ return Error::success();
+}
+
+void JITLinkTestCommon::TestResources::initializeTestSpecifics(
+ StringRef AsmSrc, const Triple &TT, bool PIC, bool LargeCodeModel) {
+ SrcMgr.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(AsmSrc), SMLoc());
+ AsCtx = llvm::make_unique<MCContext>(MAI.get(), MRI.get(), &MOFI, &SrcMgr);
+ MOFI.InitMCObjectFileInfo(TT, PIC, *AsCtx, LargeCodeModel);
+
+ std::unique_ptr<MCCodeEmitter> CE(
+ TheTarget->createMCCodeEmitter(*MCII, *MRI, *AsCtx));
+ if (!CE)
+ report_fatal_error("Could not build MCCodeEmitter");
+
+ std::unique_ptr<MCAsmBackend> MAB(
+ TheTarget->createMCAsmBackend(*STI, *MRI, Options));
+ if (!MAB)
+ report_fatal_error("Could not build MCAsmBackend for test");
+
+ std::unique_ptr<MCObjectWriter> MOW(MAB->createObjectWriter(ObjStream));
+
+ MOS.reset(TheTarget->createMCObjectStreamer(
+ TT, *AsCtx, std::move(MAB), std::move(MOW), std::move(CE), *STI,
+ Options.MCRelaxAll, Options.MCIncrementalLinkerCompatible, false));
+
+ std::unique_ptr<MCAsmParser> MAP(
+ createMCAsmParser(SrcMgr, *AsCtx, *MOS, *MAI));
+ std::unique_ptr<MCTargetAsmParser> TAP(
+ TheTarget->createMCAsmParser(*STI, *MAP, *MCII, Options));
+
+ if (!TAP)
+ report_fatal_error("Could not build MCTargetAsmParser for test");
+
+ MAP->setTargetParser(*TAP);
+
+ if (MAP->Run(false))
+ report_fatal_error("Failed to parse test case");
+}
+
+JITLinkTestCommon::TestJITLinkContext::TestJITLinkContext(
+ TestResources &TR, TestCaseFunction TestCase)
+ : TR(TR), TestCase(std::move(TestCase)) {}
+
+JITLinkTestCommon::TestJITLinkContext &
+JITLinkTestCommon::TestJITLinkContext::setMemoryManager(
+ std::unique_ptr<JITLinkMemoryManager> MM) {
+ assert(!MemMgr && "Memory manager already set");
+ MemMgr = std::move(MM);
+ return *this;
+}
+
+JITLinkMemoryManager &
+JITLinkTestCommon::TestJITLinkContext::getMemoryManager() {
+ if (!MemMgr)
+ MemMgr = llvm::make_unique<InProcessMemoryManager>();
+ return *MemMgr;
+}
+
+MemoryBufferRef JITLinkTestCommon::TestJITLinkContext::getObjectBuffer() const {
+ return TR.getTestObjectBufferRef();
+}
+
+void JITLinkTestCommon::TestJITLinkContext::notifyFailed(Error Err) {
+ ADD_FAILURE() << "Unexpected failure: " << toString(std::move(Err));
+}
+
+void JITLinkTestCommon::TestJITLinkContext::lookup(
+ const DenseSet<StringRef> &Symbols,
+ JITLinkAsyncLookupContinuation LookupContinuation) {
+ jitlink::AsyncLookupResult LookupResult;
+ DenseSet<StringRef> MissingSymbols;
+ for (const auto &Symbol : Symbols) {
+ auto I = Externals.find(Symbol);
+ if (I != Externals.end())
+ LookupResult[Symbol] = I->second;
+ else
+ MissingSymbols.insert(Symbol);
+ }
+
+ if (MissingSymbols.empty())
+ LookupContinuation(std::move(LookupResult));
+ else {
+ std::string ErrMsg;
+ {
+ raw_string_ostream ErrMsgStream(ErrMsg);
+ ErrMsgStream << "Failed to resolve external symbols: [";
+ for (auto &Sym : MissingSymbols)
+ ErrMsgStream << " " << Sym;
+ ErrMsgStream << " ]\n";
+ }
+ LookupContinuation(
+ make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()));
+ }
+}
+
+void JITLinkTestCommon::TestJITLinkContext::notifyResolved(AtomGraph &G) {
+ if (NotifyResolved)
+ NotifyResolved(G);
+}
+
+void JITLinkTestCommon::TestJITLinkContext::notifyFinalized(
+ std::unique_ptr<JITLinkMemoryManager::Allocation> A) {
+ if (NotifyFinalized)
+ NotifyFinalized(std::move(A));
+}
+
+Error JITLinkTestCommon::TestJITLinkContext::modifyPassConfig(
+ const Triple &TT, PassConfiguration &Config) {
+ if (TestCase)
+ Config.PostFixupPasses.push_back([&](AtomGraph &G) -> Error {
+ TestCase(G);
+ return Error::success();
+ });
+ return Error::success();
+}
+
+JITLinkTestCommon::JITLinkTestCommon() { initializeLLVMTargets(); }
+
+Expected<std::pair<MCInst, size_t>>
+JITLinkTestCommon::disassemble(const MCDisassembler &Dis,
+ jitlink::DefinedAtom &Atom, size_t Offset) {
+ ArrayRef<uint8_t> InstBuffer(
+ reinterpret_cast<const uint8_t *>(Atom.getContent().data()) + Offset,
+ Atom.getContent().size() - Offset);
+
+ MCInst Inst;
+ uint64_t InstSize;
+ auto Status =
+ Dis.getInstruction(Inst, InstSize, InstBuffer, 0, nulls(), nulls());
+
+ if (Status != MCDisassembler::Success)
+ return make_error<StringError>("Could not disassemble instruction",
+ inconvertibleErrorCode());
+
+ return std::make_pair(Inst, InstSize);
+}
+
+Expected<int64_t>
+JITLinkTestCommon::decodeImmediateOperand(const MCDisassembler &Dis,
+ jitlink::DefinedAtom &Atom,
+ size_t OpIdx, size_t Offset) {
+ auto InstAndSize = disassemble(Dis, Atom, Offset);
+ if (!InstAndSize)
+ return InstAndSize.takeError();
+
+ if (OpIdx >= InstAndSize->first.getNumOperands())
+ return make_error<StringError>("Invalid operand index",
+ inconvertibleErrorCode());
+
+ auto &Op = InstAndSize->first.getOperand(OpIdx);
+
+ if (!Op.isImm())
+ return make_error<StringError>("Operand at index is not immediate",
+ inconvertibleErrorCode());
+
+ return Op.getImm();
+}
+
+bool JITLinkTestCommon::AreTargetsInitialized = false;
+
+void JITLinkTestCommon::initializeLLVMTargets() {
+ if (!AreTargetsInitialized) {
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+ InitializeAllAsmParsers();
+ InitializeAllAsmPrinters();
+ InitializeAllDisassemblers();
+ AreTargetsInitialized = true;
+ }
+}
+
+} // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.h b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.h
new file mode 100644
index 0000000..8e1273e
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.h
@@ -0,0 +1,205 @@
+//===---- JITLinkTestCommon.h - Utilities for Orc Unit Tests ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Common utilities for JITLink unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKTESTCOMMON_H
+#define LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKTESTCOMMON_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+
+#include "gtest/gtest.h"
+
+namespace llvm {
+
+class JITLinkTestCommon {
+public:
+
+ class TestResources {
+ public:
+ static Expected<std::unique_ptr<TestResources>>
+ Create(StringRef AsmSrc, StringRef TripleStr, bool PIC, bool LargeCodeModel,
+ MCTargetOptions Options);
+
+ MemoryBufferRef getTestObjectBufferRef() const;
+
+ const MCDisassembler &getDisassembler() const { return *Dis; }
+
+ private:
+ TestResources(StringRef AsmSrc, StringRef TripleStr, bool PIC,
+ bool LargeCodeModel, MCTargetOptions Options, Error &Err);
+
+ Error initializeTripleSpecifics(Triple &TT);
+ void initializeTestSpecifics(StringRef AsmSource, const Triple &TT,
+ bool PIC, bool LargeCodeModel);
+
+ const Target *TheTarget = nullptr;
+ SourceMgr SrcMgr;
+ SmallVector<char, 0> ObjBuffer;
+ raw_svector_ostream ObjStream;
+
+ MCTargetOptions Options;
+ std::unique_ptr<MCRegisterInfo> MRI;
+ std::unique_ptr<MCAsmInfo> MAI;
+ std::unique_ptr<MCInstrInfo> MCII;
+ std::unique_ptr<MCSubtargetInfo> STI;
+
+ MCObjectFileInfo MOFI;
+ std::unique_ptr<MCContext> AsCtx;
+ std::unique_ptr<MCStreamer> MOS;
+
+ std::unique_ptr<MCContext> DisCtx;
+ std::unique_ptr<const MCDisassembler> Dis;
+ };
+
+ class TestJITLinkContext : public jitlink::JITLinkContext {
+ public:
+ using TestCaseFunction = std::function<void(jitlink::AtomGraph &)>;
+
+ using NotifyResolvedFunction = std::function<void(jitlink::AtomGraph &G)>;
+
+ using NotifyFinalizedFunction = std::function<void(
+ std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>)>;
+
+ TestJITLinkContext(TestResources &TR, TestCaseFunction TestCase);
+
+ StringMap<JITEvaluatedSymbol> &externals() { return Externals; }
+
+ TestJITLinkContext &
+ setNotifyResolved(NotifyResolvedFunction NotifyResolved);
+
+ TestJITLinkContext &
+ setNotifyFinalized(NotifyFinalizedFunction NotifyFinalized);
+
+ TestJITLinkContext &
+ setMemoryManager(std::unique_ptr<jitlink::JITLinkMemoryManager> MM);
+
+ jitlink::JITLinkMemoryManager &getMemoryManager() override;
+
+ MemoryBufferRef getObjectBuffer() const override;
+
+ void notifyFailed(Error Err) override;
+
+ void
+ lookup(const DenseSet<StringRef> &Symbols,
+ jitlink::JITLinkAsyncLookupContinuation LookupContinuation) override;
+
+ void notifyResolved(jitlink::AtomGraph &G) override;
+
+ void notifyFinalized(
+ std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation> A) override;
+
+ Error modifyPassConfig(const Triple &TT,
+ jitlink::PassConfiguration &Config) override;
+
+ private:
+ TestResources &TR;
+ TestCaseFunction TestCase;
+ NotifyResolvedFunction NotifyResolved;
+ NotifyFinalizedFunction NotifyFinalized;
+ std::unique_ptr<MemoryBuffer> ObjBuffer;
+ std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr;
+ StringMap<JITEvaluatedSymbol> Externals;
+ };
+
+ JITLinkTestCommon();
+
+ /// Get TestResources for this target/test.
+ ///
+ /// If this method fails it is likely because the target is not supported in
+ /// this build. The test should bail out without failing (possibly logging a
+ /// diagnostic).
+ Expected<std::unique_ptr<TestResources>>
+ getTestResources(StringRef AsmSrc, StringRef Triple, bool PIC,
+ bool LargeCodeModel, MCTargetOptions Options) const {
+ return TestResources::Create(AsmSrc, Triple, PIC, LargeCodeModel,
+ std::move(Options));
+ }
+
+ template <typename T>
+ static Expected<T> readInt(jitlink::AtomGraph &G, jitlink::DefinedAtom &A,
+ size_t Offset = 0) {
+ if (Offset + sizeof(T) > A.getContent().size())
+ return make_error<StringError>("Reading past end of atom content",
+ inconvertibleErrorCode());
+ return support::endian::read<T, 1>(A.getContent().data() + Offset,
+ G.getEndianness());
+ }
+
+ template <typename T>
+ static Expected<T> readInt(jitlink::AtomGraph &G, StringRef AtomName,
+ size_t Offset = 0) {
+ auto DA = G.findDefinedAtomByName(AtomName);
+ if (!DA)
+ return DA.takeError();
+ return readInt<T>(G, *DA);
+ }
+
+ static Expected<std::pair<MCInst, size_t>>
+ disassemble(const MCDisassembler &Dis, jitlink::DefinedAtom &Atom,
+ size_t Offset = 0);
+
+ static Expected<int64_t> decodeImmediateOperand(const MCDisassembler &Dis,
+ jitlink::DefinedAtom &Atom,
+ size_t OpIdx,
+ size_t Offset = 0);
+
+ static jitlink::Atom &atom(jitlink::AtomGraph &G, StringRef Name) {
+ return G.getAtomByName(Name);
+ }
+
+ static jitlink::DefinedAtom &definedAtom(jitlink::AtomGraph &G,
+ StringRef Name) {
+ return G.getDefinedAtomByName(Name);
+ }
+
+ static JITTargetAddress atomAddr(jitlink::AtomGraph &G, StringRef Name) {
+ return atom(G, Name).getAddress();
+ }
+
+ template <typename PredT>
+ static size_t countEdgesMatching(jitlink::DefinedAtom &DA,
+ const PredT &Pred) {
+ return std::count_if(DA.edges().begin(), DA.edges().end(), Pred);
+ }
+
+ template <typename PredT>
+ static size_t countEdgesMatching(jitlink::AtomGraph &G, StringRef Name,
+ const PredT &Pred) {
+ return countEdgesMatching(definedAtom(G, Name), Pred);
+ }
+
+private:
+
+ static bool AreTargetsInitialized;
+ void initializeLLVMTargets();
+
+ DenseMap<StringRef, JITEvaluatedSymbol> Externals;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/MachO_x86_64_Tests.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/MachO_x86_64_Tests.cpp
new file mode 100644
index 0000000..98c5d44
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/MachO_x86_64_Tests.cpp
@@ -0,0 +1,229 @@
+//===--------- MachO_x86_64.cpp - Tests for JITLink MachO/x86-64 ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "JITLinkTestCommon.h"
+
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ExecutionEngine/JITLink/MachO_x86_64.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::jitlink;
+using namespace llvm::jitlink::MachO_x86_64_Edges;
+
+namespace {
+
+class JITLinkTest_MachO_x86_64 : public JITLinkTestCommon,
+ public testing::Test {
+public:
+ using BasicVerifyGraphFunction =
+ std::function<void(AtomGraph &, const MCDisassembler &)>;
+
+ void runBasicVerifyGraphTest(StringRef AsmSrc, StringRef Triple,
+ StringMap<JITEvaluatedSymbol> Externals,
+ bool PIC, bool LargeCodeModel,
+ MCTargetOptions Options,
+ BasicVerifyGraphFunction RunGraphTest) {
+ auto TR = getTestResources(AsmSrc, Triple, PIC, LargeCodeModel,
+ std::move(Options));
+ if (!TR) {
+ dbgs() << "Skipping JITLInk unit test: " << toString(TR.takeError())
+ << "\n";
+ return;
+ }
+
+ auto JTCtx = llvm::make_unique<TestJITLinkContext>(
+ **TR, [&](AtomGraph &G) { RunGraphTest(G, (*TR)->getDisassembler()); });
+
+ JTCtx->externals() = std::move(Externals);
+
+ jitLink_MachO_x86_64(std::move(JTCtx));
+ }
+
+protected:
+ static void verifyIsPointerTo(AtomGraph &G, DefinedAtom &A, Atom &Target) {
+ EXPECT_EQ(A.edges_size(), 1U) << "Incorrect number of edges for pointer";
+ if (A.edges_size() != 1U)
+ return;
+ auto &E = *A.edges().begin();
+ EXPECT_EQ(E.getKind(), Pointer64)
+ << "Expected pointer to have a pointer64 relocation";
+ EXPECT_EQ(&E.getTarget(), &Target) << "Expected edge to point at target";
+ EXPECT_THAT_EXPECTED(readInt<uint64_t>(G, A), HasValue(Target.getAddress()))
+ << "Pointer does not point to target";
+ }
+
+ static void verifyGOTLoad(AtomGraph &G, DefinedAtom &A, Edge &E,
+ Atom &Target) {
+ EXPECT_EQ(E.getAddend(), 0U) << "Expected GOT load to have a zero addend";
+ EXPECT_TRUE(E.getTarget().isDefined())
+ << "GOT entry should be a defined atom";
+ if (!E.getTarget().isDefined())
+ return;
+
+ verifyIsPointerTo(G, static_cast<DefinedAtom &>(E.getTarget()), Target);
+ }
+
+ static void verifyCall(const MCDisassembler &Dis, AtomGraph &G,
+ DefinedAtom &Caller, Edge &E, Atom &Callee) {
+ EXPECT_EQ(E.getKind(), Branch32) << "Edge is not a Branch32";
+ EXPECT_EQ(E.getAddend(), 0U) << "Expected no addend on stub call";
+ EXPECT_EQ(&E.getTarget(), &Callee)
+ << "Edge does not point at expected callee";
+
+ JITTargetAddress FixupAddress = Caller.getAddress() + E.getOffset();
+ uint64_t PCRelDelta = Callee.getAddress() - (FixupAddress + 4);
+
+ EXPECT_THAT_EXPECTED(
+ decodeImmediateOperand(Dis, Caller, 0, E.getOffset() - 1),
+ HasValue(PCRelDelta));
+ }
+
+ static void verifyIndirectCall(const MCDisassembler &Dis, AtomGraph &G,
+ DefinedAtom &Caller, Edge &E, Atom &Callee) {
+ EXPECT_EQ(E.getKind(), PCRel32) << "Edge is not a PCRel32";
+ EXPECT_EQ(E.getAddend(), 0) << "Expected no addend on stub cal";
+ EXPECT_TRUE(E.getTarget().isDefined()) << "Target is not a defined atom";
+ if (!E.getTarget().isDefined())
+ return;
+ verifyIsPointerTo(G, static_cast<DefinedAtom &>(E.getTarget()), Callee);
+
+ JITTargetAddress FixupAddress = Caller.getAddress() + E.getOffset();
+ uint64_t PCRelDelta = E.getTarget().getAddress() - (FixupAddress + 4);
+
+ EXPECT_THAT_EXPECTED(
+ decodeImmediateOperand(Dis, Caller, 3, E.getOffset() - 2),
+ HasValue(PCRelDelta));
+ }
+
+ static void verifyCallViaStub(const MCDisassembler &Dis, AtomGraph &G,
+ DefinedAtom &Caller, Edge &E, Atom &Callee) {
+ verifyCall(Dis, G, Caller, E, E.getTarget());
+
+ if (!E.getTarget().isDefined()) {
+ ADD_FAILURE() << "Edge target is not a stub";
+ return;
+ }
+
+ auto &StubAtom = static_cast<DefinedAtom &>(E.getTarget());
+ EXPECT_EQ(StubAtom.edges_size(), 1U)
+ << "Expected one edge from stub to target";
+
+ auto &StubEdge = *StubAtom.edges().begin();
+
+ verifyIndirectCall(Dis, G, static_cast<DefinedAtom &>(StubAtom), StubEdge,
+ Callee);
+ }
+};
+
+} // end anonymous namespace
+
+// Test each operation on LegacyObjectTransformLayer.
+TEST_F(JITLinkTest_MachO_x86_64, BasicRelocations) {
+ runBasicVerifyGraphTest(
+ R"(
+ .section __TEXT,__text,regular,pure_instructions
+ .build_version macos, 10, 14
+ .globl _bar
+ .p2align 4, 0x90
+ _bar:
+ callq _baz
+
+ .globl _foo
+ .p2align 4, 0x90
+ _foo:
+ callq _bar
+ _foo.1:
+ movq _y@GOTPCREL(%rip), %rcx
+ _foo.2:
+ movq _p(%rip), %rdx
+
+ .section __DATA,__data
+ .globl _x
+ .p2align 2
+ _x:
+ .long 42
+
+ .globl _p
+ .p2align 3
+ _p:
+ .quad _x
+
+ .subsections_via_symbols)",
+ "x86_64-apple-macosx10.14",
+ {{"_y", JITEvaluatedSymbol(0xdeadbeef, JITSymbolFlags::Exported)},
+ {"_baz", JITEvaluatedSymbol(0xcafef00d, JITSymbolFlags::Exported)}},
+ true, false, MCTargetOptions(),
+ [](AtomGraph &G, const MCDisassembler &Dis) {
+ // Name the atoms in the asm above.
+ auto &Baz = atom(G, "_baz");
+ auto &Y = atom(G, "_y");
+
+ auto &Bar = definedAtom(G, "_bar");
+ auto &Foo = definedAtom(G, "_foo");
+ auto &Foo_1 = definedAtom(G, "_foo.1");
+ auto &Foo_2 = definedAtom(G, "_foo.2");
+ auto &X = definedAtom(G, "_x");
+ auto &P = definedAtom(G, "_p");
+
+ // Check unsigned reloc for _p
+ {
+ EXPECT_EQ(P.edges_size(), 1U) << "Unexpected number of relocations";
+ EXPECT_EQ(P.edges().begin()->getKind(), Pointer64)
+ << "Unexpected edge kind for _p";
+ EXPECT_THAT_EXPECTED(readInt<uint64_t>(G, P),
+ HasValue(X.getAddress()))
+ << "Unsigned relocation did not apply correctly";
+ }
+
+ // Check that _bar is a call-via-stub to _baz.
+ // This will check that the call goes to a stub, that the stub is an
+ // indirect call, and that the pointer for the indirect call points to
+ // baz.
+ {
+ EXPECT_EQ(Bar.edges_size(), 1U)
+ << "Incorrect number of edges for bar";
+ EXPECT_EQ(Bar.edges().begin()->getKind(), Branch32)
+ << "Unexpected edge kind for _bar";
+ verifyCallViaStub(Dis, G, Bar, *Bar.edges().begin(), Baz);
+ }
+
+ // Check that _foo is a direct call to _bar.
+ {
+ EXPECT_EQ(Foo.edges_size(), 1U)
+ << "Incorrect number of edges for foo";
+ EXPECT_EQ(Foo.edges().begin()->getKind(), Branch32);
+ verifyCall(Dis, G, Foo, *Foo.edges().begin(), Bar);
+ }
+
+ // Check .got load in _foo.1
+ {
+ EXPECT_EQ(Foo_1.edges_size(), 1U)
+ << "Incorrect number of edges for foo_1";
+ EXPECT_EQ(Foo_1.edges().begin()->getKind(), PCRel32);
+ verifyGOTLoad(G, Foo_1, *Foo_1.edges().begin(), Y);
+ }
+
+ // Check PCRel ref to _p in _foo.2
+ {
+ EXPECT_EQ(Foo_2.edges_size(), 1U)
+ << "Incorrect number of edges for foo_2";
+ EXPECT_EQ(Foo_2.edges().begin()->getKind(), PCRel32);
+
+ JITTargetAddress FixupAddress =
+ Foo_2.getAddress() + Foo_2.edges().begin()->getOffset();
+ uint64_t PCRelDelta = P.getAddress() - (FixupAddress + 4);
+
+ EXPECT_THAT_EXPECTED(decodeImmediateOperand(Dis, Foo_2, 4, 0),
+ HasValue(PCRelDelta))
+ << "PCRel load does not reference expected target";
+ }
+ });
+}
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
index bc1ebc5..52b3b76 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
@@ -1,9 +1,8 @@
//===- MCJITTest.cpp - Unit tests for the MCJIT -----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
index 0582c92..7a756a7 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
@@ -1,9 +1,8 @@
//===- MCJITMemoryManagerTest.cpp - Unit tests for the JIT memory manager -===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
index 856ae45..710ce6d 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
@@ -1,9 +1,8 @@
//===- MCJITMultipeModuleTest.cpp - Unit tests for the MCJIT ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -212,10 +211,10 @@
GVB = insertGlobalInt32(B.get(), "GVB", initialNum);
FA = startFunction(A.get(),
FunctionType::get(Builder.getInt32Ty(), {}, false), "FA");
- endFunctionWithRet(FA, Builder.CreateLoad(GVA));
+ endFunctionWithRet(FA, Builder.CreateLoad(Builder.getInt32Ty(), GVA));
FB = startFunction(B.get(),
FunctionType::get(Builder.getInt32Ty(), {}, false), "FB");
- endFunctionWithRet(FB, Builder.CreateLoad(GVB));
+ endFunctionWithRet(FB, Builder.CreateLoad(Builder.getInt32Ty(), GVB));
GVC = insertGlobalInt32(B.get(), "GVC", initialNum);
GVC->setLinkage(GlobalValue::InternalLinkage);
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
index 2e3d2b6..4ec2e1a 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
@@ -1,9 +1,8 @@
//===- MCJITObjectCacheTest.cpp - Unit tests for MCJIT object caching -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
index 8972fb6..1409907 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
@@ -1,9 +1,8 @@
//===- MCJITTest.cpp - Unit tests for the MCJIT -----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -102,7 +101,7 @@
Function *ReturnGlobal =
startFunction(M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false),
"ReturnGlobal");
- Value *ReadGlobal = Builder.CreateLoad(GV);
+ Value *ReadGlobal = Builder.CreateLoad(Builder.getInt32Ty(), GV);
endFunctionWithRet(ReturnGlobal, ReadGlobal);
createJIT(std::move(M));
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
index d3ebb95..0f55443 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
@@ -1,9 +1,8 @@
//===- MCJITTestBase.h - Common base class for MCJIT Unit tests ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
index 50a57f1..e0c4b07 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
@@ -1,9 +1,8 @@
//===- MCJITTestBase.h - Common base class for MCJIT Unit tests -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
index 019437d..945c992 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
@@ -4,6 +4,7 @@
ExecutionEngine
Object
OrcJIT
+ Passes
RuntimeDyld
Support
native
@@ -30,4 +31,6 @@
ThreadSafeModuleTest.cpp
)
-target_link_libraries(OrcJITTests PRIVATE ${ORC_JIT_TEST_LIBS})
+target_link_libraries(OrcJITTests PRIVATE
+ LLVMTestingSupport
+ ${ORC_JIT_TEST_LIBS})
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
index 22be76a..fb55c4b 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
@@ -1,9 +1,8 @@
//===----------- CoreAPIsTest.cpp - Unit tests for Core ORC APIs ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -11,6 +10,7 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
+#include "llvm/Testing/Support/Error.h"
#include <set>
#include <thread>
@@ -23,21 +23,16 @@
namespace {
TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
- bool OnResolutionRun = false;
- bool OnReadyRun = false;
+ bool OnCompletionRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
+ auto OnCompletion = [&](Expected<SymbolMap> Result) {
EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
auto &Resolved = *Result;
auto I = Resolved.find(Foo);
EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
EXPECT_EQ(I->second.getAddress(), FooAddr)
<< "Resolution returned incorrect result";
- OnResolutionRun = true;
- };
- auto OnReady = [&](Error Err) {
- cantFail(std::move(Err));
- OnReadyRun = true;
+ OnCompletionRun = true;
};
std::shared_ptr<MaterializationResponsibility> FooMR;
@@ -48,65 +43,51 @@
FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
})));
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, OnResolution, OnReady,
- NoDependenciesToRegister);
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
+ OnCompletion, NoDependenciesToRegister);
- EXPECT_FALSE(OnResolutionRun) << "Should not have been resolved yet";
- EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
+ EXPECT_FALSE(OnCompletionRun) << "Should not have been resolved yet";
- FooMR->resolve({{Foo, FooSym}});
+ FooMR->notifyResolved({{Foo, FooSym}});
- EXPECT_TRUE(OnResolutionRun) << "Should have been resolved";
- EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
+ EXPECT_FALSE(OnCompletionRun) << "Should not be ready yet";
- FooMR->emit();
+ FooMR->notifyEmitted();
- EXPECT_TRUE(OnReadyRun) << "Should have been marked ready";
+ EXPECT_TRUE(OnCompletionRun) << "Should have been marked ready";
}
TEST_F(CoreAPIsStandardTest, ExecutionSessionFailQuery) {
- bool OnResolutionRun = false;
- bool OnReadyRun = false;
+ bool OnCompletionRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
+ auto OnCompletion = [&](Expected<SymbolMap> Result) {
EXPECT_FALSE(!!Result) << "Resolution unexpectedly returned success";
auto Msg = toString(Result.takeError());
EXPECT_EQ(Msg, "xyz") << "Resolution returned incorrect result";
- OnResolutionRun = true;
- };
- auto OnReady = [&](Error Err) {
- cantFail(std::move(Err));
- OnReadyRun = true;
+ OnCompletionRun = true;
};
- AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), OnResolution, OnReady);
+ AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), SymbolState::Ready,
+ OnCompletion);
ES.legacyFailQuery(Q,
make_error<StringError>("xyz", inconvertibleErrorCode()));
- EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
- EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
+ EXPECT_TRUE(OnCompletionRun) << "OnCompletionCallback was not run";
}
TEST_F(CoreAPIsStandardTest, EmptyLookup) {
- bool OnResolvedRun = false;
- bool OnReadyRun = false;
+ bool OnCompletionRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
+ auto OnCompletion = [&](Expected<SymbolMap> Result) {
cantFail(std::move(Result));
- OnResolvedRun = true;
+ OnCompletionRun = true;
};
- auto OnReady = [&](Error Err) {
- cantFail(std::move(Err));
- OnReadyRun = true;
- };
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {}, SymbolState::Ready,
+ OnCompletion, NoDependenciesToRegister);
- ES.lookup(JITDylibSearchList({{&JD, false}}), {}, OnResolution, OnReady,
- NoDependenciesToRegister);
-
- EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
- EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
+ EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run for empty query";
}
TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
@@ -128,8 +109,8 @@
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[this](MaterializationResponsibility R) {
ADD_FAILURE() << "Unexpected materialization of \"Bar\"";
- R.resolve({{Bar, BarSym}});
- R.emit();
+ R.notifyResolved({{Bar, BarSym}});
+ R.notifyEmitted();
},
[&](const JITDylib &JD, const SymbolStringPtr &Name) {
EXPECT_EQ(Name, Bar) << "Expected \"Bar\" to be discarded";
@@ -148,20 +129,14 @@
ADD_FAILURE() << "\"Baz\" discarded unexpectedly";
})));
- bool OnResolvedRun = false;
- bool OnReadyRun = false;
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo, Baz},
- [&](Expected<SymbolMap> Result) {
- EXPECT_TRUE(!!Result) << "OnResolved failed unexpectedly";
- consumeError(Result.takeError());
- OnResolvedRun = true;
- },
- [&](Error Err) {
- EXPECT_FALSE(!!Err) << "OnReady failed unexpectedly";
- consumeError(std::move(Err));
- OnReadyRun = true;
- },
- NoDependenciesToRegister);
+ bool OnCompletionRun = false;
+ ES.lookup(
+ JITDylibSearchList({{&JD, false}}), {Foo, Baz}, SymbolState::Ready,
+ [&](Expected<SymbolMap> Result) {
+ cantFail(Result.takeError());
+ OnCompletionRun = true;
+ },
+ NoDependenciesToRegister);
{
// Attempt 1: Search for a missing symbol, Qux.
@@ -181,8 +156,8 @@
consumeError(std::move(Err));
}
- BazR->resolve({{Baz, BazSym}});
- BazR->emit();
+ BazR->notifyResolved({{Baz, BazSym}});
+ BazR->notifyEmitted();
{
// Attempt 3: Search now that all symbols are fully materialized
// (Foo, Baz), or not yet materialized (Bar).
@@ -193,8 +168,7 @@
EXPECT_TRUE(BarDiscarded) << "\"Bar\" should have been discarded";
EXPECT_TRUE(BarMaterializerDestructed)
<< "\"Bar\"'s materializer should have been destructed";
- EXPECT_TRUE(OnResolvedRun) << "OnResolved should have been run";
- EXPECT_TRUE(OnReadyRun) << "OnReady should have been run";
+ EXPECT_TRUE(OnCompletionRun) << "OnCompletion should have been run";
}
TEST_F(CoreAPIsStandardTest, ChainedJITDylibLookup) {
@@ -202,24 +176,18 @@
auto &JD2 = ES.createJITDylib("JD2");
- bool OnResolvedRun = false;
- bool OnReadyRun = false;
+ bool OnCompletionRun = false;
auto Q = std::make_shared<AsynchronousSymbolQuery>(
- SymbolNameSet({Foo}),
+ SymbolNameSet({Foo}), SymbolState::Ready,
[&](Expected<SymbolMap> Result) {
cantFail(std::move(Result));
- OnResolvedRun = true;
- },
- [&](Error Err) {
- cantFail(std::move(Err));
- OnReadyRun = true;
+ OnCompletionRun = true;
});
- JD2.legacyLookup(Q, JD.legacyLookup(Q, {Foo}));
+ cantFail(JD2.legacyLookup(Q, cantFail(JD.legacyLookup(Q, {Foo}))));
- EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
- EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
+ EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run for empty query";
}
TEST_F(CoreAPIsStandardTest, LookupWithHiddenSymbols) {
@@ -260,7 +228,7 @@
SymbolNameSet Names({Foo, Bar, Baz});
- auto SymbolFlags = JD.lookupFlags(Names);
+ auto SymbolFlags = cantFail(JD.lookupFlags(Names));
EXPECT_EQ(SymbolFlags.size(), 2U)
<< "Returned symbol flags contains unexpected results";
@@ -273,6 +241,27 @@
<< "Incorrect flags returned for Bar";
}
+TEST_F(CoreAPIsStandardTest, LookupWithGeneratorFailure) {
+
+ class BadGenerator {
+ public:
+ Expected<SymbolNameSet> operator()(JITDylib &, const SymbolNameSet &) {
+ return make_error<StringError>("BadGenerator", inconvertibleErrorCode());
+ }
+ };
+
+ JD.setGenerator(BadGenerator());
+
+ EXPECT_THAT_ERROR(JD.lookupFlags({Foo}).takeError(), Failed<StringError>())
+ << "Generator failure did not propagate through lookupFlags";
+
+ EXPECT_THAT_ERROR(
+ ES.lookup(JITDylibSearchList({{&JD, false}}), SymbolNameSet({Foo}))
+ .takeError(),
+ Failed<StringError>())
+ << "Generator failure did not propagate through lookup";
+}
+
TEST_F(CoreAPIsStandardTest, TestBasicAliases) {
cantFail(JD.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
cantFail(JD.define(symbolAliases({{Baz, {Foo, JITSymbolFlags::Exported}},
@@ -328,8 +317,8 @@
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) {
BarMaterialized = true;
- R.resolve({{Bar, BarSym}});
- R.emit();
+ R.notifyResolved({{Bar, BarSym}});
+ R.notifyEmitted();
});
cantFail(JD.define(BarMU));
@@ -356,7 +345,7 @@
JD.setGenerator(ReexportsGenerator(JD2, false, Filter));
- auto Flags = JD.lookupFlags({Foo, Bar, Baz});
+ auto Flags = cantFail(JD.lookupFlags({Foo, Bar, Baz}));
EXPECT_EQ(Flags.size(), 1U) << "Unexpected number of results";
EXPECT_EQ(Flags[Foo], FooSym.getFlags()) << "Unexpected flags for Foo";
@@ -375,17 +364,16 @@
cantFail(JD.define(FooMU));
bool FooReady = false;
- auto OnResolution = [](Expected<SymbolMap> R) { cantFail(std::move(R)); };
- auto OnReady = [&](Error Err) {
- cantFail(std::move(Err));
+ auto OnCompletion = [&](Expected<SymbolMap> Result) {
+ cantFail(std::move(Result));
FooReady = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, std::move(OnResolution),
- std::move(OnReady), NoDependenciesToRegister);
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
+ OnCompletion, NoDependenciesToRegister);
- FooR->resolve({{Foo, FooSym}});
- FooR->emit();
+ FooR->notifyResolved({{Foo, FooSym}});
+ FooR->notifyEmitted();
EXPECT_TRUE(FooReady)
<< "Self-dependency prevented symbol from being marked ready";
@@ -431,16 +419,18 @@
FooResolved = true;
};
- auto OnFooReady = [&](Error Err) {
- cantFail(std::move(Err));
+ auto OnFooReady = [&](Expected<SymbolMap> Result) {
+ cantFail(std::move(Result));
FooReady = true;
};
- // Issue a lookup for Foo. Use NoDependenciesToRegister: We're going to add
+ // Issue lookups for Foo. Use NoDependenciesToRegister: We're going to add
// the dependencies manually below.
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
- std::move(OnFooResolution), std::move(OnFooReady),
- NoDependenciesToRegister);
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+ std::move(OnFooResolution), NoDependenciesToRegister);
+
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
+ std::move(OnFooReady), NoDependenciesToRegister);
bool BarResolved = false;
bool BarReady = false;
@@ -449,14 +439,16 @@
BarResolved = true;
};
- auto OnBarReady = [&](Error Err) {
- cantFail(std::move(Err));
+ auto OnBarReady = [&](Expected<SymbolMap> Result) {
+ cantFail(std::move(Result));
BarReady = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar},
- std::move(OnBarResolution), std::move(OnBarReady),
- NoDependenciesToRegister);
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Resolved,
+ std::move(OnBarResolution), NoDependenciesToRegister);
+
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
+ std::move(OnBarReady), NoDependenciesToRegister);
bool BazResolved = false;
bool BazReady = false;
@@ -466,14 +458,16 @@
BazResolved = true;
};
- auto OnBazReady = [&](Error Err) {
- cantFail(std::move(Err));
+ auto OnBazReady = [&](Expected<SymbolMap> Result) {
+ cantFail(std::move(Result));
BazReady = true;
};
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz},
- std::move(OnBazResolution), std::move(OnBazReady),
- NoDependenciesToRegister);
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz}, SymbolState::Resolved,
+ std::move(OnBazResolution), NoDependenciesToRegister);
+
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz}, SymbolState::Ready,
+ std::move(OnBazReady), NoDependenciesToRegister);
// Add a circular dependency: Foo -> Bar, Bar -> Baz, Baz -> Foo.
FooR->addDependenciesForAll({{&JD, SymbolNameSet({Bar})}});
@@ -492,9 +486,9 @@
EXPECT_FALSE(BazResolved) << "\"Baz\" should not be resolved yet";
// Resolve the symbols (but do not emit them).
- FooR->resolve({{Foo, FooSym}});
- BarR->resolve({{Bar, BarSym}});
- BazR->resolve({{Baz, BazSym}});
+ FooR->notifyResolved({{Foo, FooSym}});
+ BarR->notifyResolved({{Bar, BarSym}});
+ BazR->notifyResolved({{Baz, BazSym}});
// Verify that the symbols have been resolved, but are not ready yet.
EXPECT_TRUE(FooResolved) << "\"Foo\" should be resolved now";
@@ -506,8 +500,8 @@
EXPECT_FALSE(BazReady) << "\"Baz\" should not be ready yet";
// Emit two of the symbols.
- FooR->emit();
- BarR->emit();
+ FooR->notifyEmitted();
+ BarR->notifyEmitted();
// Verify that nothing is ready until the circular dependence is resolved.
EXPECT_FALSE(FooReady) << "\"Foo\" still should not be ready";
@@ -515,7 +509,7 @@
EXPECT_FALSE(BazReady) << "\"Baz\" still should not be ready";
// Emit the last symbol.
- BazR->emit();
+ BazR->notifyEmitted();
// Verify that everything becomes ready once the circular dependence resolved.
EXPECT_TRUE(FooReady) << "\"Foo\" should be ready now";
@@ -564,8 +558,8 @@
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}, {Bar, WeakExported}}),
[&](MaterializationResponsibility R) {
assert(BarDiscarded && "Bar should have been discarded by this point");
- R.resolve(SymbolMap({{Foo, FooSym}}));
- R.emit();
+ R.notifyResolved(SymbolMap({{Foo, FooSym}}));
+ R.notifyEmitted();
FooMaterialized = true;
},
[&](const JITDylib &JD, SymbolStringPtr Name) {
@@ -578,30 +572,23 @@
SymbolNameSet Names({Foo});
- bool OnResolutionRun = false;
- bool OnReadyRun = false;
+ bool OnCompletionRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
+ auto OnCompletion = [&](Expected<SymbolMap> Result) {
EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
auto I = Result->find(Foo);
EXPECT_NE(I, Result->end()) << "Could not find symbol definition";
EXPECT_EQ(I->second.getAddress(), FooSym.getAddress())
<< "Resolution returned incorrect result";
- OnResolutionRun = true;
+ OnCompletionRun = true;
};
- auto OnReady = [&](Error Err) {
- cantFail(std::move(Err));
- OnReadyRun = true;
- };
-
- ES.lookup(JITDylibSearchList({{&JD, false}}), Names, std::move(OnResolution),
- std::move(OnReady), NoDependenciesToRegister);
+ ES.lookup(JITDylibSearchList({{&JD, false}}), Names, SymbolState::Ready,
+ std::move(OnCompletion), NoDependenciesToRegister);
EXPECT_TRUE(FooMaterialized) << "Foo was not materialized";
EXPECT_TRUE(BarDiscarded) << "Bar was not discarded";
- EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
- EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
+ EXPECT_TRUE(OnCompletionRun) << "OnResolutionCallback was not run";
}
TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
@@ -612,7 +599,7 @@
auto MU1 = llvm::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R) {
- R.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})), R.emit();
+ R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})), R.notifyEmitted();
BarMaterialized = true;
});
@@ -631,24 +618,17 @@
cantFail(JD.define(MU1));
cantFail(JD.define(MU2));
- bool OnResolvedRun = false;
- bool OnReadyRun = false;
+ bool OnCompletionRun = false;
- auto OnResolution = [&](Expected<SymbolMap> Result) {
+ auto OnCompletion = [&](Expected<SymbolMap> Result) {
cantFail(std::move(Result));
- OnResolvedRun = true;
+ OnCompletionRun = true;
};
- auto OnReady = [&](Error Err) {
- cantFail(std::move(Err));
- OnReadyRun = true;
- };
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
+ std::move(OnCompletion), NoDependenciesToRegister);
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, std::move(OnResolution),
- std::move(OnReady), NoDependenciesToRegister);
-
- EXPECT_TRUE(OnResolvedRun) << "OnResolved not run";
- EXPECT_TRUE(OnReadyRun) << "OnReady not run";
+ EXPECT_TRUE(OnCompletionRun) << "OnCompletion not run";
EXPECT_TRUE(BarMaterialized) << "Bar was not materialized at all";
EXPECT_TRUE(DuplicateBarDiscarded)
<< "Duplicate bar definition not discarded";
@@ -668,8 +648,8 @@
[&](MaterializationResponsibility R) {
cantFail(
R.defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}})));
- R.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
- R.emit();
+ R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
+ R.notifyEmitted();
});
cantFail(JD.define(MU));
@@ -704,7 +684,11 @@
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported | JITSymbolFlags::Weak},
{Bar, JITSymbolFlags::Exported | JITSymbolFlags::Weak}}),
- [&](MaterializationResponsibility R) { R.failMaterialization(); });
+ [&](MaterializationResponsibility R) {
+ dbgs() << "Before failMat:\n";
+ ES.dump(dbgs());
+ R.failMaterialization();
+ });
cantFail(JD.define(MU));
@@ -731,12 +715,47 @@
}
}
+TEST_F(CoreAPIsStandardTest, FailEmissionEarly) {
+
+ cantFail(JD.define(absoluteSymbols({{Baz, BazSym}})));
+
+ auto MU = llvm::make_unique<SimpleMaterializationUnit>(
+ SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
+ [&](MaterializationResponsibility R) {
+ R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
+
+ ES.lookup(
+ JITDylibSearchList({{&JD, false}}), SymbolNameSet({Baz}),
+ SymbolState::Resolved,
+ [&R](Expected<SymbolMap> Result) {
+ // Called when "baz" is resolved. We don't actually depend
+ // on or care about baz, but use it to trigger failure of
+ // this materialization before Baz has been finalized in
+ // order to test that error propagation is correct in this
+ // scenario.
+ cantFail(std::move(Result));
+ R.failMaterialization();
+ },
+ [&](const SymbolDependenceMap &Deps) {
+ R.addDependenciesForAll(Deps);
+ });
+ });
+
+ cantFail(JD.define(MU));
+
+ SymbolNameSet Names({Foo, Bar});
+ auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), Names);
+
+ EXPECT_THAT_EXPECTED(std::move(Result), Failed())
+ << "Unexpected success while trying to test error propagation";
+}
+
TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
[&](MaterializationResponsibility R) {
- R.resolve({{Foo, FooSym}});
- R.emit();
+ R.notifyResolved({{Foo, FooSym}});
+ R.notifyEmitted();
});
cantFail(JD.define(MU));
@@ -794,15 +813,15 @@
auto NewMU = llvm::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
[&](MaterializationResponsibility R2) {
- R2.resolve(SymbolMap({{Bar, BarSym}}));
- R2.emit();
+ R2.notifyResolved(SymbolMap({{Bar, BarSym}}));
+ R2.notifyEmitted();
BarMaterialized = true;
});
R.replace(std::move(NewMU));
- R.resolve(SymbolMap({{Foo, FooSym}}));
- R.emit();
+ R.notifyResolved(SymbolMap({{Foo, FooSym}}));
+ R.notifyEmitted();
FooMaterialized = true;
});
@@ -833,10 +852,10 @@
[&](MaterializationResponsibility R) {
auto R2 = R.delegate({Bar});
- R.resolve({{Foo, FooSym}});
- R.emit();
- R2.resolve({{Bar, BarSym}});
- R2.emit();
+ R.notifyResolved({{Foo, FooSym}});
+ R.notifyEmitted();
+ R2.notifyResolved({{Bar, BarSym}});
+ R2.notifyEmitted();
});
cantFail(JD.define(MU));
@@ -867,14 +886,12 @@
});
cantFail(JD.define(MU));
- auto OnResolution = [](Expected<SymbolMap> Result) {
+ auto OnCompletion = [](Expected<SymbolMap> Result) {
cantFail(std::move(Result));
};
- auto OnReady = [](Error Err) { cantFail(std::move(Err)); };
-
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, std::move(OnResolution),
- std::move(OnReady), NoDependenciesToRegister);
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
+ std::move(OnCompletion), NoDependenciesToRegister);
auto MU2 = llvm::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
@@ -888,8 +905,8 @@
<< "Expected a duplicate definition error";
consumeError(std::move(Err));
- FooResponsibility->resolve(SymbolMap({{Foo, FooSym}}));
- FooResponsibility->emit();
+ FooResponsibility->notifyResolved(SymbolMap({{Foo, FooSym}}));
+ FooResponsibility->notifyEmitted();
}
} // namespace
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp
index d093b2a..d3853df 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp
@@ -1,9 +1,8 @@
//===--- GlobalMappingLayerTest.cpp - Unit test the global mapping layer --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
index 1dfa0a1..e9d39ef 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
@@ -1,9 +1,8 @@
//===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting layer -===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/JITTargetMachineBuilderTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/JITTargetMachineBuilderTest.cpp
index f978a90..1f3626e 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/JITTargetMachineBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/JITTargetMachineBuilderTest.cpp
@@ -1,9 +1,8 @@
//===----------- CoreAPIsTest.cpp - Unit tests for Core ORC APIs ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
index ebe99d4..87d582b 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
@@ -41,12 +41,12 @@
SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}),
[&](MaterializationResponsibility R) {
DummyTargetMaterialized = true;
- R.resolve(
+ R.notifyResolved(
{{DummyTarget,
JITEvaluatedSymbol(static_cast<JITTargetAddress>(
reinterpret_cast<uintptr_t>(&dummyTarget)),
JITSymbolFlags::Exported)}});
- R.emit();
+ R.notifyEmitted();
})));
unsigned NotifyResolvedCount = 0;
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
index 3801fa9..cc67aa0 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
@@ -1,9 +1,8 @@
//===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting layer -===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -23,7 +22,8 @@
TEST(LazyEmittingLayerTest, Empty) {
MockBaseLayer M;
- llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M);
+ llvm::orc::LazyEmittingLayer<MockBaseLayer> L(
+ llvm::AcknowledgeORCv1Deprecation, M);
cantFail(
L.addModule(llvm::orc::VModuleKey(), std::unique_ptr<llvm::Module>()));
}
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
index 36cb710..f79d721 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
@@ -1,9 +1,8 @@
//===----------- CoreAPIsTest.cpp - Unit tests for Core ORC APIs ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -25,7 +24,7 @@
auto Resolver = createSymbolResolver(
[&](const SymbolNameSet &Symbols) {
- auto FlagsMap = JD.lookupFlags(Symbols);
+ auto FlagsMap = cantFail(JD.lookupFlags(Symbols));
SymbolNameSet Result;
for (auto &KV : FlagsMap)
if (!KV.second.isStrong())
@@ -33,7 +32,7 @@
return Result;
},
[&](std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Symbols) {
- return JD.legacyLookup(std::move(Q), Symbols);
+ return cantFail(JD.legacyLookup(std::move(Q), Symbols));
});
auto RS = Resolver->getResponsibilitySet(SymbolNameSet({Bar, Baz}));
@@ -43,10 +42,10 @@
EXPECT_EQ(RS.count(Bar), 1U)
<< "getResponsibilitySet result incorrect. Should be {'bar'}";
- bool OnResolvedRun = false;
+ bool OnCompletionRun = false;
- auto OnResolved = [&](Expected<SymbolMap> Result) {
- OnResolvedRun = true;
+ auto OnCompletion = [&](Expected<SymbolMap> Result) {
+ OnCompletionRun = true;
EXPECT_TRUE(!!Result) << "Unexpected error";
EXPECT_EQ(Result->size(), 2U) << "Unexpected number of resolved symbols";
EXPECT_EQ(Result->count(Foo), 1U) << "Missing lookup result for foo";
@@ -56,18 +55,15 @@
EXPECT_EQ((*Result)[Bar].getAddress(), BarSym.getAddress())
<< "Incorrect address for bar";
};
- auto OnReady = [&](Error Err) {
- EXPECT_FALSE(!!Err) << "Finalization should never fail in this test";
- };
- auto Q = std::make_shared<AsynchronousSymbolQuery>(SymbolNameSet({Foo, Bar}),
- OnResolved, OnReady);
+ auto Q = std::make_shared<AsynchronousSymbolQuery>(
+ SymbolNameSet({Foo, Bar}), SymbolState::Resolved, OnCompletion);
auto Unresolved =
Resolver->lookup(std::move(Q), SymbolNameSet({Foo, Bar, Baz}));
EXPECT_EQ(Unresolved.size(), 1U) << "Expected one unresolved symbol";
EXPECT_EQ(Unresolved.count(Baz), 1U) << "Expected baz to not be resolved";
- EXPECT_TRUE(OnResolvedRun) << "OnResolved was never run";
+ EXPECT_TRUE(OnCompletionRun) << "OnCompletion was never run";
}
TEST_F(LegacyAPIsStandardTest, LegacyLookupHelpersFn) {
@@ -99,10 +95,9 @@
EXPECT_FALSE(BarMaterialized)
<< "lookupFlags should not have materialized bar";
- bool OnResolvedRun = false;
- bool OnReadyRun = false;
- auto OnResolved = [&](Expected<SymbolMap> Result) {
- OnResolvedRun = true;
+ bool OnCompletionRun = false;
+ auto OnCompletion = [&](Expected<SymbolMap> Result) {
+ OnCompletionRun = true;
EXPECT_TRUE(!!Result) << "lookuWithLegacy failed to resolve";
EXPECT_EQ(Result->size(), 2U) << "Wrong number of symbols resolved";
@@ -115,17 +110,12 @@
EXPECT_EQ((*Result)[Bar].getFlags(), BarSym.getFlags())
<< "Wrong flags for bar";
};
- auto OnReady = [&](Error Err) {
- EXPECT_FALSE(!!Err) << "Finalization unexpectedly failed";
- OnReadyRun = true;
- };
- AsynchronousSymbolQuery Q({Foo, Bar}, OnResolved, OnReady);
+ AsynchronousSymbolQuery Q({Foo, Bar}, SymbolState::Resolved, OnCompletion);
auto Unresolved =
lookupWithLegacyFn(ES, Q, SymbolNameSet({Foo, Bar, Baz}), LegacyLookup);
- EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run";
- EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
+ EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run";
EXPECT_EQ(Unresolved.size(), 1U) << "Expected one unresolved symbol";
EXPECT_EQ(Unresolved.count(Baz), 1U) << "Expected baz to be unresolved";
}
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp
index 38f7a65..06b96f9 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp
@@ -1,9 +1,8 @@
//===----- CompileOnDemandLayerTest.cpp - Unit tests for the COD layer ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -77,7 +76,7 @@
};
llvm::orc::LegacyCompileOnDemandLayer<decltype(TestBaseLayer)> COD(
- ES, TestBaseLayer, GetResolver, SetResolver,
+ AcknowledgeORCv1Deprecation, ES, TestBaseLayer, GetResolver, SetResolver,
[](Function &F) { return std::set<Function *>{&F}; }, CallbackMgr,
[] { return llvm::make_unique<DummyStubsManager>(); }, true);
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp
index b3696c6..001019d 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp
@@ -1,9 +1,8 @@
//===- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer unit tests -===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -69,10 +68,11 @@
ExecutionSession ES;
- LegacyRTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey) {
- return LegacyRTDyldObjectLinkingLayer::Resources{
- MM, std::make_shared<NullResolver>()};
- });
+ LegacyRTDyldObjectLinkingLayer ObjLayer(
+ AcknowledgeORCv1Deprecation, ES, [&MM](VModuleKey) {
+ return LegacyRTDyldObjectLinkingLayer::Resources{
+ MM, std::make_shared<NullResolver>()};
+ });
LLVMContext Context;
auto M = llvm::make_unique<Module>("", Context);
@@ -131,13 +131,14 @@
std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
- LegacyRTDyldObjectLinkingLayer ObjLayer(ES, [&](VModuleKey K) {
- auto I = Resolvers.find(K);
- assert(I != Resolvers.end() && "Missing resolver");
- auto R = std::move(I->second);
- Resolvers.erase(I);
- return LegacyRTDyldObjectLinkingLayer::Resources{MM, std::move(R)};
- });
+ LegacyRTDyldObjectLinkingLayer ObjLayer(
+ AcknowledgeORCv1Deprecation, ES, [&](VModuleKey K) {
+ auto I = Resolvers.find(K);
+ assert(I != Resolvers.end() && "Missing resolver");
+ auto R = std::move(I->second);
+ Resolvers.erase(I);
+ return LegacyRTDyldObjectLinkingLayer::Resources{MM, std::move(R)};
+ });
SimpleCompiler Compile(*TM);
// Create a pair of modules that will trigger recursive finalization:
@@ -218,10 +219,11 @@
auto MM = std::make_shared<SectionMemoryManagerWrapper>();
- LegacyRTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey K) {
- return LegacyRTDyldObjectLinkingLayer::Resources{
- MM, std::make_shared<NullResolver>()};
- });
+ LegacyRTDyldObjectLinkingLayer ObjLayer(
+ AcknowledgeORCv1Deprecation, ES, [&MM](VModuleKey K) {
+ return LegacyRTDyldObjectLinkingLayer::Resources{
+ MM, std::make_shared<NullResolver>()};
+ });
SimpleCompiler Compile(*TM);
// Create a pair of unrelated modules:
@@ -279,7 +281,7 @@
TEST_F(LegacyRTDyldObjectLinkingLayerExecutionTest, TestNotifyLoadedSignature) {
ExecutionSession ES;
LegacyRTDyldObjectLinkingLayer ObjLayer(
- ES,
+ AcknowledgeORCv1Deprecation, ES,
[](VModuleKey) {
return LegacyRTDyldObjectLinkingLayer::Resources{
nullptr, std::make_shared<NullResolver>()};
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
index 1c53024..2ff7e91 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
@@ -1,9 +1,8 @@
//===- ObjectTransformLayerTest.cpp - Unit tests for ObjectTransformLayer -===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -183,17 +182,19 @@
// Create one object transform layer using a transform (as a functor)
// that allocates new objects, and deals in unique pointers.
- LegacyObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(M);
+ LegacyObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(
+ llvm::AcknowledgeORCv1Deprecation, M);
// Create a second object transform layer using a transform (as a lambda)
// that mutates objects in place, and deals in naked pointers
LegacyObjectTransformLayer<MockBaseLayer,
- std::function<std::shared_ptr<MockObjectFile>(
- std::shared_ptr<MockObjectFile>)>>
- T2(M, [](std::shared_ptr<MockObjectFile> Obj) {
- ++(*Obj);
- return Obj;
- });
+ std::function<std::shared_ptr<MockObjectFile>(
+ std::shared_ptr<MockObjectFile>)>>
+ T2(llvm::AcknowledgeORCv1Deprecation, M,
+ [](std::shared_ptr<MockObjectFile> Obj) {
+ ++(*Obj);
+ return Obj;
+ });
// Test addObject with T1 (allocating)
auto K1 = ES.allocateVModule();
@@ -282,22 +283,25 @@
};
// Construct the jit layers.
- LegacyRTDyldObjectLinkingLayer BaseLayer(ES, [](VModuleKey) {
- return LegacyRTDyldObjectLinkingLayer::Resources{
- std::make_shared<llvm::SectionMemoryManager>(),
- std::make_shared<NullResolver>()};
- });
+ LegacyRTDyldObjectLinkingLayer BaseLayer(
+ llvm::AcknowledgeORCv1Deprecation, ES, [](VModuleKey) {
+ return LegacyRTDyldObjectLinkingLayer::Resources{
+ std::make_shared<llvm::SectionMemoryManager>(),
+ std::make_shared<NullResolver>()};
+ });
auto IdentityTransform = [](std::unique_ptr<llvm::MemoryBuffer> Obj) {
return Obj;
};
LegacyObjectTransformLayer<decltype(BaseLayer), decltype(IdentityTransform)>
- TransformLayer(BaseLayer, IdentityTransform);
+ TransformLayer(llvm::AcknowledgeORCv1Deprecation, BaseLayer,
+ IdentityTransform);
auto NullCompiler = [](llvm::Module &) {
return std::unique_ptr<llvm::MemoryBuffer>(nullptr);
};
LegacyIRCompileLayer<decltype(TransformLayer), decltype(NullCompiler)>
- CompileLayer(TransformLayer, NullCompiler);
+ CompileLayer(llvm::AcknowledgeORCv1Deprecation, TransformLayer,
+ NullCompiler);
// Make sure that the calls from LegacyIRCompileLayer to LegacyObjectTransformLayer
// compile.
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
index 54d8156..39fdc2e 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
@@ -1,9 +1,8 @@
//===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
index a12b187..2a3223a 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
@@ -1,9 +1,8 @@
//===--------- OrcTestCommon.cpp - Utilities for Orc Unit Tests -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
index e25c513..d82012b 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
@@ -1,9 +1,8 @@
//===------ OrcTestCommon.h - Utilities for Orc Unit Tests ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.cpp
index e309a7e..7556f8a 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.cpp
@@ -1,9 +1,8 @@
//===-------- QueueChannel.cpp - Unit tests the remote executors ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h
index d8c1681..56a3926 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h
@@ -1,9 +1,8 @@
//===----------------------- Queue.h - RPC Queue ------------------*-c++-*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
index c884aaa..1f7c88d 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
@@ -1,9 +1,8 @@
//===----------- RPCUtilsTest.cpp - Unit tests the Orc RPC utils ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
index 2db237f..440b840 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
@@ -1,9 +1,8 @@
//===--- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -62,12 +61,11 @@
cantFail(std::move(R));
};
- auto OnReadyDoNothing = [](Error Err) { cantFail(std::move(Err)); };
-
ObjLayer.setProcessAllSections(ProcessAllSections);
cantFail(ObjLayer.add(JD, std::move(Obj), ES.allocateVModule()));
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, OnResolveDoNothing,
- OnReadyDoNothing, NoDependenciesToRegister);
+ ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+ OnResolveDoNothing, NoDependenciesToRegister);
+
return DebugSectionSeen;
}
@@ -161,10 +159,10 @@
ObjLayer.setOverrideObjectFlagsWithResponsibilityFlags(true);
cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
- [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
- [](Error Err) { cantFail(std::move(Err)); },
- NoDependenciesToRegister);
+ ES.lookup(
+ JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+ [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
+ NoDependenciesToRegister);
}
TEST(RTDyldObjectLinkingLayerTest, TestAutoClaimResponsibilityForSymbols) {
@@ -226,10 +224,10 @@
ObjLayer.setAutoClaimResponsibilityForObjectSymbols(true);
cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
- ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
- [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
- [](Error Err) { cantFail(std::move(Err)); },
- NoDependenciesToRegister);
+ ES.lookup(
+ JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+ [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
+ NoDependenciesToRegister);
}
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp
index 4ffd741..4377d52 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp
@@ -1,9 +1,8 @@
//===---------------------- RemoteObjectLayerTest.cpp ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -128,7 +127,8 @@
std::copy(ObjBytes.begin(), ObjBytes.end(), ObjContents.begin());
RPCEndpoint ClientEP(*Channels.first, true);
- RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+ RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+ ClientEP, ReportError);
RPCEndpoint ServerEP(*Channels.second, true);
MockObjectLayer BaseLayer(
@@ -145,9 +145,8 @@
return 1;
});
- RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
- ServerEP,
- ReportError);
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+ AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
bool Finished = false;
ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -182,7 +181,8 @@
};
RPCEndpoint ClientEP(*Channels.first, true);
- RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+ RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+ ClientEP, ReportError);
RPCEndpoint ServerEP(*Channels.second, true);
MockObjectLayer BaseLayer(
@@ -192,9 +192,8 @@
return make_error<StringError>("AddObjectFailure - Test Message",
inconvertibleErrorCode());
});
- RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
- ServerEP,
- ReportError);
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+ AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
bool Finished = false;
ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -234,7 +233,8 @@
};
RPCEndpoint ClientEP(*Channels.first, true);
- RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+ RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+ ClientEP, ReportError);
RPCEndpoint ServerEP(*Channels.second, true);
@@ -244,9 +244,8 @@
SymTab[1] = MockObjectLayer::LookupFn();
return 1;
});
- RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
- ServerEP,
- ReportError);
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+ AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
bool Finished = false;
ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -284,7 +283,8 @@
};
RPCEndpoint ClientEP(*Channels.first, true);
- RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+ RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+ ClientEP, ReportError);
RPCEndpoint ServerEP(*Channels.second, true);
@@ -295,9 +295,8 @@
MockObjectLayer::SymbolLookupTable &SymTab) {
return 42;
});
- RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
- ServerEP,
- ReportError);
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+ AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
bool Finished = false;
ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -340,7 +339,8 @@
};
RPCEndpoint ClientEP(*Channels.first, true);
- RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+ RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+ ClientEP, ReportError);
RPCEndpoint ServerEP(*Channels.second, true);
@@ -359,9 +359,8 @@
};
return 42;
});
- RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
- ServerEP,
- ReportError);
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+ AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
bool Finished = false;
ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -422,7 +421,8 @@
};
RPCEndpoint ClientEP(*Channels.first, true);
- RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+ RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+ ClientEP, ReportError);
RPCEndpoint ServerEP(*Channels.second, true);
@@ -448,9 +448,8 @@
return 42;
});
- RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
- ServerEP,
- ReportError);
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+ AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
bool Finished = false;
ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -497,7 +496,8 @@
};
RPCEndpoint ClientEP(*Channels.first, true);
- RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+ RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+ ClientEP, ReportError);
RPCEndpoint ServerEP(*Channels.second, true);
@@ -507,9 +507,8 @@
SymTab[1] = MockObjectLayer::LookupFn();
return 1;
});
- RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
- ServerEP,
- ReportError);
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+ AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
bool Finished = false;
ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -548,7 +547,8 @@
};
RPCEndpoint ClientEP(*Channels.first, true);
- RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+ RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+ ClientEP, ReportError);
RPCEndpoint ServerEP(*Channels.second, true);
@@ -557,9 +557,8 @@
MockObjectLayer::SymbolLookupTable &SymTab) {
return 1;
});
- RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
- ServerEP,
- ReportError);
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+ AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
bool Finished = false;
ServerEP.addHandler<remote::utils::TerminateSession>(
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/SymbolStringPoolTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/SymbolStringPoolTest.cpp
index 861a966..a68da0b 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/SymbolStringPoolTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/SymbolStringPoolTest.cpp
@@ -1,9 +1,8 @@
//===----- SymbolStringPoolTest.cpp - Unit tests for SymbolStringPool -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ThreadSafeModuleTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ThreadSafeModuleTest.cpp
index eb2cd41..6cd6c20 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ThreadSafeModuleTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ThreadSafeModuleTest.cpp
@@ -1,9 +1,8 @@
//===--- ThreadSafeModuleTest.cpp - Test basic use of ThreadSafeModule ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/FuzzMutate/OperationsTest.cpp b/src/llvm-project/llvm/unittests/FuzzMutate/OperationsTest.cpp
index 0fc6b2c..a077c5c 100644
--- a/src/llvm-project/llvm/unittests/FuzzMutate/OperationsTest.cpp
+++ b/src/llvm-project/llvm/unittests/FuzzMutate/OperationsTest.cpp
@@ -1,9 +1,8 @@
//===- OperationsTest.cpp - Tests for fuzzer operations -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp b/src/llvm-project/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp
index d6ad07d..1528be6 100644
--- a/src/llvm-project/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp
@@ -1,9 +1,8 @@
//===- RandomIRBuilderTest.cpp - Tests for injector strategy --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/FuzzMutate/ReservoirSamplerTest.cpp b/src/llvm-project/llvm/unittests/FuzzMutate/ReservoirSamplerTest.cpp
index d246ba1..ac9270a 100644
--- a/src/llvm-project/llvm/unittests/FuzzMutate/ReservoirSamplerTest.cpp
+++ b/src/llvm-project/llvm/unittests/FuzzMutate/ReservoirSamplerTest.cpp
@@ -1,9 +1,8 @@
//===- ReservoirSampler.cpp - Tests for the ReservoirSampler --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/FuzzMutate/StrategiesTest.cpp b/src/llvm-project/llvm/unittests/FuzzMutate/StrategiesTest.cpp
index 320a4e9..9ef88e2 100644
--- a/src/llvm-project/llvm/unittests/FuzzMutate/StrategiesTest.cpp
+++ b/src/llvm-project/llvm/unittests/FuzzMutate/StrategiesTest.cpp
@@ -1,9 +1,8 @@
//===- InjectorIRStrategyTest.cpp - Tests for injector strategy -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/AsmWriterTest.cpp b/src/llvm-project/llvm/unittests/IR/AsmWriterTest.cpp
index 9ad5523..0e13cca 100644
--- a/src/llvm-project/llvm/unittests/IR/AsmWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/AsmWriterTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/AsmWriter.cpp - AsmWriter tests -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/BinaryFormat/Dwarf.h"
diff --git a/src/llvm-project/llvm/unittests/IR/AttributesTest.cpp b/src/llvm-project/llvm/unittests/IR/AttributesTest.cpp
index dd88cc3..06da35a 100644
--- a/src/llvm-project/llvm/unittests/IR/AttributesTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/AttributesTest.cpp
@@ -1,14 +1,14 @@
//===- llvm/unittest/IR/AttributesTest.cpp - Attributes unit tests --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/IR/Attributes.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/DerivedTypes.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -41,6 +41,10 @@
EXPECT_TRUE(Align4 < Deref5);
EXPECT_TRUE(Align5 < Deref4);
+ Attribute ByVal = Attribute::get(C, Attribute::ByVal, Type::getInt32Ty(C));
+ EXPECT_FALSE(ByVal < Attribute::get(C, Attribute::ZExt));
+ EXPECT_TRUE(ByVal < Align4);
+
AttributeList ASs[] = {AttributeList::get(C, 2, Attribute::ZExt),
AttributeList::get(C, 1, Attribute::SExt)};
@@ -167,4 +171,19 @@
EXPECT_EQ(2U, AL.getNumAttrSets());
}
+TEST(Attributes, StringRepresentation) {
+ LLVMContext C;
+ StructType *Ty = StructType::create(Type::getInt32Ty(C), "mystruct");
+
+ // Insufficiently careful printing can result in byval(%mystruct = { i32 })
+ Attribute A = Attribute::getWithByValType(C, Ty);
+ EXPECT_EQ(A.getAsString(), "byval(%mystruct)");
+
+ A = Attribute::getWithByValType(C, nullptr);
+ EXPECT_EQ(A.getAsString(), "byval");
+
+ A = Attribute::getWithByValType(C, Type::getInt32Ty(C));
+ EXPECT_EQ(A.getAsString(), "byval(i32)");
+}
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/BasicBlockTest.cpp b/src/llvm-project/llvm/unittests/IR/BasicBlockTest.cpp
index 07ed997..95bc242 100644
--- a/src/llvm-project/llvm/unittests/IR/BasicBlockTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/BasicBlockTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/BasicBlockTest.cpp - BasicBlock unit tests --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -101,10 +100,9 @@
Argument *V = new Argument(Type::getInt32Ty(Ctx));
Function *F = Function::Create(FT, Function::ExternalLinkage, "", M);
- Value *DbgAddr = Intrinsic::getDeclaration(M, Intrinsic::dbg_addr);
- Value *DbgDeclare =
- Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
- Value *DbgValue = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
+ Function *DbgAddr = Intrinsic::getDeclaration(M, Intrinsic::dbg_addr);
+ Function *DbgDeclare = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
+ Function *DbgValue = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
Value *DIV = MetadataAsValue::get(Ctx, (Metadata *)nullptr);
SmallVector<Value *, 3> Args = {DIV, DIV, DIV};
diff --git a/src/llvm-project/llvm/unittests/IR/CFGBuilder.cpp b/src/llvm-project/llvm/unittests/IR/CFGBuilder.cpp
index 886ab8a..1ce5987 100644
--- a/src/llvm-project/llvm/unittests/IR/CFGBuilder.cpp
+++ b/src/llvm-project/llvm/unittests/IR/CFGBuilder.cpp
@@ -1,14 +1,14 @@
//===- llvm/Testing/Support/CFGBuilder.cpp --------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "CFGBuilder.h"
+#include "llvm/IR/CFG.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Debug.h"
@@ -23,7 +23,7 @@
: Context(llvm::make_unique<LLVMContext>()),
M(llvm::make_unique<Module>(ModuleName, *Context)) {
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Context), {}, false);
- F = cast<Function>(M->getOrInsertFunction(FunctionName, FTy));
+ F = Function::Create(FTy, Function::ExternalLinkage, FunctionName, M.get());
}
CFGHolder::~CFGHolder() = default;
@@ -266,3 +266,11 @@
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("c")->getTerminator()));
EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("d")->getTerminator()));
}
+
+static_assert(is_trivially_copyable<succ_iterator>::value,
+ "trivially copyable");
+static_assert(is_trivially_copyable<succ_const_iterator>::value,
+ "trivially copyable");
+static_assert(is_trivially_copyable<succ_range>::value, "trivially copyable");
+static_assert(is_trivially_copyable<succ_const_range>::value,
+ "trivially copyable");
diff --git a/src/llvm-project/llvm/unittests/IR/CFGBuilder.h b/src/llvm-project/llvm/unittests/IR/CFGBuilder.h
index d9d9c37..97be4a1 100644
--- a/src/llvm-project/llvm/unittests/IR/CFGBuilder.h
+++ b/src/llvm-project/llvm/unittests/IR/CFGBuilder.h
@@ -1,9 +1,8 @@
//===- CFGBuilder.h - CFG building and updating utility ----------*- C++ -*-==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/src/llvm-project/llvm/unittests/IR/CMakeLists.txt b/src/llvm-project/llvm/unittests/IR/CMakeLists.txt
index f33835f..d27c6d9 100644
--- a/src/llvm-project/llvm/unittests/IR/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/IR/CMakeLists.txt
@@ -13,11 +13,11 @@
CFGBuilder.cpp
ConstantRangeTest.cpp
ConstantsTest.cpp
+ DataLayoutTest.cpp
DebugInfoTest.cpp
DebugTypeODRUniquingTest.cpp
DominatorTreeTest.cpp
DominatorTreeBatchUpdatesTest.cpp
- DomTreeUpdaterTest.cpp
FunctionTest.cpp
PassBuilderCallbacksTest.cpp
IRBuilderTest.cpp
@@ -30,12 +30,14 @@
ModuleTest.cpp
PassManagerTest.cpp
PatternMatch.cpp
+ TimePassesTest.cpp
TypesTest.cpp
UseTest.cpp
UserTest.cpp
ValueHandleTest.cpp
ValueMapTest.cpp
ValueTest.cpp
+ VectorTypesTest.cpp
VerifierTest.cpp
WaymarkTest.cpp
)
diff --git a/src/llvm-project/llvm/unittests/IR/ConstantRangeTest.cpp b/src/llvm-project/llvm/unittests/IR/ConstantRangeTest.cpp
index c0a30f1..c0166b2 100644
--- a/src/llvm-project/llvm/unittests/IR/ConstantRangeTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ConstantRangeTest.cpp
@@ -1,15 +1,16 @@
//===- ConstantRangeTest.cpp - ConstantRange tests ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/BitVector.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
+#include "llvm/Support/KnownBits.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -25,7 +26,114 @@
static ConstantRange Wrap;
};
-ConstantRange ConstantRangeTest::Full(16);
+template<typename Fn>
+static void EnumerateConstantRanges(unsigned Bits, Fn TestFn) {
+ unsigned Max = 1 << Bits;
+ for (unsigned Lo = 0; Lo < Max; Lo++) {
+ for (unsigned Hi = 0; Hi < Max; Hi++) {
+ // Enforce ConstantRange invariant.
+ if (Lo == Hi && Lo != 0 && Lo != Max - 1)
+ continue;
+
+ ConstantRange CR(APInt(Bits, Lo), APInt(Bits, Hi));
+ TestFn(CR);
+ }
+ }
+}
+
+template<typename Fn>
+static void EnumerateTwoConstantRanges(unsigned Bits, Fn TestFn) {
+ EnumerateConstantRanges(Bits, [&](const ConstantRange &CR1) {
+ EnumerateConstantRanges(Bits, [&](const ConstantRange &CR2) {
+ TestFn(CR1, CR2);
+ });
+ });
+}
+
+template<typename Fn>
+static void ForeachNumInConstantRange(const ConstantRange &CR, Fn TestFn) {
+ if (!CR.isEmptySet()) {
+ APInt N = CR.getLower();
+ do TestFn(N);
+ while (++N != CR.getUpper());
+ }
+}
+
+template<typename Fn1, typename Fn2>
+static void TestUnsignedBinOpExhaustive(
+ Fn1 RangeFn, Fn2 IntFn,
+ bool SkipZeroRHS = false, bool CorrectnessOnly = false) {
+ unsigned Bits = 4;
+ EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1,
+ const ConstantRange &CR2) {
+ APInt Min = APInt::getMaxValue(Bits);
+ APInt Max = APInt::getMinValue(Bits);
+ ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+ ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+ if (SkipZeroRHS && N2 == 0)
+ return;
+
+ APInt N = IntFn(N1, N2);
+ if (N.ult(Min))
+ Min = N;
+ if (N.ugt(Max))
+ Max = N;
+ });
+ });
+
+ ConstantRange CR = RangeFn(CR1, CR2);
+ if (Min.ugt(Max)) {
+ EXPECT_TRUE(CR.isEmptySet());
+ return;
+ }
+
+ ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1);
+ if (CorrectnessOnly) {
+ EXPECT_TRUE(CR.contains(Exact));
+ } else {
+ EXPECT_EQ(Exact, CR);
+ }
+ });
+}
+
+template<typename Fn1, typename Fn2>
+static void TestSignedBinOpExhaustive(
+ Fn1 RangeFn, Fn2 IntFn,
+ bool SkipZeroRHS = false, bool CorrectnessOnly = false) {
+ unsigned Bits = 4;
+ EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1,
+ const ConstantRange &CR2) {
+ APInt Min = APInt::getSignedMaxValue(Bits);
+ APInt Max = APInt::getSignedMinValue(Bits);
+ ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+ ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+ if (SkipZeroRHS && N2 == 0)
+ return;
+
+ APInt N = IntFn(N1, N2);
+ if (N.slt(Min))
+ Min = N;
+ if (N.sgt(Max))
+ Max = N;
+ });
+ });
+
+ ConstantRange CR = RangeFn(CR1, CR2);
+ if (Min.sgt(Max)) {
+ EXPECT_TRUE(CR.isEmptySet());
+ return;
+ }
+
+ ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1);
+ if (CorrectnessOnly) {
+ EXPECT_TRUE(CR.contains(Exact));
+ } else {
+ EXPECT_EQ(Exact, CR);
+ }
+ });
+}
+
+ConstantRange ConstantRangeTest::Full(16, true);
ConstantRange ConstantRangeTest::Empty(16, false);
ConstantRange ConstantRangeTest::One(APInt(16, 0xa));
ConstantRange ConstantRangeTest::Some(APInt(16, 0xa), APInt(16, 0xaaa));
@@ -122,18 +230,6 @@
EXPECT_FALSE(Wrap.isSingleElement());
}
-TEST_F(ConstantRangeTest, GetSetSize) {
- EXPECT_EQ(Full.getSetSize(), APInt(17, 65536));
- EXPECT_EQ(Empty.getSetSize(), APInt(17, 0));
- EXPECT_EQ(One.getSetSize(), APInt(17, 1));
- EXPECT_EQ(Some.getSetSize(), APInt(17, 0xaa0));
-
- ConstantRange Wrap(APInt(4, 7), APInt(4, 3));
- ConstantRange Wrap2(APInt(4, 8), APInt(4, 7));
- EXPECT_EQ(Wrap.getSetSize(), APInt(5, 12));
- EXPECT_EQ(Wrap2.getSetSize(), APInt(5, 15));
-}
-
TEST_F(ConstantRangeTest, GetMinsAndMaxes) {
EXPECT_EQ(Full.getUnsignedMax(), APInt(16, UINT16_MAX));
EXPECT_EQ(One.getUnsignedMax(), APInt(16, 0xa));
@@ -161,7 +257,7 @@
}
TEST_F(ConstantRangeTest, SignWrapped) {
- EXPECT_TRUE(Full.isSignWrappedSet());
+ EXPECT_FALSE(Full.isSignWrappedSet());
EXPECT_FALSE(Empty.isSignWrappedSet());
EXPECT_FALSE(One.isSignWrappedSet());
EXPECT_FALSE(Some.isSignWrappedSet());
@@ -176,6 +272,29 @@
EXPECT_FALSE(ConstantRange(APInt(8, 250), APInt(8, 251)).isSignWrappedSet());
}
+TEST_F(ConstantRangeTest, UpperWrapped) {
+ // The behavior here is the same as for isWrappedSet() / isSignWrappedSet().
+ EXPECT_FALSE(Full.isUpperWrapped());
+ EXPECT_FALSE(Empty.isUpperWrapped());
+ EXPECT_FALSE(One.isUpperWrapped());
+ EXPECT_FALSE(Some.isUpperWrapped());
+ EXPECT_TRUE(Wrap.isUpperWrapped());
+ EXPECT_FALSE(Full.isUpperSignWrapped());
+ EXPECT_FALSE(Empty.isUpperSignWrapped());
+ EXPECT_FALSE(One.isUpperSignWrapped());
+ EXPECT_FALSE(Some.isUpperSignWrapped());
+ EXPECT_TRUE(Wrap.isUpperSignWrapped());
+
+ // The behavior differs if Upper is the Min/SignedMin value.
+ ConstantRange CR1(APInt(8, 42), APInt::getMinValue(8));
+ EXPECT_FALSE(CR1.isWrappedSet());
+ EXPECT_TRUE(CR1.isUpperWrapped());
+
+ ConstantRange CR2(APInt(8, 42), APInt::getSignedMinValue(8));
+ EXPECT_FALSE(CR2.isSignWrappedSet());
+ EXPECT_TRUE(CR2.isUpperSignWrapped());
+}
+
TEST_F(ConstantRangeTest, Trunc) {
ConstantRange TFull = Full.truncate(10);
ConstantRange TEmpty = Empty.truncate(10);
@@ -299,13 +418,163 @@
LHS = ConstantRange(APInt(32, 4), APInt(32, 2));
RHS = ConstantRange(APInt(32, 1), APInt(32, 0));
EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 2)));
-
+
// [15, 0) /\ [7, 6) = [15, 0)
LHS = ConstantRange(APInt(32, 15), APInt(32, 0));
RHS = ConstantRange(APInt(32, 7), APInt(32, 6));
EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 15), APInt(32, 0)));
}
+template<typename Fn1, typename Fn2>
+void testBinarySetOperationExhaustive(Fn1 OpFn, Fn2 InResultFn) {
+ unsigned Bits = 4;
+ EnumerateTwoConstantRanges(Bits,
+ [=](const ConstantRange &CR1, const ConstantRange &CR2) {
+ // Collect up to three contiguous unsigned ranges. The HaveInterrupt
+ // variables are used determine when we have to switch to the next
+ // range because the previous one ended.
+ APInt Lower1(Bits, 0), Upper1(Bits, 0);
+ APInt Lower2(Bits, 0), Upper2(Bits, 0);
+ APInt Lower3(Bits, 0), Upper3(Bits, 0);
+ bool HaveRange1 = false, HaveInterrupt1 = false;
+ bool HaveRange2 = false, HaveInterrupt2 = false;
+ bool HaveRange3 = false, HaveInterrupt3 = false;
+
+ APInt Num(Bits, 0);
+ for (unsigned I = 0, Limit = 1 << Bits; I < Limit; ++I, ++Num) {
+ if (!InResultFn(CR1, CR2, Num)) {
+ if (HaveRange3)
+ HaveInterrupt3 = true;
+ else if (HaveRange2)
+ HaveInterrupt2 = true;
+ else if (HaveRange1)
+ HaveInterrupt1 = true;
+ continue;
+ }
+
+ if (HaveRange3) {
+ Upper3 = Num;
+ } else if (HaveInterrupt2) {
+ HaveRange3 = true;
+ Lower3 = Upper3 = Num;
+ } else if (HaveRange2) {
+ Upper2 = Num;
+ } else if (HaveInterrupt1) {
+ HaveRange2 = true;
+ Lower2 = Upper2 = Num;
+ } else if (HaveRange1) {
+ Upper1 = Num;
+ } else {
+ HaveRange1 = true;
+ Lower1 = Upper1 = Num;
+ }
+ }
+
+ (void)HaveInterrupt3;
+ assert(!HaveInterrupt3 && "Should have at most three ranges");
+
+ ConstantRange SmallestCR = OpFn(CR1, CR2, ConstantRange::Smallest);
+ ConstantRange UnsignedCR = OpFn(CR1, CR2, ConstantRange::Unsigned);
+ ConstantRange SignedCR = OpFn(CR1, CR2, ConstantRange::Signed);
+
+ if (!HaveRange1) {
+ EXPECT_TRUE(SmallestCR.isEmptySet());
+ EXPECT_TRUE(UnsignedCR.isEmptySet());
+ EXPECT_TRUE(SignedCR.isEmptySet());
+ return;
+ }
+
+ if (!HaveRange2) {
+ if (Lower1 == Upper1 + 1) {
+ EXPECT_TRUE(SmallestCR.isFullSet());
+ EXPECT_TRUE(UnsignedCR.isFullSet());
+ EXPECT_TRUE(SignedCR.isFullSet());
+ } else {
+ ConstantRange Expected(Lower1, Upper1 + 1);
+ EXPECT_EQ(Expected, SmallestCR);
+ EXPECT_EQ(Expected, UnsignedCR);
+ EXPECT_EQ(Expected, SignedCR);
+ }
+ return;
+ }
+
+ ConstantRange Variant1(Bits, /*full*/ true);
+ ConstantRange Variant2(Bits, /*full*/ true);
+ if (!HaveRange3) {
+ // Compute the two possible ways to cover two disjoint ranges.
+ if (Lower1 != Upper2 + 1)
+ Variant1 = ConstantRange(Lower1, Upper2 + 1);
+ if (Lower2 != Upper1 + 1)
+ Variant2 = ConstantRange(Lower2, Upper1 + 1);
+ } else {
+ // If we have three ranges, the first and last one have to be adjacent
+ // to the unsigned domain. It's better to think of this as having two
+ // holes, and we can construct one range using each hole.
+ assert(Lower1.isNullValue() && Upper3.isMaxValue());
+ Variant1 = ConstantRange(Lower2, Upper1 + 1);
+ Variant2 = ConstantRange(Lower3, Upper2 + 1);
+ }
+
+ // Smallest: Smaller set, then any set.
+ if (Variant1.isSizeStrictlySmallerThan(Variant2))
+ EXPECT_EQ(Variant1, SmallestCR);
+ else if (Variant2.isSizeStrictlySmallerThan(Variant1))
+ EXPECT_EQ(Variant2, SmallestCR);
+ else
+ EXPECT_TRUE(Variant1 == SmallestCR || Variant2 == SmallestCR);
+
+ // Unsigned: Non-wrapped set, then smaller set, then any set.
+ bool Variant1Full = Variant1.isFullSet() || Variant1.isWrappedSet();
+ bool Variant2Full = Variant2.isFullSet() || Variant2.isWrappedSet();
+ if (!Variant1Full && Variant2Full)
+ EXPECT_EQ(Variant1, UnsignedCR);
+ else if (Variant1Full && !Variant2Full)
+ EXPECT_EQ(Variant2, UnsignedCR);
+ else if (Variant1.isSizeStrictlySmallerThan(Variant2))
+ EXPECT_EQ(Variant1, UnsignedCR);
+ else if (Variant2.isSizeStrictlySmallerThan(Variant1))
+ EXPECT_EQ(Variant2, UnsignedCR);
+ else
+ EXPECT_TRUE(Variant1 == UnsignedCR || Variant2 == UnsignedCR);
+
+ // Signed: Signed non-wrapped set, then smaller set, then any set.
+ Variant1Full = Variant1.isFullSet() || Variant1.isSignWrappedSet();
+ Variant2Full = Variant2.isFullSet() || Variant2.isSignWrappedSet();
+ if (!Variant1Full && Variant2Full)
+ EXPECT_EQ(Variant1, SignedCR);
+ else if (Variant1Full && !Variant2Full)
+ EXPECT_EQ(Variant2, SignedCR);
+ else if (Variant1.isSizeStrictlySmallerThan(Variant2))
+ EXPECT_EQ(Variant1, SignedCR);
+ else if (Variant2.isSizeStrictlySmallerThan(Variant1))
+ EXPECT_EQ(Variant2, SignedCR);
+ else
+ EXPECT_TRUE(Variant1 == SignedCR || Variant2 == SignedCR);
+ });
+}
+
+TEST_F(ConstantRangeTest, IntersectWithExhaustive) {
+ testBinarySetOperationExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2,
+ ConstantRange::PreferredRangeType Type) {
+ return CR1.intersectWith(CR2, Type);
+ },
+ [](const ConstantRange &CR1, const ConstantRange &CR2, const APInt &N) {
+ return CR1.contains(N) && CR2.contains(N);
+ });
+}
+
+TEST_F(ConstantRangeTest, UnionWithExhaustive) {
+ testBinarySetOperationExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2,
+ ConstantRange::PreferredRangeType Type) {
+ return CR1.unionWith(CR2, Type);
+ },
+ [](const ConstantRange &CR1, const ConstantRange &CR2, const APInt &N) {
+ return CR1.contains(N) || CR2.contains(N);
+ });
+}
+
TEST_F(ConstantRangeTest, UnionWith) {
EXPECT_EQ(Wrap.unionWith(One),
ConstantRange(APInt(16, 0xaaa), APInt(16, 0xb)));
@@ -320,10 +589,10 @@
ConstantRange(APInt(16, 14), APInt(16, 8)));
EXPECT_EQ(ConstantRange(APInt(16, 6), APInt(16, 4)).unionWith(
ConstantRange(APInt(16, 4), APInt(16, 0))),
- ConstantRange(16));
+ ConstantRange::getFull(16));
EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 0)).unionWith(
ConstantRange(APInt(16, 2), APInt(16, 1))),
- ConstantRange(16));
+ ConstantRange::getFull(16));
}
TEST_F(ConstantRangeTest, SetDifference) {
@@ -564,9 +833,187 @@
EXPECT_EQ(Some.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 0x111)));
EXPECT_EQ(Some.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
EXPECT_EQ(Wrap.udiv(Wrap), Full);
+
+
+ ConstantRange Zero(APInt(16, 0));
+ EXPECT_EQ(Zero.udiv(One), Zero);
+ EXPECT_EQ(Zero.udiv(Full), Zero);
+
+ EXPECT_EQ(ConstantRange(APInt(16, 0), APInt(16, 99)).udiv(Full),
+ ConstantRange(APInt(16, 0), APInt(16, 99)));
+ EXPECT_EQ(ConstantRange(APInt(16, 10), APInt(16, 99)).udiv(Full),
+ ConstantRange(APInt(16, 0), APInt(16, 99)));
+}
+
+TEST_F(ConstantRangeTest, SDiv) {
+ unsigned Bits = 4;
+ EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1,
+ const ConstantRange &CR2) {
+ // Collect possible results in a bit vector. We store the signed value plus
+ // a bias to make it unsigned.
+ int Bias = 1 << (Bits - 1);
+ BitVector Results(1 << Bits);
+ ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+ ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+ // Division by zero is UB.
+ if (N2 == 0)
+ return;
+
+ // SignedMin / -1 is UB.
+ if (N1.isMinSignedValue() && N2.isAllOnesValue())
+ return;
+
+ APInt N = N1.sdiv(N2);
+ Results.set(N.getSExtValue() + Bias);
+ });
+ });
+
+ ConstantRange CR = CR1.sdiv(CR2);
+ if (Results.none()) {
+ EXPECT_TRUE(CR.isEmptySet());
+ return;
+ }
+
+ // If there is a non-full signed envelope, that should be the result.
+ APInt SMin(Bits, Results.find_first() - Bias);
+ APInt SMax(Bits, Results.find_last() - Bias);
+ ConstantRange Envelope = ConstantRange::getNonEmpty(SMin, SMax + 1);
+ if (!Envelope.isFullSet()) {
+ EXPECT_EQ(Envelope, CR);
+ return;
+ }
+
+ // If the signed envelope is a full set, try to find a smaller sign wrapped
+ // set that is separated in negative and positive components (or one which
+ // can also additionally contain zero).
+ int LastNeg = Results.find_last_in(0, Bias) - Bias;
+ int LastPos = Results.find_next(Bias) - Bias;
+ if (Results[Bias]) {
+ if (LastNeg == -1)
+ ++LastNeg;
+ else if (LastPos == 1)
+ --LastPos;
+ }
+
+ APInt WMax(Bits, LastNeg);
+ APInt WMin(Bits, LastPos);
+ ConstantRange Wrapped = ConstantRange::getNonEmpty(WMin, WMax + 1);
+ EXPECT_EQ(Wrapped, CR);
+ });
+}
+
+TEST_F(ConstantRangeTest, URem) {
+ EXPECT_EQ(Full.urem(Empty), Empty);
+ EXPECT_EQ(Empty.urem(Full), Empty);
+ // urem by zero is poison.
+ EXPECT_EQ(Full.urem(ConstantRange(APInt(16, 0))), Empty);
+ // urem by full range doesn't contain MaxValue.
+ EXPECT_EQ(Full.urem(Full), ConstantRange(APInt(16, 0), APInt(16, 0xffff)));
+ // urem is upper bounded by maximum RHS minus one.
+ EXPECT_EQ(Full.urem(ConstantRange(APInt(16, 0), APInt(16, 123))),
+ ConstantRange(APInt(16, 0), APInt(16, 122)));
+ // urem is upper bounded by maximum LHS.
+ EXPECT_EQ(ConstantRange(APInt(16, 0), APInt(16, 123)).urem(Full),
+ ConstantRange(APInt(16, 0), APInt(16, 123)));
+ // If the LHS is always lower than the RHS, the result is the LHS.
+ EXPECT_EQ(ConstantRange(APInt(16, 10), APInt(16, 20))
+ .urem(ConstantRange(APInt(16, 20), APInt(16, 30))),
+ ConstantRange(APInt(16, 10), APInt(16, 20)));
+ // It has to be strictly lower, otherwise the top value may wrap to zero.
+ EXPECT_EQ(ConstantRange(APInt(16, 10), APInt(16, 20))
+ .urem(ConstantRange(APInt(16, 19), APInt(16, 30))),
+ ConstantRange(APInt(16, 0), APInt(16, 20)));
+ // [12, 14] % 10 is [2, 4], but we conservatively compute [0, 9].
+ EXPECT_EQ(ConstantRange(APInt(16, 12), APInt(16, 15))
+ .urem(ConstantRange(APInt(16, 10))),
+ ConstantRange(APInt(16, 0), APInt(16, 10)));
+
+ TestUnsignedBinOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.urem(CR2);
+ },
+ [](const APInt &N1, const APInt &N2) {
+ return N1.urem(N2);
+ },
+ /* SkipZeroRHS */ true, /* CorrectnessOnly */ true);
+}
+
+TEST_F(ConstantRangeTest, SRem) {
+ EXPECT_EQ(Full.srem(Empty), Empty);
+ EXPECT_EQ(Empty.srem(Full), Empty);
+ // srem by zero is UB.
+ EXPECT_EQ(Full.srem(ConstantRange(APInt(16, 0))), Empty);
+ // srem by full range doesn't contain SignedMinValue.
+ EXPECT_EQ(Full.srem(Full), ConstantRange(APInt::getSignedMinValue(16) + 1,
+ APInt::getSignedMinValue(16)));
+
+ ConstantRange PosMod(APInt(16, 10), APInt(16, 21)); // [10, 20]
+ ConstantRange NegMod(APInt(16, -20), APInt(16, -9)); // [-20, -10]
+ ConstantRange IntMinMod(APInt::getSignedMinValue(16));
+
+ ConstantRange Expected(16, true);
+
+ // srem is bounded by abs(RHS) minus one.
+ ConstantRange PosLargeLHS(APInt(16, 0), APInt(16, 41));
+ Expected = ConstantRange(APInt(16, 0), APInt(16, 20));
+ EXPECT_EQ(PosLargeLHS.srem(PosMod), Expected);
+ EXPECT_EQ(PosLargeLHS.srem(NegMod), Expected);
+ ConstantRange NegLargeLHS(APInt(16, -40), APInt(16, 1));
+ Expected = ConstantRange(APInt(16, -19), APInt(16, 1));
+ EXPECT_EQ(NegLargeLHS.srem(PosMod), Expected);
+ EXPECT_EQ(NegLargeLHS.srem(NegMod), Expected);
+ ConstantRange PosNegLargeLHS(APInt(16, -32), APInt(16, 38));
+ Expected = ConstantRange(APInt(16, -19), APInt(16, 20));
+ EXPECT_EQ(PosNegLargeLHS.srem(PosMod), Expected);
+ EXPECT_EQ(PosNegLargeLHS.srem(NegMod), Expected);
+
+ // srem is bounded by LHS.
+ ConstantRange PosLHS(APInt(16, 0), APInt(16, 16));
+ EXPECT_EQ(PosLHS.srem(PosMod), PosLHS);
+ EXPECT_EQ(PosLHS.srem(NegMod), PosLHS);
+ EXPECT_EQ(PosLHS.srem(IntMinMod), PosLHS);
+ ConstantRange NegLHS(APInt(16, -15), APInt(16, 1));
+ EXPECT_EQ(NegLHS.srem(PosMod), NegLHS);
+ EXPECT_EQ(NegLHS.srem(NegMod), NegLHS);
+ EXPECT_EQ(NegLHS.srem(IntMinMod), NegLHS);
+ ConstantRange PosNegLHS(APInt(16, -12), APInt(16, 18));
+ EXPECT_EQ(PosNegLHS.srem(PosMod), PosNegLHS);
+ EXPECT_EQ(PosNegLHS.srem(NegMod), PosNegLHS);
+ EXPECT_EQ(PosNegLHS.srem(IntMinMod), PosNegLHS);
+
+ // srem is LHS if it is smaller than RHS.
+ ConstantRange PosSmallLHS(APInt(16, 3), APInt(16, 8));
+ EXPECT_EQ(PosSmallLHS.srem(PosMod), PosSmallLHS);
+ EXPECT_EQ(PosSmallLHS.srem(NegMod), PosSmallLHS);
+ EXPECT_EQ(PosSmallLHS.srem(IntMinMod), PosSmallLHS);
+ ConstantRange NegSmallLHS(APInt(16, -7), APInt(16, -2));
+ EXPECT_EQ(NegSmallLHS.srem(PosMod), NegSmallLHS);
+ EXPECT_EQ(NegSmallLHS.srem(NegMod), NegSmallLHS);
+ EXPECT_EQ(NegSmallLHS.srem(IntMinMod), NegSmallLHS);
+ ConstantRange PosNegSmallLHS(APInt(16, -3), APInt(16, 8));
+ EXPECT_EQ(PosNegSmallLHS.srem(PosMod), PosNegSmallLHS);
+ EXPECT_EQ(PosNegSmallLHS.srem(NegMod), PosNegSmallLHS);
+ EXPECT_EQ(PosNegSmallLHS.srem(IntMinMod), PosNegSmallLHS);
+
+ // Example of a suboptimal result:
+ // [12, 14] srem 10 is [2, 4], but we conservatively compute [0, 9].
+ EXPECT_EQ(ConstantRange(APInt(16, 12), APInt(16, 15))
+ .srem(ConstantRange(APInt(16, 10))),
+ ConstantRange(APInt(16, 0), APInt(16, 10)));
+
+ TestSignedBinOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.srem(CR2);
+ },
+ [](const APInt &N1, const APInt &N2) {
+ return N1.srem(N2);
+ },
+ /* SkipZeroRHS */ true, /* CorrectnessOnly */ true);
}
TEST_F(ConstantRangeTest, Shl) {
+ ConstantRange Some2(APInt(16, 0xfff), APInt(16, 0x8000));
+ ConstantRange WrapNullMax(APInt(16, 0x1), APInt(16, 0x0));
EXPECT_EQ(Full.shl(Full), Full);
EXPECT_EQ(Full.shl(Empty), Empty);
EXPECT_EQ(Full.shl(One), Full); // TODO: [0, (-1 << 0xa) + 1)
@@ -583,6 +1030,10 @@
EXPECT_EQ(Some.shl(Some), Full); // TODO: [0xa << 0xa, 0xfc01)
EXPECT_EQ(Some.shl(Wrap), Full); // TODO: [0xa, 0x7ff << 0x5 + 1)
EXPECT_EQ(Wrap.shl(Wrap), Full);
+ EXPECT_EQ(
+ Some2.shl(ConstantRange(APInt(16, 0x1))),
+ ConstantRange(APInt(16, 0xfff << 0x1), APInt(16, 0x7fff << 0x1) + 1));
+ EXPECT_EQ(One.shl(WrapNullMax), Full);
}
TEST_F(ConstantRangeTest, Lshr) {
@@ -710,12 +1161,6 @@
EXPECT_FALSE(NSWRegion.isEmptySet());
- auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap);
-
- EXPECT_FALSE(NoWrapRegion.isEmptySet());
- EXPECT_TRUE(NUWRegion.intersectWith(NSWRegion).contains(NoWrapRegion));
-
for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;
++I) {
bool Overflow = false;
@@ -729,17 +1174,6 @@
(void)I.sadd_ov(C, Overflow);
EXPECT_FALSE(Overflow);
}
-
- for (APInt I = NoWrapRegion.getLower(), E = NoWrapRegion.getUpper(); I != E;
- ++I) {
- bool Overflow = false;
-
- (void)I.sadd_ov(C, Overflow);
- EXPECT_FALSE(Overflow);
-
- (void)I.uadd_ov(C, Overflow);
- EXPECT_FALSE(Overflow);
- }
}
for (int Const : {0, -1, -2, 1, 2, IntMin4Bits, IntMax4Bits}) {
@@ -755,12 +1189,6 @@
EXPECT_FALSE(NSWRegion.isEmptySet());
- auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap);
-
- EXPECT_FALSE(NoWrapRegion.isEmptySet());
- EXPECT_TRUE(NUWRegion.intersectWith(NSWRegion).contains(NoWrapRegion));
-
for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;
++I) {
bool Overflow = false;
@@ -774,17 +1202,6 @@
(void)I.ssub_ov(C, Overflow);
EXPECT_FALSE(Overflow);
}
-
- for (APInt I = NoWrapRegion.getLower(), E = NoWrapRegion.getUpper(); I != E;
- ++I) {
- bool Overflow = false;
-
- (void)I.ssub_ov(C, Overflow);
- EXPECT_FALSE(Overflow);
-
- (void)I.usub_ov(C, Overflow);
- EXPECT_FALSE(Overflow);
- }
}
auto NSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
@@ -811,32 +1228,14 @@
EXPECT_TRUE(NUWForAllValues.isSingleElement() &&
NUWForAllValues.getSingleElement()->isMaxValue());
- auto NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap);
- EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
- NUWAndNSWForAllValues.getSingleElement()->isMinValue());
-
- NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, ConstantRange(32, /* isFullSet = */ true),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap);
- EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
- NUWAndNSWForAllValues.getSingleElement()->isMaxValue());
-
EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());
EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, APInt(32, 0), OBO::NoSignedWrap).isFullSet());
EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, APInt(32, 0),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap).isFullSet());
- EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());
EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, APInt(32, 0), OBO::NoSignedWrap).isFullSet());
- EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, APInt(32, 0),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap).isFullSet());
ConstantRange OneToFive(APInt(32, 1), APInt(32, 6));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -846,10 +1245,6 @@
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, OneToFive, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMinValue(32), APInt::getMinValue(32) - 5));
- EXPECT_EQ(
- ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, OneToFive, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMinValue(32), APInt::getSignedMaxValue(32) - 4));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, OneToFive, OBO::NoSignedWrap),
ConstantRange(APInt::getSignedMinValue(32) + 5,
@@ -857,10 +1252,6 @@
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, OneToFive, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMinValue(32) + 5, APInt::getMinValue(32)));
- EXPECT_EQ(
- ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, OneToFive, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMinValue(32) + 5, APInt::getSignedMinValue(32)));
ConstantRange MinusFiveToMinusTwo(APInt(32, -5), APInt(32, -1));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -871,10 +1262,6 @@
Instruction::Add, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),
ConstantRange(APInt(32, 0), APInt(32, 2)));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, MinusFiveToMinusTwo,
- OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt(32, 0), APInt(32, 2)));
- EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, MinusFiveToMinusTwo, OBO::NoSignedWrap),
ConstantRange(APInt::getSignedMinValue(32),
APInt::getSignedMaxValue(32) - 4));
@@ -882,11 +1269,6 @@
Instruction::Sub, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMaxValue(32) - 1,
APInt::getMinValue(32)));
- EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, MinusFiveToMinusTwo,
- OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMaxValue(32) - 1,
- APInt::getMinValue(32)));
ConstantRange MinusOneToOne(APInt(32, -1), APInt(32, 2));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -897,10 +1279,6 @@
Instruction::Add, MinusOneToOne, OBO::NoUnsignedWrap),
ConstantRange(APInt(32, 0), APInt(32, 1)));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, MinusOneToOne,
- OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt(32, 0), APInt(32, 1)));
- EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, MinusOneToOne, OBO::NoSignedWrap),
ConstantRange(APInt::getSignedMinValue(32) + 1,
APInt::getSignedMinValue(32) - 1));
@@ -908,11 +1286,6 @@
Instruction::Sub, MinusOneToOne, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMaxValue(32),
APInt::getMinValue(32)));
- EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, MinusOneToOne,
- OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMaxValue(32),
- APInt::getMinValue(32)));
ConstantRange One(APInt(32, 1), APInt(32, 2));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -922,10 +1295,6 @@
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, One, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMinValue(32), APInt::getMaxValue(32)));
- EXPECT_EQ(
- ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, One, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt(32, 0), APInt::getSignedMaxValue(32)));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, One, OBO::NoSignedWrap),
ConstantRange(APInt::getSignedMinValue(32) + 1,
@@ -933,10 +1302,84 @@
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, One, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMinValue(32) + 1, APInt::getMinValue(32)));
- EXPECT_EQ(
- ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, One, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMinValue(32) + 1, APInt::getSignedMinValue(32)));
+}
+
+template<typename Fn>
+void TestNoWrapRegionExhaustive(Instruction::BinaryOps BinOp,
+ unsigned NoWrapKind, Fn OverflowFn) {
+ // When using 4 bits this test needs ~3s on a debug build.
+ unsigned Bits = 3;
+ EnumerateTwoConstantRanges(Bits,
+ [&](const ConstantRange &CR1, const ConstantRange &CR2) {
+ if (CR2.isEmptySet())
+ return;
+
+ ConstantRange NoWrap =
+ ConstantRange::makeGuaranteedNoWrapRegion(BinOp, CR2, NoWrapKind);
+ ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+ bool NoOverflow = true;
+ bool Overflow = true;
+ ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+ if (OverflowFn(N1, N2))
+ NoOverflow = false;
+ else
+ Overflow = false;
+ });
+ EXPECT_EQ(NoOverflow, NoWrap.contains(N1));
+
+ // The no-wrap range is exact for single-element ranges.
+ if (CR2.isSingleElement()) {
+ EXPECT_EQ(Overflow, !NoWrap.contains(N1));
+ }
+ });
+ });
+}
+
+// Show that makeGuaranteedNoWrapRegion() is maximal, and for single-element
+// ranges also exact.
+TEST(ConstantRange, NoWrapRegionExhaustive) {
+ TestNoWrapRegionExhaustive(
+ Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap,
+ [](const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.uadd_ov(N2, Overflow);
+ return Overflow;
+ });
+ TestNoWrapRegionExhaustive(
+ Instruction::Add, OverflowingBinaryOperator::NoSignedWrap,
+ [](const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.sadd_ov(N2, Overflow);
+ return Overflow;
+ });
+ TestNoWrapRegionExhaustive(
+ Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap,
+ [](const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.usub_ov(N2, Overflow);
+ return Overflow;
+ });
+ TestNoWrapRegionExhaustive(
+ Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap,
+ [](const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.ssub_ov(N2, Overflow);
+ return Overflow;
+ });
+ TestNoWrapRegionExhaustive(
+ Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap,
+ [](const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.umul_ov(N2, Overflow);
+ return Overflow;
+ });
+ TestNoWrapRegionExhaustive(
+ Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap,
+ [](const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.smul_ov(N2, Overflow);
+ return Overflow;
+ });
}
TEST(ConstantRange, GetEquivalentICmp) {
@@ -1060,26 +1503,6 @@
}
}
-TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulUnsignedAndSignedSingleValue) {
- typedef OverflowingBinaryOperator OBO;
-
- for (uint64_t I = std::numeric_limits<uint8_t>::min();
- I <= std::numeric_limits<uint8_t>::max(); I++) {
- auto Range = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Mul, ConstantRange(APInt(8, I), APInt(8, I + 1)),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap);
-
- for (uint64_t V = std::numeric_limits<uint8_t>::min();
- V <= std::numeric_limits<uint8_t>::max(); V++) {
- bool UOverflow;
- (void)APInt(8, I).umul_ov(APInt(8, V), UOverflow);
- bool SOverflow;
- (void)APInt(8, I).smul_ov(APInt(8, V), SOverflow);
- EXPECT_EQ(!(UOverflow || SOverflow), Range.contains(APInt(8, V)));
- }
- }
-}
-
TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulUnsignedRange) {
typedef OverflowingBinaryOperator OBO;
@@ -1120,4 +1543,455 @@
}
}
+#define EXPECT_MAY_OVERFLOW(op) \
+ EXPECT_EQ(ConstantRange::OverflowResult::MayOverflow, (op))
+#define EXPECT_ALWAYS_OVERFLOWS_LOW(op) \
+ EXPECT_EQ(ConstantRange::OverflowResult::AlwaysOverflowsLow, (op))
+#define EXPECT_ALWAYS_OVERFLOWS_HIGH(op) \
+ EXPECT_EQ(ConstantRange::OverflowResult::AlwaysOverflowsHigh, (op))
+#define EXPECT_NEVER_OVERFLOWS(op) \
+ EXPECT_EQ(ConstantRange::OverflowResult::NeverOverflows, (op))
+
+TEST_F(ConstantRangeTest, UnsignedAddOverflow) {
+ // Ill-defined - may overflow is a conservative result.
+ EXPECT_MAY_OVERFLOW(Some.unsignedAddMayOverflow(Empty));
+ EXPECT_MAY_OVERFLOW(Empty.unsignedAddMayOverflow(Some));
+
+ // Never overflow despite one full/wrap set.
+ ConstantRange Zero(APInt::getNullValue(16));
+ EXPECT_NEVER_OVERFLOWS(Full.unsignedAddMayOverflow(Zero));
+ EXPECT_NEVER_OVERFLOWS(Wrap.unsignedAddMayOverflow(Zero));
+ EXPECT_NEVER_OVERFLOWS(Zero.unsignedAddMayOverflow(Full));
+ EXPECT_NEVER_OVERFLOWS(Zero.unsignedAddMayOverflow(Wrap));
+
+ // But usually full/wrap always may overflow.
+ EXPECT_MAY_OVERFLOW(Full.unsignedAddMayOverflow(One));
+ EXPECT_MAY_OVERFLOW(Wrap.unsignedAddMayOverflow(One));
+ EXPECT_MAY_OVERFLOW(One.unsignedAddMayOverflow(Full));
+ EXPECT_MAY_OVERFLOW(One.unsignedAddMayOverflow(Wrap));
+
+ ConstantRange A(APInt(16, 0xfd00), APInt(16, 0xfe00));
+ ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));
+ ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));
+ EXPECT_NEVER_OVERFLOWS(A.unsignedAddMayOverflow(B1));
+ EXPECT_MAY_OVERFLOW(A.unsignedAddMayOverflow(B2));
+ EXPECT_NEVER_OVERFLOWS(B1.unsignedAddMayOverflow(A));
+ EXPECT_MAY_OVERFLOW(B2.unsignedAddMayOverflow(A));
+
+ ConstantRange C1(APInt(16, 0x0299), APInt(16, 0x0400));
+ ConstantRange C2(APInt(16, 0x0300), APInt(16, 0x0400));
+ EXPECT_MAY_OVERFLOW(A.unsignedAddMayOverflow(C1));
+ EXPECT_ALWAYS_OVERFLOWS_HIGH(A.unsignedAddMayOverflow(C2));
+ EXPECT_MAY_OVERFLOW(C1.unsignedAddMayOverflow(A));
+ EXPECT_ALWAYS_OVERFLOWS_HIGH(C2.unsignedAddMayOverflow(A));
+}
+
+TEST_F(ConstantRangeTest, UnsignedSubOverflow) {
+ // Ill-defined - may overflow is a conservative result.
+ EXPECT_MAY_OVERFLOW(Some.unsignedSubMayOverflow(Empty));
+ EXPECT_MAY_OVERFLOW(Empty.unsignedSubMayOverflow(Some));
+
+ // Never overflow despite one full/wrap set.
+ ConstantRange Zero(APInt::getNullValue(16));
+ ConstantRange Max(APInt::getAllOnesValue(16));
+ EXPECT_NEVER_OVERFLOWS(Full.unsignedSubMayOverflow(Zero));
+ EXPECT_NEVER_OVERFLOWS(Wrap.unsignedSubMayOverflow(Zero));
+ EXPECT_NEVER_OVERFLOWS(Max.unsignedSubMayOverflow(Full));
+ EXPECT_NEVER_OVERFLOWS(Max.unsignedSubMayOverflow(Wrap));
+
+ // But usually full/wrap always may overflow.
+ EXPECT_MAY_OVERFLOW(Full.unsignedSubMayOverflow(One));
+ EXPECT_MAY_OVERFLOW(Wrap.unsignedSubMayOverflow(One));
+ EXPECT_MAY_OVERFLOW(One.unsignedSubMayOverflow(Full));
+ EXPECT_MAY_OVERFLOW(One.unsignedSubMayOverflow(Wrap));
+
+ ConstantRange A(APInt(16, 0x0000), APInt(16, 0x0100));
+ ConstantRange B(APInt(16, 0x0100), APInt(16, 0x0200));
+ EXPECT_NEVER_OVERFLOWS(B.unsignedSubMayOverflow(A));
+ EXPECT_ALWAYS_OVERFLOWS_LOW(A.unsignedSubMayOverflow(B));
+
+ ConstantRange A1(APInt(16, 0x0000), APInt(16, 0x0101));
+ ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));
+ EXPECT_NEVER_OVERFLOWS(B1.unsignedSubMayOverflow(A1));
+ EXPECT_MAY_OVERFLOW(A1.unsignedSubMayOverflow(B1));
+
+ ConstantRange A2(APInt(16, 0x0000), APInt(16, 0x0102));
+ ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));
+ EXPECT_MAY_OVERFLOW(B2.unsignedSubMayOverflow(A2));
+ EXPECT_MAY_OVERFLOW(A2.unsignedSubMayOverflow(B2));
+}
+
+TEST_F(ConstantRangeTest, SignedAddOverflow) {
+ // Ill-defined - may overflow is a conservative result.
+ EXPECT_MAY_OVERFLOW(Some.signedAddMayOverflow(Empty));
+ EXPECT_MAY_OVERFLOW(Empty.signedAddMayOverflow(Some));
+
+ // Never overflow despite one full/wrap set.
+ ConstantRange Zero(APInt::getNullValue(16));
+ EXPECT_NEVER_OVERFLOWS(Full.signedAddMayOverflow(Zero));
+ EXPECT_NEVER_OVERFLOWS(Wrap.signedAddMayOverflow(Zero));
+ EXPECT_NEVER_OVERFLOWS(Zero.signedAddMayOverflow(Full));
+ EXPECT_NEVER_OVERFLOWS(Zero.signedAddMayOverflow(Wrap));
+
+ // But usually full/wrap always may overflow.
+ EXPECT_MAY_OVERFLOW(Full.signedAddMayOverflow(One));
+ EXPECT_MAY_OVERFLOW(Wrap.signedAddMayOverflow(One));
+ EXPECT_MAY_OVERFLOW(One.signedAddMayOverflow(Full));
+ EXPECT_MAY_OVERFLOW(One.signedAddMayOverflow(Wrap));
+
+ ConstantRange A(APInt(16, 0x7d00), APInt(16, 0x7e00));
+ ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));
+ ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));
+ EXPECT_NEVER_OVERFLOWS(A.signedAddMayOverflow(B1));
+ EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B2));
+ ConstantRange B3(APInt(16, 0x8000), APInt(16, 0x0201));
+ ConstantRange B4(APInt(16, 0x8000), APInt(16, 0x0202));
+ EXPECT_NEVER_OVERFLOWS(A.signedAddMayOverflow(B3));
+ EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B4));
+ ConstantRange B5(APInt(16, 0x0299), APInt(16, 0x0400));
+ ConstantRange B6(APInt(16, 0x0300), APInt(16, 0x0400));
+ EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B5));
+ EXPECT_ALWAYS_OVERFLOWS_HIGH(A.signedAddMayOverflow(B6));
+
+ ConstantRange C(APInt(16, 0x8200), APInt(16, 0x8300));
+ ConstantRange D1(APInt(16, 0xfe00), APInt(16, 0xff00));
+ ConstantRange D2(APInt(16, 0xfd99), APInt(16, 0xff00));
+ EXPECT_NEVER_OVERFLOWS(C.signedAddMayOverflow(D1));
+ EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D2));
+ ConstantRange D3(APInt(16, 0xfe00), APInt(16, 0x8000));
+ ConstantRange D4(APInt(16, 0xfd99), APInt(16, 0x8000));
+ EXPECT_NEVER_OVERFLOWS(C.signedAddMayOverflow(D3));
+ EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D4));
+ ConstantRange D5(APInt(16, 0xfc00), APInt(16, 0xfd02));
+ ConstantRange D6(APInt(16, 0xfc00), APInt(16, 0xfd01));
+ EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D5));
+ EXPECT_ALWAYS_OVERFLOWS_LOW(C.signedAddMayOverflow(D6));
+
+ ConstantRange E(APInt(16, 0xff00), APInt(16, 0x0100));
+ EXPECT_NEVER_OVERFLOWS(E.signedAddMayOverflow(E));
+ ConstantRange F(APInt(16, 0xf000), APInt(16, 0x7000));
+ EXPECT_MAY_OVERFLOW(F.signedAddMayOverflow(F));
+}
+
+TEST_F(ConstantRangeTest, SignedSubOverflow) {
+ // Ill-defined - may overflow is a conservative result.
+ EXPECT_MAY_OVERFLOW(Some.signedSubMayOverflow(Empty));
+ EXPECT_MAY_OVERFLOW(Empty.signedSubMayOverflow(Some));
+
+ // Never overflow despite one full/wrap set.
+ ConstantRange Zero(APInt::getNullValue(16));
+ EXPECT_NEVER_OVERFLOWS(Full.signedSubMayOverflow(Zero));
+ EXPECT_NEVER_OVERFLOWS(Wrap.signedSubMayOverflow(Zero));
+
+ // But usually full/wrap always may overflow.
+ EXPECT_MAY_OVERFLOW(Full.signedSubMayOverflow(One));
+ EXPECT_MAY_OVERFLOW(Wrap.signedSubMayOverflow(One));
+ EXPECT_MAY_OVERFLOW(One.signedSubMayOverflow(Full));
+ EXPECT_MAY_OVERFLOW(One.signedSubMayOverflow(Wrap));
+
+ ConstantRange A(APInt(16, 0x7d00), APInt(16, 0x7e00));
+ ConstantRange B1(APInt(16, 0xfe00), APInt(16, 0xff00));
+ ConstantRange B2(APInt(16, 0xfd99), APInt(16, 0xff00));
+ EXPECT_NEVER_OVERFLOWS(A.signedSubMayOverflow(B1));
+ EXPECT_MAY_OVERFLOW(A.signedSubMayOverflow(B2));
+ ConstantRange B3(APInt(16, 0xfc00), APInt(16, 0xfd02));
+ ConstantRange B4(APInt(16, 0xfc00), APInt(16, 0xfd01));
+ EXPECT_MAY_OVERFLOW(A.signedSubMayOverflow(B3));
+ EXPECT_ALWAYS_OVERFLOWS_HIGH(A.signedSubMayOverflow(B4));
+
+ ConstantRange C(APInt(16, 0x8200), APInt(16, 0x8300));
+ ConstantRange D1(APInt(16, 0x0100), APInt(16, 0x0201));
+ ConstantRange D2(APInt(16, 0x0100), APInt(16, 0x0202));
+ EXPECT_NEVER_OVERFLOWS(C.signedSubMayOverflow(D1));
+ EXPECT_MAY_OVERFLOW(C.signedSubMayOverflow(D2));
+ ConstantRange D3(APInt(16, 0x0299), APInt(16, 0x0400));
+ ConstantRange D4(APInt(16, 0x0300), APInt(16, 0x0400));
+ EXPECT_MAY_OVERFLOW(C.signedSubMayOverflow(D3));
+ EXPECT_ALWAYS_OVERFLOWS_LOW(C.signedSubMayOverflow(D4));
+
+ ConstantRange E(APInt(16, 0xff00), APInt(16, 0x0100));
+ EXPECT_NEVER_OVERFLOWS(E.signedSubMayOverflow(E));
+ ConstantRange F(APInt(16, 0xf000), APInt(16, 0x7001));
+ EXPECT_MAY_OVERFLOW(F.signedSubMayOverflow(F));
+}
+
+template<typename Fn1, typename Fn2>
+static void TestOverflowExhaustive(Fn1 OverflowFn, Fn2 MayOverflowFn) {
+ // Constant range overflow checks are tested exhaustively on 4-bit numbers.
+ unsigned Bits = 4;
+ EnumerateTwoConstantRanges(Bits, [=](const ConstantRange &CR1,
+ const ConstantRange &CR2) {
+ // Loop over all N1 in CR1 and N2 in CR2 and check whether any of the
+ // operations have overflow / have no overflow.
+ bool RangeHasOverflowLow = false;
+ bool RangeHasOverflowHigh = false;
+ bool RangeHasNoOverflow = false;
+ ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+ ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+ bool IsOverflowHigh;
+ if (!OverflowFn(IsOverflowHigh, N1, N2)) {
+ RangeHasNoOverflow = true;
+ return;
+ }
+
+ if (IsOverflowHigh)
+ RangeHasOverflowHigh = true;
+ else
+ RangeHasOverflowLow = true;
+ });
+ });
+
+ ConstantRange::OverflowResult OR = MayOverflowFn(CR1, CR2);
+ switch (OR) {
+ case ConstantRange::OverflowResult::AlwaysOverflowsLow:
+ EXPECT_TRUE(RangeHasOverflowLow);
+ EXPECT_FALSE(RangeHasOverflowHigh);
+ EXPECT_FALSE(RangeHasNoOverflow);
+ break;
+ case ConstantRange::OverflowResult::AlwaysOverflowsHigh:
+ EXPECT_TRUE(RangeHasOverflowHigh);
+ EXPECT_FALSE(RangeHasOverflowLow);
+ EXPECT_FALSE(RangeHasNoOverflow);
+ break;
+ case ConstantRange::OverflowResult::NeverOverflows:
+ EXPECT_FALSE(RangeHasOverflowLow);
+ EXPECT_FALSE(RangeHasOverflowHigh);
+ EXPECT_TRUE(RangeHasNoOverflow);
+ break;
+ case ConstantRange::OverflowResult::MayOverflow:
+ // We return MayOverflow for empty sets as a conservative result,
+ // but of course neither the RangeHasOverflow nor the
+ // RangeHasNoOverflow flags will be set.
+ if (CR1.isEmptySet() || CR2.isEmptySet())
+ break;
+
+ EXPECT_TRUE(RangeHasOverflowLow || RangeHasOverflowHigh);
+ EXPECT_TRUE(RangeHasNoOverflow);
+ break;
+ }
+ });
+}
+
+TEST_F(ConstantRangeTest, UnsignedAddOverflowExhaustive) {
+ TestOverflowExhaustive(
+ [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.uadd_ov(N2, Overflow);
+ IsOverflowHigh = true;
+ return Overflow;
+ },
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.unsignedAddMayOverflow(CR2);
+ });
+}
+
+TEST_F(ConstantRangeTest, UnsignedSubOverflowExhaustive) {
+ TestOverflowExhaustive(
+ [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.usub_ov(N2, Overflow);
+ IsOverflowHigh = false;
+ return Overflow;
+ },
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.unsignedSubMayOverflow(CR2);
+ });
+}
+
+TEST_F(ConstantRangeTest, UnsignedMulOverflowExhaustive) {
+ TestOverflowExhaustive(
+ [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.umul_ov(N2, Overflow);
+ IsOverflowHigh = true;
+ return Overflow;
+ },
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.unsignedMulMayOverflow(CR2);
+ });
+}
+
+TEST_F(ConstantRangeTest, SignedAddOverflowExhaustive) {
+ TestOverflowExhaustive(
+ [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.sadd_ov(N2, Overflow);
+ IsOverflowHigh = N1.isNonNegative();
+ return Overflow;
+ },
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.signedAddMayOverflow(CR2);
+ });
+}
+
+TEST_F(ConstantRangeTest, SignedSubOverflowExhaustive) {
+ TestOverflowExhaustive(
+ [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+ bool Overflow;
+ (void) N1.ssub_ov(N2, Overflow);
+ IsOverflowHigh = N1.isNonNegative();
+ return Overflow;
+ },
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.signedSubMayOverflow(CR2);
+ });
+}
+
+TEST_F(ConstantRangeTest, FromKnownBits) {
+ KnownBits Unknown(16);
+ EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/false));
+ EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/true));
+
+ // .10..01. -> unsigned 01000010 (66) to 11011011 (219)
+ // -> signed 11000010 (194) to 01011011 (91)
+ KnownBits Known(8);
+ Known.Zero = 36;
+ Known.One = 66;
+ ConstantRange Unsigned(APInt(8, 66), APInt(8, 219 + 1));
+ ConstantRange Signed(APInt(8, 194), APInt(8, 91 + 1));
+ EXPECT_EQ(Unsigned, ConstantRange::fromKnownBits(Known, /*signed*/false));
+ EXPECT_EQ(Signed, ConstantRange::fromKnownBits(Known, /*signed*/true));
+
+ // 1.10.10. -> 10100100 (164) to 11101101 (237)
+ Known.Zero = 18;
+ Known.One = 164;
+ ConstantRange CR1(APInt(8, 164), APInt(8, 237 + 1));
+ EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/false));
+ EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/true));
+
+ // 01.0.1.0 -> 01000100 (68) to 01101110 (110)
+ Known.Zero = 145;
+ Known.One = 68;
+ ConstantRange CR2(APInt(8, 68), APInt(8, 110 + 1));
+ EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/false));
+ EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/true));
+}
+
+TEST_F(ConstantRangeTest, FromKnownBitsExhaustive) {
+ unsigned Bits = 4;
+ unsigned Max = 1 << Bits;
+ KnownBits Known(Bits);
+ for (unsigned Zero = 0; Zero < Max; ++Zero) {
+ for (unsigned One = 0; One < Max; ++One) {
+ Known.Zero = Zero;
+ Known.One = One;
+ if (Known.hasConflict() || Known.isUnknown())
+ continue;
+
+ APInt MinUnsigned = APInt::getMaxValue(Bits);
+ APInt MaxUnsigned = APInt::getMinValue(Bits);
+ APInt MinSigned = APInt::getSignedMaxValue(Bits);
+ APInt MaxSigned = APInt::getSignedMinValue(Bits);
+ for (unsigned N = 0; N < Max; ++N) {
+ APInt Num(Bits, N);
+ if ((Num & Known.Zero) != 0 || (~Num & Known.One) != 0)
+ continue;
+
+ if (Num.ult(MinUnsigned)) MinUnsigned = Num;
+ if (Num.ugt(MaxUnsigned)) MaxUnsigned = Num;
+ if (Num.slt(MinSigned)) MinSigned = Num;
+ if (Num.sgt(MaxSigned)) MaxSigned = Num;
+ }
+
+ ConstantRange UnsignedCR(MinUnsigned, MaxUnsigned + 1);
+ ConstantRange SignedCR(MinSigned, MaxSigned + 1);
+ EXPECT_EQ(UnsignedCR, ConstantRange::fromKnownBits(Known, false));
+ EXPECT_EQ(SignedCR, ConstantRange::fromKnownBits(Known, true));
+ }
+ }
+}
+
+TEST_F(ConstantRangeTest, Negative) {
+ // All elements in an empty set (of which there are none) are both negative
+ // and non-negative. Empty & full sets checked explicitly for clarity, but
+ // they are also covered by the exhaustive test below.
+ EXPECT_TRUE(Empty.isAllNegative());
+ EXPECT_TRUE(Empty.isAllNonNegative());
+ EXPECT_FALSE(Full.isAllNegative());
+ EXPECT_FALSE(Full.isAllNonNegative());
+
+ unsigned Bits = 4;
+ EnumerateConstantRanges(Bits, [](const ConstantRange &CR) {
+ bool AllNegative = true;
+ bool AllNonNegative = true;
+ ForeachNumInConstantRange(CR, [&](const APInt &N) {
+ if (!N.isNegative())
+ AllNegative = false;
+ if (!N.isNonNegative())
+ AllNonNegative = false;
+ });
+ assert((CR.isEmptySet() || !AllNegative || !AllNonNegative) &&
+ "Only empty set can be both all negative and all non-negative");
+
+ EXPECT_EQ(AllNegative, CR.isAllNegative());
+ EXPECT_EQ(AllNonNegative, CR.isAllNonNegative());
+ });
+}
+
+TEST_F(ConstantRangeTest, UAddSat) {
+ TestUnsignedBinOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.uadd_sat(CR2);
+ },
+ [](const APInt &N1, const APInt &N2) {
+ return N1.uadd_sat(N2);
+ });
+}
+
+TEST_F(ConstantRangeTest, USubSat) {
+ TestUnsignedBinOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.usub_sat(CR2);
+ },
+ [](const APInt &N1, const APInt &N2) {
+ return N1.usub_sat(N2);
+ });
+}
+
+TEST_F(ConstantRangeTest, SAddSat) {
+ TestSignedBinOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.sadd_sat(CR2);
+ },
+ [](const APInt &N1, const APInt &N2) {
+ return N1.sadd_sat(N2);
+ });
+}
+
+TEST_F(ConstantRangeTest, SSubSat) {
+ TestSignedBinOpExhaustive(
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.ssub_sat(CR2);
+ },
+ [](const APInt &N1, const APInt &N2) {
+ return N1.ssub_sat(N2);
+ });
+}
+
+TEST_F(ConstantRangeTest, Abs) {
+ unsigned Bits = 4;
+ EnumerateConstantRanges(Bits, [&](const ConstantRange &CR) {
+ // We're working with unsigned integers here, because it makes the signed
+ // min case non-wrapping.
+ APInt Min = APInt::getMaxValue(Bits);
+ APInt Max = APInt::getMinValue(Bits);
+ ForeachNumInConstantRange(CR, [&](const APInt &N) {
+ APInt AbsN = N.abs();
+ if (AbsN.ult(Min))
+ Min = AbsN;
+ if (AbsN.ugt(Max))
+ Max = AbsN;
+ });
+
+ ConstantRange AbsCR = CR.abs();
+ if (Min.ugt(Max)) {
+ EXPECT_TRUE(AbsCR.isEmptySet());
+ return;
+ }
+
+ ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1);
+ EXPECT_EQ(Exact, AbsCR);
+ });
+}
+
} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/ConstantsTest.cpp b/src/llvm-project/llvm/unittests/IR/ConstantsTest.cpp
index cf67e55..6c3497a 100644
--- a/src/llvm-project/llvm/unittests/IR/ConstantsTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ConstantsTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/ConstantsTest.cpp - Constants unit tests ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -230,7 +229,7 @@
#define P6STR "bitcast (i32 ptrtoint (i32** @dummy2 to i32) to <2 x i16>)"
CHECK(ConstantExpr::getNeg(P0), "sub i32 0, " P0STR);
- CHECK(ConstantExpr::getFNeg(P1), "fsub float -0.000000e+00, " P1STR);
+ CHECK(ConstantExpr::getFNeg(P1), "fneg float " P1STR);
CHECK(ConstantExpr::getNot(P0), "xor i32 " P0STR ", -1");
CHECK(ConstantExpr::getAdd(P0, P0), "add i32 " P0STR ", " P0STR);
CHECK(ConstantExpr::getAdd(P0, P0, false, true), "add nsw i32 " P0STR ", "
@@ -476,5 +475,113 @@
ASSERT_EQ(cast<ConstantExpr>(C)->getOpcode(), Instruction::BitCast);
}
+bool foldFuncPtrAndConstToNull(LLVMContext &Context, Module *TheModule,
+ uint64_t AndValue, unsigned FunctionAlign = 0) {
+ Type *VoidType(Type::getVoidTy(Context));
+ FunctionType *FuncType(FunctionType::get(VoidType, false));
+ Function *Func(Function::Create(
+ FuncType, GlobalValue::ExternalLinkage, "", TheModule));
+
+ if (FunctionAlign) Func->setAlignment(FunctionAlign);
+
+ IntegerType *ConstantIntType(Type::getInt32Ty(Context));
+ ConstantInt *TheConstant(ConstantInt::get(ConstantIntType, AndValue));
+
+ Constant *TheConstantExpr(
+ ConstantExpr::getPtrToInt(Func, ConstantIntType));
+
+
+ bool result = ConstantExpr::get(Instruction::And, TheConstantExpr,
+ TheConstant)->isNullValue();
+
+ if (!TheModule) {
+ // If the Module exists then it will delete the Function.
+ delete Func;
+ }
+
+ return result;
+}
+
+TEST(ConstantsTest, FoldFunctionPtrAlignUnknownAnd2) {
+ LLVMContext Context;
+ Module TheModule("TestModule", Context);
+ // When the DataLayout doesn't specify a function pointer alignment we
+ // assume in this case that it is 4 byte aligned. This is a bug but we can't
+ // fix it directly because it causes a code size regression on X86.
+ // FIXME: This test should be changed once existing targets have
+ // appropriate defaults. See associated FIXME in ConstantFoldBinaryInstruction
+ ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, 2));
+}
+
+TEST(ConstantsTest, DontFoldFunctionPtrAlignUnknownAnd4) {
+ LLVMContext Context;
+ Module TheModule("TestModule", Context);
+ ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 4));
+}
+
+TEST(ConstantsTest, FoldFunctionPtrAlign4) {
+ LLVMContext Context;
+ Module TheModule("TestModule", Context);
+ const char* AlignmentStrings[] = { "Fi32", "Fn32" };
+
+ for (unsigned AndValue = 1; AndValue <= 2; ++AndValue) {
+ for (const char *AlignmentString : AlignmentStrings) {
+ TheModule.setDataLayout(AlignmentString);
+ ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, AndValue));
+ }
+ }
+}
+
+TEST(ConstantsTest, DontFoldFunctionPtrAlign1) {
+ LLVMContext Context;
+ Module TheModule("TestModule", Context);
+ const char* AlignmentStrings[] = { "Fi8", "Fn8" };
+
+ for (const char* AlignmentString : AlignmentStrings) {
+ TheModule.setDataLayout(AlignmentString);
+ ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 2));
+ }
+}
+
+TEST(ConstantsTest, FoldFunctionAlign4PtrAlignMultiple) {
+ LLVMContext Context;
+ Module TheModule("TestModule", Context);
+ TheModule.setDataLayout("Fn8");
+ ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, 2, 4));
+}
+
+TEST(ConstantsTest, DontFoldFunctionAlign4PtrAlignIndependent) {
+ LLVMContext Context;
+ Module TheModule("TestModule", Context);
+ TheModule.setDataLayout("Fi8");
+ ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 2, 4));
+}
+
+TEST(ConstantsTest, DontFoldFunctionPtrIfNoModule) {
+ LLVMContext Context;
+ // Even though the function is explicitly 4 byte aligned, in the absence of a
+ // DataLayout we can't assume that the function pointer is aligned.
+ ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, nullptr, 2, 4));
+}
+
+TEST(ConstantsTest, FoldGlobalVariablePtr) {
+ LLVMContext Context;
+
+ IntegerType *IntType(Type::getInt32Ty(Context));
+
+ std::unique_ptr<GlobalVariable> Global(
+ new GlobalVariable(IntType, true, GlobalValue::ExternalLinkage));
+
+ Global->setAlignment(4);
+
+ ConstantInt *TheConstant(ConstantInt::get(IntType, 2));
+
+ Constant *TheConstantExpr(
+ ConstantExpr::getPtrToInt(Global.get(), IntType));
+
+ ASSERT_TRUE(ConstantExpr::get( \
+ Instruction::And, TheConstantExpr, TheConstant)->isNullValue());
+}
+
} // end anonymous namespace
} // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/IR/DataLayoutTest.cpp b/src/llvm-project/llvm/unittests/IR/DataLayoutTest.cpp
new file mode 100644
index 0000000..e7ed70b
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/IR/DataLayoutTest.cpp
@@ -0,0 +1,47 @@
+//===- ConstantRangeTest.cpp - ConstantRange tests ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/DataLayout.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(DataLayoutTest, FunctionPtrAlign) {
+ EXPECT_EQ(0U, DataLayout("").getFunctionPtrAlign());
+ EXPECT_EQ(1U, DataLayout("Fi8").getFunctionPtrAlign());
+ EXPECT_EQ(2U, DataLayout("Fi16").getFunctionPtrAlign());
+ EXPECT_EQ(4U, DataLayout("Fi32").getFunctionPtrAlign());
+ EXPECT_EQ(8U, DataLayout("Fi64").getFunctionPtrAlign());
+ EXPECT_EQ(1U, DataLayout("Fn8").getFunctionPtrAlign());
+ EXPECT_EQ(2U, DataLayout("Fn16").getFunctionPtrAlign());
+ EXPECT_EQ(4U, DataLayout("Fn32").getFunctionPtrAlign());
+ EXPECT_EQ(8U, DataLayout("Fn64").getFunctionPtrAlign());
+ EXPECT_EQ(DataLayout::FunctionPtrAlignType::Independent, \
+ DataLayout("").getFunctionPtrAlignType());
+ EXPECT_EQ(DataLayout::FunctionPtrAlignType::Independent, \
+ DataLayout("Fi8").getFunctionPtrAlignType());
+ EXPECT_EQ(DataLayout::FunctionPtrAlignType::MultipleOfFunctionAlign, \
+ DataLayout("Fn8").getFunctionPtrAlignType());
+ EXPECT_EQ(DataLayout("Fi8"), DataLayout("Fi8"));
+ EXPECT_NE(DataLayout("Fi8"), DataLayout("Fi16"));
+ EXPECT_NE(DataLayout("Fi8"), DataLayout("Fn8"));
+
+ DataLayout a(""), b("Fi8"), c("Fn8");
+ EXPECT_NE(a, b);
+ EXPECT_NE(a, c);
+ EXPECT_NE(b, c);
+
+ a = b;
+ EXPECT_EQ(a, b);
+ a = c;
+ EXPECT_EQ(a, c);
+}
+
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/DebugInfoTest.cpp b/src/llvm-project/llvm/unittests/IR/DebugInfoTest.cpp
index a80df3c..9324790 100644
--- a/src/llvm-project/llvm/unittests/IR/DebugInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/DebugInfoTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/DebugInfo.cpp - DebugInfo tests -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp b/src/llvm-project/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
index af77091..8031bf7 100644
--- a/src/llvm-project/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
@@ -1,9 +1,8 @@
//===- DebugTypeODRUniquingTest.cpp - Debug type ODR uniquing tests -------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp b/src/llvm-project/llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp
index 6775fc1..a2d5805 100644
--- a/src/llvm-project/llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp ----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/DominatorTreeTest.cpp b/src/llvm-project/llvm/unittests/IR/DominatorTreeTest.cpp
index 7539bbc..7773856 100644
--- a/src/llvm-project/llvm/unittests/IR/DominatorTreeTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/DominatorTreeTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittests/IR/DominatorTreeTest.cpp - Constants unit tests -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/FunctionTest.cpp b/src/llvm-project/llvm/unittests/IR/FunctionTest.cpp
index 6838d7e..6f3e8f9 100644
--- a/src/llvm-project/llvm/unittests/IR/FunctionTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/FunctionTest.cpp
@@ -1,9 +1,8 @@
//===- FunctionTest.cpp - Function unit tests -----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -130,4 +129,29 @@
EXPECT_TRUE(F->hasSection());
}
+TEST(FunctionTest, GetPointerAlignment) {
+ LLVMContext Context;
+ Type *VoidType(Type::getVoidTy(Context));
+ FunctionType *FuncType(FunctionType::get(VoidType, false));
+ std::unique_ptr<Function> Func(Function::Create(
+ FuncType, GlobalValue::ExternalLinkage));
+ EXPECT_EQ(0U, Func->getPointerAlignment(DataLayout("")));
+ EXPECT_EQ(1U, Func->getPointerAlignment(DataLayout("Fi8")));
+ EXPECT_EQ(1U, Func->getPointerAlignment(DataLayout("Fn8")));
+ EXPECT_EQ(2U, Func->getPointerAlignment(DataLayout("Fi16")));
+ EXPECT_EQ(2U, Func->getPointerAlignment(DataLayout("Fn16")));
+ EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fi32")));
+ EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn32")));
+
+ Func->setAlignment(4U);
+
+ EXPECT_EQ(0U, Func->getPointerAlignment(DataLayout("")));
+ EXPECT_EQ(1U, Func->getPointerAlignment(DataLayout("Fi8")));
+ EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn8")));
+ EXPECT_EQ(2U, Func->getPointerAlignment(DataLayout("Fi16")));
+ EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn16")));
+ EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fi32")));
+ EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn32")));
+}
+
} // end namespace
diff --git a/src/llvm-project/llvm/unittests/IR/IRBuilderTest.cpp b/src/llvm-project/llvm/unittests/IR/IRBuilderTest.cpp
index db174fa..667b9ef 100644
--- a/src/llvm-project/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/IRBuilderTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -55,7 +54,7 @@
CallInst *Call;
IntrinsicInst *II;
- V = Builder.CreateLoad(GV);
+ V = Builder.CreateLoad(GV->getValueType(), GV);
I = cast<Instruction>(Builder.CreateFAdd(V, V));
I->setHasNoInfs(true);
I->setHasNoNaNs(false);
@@ -123,6 +122,70 @@
EXPECT_FALSE(II->hasNoNaNs());
}
+TEST_F(IRBuilderTest, ConstrainedFP) {
+ IRBuilder<> Builder(BB);
+ Value *V;
+ CallInst *Call;
+ IntrinsicInst *II;
+
+ V = Builder.CreateLoad(GV->getValueType(), GV);
+
+ // See if we get constrained intrinsics instead of non-constrained
+ // instructions.
+ Builder.setIsFPConstrained(true);
+
+ V = Builder.CreateFAdd(V, V);
+ ASSERT_TRUE(isa<IntrinsicInst>(V));
+ II = cast<IntrinsicInst>(V);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fadd);
+
+ V = Builder.CreateFSub(V, V);
+ ASSERT_TRUE(isa<IntrinsicInst>(V));
+ II = cast<IntrinsicInst>(V);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fsub);
+
+ V = Builder.CreateFMul(V, V);
+ ASSERT_TRUE(isa<IntrinsicInst>(V));
+ II = cast<IntrinsicInst>(V);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fmul);
+
+ V = Builder.CreateFDiv(V, V);
+ ASSERT_TRUE(isa<IntrinsicInst>(V));
+ II = cast<IntrinsicInst>(V);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fdiv);
+
+ V = Builder.CreateFRem(V, V);
+ ASSERT_TRUE(isa<IntrinsicInst>(V));
+ II = cast<IntrinsicInst>(V);
+ EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_frem);
+
+ // Verify the codepaths for setting and overriding the default metadata.
+ V = Builder.CreateFAdd(V, V);
+ ASSERT_TRUE(isa<ConstrainedFPIntrinsic>(V));
+ auto *CII = cast<ConstrainedFPIntrinsic>(V);
+ ASSERT_TRUE(CII->getExceptionBehavior() == ConstrainedFPIntrinsic::ebStrict);
+ ASSERT_TRUE(CII->getRoundingMode() == ConstrainedFPIntrinsic::rmDynamic);
+
+ Builder.setDefaultConstrainedExcept(ConstrainedFPIntrinsic::ebIgnore);
+ Builder.setDefaultConstrainedRounding(ConstrainedFPIntrinsic::rmUpward);
+ V = Builder.CreateFAdd(V, V);
+ CII = cast<ConstrainedFPIntrinsic>(V);
+ ASSERT_TRUE(CII->getExceptionBehavior() == ConstrainedFPIntrinsic::ebIgnore);
+ ASSERT_TRUE(CII->getRoundingMode() == ConstrainedFPIntrinsic::rmUpward);
+
+ // Now override the defaults.
+ Call = Builder.CreateConstrainedFPBinOp(
+ Intrinsic::experimental_constrained_fadd, V, V, nullptr, "", nullptr,
+ ConstrainedFPIntrinsic::rmDownward, ConstrainedFPIntrinsic::ebMayTrap);
+ CII = cast<ConstrainedFPIntrinsic>(Call);
+ EXPECT_EQ(CII->getIntrinsicID(), Intrinsic::experimental_constrained_fadd);
+ ASSERT_TRUE(CII->getExceptionBehavior() == ConstrainedFPIntrinsic::ebMayTrap);
+ ASSERT_TRUE(CII->getRoundingMode() == ConstrainedFPIntrinsic::rmDownward);
+
+ Builder.CreateRetVoid();
+ EXPECT_FALSE(verifyModule(*M));
+}
+
TEST_F(IRBuilderTest, Lifetime) {
IRBuilder<> Builder(BB);
AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
@@ -203,12 +266,34 @@
delete DL;
}
+TEST_F(IRBuilderTest, UnaryOperators) {
+ IRBuilder<NoFolder> Builder(BB);
+ Value *V = Builder.CreateLoad(GV->getValueType(), GV);
+
+ // Test CreateUnOp(X)
+ Value *U = Builder.CreateUnOp(Instruction::FNeg, V);
+ ASSERT_TRUE(isa<Instruction>(U));
+ ASSERT_TRUE(isa<FPMathOperator>(U));
+ ASSERT_TRUE(isa<UnaryOperator>(U));
+ ASSERT_FALSE(isa<BinaryOperator>(U));
+
+ // Test CreateFNegFMF(X)
+ Instruction *I = cast<Instruction>(V);
+ I->setHasNoSignedZeros(true);
+ I->setHasNoNaNs(true);
+ Value *VFMF = Builder.CreateFNegFMF(V, I);
+ Instruction *IFMF = cast<Instruction>(VFMF);
+ EXPECT_TRUE(IFMF->hasNoSignedZeros());
+ EXPECT_TRUE(IFMF->hasNoNaNs());
+ EXPECT_FALSE(IFMF->hasAllowReassoc());
+}
+
TEST_F(IRBuilderTest, FastMathFlags) {
IRBuilder<> Builder(BB);
Value *F, *FC;
Instruction *FDiv, *FAdd, *FCmp, *FCall;
- F = Builder.CreateLoad(GV);
+ F = Builder.CreateLoad(GV->getValueType(), GV);
F = Builder.CreateFAdd(F, F);
EXPECT_FALSE(Builder.getFastMathFlags().any());
@@ -354,7 +439,7 @@
FCall = Builder.CreateCall(Callee, None);
EXPECT_FALSE(FCall->hasNoNaNs());
- Value *V =
+ Function *V =
Function::Create(CalleeTy, Function::ExternalLinkage, "", M.get());
FCall = Builder.CreateCall(V, None);
EXPECT_FALSE(FCall->hasNoNaNs());
@@ -375,7 +460,7 @@
Builder.clearFastMathFlags();
- // To test a copy, make sure that a '0' and a '1' change state.
+ // To test a copy, make sure that a '0' and a '1' change state.
F = Builder.CreateFDiv(F, F);
ASSERT_TRUE(isa<Instruction>(F));
FDiv = cast<Instruction>(F);
@@ -395,7 +480,7 @@
// Test instructions.
GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true,
GlobalValue::ExternalLinkage, nullptr);
- Value *V = Builder.CreateLoad(G);
+ Value *V = Builder.CreateLoad(G->getValueType(), G);
EXPECT_TRUE(
cast<BinaryOperator>(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap());
EXPECT_TRUE(
@@ -462,7 +547,7 @@
EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());
- Value *F = Builder.CreateLoad(GV);
+ Value *F = Builder.CreateLoad(GV->getValueType(), GV);
{
IRBuilder<>::InsertPointGuard Guard(Builder);
diff --git a/src/llvm-project/llvm/unittests/IR/InstructionsTest.cpp b/src/llvm-project/llvm/unittests/IR/InstructionsTest.cpp
index 080e35c..b2ea384 100644
--- a/src/llvm-project/llvm/unittests/IR/InstructionsTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/InstructionsTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/InstructionsTest.cpp - Instructions unit tests ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -505,14 +504,15 @@
LLVMContext C;
Type *Int32Ty = Type::getInt32Ty(C);
Type *ArgTys[] = {Int32Ty, Int32Ty, Int32Ty};
- Type *FnTy = FunctionType::get(Int32Ty, ArgTys, /*isVarArg=*/false);
+ FunctionType *FnTy = FunctionType::get(Int32Ty, ArgTys, /*isVarArg=*/false);
Value *Callee = Constant::getNullValue(FnTy->getPointerTo());
Value *Args[] = {
ConstantInt::get(Int32Ty, 1),
ConstantInt::get(Int32Ty, 2),
ConstantInt::get(Int32Ty, 3)
};
- std::unique_ptr<CallInst> Call(CallInst::Create(Callee, Args, "result"));
+ std::unique_ptr<CallInst> Call(
+ CallInst::Create(FnTy, Callee, Args, "result"));
// Test cloning the tail call kind.
CallInst::TailCallKind Kinds[] = {CallInst::TCK_None, CallInst::TCK_Tail,
@@ -538,12 +538,12 @@
TEST(InstructionsTest, AlterCallBundles) {
LLVMContext C;
Type *Int32Ty = Type::getInt32Ty(C);
- Type *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);
+ FunctionType *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);
Value *Callee = Constant::getNullValue(FnTy->getPointerTo());
Value *Args[] = {ConstantInt::get(Int32Ty, 42)};
OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty));
std::unique_ptr<CallInst> Call(
- CallInst::Create(Callee, Args, OldBundle, "result"));
+ CallInst::Create(FnTy, Callee, Args, OldBundle, "result"));
Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail);
AttrBuilder AB;
AB.addAttribute(Attribute::Cold);
@@ -565,14 +565,15 @@
TEST(InstructionsTest, AlterInvokeBundles) {
LLVMContext C;
Type *Int32Ty = Type::getInt32Ty(C);
- Type *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);
+ FunctionType *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);
Value *Callee = Constant::getNullValue(FnTy->getPointerTo());
Value *Args[] = {ConstantInt::get(Int32Ty, 42)};
std::unique_ptr<BasicBlock> NormalDest(BasicBlock::Create(C));
std::unique_ptr<BasicBlock> UnwindDest(BasicBlock::Create(C));
OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty));
- std::unique_ptr<InvokeInst> Invoke(InvokeInst::Create(
- Callee, NormalDest.get(), UnwindDest.get(), Args, OldBundle, "result"));
+ std::unique_ptr<InvokeInst> Invoke(
+ InvokeInst::Create(FnTy, Callee, NormalDest.get(), UnwindDest.get(), Args,
+ OldBundle, "result"));
AttrBuilder AB;
AB.addAttribute(Attribute::Cold);
Invoke->setAttributes(
@@ -646,7 +647,8 @@
{
Value *GEPBase = Constant::getNullValue(B.getInt8PtrTy());
- auto *GI = cast<GetElementPtrInst>(B.CreateInBoundsGEP(GEPBase, {Arg0}));
+ auto *GI = cast<GetElementPtrInst>(
+ B.CreateInBoundsGEP(B.getInt8Ty(), GEPBase, Arg0));
ASSERT_TRUE(GI->isInBounds());
GI->dropPoisonGeneratingFlags();
ASSERT_FALSE(GI->isInBounds());
@@ -751,6 +753,47 @@
EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor());
}
+TEST(InstructionsTest, SwitchInstProfUpdateWrapper) {
+ LLVMContext C;
+
+ std::unique_ptr<BasicBlock> BB1, BB2, BB3;
+ BB1.reset(BasicBlock::Create(C));
+ BB2.reset(BasicBlock::Create(C));
+ BB3.reset(BasicBlock::Create(C));
+
+ // We create block 0 after the others so that it gets destroyed first and
+ // clears the uses of the other basic blocks.
+ std::unique_ptr<BasicBlock> BB0(BasicBlock::Create(C));
+
+ auto *Int32Ty = Type::getInt32Ty(C);
+
+ SwitchInst *SI =
+ SwitchInst::Create(UndefValue::get(Int32Ty), BB0.get(), 4, BB0.get());
+ SI->addCase(ConstantInt::get(Int32Ty, 1), BB1.get());
+ SI->addCase(ConstantInt::get(Int32Ty, 2), BB2.get());
+ SI->setMetadata(LLVMContext::MD_prof,
+ MDBuilder(C).createBranchWeights({ 9, 1, 22 }));
+
+ {
+ SwitchInstProfUpdateWrapper SIW(*SI);
+ EXPECT_EQ(*SIW.getSuccessorWeight(0), 9u);
+ EXPECT_EQ(*SIW.getSuccessorWeight(1), 1u);
+ EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u);
+ SIW.setSuccessorWeight(0, 99u);
+ SIW.setSuccessorWeight(1, 11u);
+ EXPECT_EQ(*SIW.getSuccessorWeight(0), 99u);
+ EXPECT_EQ(*SIW.getSuccessorWeight(1), 11u);
+ EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u);
+ }
+
+ { // Create another wrapper and check that the data persist.
+ SwitchInstProfUpdateWrapper SIW(*SI);
+ EXPECT_EQ(*SIW.getSuccessorWeight(0), 99u);
+ EXPECT_EQ(*SIW.getSuccessorWeight(1), 11u);
+ EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u);
+ }
+}
+
TEST(InstructionsTest, CommuteShuffleMask) {
SmallVector<int, 16> Indices({-1, 0, 7});
ShuffleVectorInst::commuteShuffleMask(Indices, 4);
@@ -991,5 +1034,83 @@
EXPECT_EQ(nullptr, Term->getNextNonDebugInstruction());
}
+TEST(InstructionsTest, PhiIsNotFPMathOperator) {
+ LLVMContext Context;
+ IRBuilder<> Builder(Context);
+ MDBuilder MDHelper(Context);
+ Instruction *I = Builder.CreatePHI(Builder.getDoubleTy(), 0);
+ EXPECT_FALSE(isa<FPMathOperator>(I));
+ I->deleteValue();
+}
+
+TEST(InstructionsTest, FNegInstruction) {
+ LLVMContext Context;
+ Type *FltTy = Type::getFloatTy(Context);
+ Constant *One = ConstantFP::get(FltTy, 1.0);
+ BinaryOperator *FAdd = BinaryOperator::CreateFAdd(One, One);
+ FAdd->setHasNoNaNs(true);
+ UnaryOperator *FNeg = UnaryOperator::CreateFNegFMF(One, FAdd);
+ EXPECT_TRUE(FNeg->hasNoNaNs());
+ EXPECT_FALSE(FNeg->hasNoInfs());
+ EXPECT_FALSE(FNeg->hasNoSignedZeros());
+ EXPECT_FALSE(FNeg->hasAllowReciprocal());
+ EXPECT_FALSE(FNeg->hasAllowContract());
+ EXPECT_FALSE(FNeg->hasAllowReassoc());
+ EXPECT_FALSE(FNeg->hasApproxFunc());
+ FAdd->deleteValue();
+ FNeg->deleteValue();
+}
+
+TEST(InstructionsTest, CallBrInstruction) {
+ LLVMContext Context;
+ std::unique_ptr<Module> M = parseIR(Context, R"(
+define void @foo() {
+entry:
+ callbr void asm sideeffect "// XXX: ${0:l}", "X"(i8* blockaddress(@foo, %branch_test.exit))
+ to label %land.rhs.i [label %branch_test.exit]
+
+land.rhs.i:
+ br label %branch_test.exit
+
+branch_test.exit:
+ %0 = phi i1 [ true, %entry ], [ false, %land.rhs.i ]
+ br i1 %0, label %if.end, label %if.then
+
+if.then:
+ ret void
+
+if.end:
+ ret void
+}
+)");
+ Function *Foo = M->getFunction("foo");
+ auto BBs = Foo->getBasicBlockList().begin();
+ CallBrInst &CBI = cast<CallBrInst>(BBs->front());
+ ++BBs;
+ ++BBs;
+ BasicBlock &BranchTestExit = *BBs;
+ ++BBs;
+ BasicBlock &IfThen = *BBs;
+
+ // Test that setting the first indirect destination of callbr updates the dest
+ EXPECT_EQ(&BranchTestExit, CBI.getIndirectDest(0));
+ CBI.setIndirectDest(0, &IfThen);
+ EXPECT_EQ(&IfThen, CBI.getIndirectDest(0));
+
+ // Further, test that changing the indirect destination updates the arg
+ // operand to use the block address of the new indirect destination basic
+ // block. This is a critical invariant of CallBrInst.
+ BlockAddress *IndirectBA = BlockAddress::get(CBI.getIndirectDest(0));
+ BlockAddress *ArgBA = cast<BlockAddress>(CBI.getArgOperand(0));
+ EXPECT_EQ(IndirectBA, ArgBA)
+ << "After setting the indirect destination, callbr had an indirect "
+ "destination of '"
+ << CBI.getIndirectDest(0)->getName() << "', but a argument of '"
+ << ArgBA->getBasicBlock()->getName() << "'. These should always match:\n"
+ << CBI;
+ EXPECT_EQ(IndirectBA->getBasicBlock(), &IfThen);
+ EXPECT_EQ(ArgBA->getBasicBlock(), &IfThen);
+}
+
} // end anonymous namespace
} // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/IR/IntrinsicsTest.cpp b/src/llvm-project/llvm/unittests/IR/IntrinsicsTest.cpp
index 0d12126..a500346 100644
--- a/src/llvm-project/llvm/unittests/IR/IntrinsicsTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/IntrinsicsTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/IntrinsicsTest.cpp - ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/LegacyPassManagerTest.cpp b/src/llvm-project/llvm/unittests/IR/LegacyPassManagerTest.cpp
index 9f5f431..6c0c251 100644
--- a/src/llvm-project/llvm/unittests/IR/LegacyPassManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/LegacyPassManagerTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/LegacyPassManager.cpp - Legacy PassManager tests --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -401,7 +400,12 @@
struct CustomOptPassGate : public OptPassGate {
bool Skip;
CustomOptPassGate(bool Skip) : Skip(Skip) { }
- bool shouldRunPass(const Pass *P, const Module &U) { return !Skip; }
+ bool shouldRunPass(const Pass *P, StringRef IRDescription) {
+ if (P->getPassKind() == PT_Module)
+ return !Skip;
+ return OptPassGate::shouldRunPass(P, IRDescription);
+ }
+ bool isEnabled() const { return true; }
};
// Optional module pass.
diff --git a/src/llvm-project/llvm/unittests/IR/MDBuilderTest.cpp b/src/llvm-project/llvm/unittests/IR/MDBuilderTest.cpp
index ab2d34e..f8d08b5 100644
--- a/src/llvm-project/llvm/unittests/IR/MDBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/MDBuilderTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittests/MDBuilderTest.cpp - MDBuilder unit tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/ManglerTest.cpp b/src/llvm-project/llvm/unittests/IR/ManglerTest.cpp
index 04f1ca6..f0ef15e5 100644
--- a/src/llvm-project/llvm/unittests/IR/ManglerTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ManglerTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/ManglerTest.cpp - Mangler unit tests --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/MetadataTest.cpp b/src/llvm-project/llvm/unittests/IR/MetadataTest.cpp
index 883a582..c1bce90 100644
--- a/src/llvm-project/llvm/unittests/IR/MetadataTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/MetadataTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/IR/MetadataTest.cpp - Metadata unit tests ----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -118,8 +117,9 @@
32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, "");
}
Function *getFunction(StringRef Name) {
- return cast<Function>(M.getOrInsertFunction(
- Name, FunctionType::get(Type::getVoidTy(Context), None, false)));
+ return Function::Create(
+ FunctionType::get(Type::getVoidTy(Context), None, false),
+ Function::ExternalLinkage, Name, M);
}
};
typedef MetadataTest MDStringTest;
@@ -1050,35 +1050,41 @@
EXPECT_EQ(0U, L1->getBaseDiscriminator());
EXPECT_EQ(1U, L1->getDuplicationFactor());
- auto L2 = L1->setBaseDiscriminator(1).getValue();
+ EXPECT_EQ(L1, L1->cloneWithBaseDiscriminator(0).getValue());
+ EXPECT_EQ(L1, L1->cloneByMultiplyingDuplicationFactor(0).getValue());
+ EXPECT_EQ(L1, L1->cloneByMultiplyingDuplicationFactor(1).getValue());
+
+ auto L2 = L1->cloneWithBaseDiscriminator(1).getValue();
EXPECT_EQ(0U, L1->getBaseDiscriminator());
EXPECT_EQ(1U, L1->getDuplicationFactor());
EXPECT_EQ(1U, L2->getBaseDiscriminator());
EXPECT_EQ(1U, L2->getDuplicationFactor());
- auto L3 = L2->cloneWithDuplicationFactor(2).getValue();
+ auto L3 = L2->cloneByMultiplyingDuplicationFactor(2).getValue();
EXPECT_EQ(1U, L3->getBaseDiscriminator());
EXPECT_EQ(2U, L3->getDuplicationFactor());
- auto L4 = L3->cloneWithDuplicationFactor(4).getValue();
+ EXPECT_EQ(L2, L2->cloneByMultiplyingDuplicationFactor(1).getValue());
+
+ auto L4 = L3->cloneByMultiplyingDuplicationFactor(4).getValue();
EXPECT_EQ(1U, L4->getBaseDiscriminator());
EXPECT_EQ(8U, L4->getDuplicationFactor());
- auto L5 = L4->setBaseDiscriminator(2).getValue();
+ auto L5 = L4->cloneWithBaseDiscriminator(2).getValue();
EXPECT_EQ(2U, L5->getBaseDiscriminator());
- EXPECT_EQ(1U, L5->getDuplicationFactor());
+ EXPECT_EQ(8U, L5->getDuplicationFactor());
// Check extreme cases
- auto L6 = L1->setBaseDiscriminator(0xfff).getValue();
+ auto L6 = L1->cloneWithBaseDiscriminator(0xfff).getValue();
EXPECT_EQ(0xfffU, L6->getBaseDiscriminator());
- EXPECT_EQ(
- 0xfffU,
- L6->cloneWithDuplicationFactor(0xfff).getValue()->getDuplicationFactor());
+ EXPECT_EQ(0xfffU, L6->cloneByMultiplyingDuplicationFactor(0xfff)
+ .getValue()
+ ->getDuplicationFactor());
// Check we return None for unencodable cases.
- EXPECT_EQ(None, L4->setBaseDiscriminator(0x1000));
- EXPECT_EQ(None, L4->cloneWithDuplicationFactor(0x1000));
+ EXPECT_EQ(None, L4->cloneWithBaseDiscriminator(0x1000));
+ EXPECT_EQ(None, L4->cloneByMultiplyingDuplicationFactor(0x1000));
}
@@ -2329,7 +2335,11 @@
// Test DIExpression::prepend().
uint64_t Elts0[] = {dwarf::DW_OP_LLVM_fragment, 0, 32};
auto *N0 = DIExpression::get(Context, Elts0);
- auto *N0WithPrependedOps = DIExpression::prepend(N0, true, 64, true, true);
+ uint8_t DIExprFlags = DIExpression::ApplyOffset;
+ DIExprFlags |= DIExpression::DerefBefore;
+ DIExprFlags |= DIExpression::DerefAfter;
+ DIExprFlags |= DIExpression::StackValue;
+ auto *N0WithPrependedOps = DIExpression::prepend(N0, DIExprFlags, 64);
uint64_t Elts1[] = {dwarf::DW_OP_deref,
dwarf::DW_OP_plus_uconst, 64,
dwarf::DW_OP_deref,
@@ -2746,7 +2756,7 @@
F = getFunction("bar");
EXPECT_FALSE(F->getEntryCount().hasValue());
F->setEntryCount(123, Function::PCT_Synthetic);
- Count = F->getEntryCount();
+ Count = F->getEntryCount(true /*allow synthetic*/);
EXPECT_TRUE(Count.hasValue());
EXPECT_EQ(123u, Count.getCount());
EXPECT_EQ(Function::PCT_Synthetic, Count.getType());
diff --git a/src/llvm-project/llvm/unittests/IR/ModuleTest.cpp b/src/llvm-project/llvm/unittests/IR/ModuleTest.cpp
index af55a09..ae420bb 100644
--- a/src/llvm-project/llvm/unittests/IR/ModuleTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ModuleTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/IR/ModuleTest.cpp - Module unit tests --------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp b/src/llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
index 63fdc67..bb7e227 100644
--- a/src/llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/IR/PassBuilderCallbacksTest.cpp - PB Callback Tests --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -415,7 +414,8 @@
"exit:\n"
" ret void\n"
"}\n")),
- CallbacksHandle(), PB(nullptr, None, &CallbacksHandle.Callbacks),
+ CallbacksHandle(),
+ PB(nullptr, PipelineTuningOptions(), None, &CallbacksHandle.Callbacks),
PM(true), LAM(true), FAM(true), CGAM(true), AM(true) {
/// Register a callback for analysis registration.
diff --git a/src/llvm-project/llvm/unittests/IR/PassManagerTest.cpp b/src/llvm-project/llvm/unittests/IR/PassManagerTest.cpp
index 13b87f1..304803d 100644
--- a/src/llvm-project/llvm/unittests/IR/PassManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/PassManagerTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/PatternMatch.cpp b/src/llvm-project/llvm/unittests/IR/PatternMatch.cpp
index 976e42d..600494f 100644
--- a/src/llvm-project/llvm/unittests/IR/PatternMatch.cpp
+++ b/src/llvm-project/llvm/unittests/IR/PatternMatch.cpp
@@ -1,9 +1,8 @@
//===---- llvm/unittest/IR/PatternMatch.cpp - PatternMatch unit tests ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -65,6 +64,396 @@
EXPECT_FALSE(m_OneUse(m_Value()).match(Leaf));
}
+TEST_F(PatternMatchTest, SpecificIntEQ) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntNE) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntUGT) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntUGE) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntULT) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntULE) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntSGT) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntSGE) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntSLT) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntSLE) {
+ Type *IntTy = IRB.getInt32Ty();
+ unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+ Value *Zero = ConstantInt::get(IntTy, 0);
+ Value *One = ConstantInt::get(IntTy, 1);
+ Value *NegOne = ConstantInt::get(IntTy, -1);
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0))
+ .match(NegOne));
+
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1))
+ .match(Zero));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1))
+ .match(NegOne));
+
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1))
+ .match(Zero));
+ EXPECT_FALSE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1))
+ .match(One));
+ EXPECT_TRUE(
+ m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1))
+ .match(NegOne));
+}
+
TEST_F(PatternMatchTest, CommutativeDeferredValue) {
Value *X = IRB.getInt32(1);
Value *Y = IRB.getInt32(2);
@@ -398,7 +787,7 @@
// store i32 42, i32* %0
Value *Alloca = IRB.CreateAlloca(IRB.getInt32Ty());
- Value *LoadInst = IRB.CreateLoad(Alloca);
+ Value *LoadInst = IRB.CreateLoad(IRB.getInt32Ty(), Alloca);
Value *FourtyTwo = IRB.getInt32(42);
Value *StoreInst = IRB.CreateStore(FourtyTwo, Alloca);
Value *MatchLoad, *MatchStoreVal, *MatchStorePointer;
@@ -590,6 +979,35 @@
EXPECT_TRUE(match(VectorZeroUndef, m_AnyZeroFP()));
}
+TEST_F(PatternMatchTest, FloatingPointFNeg) {
+ Type *FltTy = IRB.getFloatTy();
+ Value *One = ConstantFP::get(FltTy, 1.0);
+ Value *Z = ConstantFP::get(FltTy, 0.0);
+ Value *NZ = ConstantFP::get(FltTy, -0.0);
+ Value *V = IRB.CreateFNeg(One);
+ Value *V1 = IRB.CreateFSub(NZ, One);
+ Value *V2 = IRB.CreateFSub(Z, One);
+ Value *V3 = IRB.CreateFAdd(NZ, One);
+ Value *Match;
+
+ // Test FNeg(1.0)
+ EXPECT_TRUE(match(V, m_FNeg(m_Value(Match))));
+ EXPECT_EQ(One, Match);
+
+ // Test FSub(-0.0, 1.0)
+ EXPECT_TRUE(match(V1, m_FNeg(m_Value(Match))));
+ EXPECT_EQ(One, Match);
+
+ // Test FSub(0.0, 1.0)
+ EXPECT_FALSE(match(V2, m_FNeg(m_Value(Match))));
+ cast<Instruction>(V2)->setHasNoSignedZeros(true);
+ EXPECT_TRUE(match(V2, m_FNeg(m_Value(Match))));
+ EXPECT_EQ(One, Match);
+
+ // Test FAdd(-0.0, 1.0)
+ EXPECT_FALSE(match(V3, m_FNeg(m_Value(Match))));
+}
+
template <typename T> struct MutableConstTest : PatternMatchTest { };
typedef ::testing::Types<std::tuple<Value*, Instruction*>,
diff --git a/src/llvm-project/llvm/unittests/IR/TimePassesTest.cpp b/src/llvm-project/llvm/unittests/IR/TimePassesTest.cpp
new file mode 100644
index 0000000..a766522
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/IR/TimePassesTest.cpp
@@ -0,0 +1,169 @@
+//===- unittests/IR/TimePassesTest.cpp - TimePassesHandler tests ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <gtest/gtest.h>
+#include <llvm/ADT/SmallString.h>
+#include "llvm/IR/LegacyPassManager.h"
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/Module.h>
+#include <llvm/IR/PassInstrumentation.h>
+#include <llvm/IR/PassManager.h>
+#include <llvm/IR/PassTimingInfo.h>
+#include <llvm/Support/raw_ostream.h>
+
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Define dummy passes for legacy pass manager run.
+
+namespace llvm {
+
+void initializePass1Pass(PassRegistry &);
+void initializePass2Pass(PassRegistry &);
+
+namespace {
+struct Pass1 : public ModulePass {
+ static char ID;
+
+public:
+ Pass1() : ModulePass(ID) {}
+ bool runOnModule(Module &M) override { return false; }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+ StringRef getPassName() const override { return "Pass1"; }
+};
+char Pass1::ID;
+
+struct Pass2 : public ModulePass {
+ static char ID;
+
+public:
+ Pass2() : ModulePass(ID) {}
+ bool runOnModule(Module &M) override { return false; }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+ StringRef getPassName() const override { return "Pass2"; }
+};
+char Pass2::ID;
+} // namespace
+} // namespace llvm
+
+INITIALIZE_PASS(Pass1, "Pass1", "Pass1", false, false)
+INITIALIZE_PASS(Pass2, "Pass2", "Pass2", false, false)
+
+namespace {
+
+TEST(TimePassesTest, LegacyCustomOut) {
+ PassInstrumentationCallbacks PIC;
+ PassInstrumentation PI(&PIC);
+
+ LLVMContext Context;
+ Module M("TestModule", Context);
+
+ SmallString<0> TimePassesStr;
+ raw_svector_ostream ReportStream(TimePassesStr);
+
+ // Setup pass manager
+ legacy::PassManager PM1;
+ PM1.add(new llvm::Pass1());
+ PM1.add(new llvm::Pass2());
+
+ // Enable time-passes and run passes.
+ TimePassesIsEnabled = true;
+ PM1.run(M);
+
+ // Generating report.
+ reportAndResetTimings(&ReportStream);
+
+ // There should be Pass1 and Pass2 in the report
+ EXPECT_FALSE(TimePassesStr.empty());
+ EXPECT_TRUE(TimePassesStr.str().contains("report"));
+ EXPECT_TRUE(TimePassesStr.str().contains("Pass1"));
+ EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));
+
+ // Clear and generate report again.
+ TimePassesStr.clear();
+ reportAndResetTimings(&ReportStream);
+
+ // Since we did not run any passes since last print, report should be empty.
+ EXPECT_TRUE(TimePassesStr.empty());
+
+ // Now run just a single pass to populate timers again.
+ legacy::PassManager PM2;
+ PM2.add(new llvm::Pass2());
+ PM2.run(M);
+
+ // Generate report again.
+ reportAndResetTimings(&ReportStream);
+
+ // There should be Pass2 in this report and no Pass1.
+ EXPECT_FALSE(TimePassesStr.str().empty());
+ EXPECT_TRUE(TimePassesStr.str().contains("report"));
+ EXPECT_FALSE(TimePassesStr.str().contains("Pass1"));
+ EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));
+}
+
+class MyPass1 : public PassInfoMixin<MyPass1> {};
+class MyPass2 : public PassInfoMixin<MyPass2> {};
+
+TEST(TimePassesTest, CustomOut) {
+ PassInstrumentationCallbacks PIC;
+ PassInstrumentation PI(&PIC);
+
+ LLVMContext Context;
+ Module M("TestModule", Context);
+ MyPass1 Pass1;
+ MyPass2 Pass2;
+
+ SmallString<0> TimePassesStr;
+ raw_svector_ostream ReportStream(TimePassesStr);
+
+ // Setup time-passes handler and redirect output to the stream.
+ std::unique_ptr<TimePassesHandler> TimePasses =
+ llvm::make_unique<TimePassesHandler>(true);
+ TimePasses->setOutStream(ReportStream);
+ TimePasses->registerCallbacks(PIC);
+
+ // Pretending that passes are running to trigger the timers.
+ PI.runBeforePass(Pass1, M);
+ PI.runBeforePass(Pass2, M);
+ PI.runAfterPass(Pass2, M);
+ PI.runAfterPass(Pass1, M);
+
+ // Generating report.
+ TimePasses->print();
+
+ // There should be Pass1 and Pass2 in the report
+ EXPECT_FALSE(TimePassesStr.empty());
+ EXPECT_TRUE(TimePassesStr.str().contains("report"));
+ EXPECT_TRUE(TimePassesStr.str().contains("Pass1"));
+ EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));
+
+ // Clear and generate report again.
+ TimePassesStr.clear();
+ TimePasses->print();
+ // Since we did not run any passes since last print, report should be empty.
+ EXPECT_TRUE(TimePassesStr.empty());
+
+ // Now trigger just a single pass to populate timers again.
+ PI.runBeforePass(Pass2, M);
+ PI.runAfterPass(Pass2, M);
+
+ // Generate report by deleting the handler.
+ TimePasses.reset();
+
+ // There should be Pass2 in this report and no Pass1.
+ EXPECT_FALSE(TimePassesStr.str().empty());
+ EXPECT_TRUE(TimePassesStr.str().contains("report"));
+ EXPECT_FALSE(TimePassesStr.str().contains("Pass1"));
+ EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/TypesTest.cpp b/src/llvm-project/llvm/unittests/IR/TypesTest.cpp
index f006db51..a147367 100644
--- a/src/llvm-project/llvm/unittests/IR/TypesTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/TypesTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/TypesTest.cpp - Type unit tests -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/UseTest.cpp b/src/llvm-project/llvm/unittests/IR/UseTest.cpp
index 51ac2f4..a647ec7 100644
--- a/src/llvm-project/llvm/unittests/IR/UseTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/UseTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/UseTest.cpp - Use unit tests ----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/UserTest.cpp b/src/llvm-project/llvm/unittests/IR/UserTest.cpp
index 794dfc1..e495735 100644
--- a/src/llvm-project/llvm/unittests/IR/UserTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/UserTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/UserTest.cpp - User unit tests --------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/ValueHandleTest.cpp b/src/llvm-project/llvm/unittests/IR/ValueHandleTest.cpp
index 9a4ce15..b799ff0 100644
--- a/src/llvm-project/llvm/unittests/IR/ValueHandleTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ValueHandleTest.cpp
@@ -1,9 +1,8 @@
//===- ValueHandleTest.cpp - ValueHandle tests ----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/ValueMapTest.cpp b/src/llvm-project/llvm/unittests/IR/ValueMapTest.cpp
index cbcd6f6..9dcb4fa 100644
--- a/src/llvm-project/llvm/unittests/IR/ValueMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ValueMapTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/ADT/ValueMapTest.cpp - ValueMap unit tests -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/ValueTest.cpp b/src/llvm-project/llvm/unittests/IR/ValueTest.cpp
index 90466b2..03523a7 100644
--- a/src/llvm-project/llvm/unittests/IR/ValueTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ValueTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/ValueTest.cpp - Value unit tests ------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/IR/VectorTypesTest.cpp b/src/llvm-project/llvm/unittests/IR/VectorTypesTest.cpp
new file mode 100644
index 0000000..f3caf6d
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/IR/VectorTypesTest.cpp
@@ -0,0 +1,164 @@
+//===--- llvm/unittest/IR/VectorTypesTest.cpp - vector types unit tests ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Support/ScalableSize.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace {
+TEST(VectorTypesTest, FixedLength) {
+ LLVMContext Ctx;
+
+ Type *Int16Ty = Type::getInt16Ty(Ctx);
+ Type *Int32Ty = Type::getInt32Ty(Ctx);
+ Type *Int64Ty = Type::getInt64Ty(Ctx);
+ Type *Float64Ty = Type::getDoubleTy(Ctx);
+
+ VectorType *V8Int32Ty = VectorType::get(Int32Ty, 8);
+ ASSERT_FALSE(V8Int32Ty->isScalable());
+ EXPECT_EQ(V8Int32Ty->getNumElements(), 8U);
+ EXPECT_EQ(V8Int32Ty->getElementType()->getScalarSizeInBits(), 32U);
+
+ VectorType *V8Int16Ty = VectorType::get(Int16Ty, {8, false});
+ ASSERT_FALSE(V8Int16Ty->isScalable());
+ EXPECT_EQ(V8Int16Ty->getNumElements(), 8U);
+ EXPECT_EQ(V8Int16Ty->getElementType()->getScalarSizeInBits(), 16U);
+
+ ElementCount EltCnt(4, false);
+ VectorType *V4Int64Ty = VectorType::get(Int64Ty, EltCnt);
+ ASSERT_FALSE(V4Int64Ty->isScalable());
+ EXPECT_EQ(V4Int64Ty->getNumElements(), 4U);
+ EXPECT_EQ(V4Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *V2Int64Ty = VectorType::get(Int64Ty, EltCnt/2);
+ ASSERT_FALSE(V2Int64Ty->isScalable());
+ EXPECT_EQ(V2Int64Ty->getNumElements(), 2U);
+ EXPECT_EQ(V2Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *V8Int64Ty = VectorType::get(Int64Ty, EltCnt*2);
+ ASSERT_FALSE(V8Int64Ty->isScalable());
+ EXPECT_EQ(V8Int64Ty->getNumElements(), 8U);
+ EXPECT_EQ(V8Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *V4Float64Ty = VectorType::get(Float64Ty, EltCnt);
+ ASSERT_FALSE(V4Float64Ty->isScalable());
+ EXPECT_EQ(V4Float64Ty->getNumElements(), 4U);
+ EXPECT_EQ(V4Float64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *ExtTy = VectorType::getExtendedElementVectorType(V8Int16Ty);
+ EXPECT_EQ(ExtTy, V8Int32Ty);
+ ASSERT_FALSE(ExtTy->isScalable());
+ EXPECT_EQ(ExtTy->getNumElements(), 8U);
+ EXPECT_EQ(ExtTy->getElementType()->getScalarSizeInBits(), 32U);
+
+ VectorType *TruncTy = VectorType::getTruncatedElementVectorType(V8Int32Ty);
+ EXPECT_EQ(TruncTy, V8Int16Ty);
+ ASSERT_FALSE(TruncTy->isScalable());
+ EXPECT_EQ(TruncTy->getNumElements(), 8U);
+ EXPECT_EQ(TruncTy->getElementType()->getScalarSizeInBits(), 16U);
+
+ VectorType *HalvedTy = VectorType::getHalfElementsVectorType(V4Int64Ty);
+ EXPECT_EQ(HalvedTy, V2Int64Ty);
+ ASSERT_FALSE(HalvedTy->isScalable());
+ EXPECT_EQ(HalvedTy->getNumElements(), 2U);
+ EXPECT_EQ(HalvedTy->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *DoubledTy = VectorType::getDoubleElementsVectorType(V4Int64Ty);
+ EXPECT_EQ(DoubledTy, V8Int64Ty);
+ ASSERT_FALSE(DoubledTy->isScalable());
+ EXPECT_EQ(DoubledTy->getNumElements(), 8U);
+ EXPECT_EQ(DoubledTy->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *ConvTy = VectorType::getInteger(V4Float64Ty);
+ EXPECT_EQ(ConvTy, V4Int64Ty);
+ ASSERT_FALSE(ConvTy->isScalable());
+ EXPECT_EQ(ConvTy->getNumElements(), 4U);
+ EXPECT_EQ(ConvTy->getElementType()->getScalarSizeInBits(), 64U);
+
+ EltCnt = V8Int64Ty->getElementCount();
+ EXPECT_EQ(EltCnt.Min, 8U);
+ ASSERT_FALSE(EltCnt.Scalable);
+}
+
+TEST(VectorTypesTest, Scalable) {
+ LLVMContext Ctx;
+
+ Type *Int16Ty = Type::getInt16Ty(Ctx);
+ Type *Int32Ty = Type::getInt32Ty(Ctx);
+ Type *Int64Ty = Type::getInt64Ty(Ctx);
+ Type *Float64Ty = Type::getDoubleTy(Ctx);
+
+ VectorType *ScV8Int32Ty = VectorType::get(Int32Ty, 8, true);
+ ASSERT_TRUE(ScV8Int32Ty->isScalable());
+ EXPECT_EQ(ScV8Int32Ty->getNumElements(), 8U);
+ EXPECT_EQ(ScV8Int32Ty->getElementType()->getScalarSizeInBits(), 32U);
+
+ VectorType *ScV8Int16Ty = VectorType::get(Int16Ty, {8, true});
+ ASSERT_TRUE(ScV8Int16Ty->isScalable());
+ EXPECT_EQ(ScV8Int16Ty->getNumElements(), 8U);
+ EXPECT_EQ(ScV8Int16Ty->getElementType()->getScalarSizeInBits(), 16U);
+
+ ElementCount EltCnt(4, true);
+ VectorType *ScV4Int64Ty = VectorType::get(Int64Ty, EltCnt);
+ ASSERT_TRUE(ScV4Int64Ty->isScalable());
+ EXPECT_EQ(ScV4Int64Ty->getNumElements(), 4U);
+ EXPECT_EQ(ScV4Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *ScV2Int64Ty = VectorType::get(Int64Ty, EltCnt/2);
+ ASSERT_TRUE(ScV2Int64Ty->isScalable());
+ EXPECT_EQ(ScV2Int64Ty->getNumElements(), 2U);
+ EXPECT_EQ(ScV2Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *ScV8Int64Ty = VectorType::get(Int64Ty, EltCnt*2);
+ ASSERT_TRUE(ScV8Int64Ty->isScalable());
+ EXPECT_EQ(ScV8Int64Ty->getNumElements(), 8U);
+ EXPECT_EQ(ScV8Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *ScV4Float64Ty = VectorType::get(Float64Ty, EltCnt);
+ ASSERT_TRUE(ScV4Float64Ty->isScalable());
+ EXPECT_EQ(ScV4Float64Ty->getNumElements(), 4U);
+ EXPECT_EQ(ScV4Float64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *ExtTy = VectorType::getExtendedElementVectorType(ScV8Int16Ty);
+ EXPECT_EQ(ExtTy, ScV8Int32Ty);
+ ASSERT_TRUE(ExtTy->isScalable());
+ EXPECT_EQ(ExtTy->getNumElements(), 8U);
+ EXPECT_EQ(ExtTy->getElementType()->getScalarSizeInBits(), 32U);
+
+ VectorType *TruncTy = VectorType::getTruncatedElementVectorType(ScV8Int32Ty);
+ EXPECT_EQ(TruncTy, ScV8Int16Ty);
+ ASSERT_TRUE(TruncTy->isScalable());
+ EXPECT_EQ(TruncTy->getNumElements(), 8U);
+ EXPECT_EQ(TruncTy->getElementType()->getScalarSizeInBits(), 16U);
+
+ VectorType *HalvedTy = VectorType::getHalfElementsVectorType(ScV4Int64Ty);
+ EXPECT_EQ(HalvedTy, ScV2Int64Ty);
+ ASSERT_TRUE(HalvedTy->isScalable());
+ EXPECT_EQ(HalvedTy->getNumElements(), 2U);
+ EXPECT_EQ(HalvedTy->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *DoubledTy = VectorType::getDoubleElementsVectorType(ScV4Int64Ty);
+ EXPECT_EQ(DoubledTy, ScV8Int64Ty);
+ ASSERT_TRUE(DoubledTy->isScalable());
+ EXPECT_EQ(DoubledTy->getNumElements(), 8U);
+ EXPECT_EQ(DoubledTy->getElementType()->getScalarSizeInBits(), 64U);
+
+ VectorType *ConvTy = VectorType::getInteger(ScV4Float64Ty);
+ EXPECT_EQ(ConvTy, ScV4Int64Ty);
+ ASSERT_TRUE(ConvTy->isScalable());
+ EXPECT_EQ(ConvTy->getNumElements(), 4U);
+ EXPECT_EQ(ConvTy->getElementType()->getScalarSizeInBits(), 64U);
+
+ EltCnt = ScV8Int64Ty->getElementCount();
+ EXPECT_EQ(EltCnt.Min, 8U);
+ ASSERT_TRUE(EltCnt.Scalable);
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/VerifierTest.cpp b/src/llvm-project/llvm/unittests/IR/VerifierTest.cpp
index 53e5d6f..a85f0a2 100644
--- a/src/llvm-project/llvm/unittests/IR/VerifierTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/VerifierTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -27,7 +26,7 @@
LLVMContext C;
Module M("M", C);
FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
- Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
ReturnInst::Create(C, Exit);
@@ -50,7 +49,7 @@
LLVMContext C;
Module M("M", C);
FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
- Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
AttributeList AS = F->getAttributes();
F->setAttributes(
AS.addAttribute(C, AttributeList::ReturnIndex, Attribute::UWTable));
@@ -68,9 +67,9 @@
Module M2("M2", C);
Module M3("M3", C);
FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
- Function *F1 = cast<Function>(M1.getOrInsertFunction("foo1", FTy));
- Function *F2 = cast<Function>(M2.getOrInsertFunction("foo2", FTy));
- Function *F3 = cast<Function>(M3.getOrInsertFunction("foo3", FTy));
+ Function *F1 = Function::Create(FTy, Function::ExternalLinkage, "foo1", M1);
+ Function *F2 = Function::Create(FTy, Function::ExternalLinkage, "foo2", M2);
+ Function *F3 = Function::Create(FTy, Function::ExternalLinkage, "foo3", M3);
BasicBlock *Entry1 = BasicBlock::Create(C, "entry", F1);
BasicBlock *Entry3 = BasicBlock::Create(C, "entry", F3);
@@ -174,8 +173,8 @@
new GlobalVariable(M, Type::getInt8Ty(C), false,
GlobalValue::ExternalLinkage, nullptr, "g");
- auto *F = cast<Function>(M.getOrInsertFunction(
- "f", FunctionType::get(Type::getVoidTy(C), false)));
+ auto *F = Function::Create(FunctionType::get(Type::getVoidTy(C), false),
+ Function::ExternalLinkage, "f", M);
IRBuilder<> Builder(BasicBlock::Create(C, "", F));
Builder.CreateUnreachable();
F->setSubprogram(DIB.createFunction(
diff --git a/src/llvm-project/llvm/unittests/IR/WaymarkTest.cpp b/src/llvm-project/llvm/unittests/IR/WaymarkTest.cpp
index 4d2671c..2f64fe0 100644
--- a/src/llvm-project/llvm/unittests/IR/WaymarkTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/WaymarkTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/IR/WaymarkTest.cpp - getUser() unit tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/LineEditor/LineEditor.cpp b/src/llvm-project/llvm/unittests/LineEditor/LineEditor.cpp
index 4d9081f..42e5c6c 100644
--- a/src/llvm-project/llvm/unittests/LineEditor/LineEditor.cpp
+++ b/src/llvm-project/llvm/unittests/LineEditor/LineEditor.cpp
@@ -1,9 +1,8 @@
//===-- LineEditor.cpp ----------------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Linker/LinkModulesTest.cpp b/src/llvm-project/llvm/unittests/Linker/LinkModulesTest.cpp
index b8e2449..832e50c 100644
--- a/src/llvm-project/llvm/unittests/Linker/LinkModulesTest.cpp
+++ b/src/llvm-project/llvm/unittests/Linker/LinkModulesTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Linker/LinkModulesTest.cpp - IRBuilder tests ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -84,7 +83,7 @@
GEPIndices.push_back(&*F->arg_begin());
Value *GEP = Builder.CreateGEP(AT, GV, GEPIndices, "switch.gep");
- Value *Load = Builder.CreateLoad(GEP, "switch.load");
+ Value *Load = Builder.CreateLoad(AT->getElementType(), GEP, "switch.load");
Builder.CreateRet(Load);
diff --git a/src/llvm-project/llvm/unittests/MC/Disassembler.cpp b/src/llvm-project/llvm/unittests/MC/Disassembler.cpp
index ca9581a..cdb3444 100644
--- a/src/llvm-project/llvm/unittests/MC/Disassembler.cpp
+++ b/src/llvm-project/llvm/unittests/MC/Disassembler.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Object/Disassembler.cpp ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/MC/DwarfLineTables.cpp b/src/llvm-project/llvm/unittests/MC/DwarfLineTables.cpp
index 1b1a4d6..af1250d 100644
--- a/src/llvm-project/llvm/unittests/MC/DwarfLineTables.cpp
+++ b/src/llvm-project/llvm/unittests/MC/DwarfLineTables.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/MC/DwarfLineTables.cpp ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -58,9 +57,7 @@
raw_svector_ostream EncodingOS(Buffer);
MCDwarfLineAddr::Encode(getContext(), Params, LineDelta, AddrDelta,
EncodingOS);
- ArrayRef<uint8_t> Encoding(reinterpret_cast<uint8_t *>(Buffer.data()),
- Buffer.size());
- EXPECT_EQ(ExpectedEncoding, Encoding);
+ EXPECT_EQ(ExpectedEncoding, arrayRefFromStringRef(Buffer));
}
TEST(DwarfLineTables, TestDefaultParams) {
diff --git a/src/llvm-project/llvm/unittests/MC/StringTableBuilderTest.cpp b/src/llvm-project/llvm/unittests/MC/StringTableBuilderTest.cpp
index b547f93..81b7fa3 100644
--- a/src/llvm-project/llvm/unittests/MC/StringTableBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/MC/StringTableBuilderTest.cpp
@@ -1,9 +1,8 @@
//===----------- StringTableBuilderTest.cpp -------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/MC/TargetRegistry.cpp b/src/llvm-project/llvm/unittests/MC/TargetRegistry.cpp
index eb46b22..587b2ee 100644
--- a/src/llvm-project/llvm/unittests/MC/TargetRegistry.cpp
+++ b/src/llvm-project/llvm/unittests/MC/TargetRegistry.cpp
@@ -1,9 +1,8 @@
//===- unittests/MC/TargetRegistry.cpp ------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Object/CMakeLists.txt b/src/llvm-project/llvm/unittests/Object/CMakeLists.txt
index e1376bf..e0be1ba 100644
--- a/src/llvm-project/llvm/unittests/Object/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Object/CMakeLists.txt
@@ -1,9 +1,12 @@
set(LLVM_LINK_COMPONENTS
+ BinaryFormat
Object
)
add_llvm_unittest(ObjectTests
+ MinidumpTest.cpp
SymbolSizeTest.cpp
SymbolicFileTest.cpp
)
+target_link_libraries(ObjectTests PRIVATE LLVMTestingSupport)
diff --git a/src/llvm-project/llvm/unittests/Object/MinidumpTest.cpp b/src/llvm-project/llvm/unittests/Object/MinidumpTest.cpp
new file mode 100644
index 0000000..ba9af5a
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Object/MinidumpTest.cpp
@@ -0,0 +1,513 @@
+//===- MinidumpTest.cpp - Tests for Minidump.cpp --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/Minidump.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::object;
+using namespace minidump;
+
+static Expected<std::unique_ptr<MinidumpFile>> create(ArrayRef<uint8_t> Data) {
+ return MinidumpFile::create(
+ MemoryBufferRef(toStringRef(Data), "Test buffer"));
+}
+
+TEST(MinidumpFile, BasicInterface) {
+ std::vector<uint8_t> Data{ // Header
+ 'M', 'D', 'M', 'P', // Signature
+ 0x93, 0xa7, 0, 0, // Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 3, 0, 0x67, 0x47, 7, 0, 0, 0, // Type, DataSize,
+ 0x2c, 0, 0, 0, // RVA
+ // Stream
+ 'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+ // A very simple minidump file which contains just a single stream.
+ auto ExpectedFile = create(Data);
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ const MinidumpFile &File = **ExpectedFile;
+ const Header &H = File.header();
+ EXPECT_EQ(Header::MagicSignature, H.Signature);
+ EXPECT_EQ(Header::MagicVersion, H.Version);
+ EXPECT_EQ(1u, H.NumberOfStreams);
+ EXPECT_EQ(0x20u, H.StreamDirectoryRVA);
+ EXPECT_EQ(0x03020100u, H.Checksum);
+ EXPECT_EQ(0x07060504u, H.TimeDateStamp);
+ EXPECT_EQ(uint64_t(0x0504030201000908), H.Flags);
+
+ ASSERT_EQ(1u, File.streams().size());
+ const Directory &Stream0 = File.streams()[0];
+ EXPECT_EQ(StreamType::LinuxCPUInfo, Stream0.Type);
+ EXPECT_EQ(7u, Stream0.Location.DataSize);
+ EXPECT_EQ(0x2cu, Stream0.Location.RVA);
+
+ EXPECT_EQ("CPUINFO", toStringRef(File.getRawStream(Stream0)));
+ EXPECT_EQ("CPUINFO",
+ toStringRef(*File.getRawStream(StreamType::LinuxCPUInfo)));
+
+ EXPECT_THAT_EXPECTED(File.getSystemInfo(), Failed<BinaryError>());
+}
+
+// Use the input from the previous test, but corrupt it in various ways
+TEST(MinidumpFile, create_ErrorCases) {
+ std::vector<uint8_t> FileTooShort{'M', 'D', 'M', 'P'};
+ EXPECT_THAT_EXPECTED(create(FileTooShort), Failed<BinaryError>());
+
+ std::vector<uint8_t> WrongSignature{
+ // Header
+ '!', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 3, 0, 0x67, 0x47, 7, 0, 0, 0, // Type, DataSize,
+ 0x2c, 0, 0, 0, // RVA
+ // Stream
+ 'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+ EXPECT_THAT_EXPECTED(create(WrongSignature), Failed<BinaryError>());
+
+ std::vector<uint8_t> WrongVersion{
+ // Header
+ 'M', 'D', 'M', 'P', 0x39, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 3, 0, 0x67, 0x47, 7, 0, 0, 0, // Type, DataSize,
+ 0x2c, 0, 0, 0, // RVA
+ // Stream
+ 'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+ EXPECT_THAT_EXPECTED(create(WrongVersion), Failed<BinaryError>());
+
+ std::vector<uint8_t> DirectoryAfterEOF{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 0x20, 1, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 3, 0, 0x67, 0x47, 7, 0, 0, 0, // Type, DataSize,
+ 0x2c, 0, 0, 0, // RVA
+ // Stream
+ 'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+ EXPECT_THAT_EXPECTED(create(DirectoryAfterEOF), Failed<BinaryError>());
+
+ std::vector<uint8_t> TruncatedDirectory{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 1, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 3, 0, 0x67, 0x47, 7, 0, 0, 0, // Type, DataSize,
+ 0x2c, 0, 0, 0, // RVA
+ // Stream
+ 'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+ EXPECT_THAT_EXPECTED(create(TruncatedDirectory), Failed<BinaryError>());
+
+ std::vector<uint8_t> Stream0AfterEOF{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 3, 0, 0x67, 0x47, 7, 0, 0, 0, // Type, DataSize,
+ 0x2c, 1, 0, 0, // RVA
+ // Stream
+ 'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+ EXPECT_THAT_EXPECTED(create(Stream0AfterEOF), Failed<BinaryError>());
+
+ std::vector<uint8_t> Stream0Truncated{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 3, 0, 0x67, 0x47, 8, 0, 0, 0, // Type, DataSize,
+ 0x2c, 0, 0, 0, // RVA
+ // Stream
+ 'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+ EXPECT_THAT_EXPECTED(create(Stream0Truncated), Failed<BinaryError>());
+
+ std::vector<uint8_t> DuplicateStream{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 2, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 3, 0, 0x67, 0x47, 7, 0, 0, 0, // Type, DataSize,
+ 0x40, 0, 0, 0, // RVA
+ // Stream
+ 3, 0, 0x67, 0x47, 7, 0, 0, 0, // Type, DataSize,
+ 0x40, 0, 0, 0, // RVA
+ // Stream
+ 'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+ EXPECT_THAT_EXPECTED(create(DuplicateStream), Failed<BinaryError>());
+
+ std::vector<uint8_t> DenseMapInfoConflict{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 0xff, 0xff, 0xff, 0xff, 7, 0, 0, 0, // Type, DataSize,
+ 0x2c, 0, 0, 0, // RVA
+ // Stream
+ 'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+ EXPECT_THAT_EXPECTED(create(DenseMapInfoConflict), Failed<BinaryError>());
+}
+
+TEST(MinidumpFile, IngoresDummyStreams) {
+ std::vector<uint8_t> TwoDummyStreams{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 2, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 0, 0, 0, 0, 0, 0, 0, 0, // Type, DataSize,
+ 0x20, 0, 0, 0, // RVA
+ 0, 0, 0, 0, 0, 0, 0, 0, // Type, DataSize,
+ 0x20, 0, 0, 0, // RVA
+ };
+ auto ExpectedFile = create(TwoDummyStreams);
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ const MinidumpFile &File = **ExpectedFile;
+ ASSERT_EQ(2u, File.streams().size());
+ EXPECT_EQ(StreamType::Unused, File.streams()[0].Type);
+ EXPECT_EQ(StreamType::Unused, File.streams()[1].Type);
+ EXPECT_EQ(None, File.getRawStream(StreamType::Unused));
+}
+
+TEST(MinidumpFile, getSystemInfo) {
+ std::vector<uint8_t> Data{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 7, 0, 0, 0, 56, 0, 0, 0, // Type, DataSize,
+ 0x2c, 0, 0, 0, // RVA
+ // SystemInfo
+ 0, 0, 1, 2, // ProcessorArch, ProcessorLevel
+ 3, 4, 5, 6, // ProcessorRevision, NumberOfProcessors, ProductType
+ 7, 8, 9, 0, 1, 2, 3, 4, // MajorVersion, MinorVersion
+ 5, 6, 7, 8, 2, 0, 0, 0, // BuildNumber, PlatformId
+ 1, 2, 3, 4, 5, 6, 7, 8, // CSDVersionRVA, SuiteMask, Reserved
+ 'L', 'L', 'V', 'M', 'L', 'L', 'V', 'M', 'L', 'L', 'V', 'M', // VendorID
+ 1, 2, 3, 4, 5, 6, 7, 8, // VersionInfo, FeatureInfo
+ 9, 0, 1, 2, // AMDExtendedFeatures
+ };
+ auto ExpectedFile = create(Data);
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ const MinidumpFile &File = **ExpectedFile;
+
+ auto ExpectedInfo = File.getSystemInfo();
+ ASSERT_THAT_EXPECTED(ExpectedInfo, Succeeded());
+ const SystemInfo &Info = *ExpectedInfo;
+ EXPECT_EQ(ProcessorArchitecture::X86, Info.ProcessorArch);
+ EXPECT_EQ(0x0201, Info.ProcessorLevel);
+ EXPECT_EQ(0x0403, Info.ProcessorRevision);
+ EXPECT_EQ(5, Info.NumberOfProcessors);
+ EXPECT_EQ(6, Info.ProductType);
+ EXPECT_EQ(0x00090807u, Info.MajorVersion);
+ EXPECT_EQ(0x04030201u, Info.MinorVersion);
+ EXPECT_EQ(0x08070605u, Info.BuildNumber);
+ EXPECT_EQ(OSPlatform::Win32NT, Info.PlatformId);
+ EXPECT_EQ(0x04030201u, Info.CSDVersionRVA);
+ EXPECT_EQ(0x0605u, Info.SuiteMask);
+ EXPECT_EQ(0x0807u, Info.Reserved);
+ EXPECT_EQ("LLVMLLVMLLVM", llvm::StringRef(Info.CPU.X86.VendorID,
+ sizeof(Info.CPU.X86.VendorID)));
+ EXPECT_EQ(0x04030201u, Info.CPU.X86.VersionInfo);
+ EXPECT_EQ(0x08070605u, Info.CPU.X86.FeatureInfo);
+ EXPECT_EQ(0x02010009u, Info.CPU.X86.AMDExtendedFeatures);
+}
+
+TEST(MinidumpFile, getString) {
+ std::vector<uint8_t> ManyStrings{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 2, 0, 0, 0, // NumberOfStreams,
+ 0x20, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 8, 9, 0, 1, 2, 3, 4, 5, // Flags
+ // Stream Directory
+ 0, 0, 0, 0, 0, 0, 0, 0, // Type, DataSize,
+ 0x20, 0, 0, 0, // RVA
+ 1, 0, 0, 0, 0, 0, // String1 - odd length
+ 0, 0, 1, 0, 0, 0, // String2 - too long
+ 2, 0, 0, 0, 0, 0xd8, // String3 - invalid utf16
+ 0, 0, 0, 0, 0, 0, // String4 - ""
+ 2, 0, 0, 0, 'a', 0, // String5 - "a"
+ 0, // Mis-align next string
+ 2, 0, 0, 0, 'a', 0, // String6 - "a"
+
+ };
+ auto ExpectedFile = create(ManyStrings);
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ const MinidumpFile &File = **ExpectedFile;
+ EXPECT_THAT_EXPECTED(File.getString(44), Failed<BinaryError>());
+ EXPECT_THAT_EXPECTED(File.getString(50), Failed<BinaryError>());
+ EXPECT_THAT_EXPECTED(File.getString(56), Failed<BinaryError>());
+ EXPECT_THAT_EXPECTED(File.getString(62), HasValue(""));
+ EXPECT_THAT_EXPECTED(File.getString(68), HasValue("a"));
+ EXPECT_THAT_EXPECTED(File.getString(75), HasValue("a"));
+
+ // Check the case when the size field does not fit into the remaining data.
+ EXPECT_THAT_EXPECTED(File.getString(ManyStrings.size() - 2),
+ Failed<BinaryError>());
+}
+
+TEST(MinidumpFile, getModuleList) {
+ std::vector<uint8_t> OneModule{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 32, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 0, 0, 0, 0, 0, 0, 0, 0, // Flags
+ // Stream Directory
+ 4, 0, 0, 0, 112, 0, 0, 0, // Type, DataSize,
+ 44, 0, 0, 0, // RVA
+ // ModuleList
+ 1, 0, 0, 0, // NumberOfModules
+ 1, 2, 3, 4, 5, 6, 7, 8, // BaseOfImage
+ 9, 0, 1, 2, 3, 4, 5, 6, // SizeOfImage, Checksum
+ 7, 8, 9, 0, 1, 2, 3, 4, // TimeDateStamp, ModuleNameRVA
+ 0, 0, 0, 0, 0, 0, 0, 0, // Signature, StructVersion
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileVersion
+ 0, 0, 0, 0, 0, 0, 0, 0, // ProductVersion
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileFlagsMask, FileFlags
+ 0, 0, 0, 0, // FileOS
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileType, FileSubType
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileDate
+ 1, 2, 3, 4, 5, 6, 7, 8, // CvRecord
+ 9, 0, 1, 2, 3, 4, 5, 6, // MiscRecord
+ 7, 8, 9, 0, 1, 2, 3, 4, // Reserved0
+ 5, 6, 7, 8, 9, 0, 1, 2, // Reserved1
+ };
+ // Same as before, but with a padded module list.
+ std::vector<uint8_t> PaddedModule{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 32, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 0, 0, 0, 0, 0, 0, 0, 0, // Flags
+ // Stream Directory
+ 4, 0, 0, 0, 116, 0, 0, 0, // Type, DataSize,
+ 44, 0, 0, 0, // RVA
+ // ModuleList
+ 1, 0, 0, 0, // NumberOfModules
+ 0, 0, 0, 0, // Padding
+ 1, 2, 3, 4, 5, 6, 7, 8, // BaseOfImage
+ 9, 0, 1, 2, 3, 4, 5, 6, // SizeOfImage, Checksum
+ 7, 8, 9, 0, 1, 2, 3, 4, // TimeDateStamp, ModuleNameRVA
+ 0, 0, 0, 0, 0, 0, 0, 0, // Signature, StructVersion
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileVersion
+ 0, 0, 0, 0, 0, 0, 0, 0, // ProductVersion
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileFlagsMask, FileFlags
+ 0, 0, 0, 0, // FileOS
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileType, FileSubType
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileDate
+ 1, 2, 3, 4, 5, 6, 7, 8, // CvRecord
+ 9, 0, 1, 2, 3, 4, 5, 6, // MiscRecord
+ 7, 8, 9, 0, 1, 2, 3, 4, // Reserved0
+ 5, 6, 7, 8, 9, 0, 1, 2, // Reserved1
+ };
+
+ for (ArrayRef<uint8_t> Data : {OneModule, PaddedModule}) {
+ auto ExpectedFile = create(Data);
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ const MinidumpFile &File = **ExpectedFile;
+ Expected<ArrayRef<Module>> ExpectedModule = File.getModuleList();
+ ASSERT_THAT_EXPECTED(ExpectedModule, Succeeded());
+ ASSERT_EQ(1u, ExpectedModule->size());
+ const Module &M = ExpectedModule.get()[0];
+ EXPECT_EQ(0x0807060504030201u, M.BaseOfImage);
+ EXPECT_EQ(0x02010009u, M.SizeOfImage);
+ EXPECT_EQ(0x06050403u, M.Checksum);
+ EXPECT_EQ(0x00090807u, M.TimeDateStamp);
+ EXPECT_EQ(0x04030201u, M.ModuleNameRVA);
+ EXPECT_EQ(0x04030201u, M.CvRecord.DataSize);
+ EXPECT_EQ(0x08070605u, M.CvRecord.RVA);
+ EXPECT_EQ(0x02010009u, M.MiscRecord.DataSize);
+ EXPECT_EQ(0x06050403u, M.MiscRecord.RVA);
+ EXPECT_EQ(0x0403020100090807u, M.Reserved0);
+ EXPECT_EQ(0x0201000908070605u, M.Reserved1);
+ }
+
+ std::vector<uint8_t> StreamTooShort{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 32, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 0, 0, 0, 0, 0, 0, 0, 0, // Flags
+ // Stream Directory
+ 4, 0, 0, 0, 111, 0, 0, 0, // Type, DataSize,
+ 44, 0, 0, 0, // RVA
+ // ModuleList
+ 1, 0, 0, 0, // NumberOfModules
+ 1, 2, 3, 4, 5, 6, 7, 8, // BaseOfImage
+ 9, 0, 1, 2, 3, 4, 5, 6, // SizeOfImage, Checksum
+ 7, 8, 9, 0, 1, 2, 3, 4, // TimeDateStamp, ModuleNameRVA
+ 0, 0, 0, 0, 0, 0, 0, 0, // Signature, StructVersion
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileVersion
+ 0, 0, 0, 0, 0, 0, 0, 0, // ProductVersion
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileFlagsMask, FileFlags
+ 0, 0, 0, 0, // FileOS
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileType, FileSubType
+ 0, 0, 0, 0, 0, 0, 0, 0, // FileDate
+ 1, 2, 3, 4, 5, 6, 7, 8, // CvRecord
+ 9, 0, 1, 2, 3, 4, 5, 6, // MiscRecord
+ 7, 8, 9, 0, 1, 2, 3, 4, // Reserved0
+ 5, 6, 7, 8, 9, 0, 1, 2, // Reserved1
+ };
+ auto ExpectedFile = create(StreamTooShort);
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ const MinidumpFile &File = **ExpectedFile;
+ EXPECT_THAT_EXPECTED(File.getModuleList(), Failed<BinaryError>());
+}
+
+TEST(MinidumpFile, getThreadList) {
+ std::vector<uint8_t> OneThread{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 32, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 0, 0, 0, 0, 0, 0, 0, 0, // Flags
+ // Stream Directory
+ 3, 0, 0, 0, 52, 0, 0, 0, // Type, DataSize,
+ 44, 0, 0, 0, // RVA
+ // ThreadList
+ 1, 0, 0, 0, // NumberOfThreads
+ 1, 2, 3, 4, 5, 6, 7, 8, // ThreadId, SuspendCount
+ 9, 0, 1, 2, 3, 4, 5, 6, // PriorityClass, Priority
+ 7, 8, 9, 0, 1, 2, 3, 4, // EnvironmentBlock
+ // Stack
+ 5, 6, 7, 8, 9, 0, 1, 2, // StartOfMemoryRange
+ 3, 4, 5, 6, 7, 8, 9, 0, // DataSize, RVA
+ // Context
+ 1, 2, 3, 4, 5, 6, 7, 8, // DataSize, RVA
+ };
+ // Same as before, but with a padded thread list.
+ std::vector<uint8_t> PaddedThread{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 32, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 0, 0, 0, 0, 0, 0, 0, 0, // Flags
+ // Stream Directory
+ 3, 0, 0, 0, 56, 0, 0, 0, // Type, DataSize,
+ 44, 0, 0, 0, // RVA
+ // ThreadList
+ 1, 0, 0, 0, // NumberOfThreads
+ 0, 0, 0, 0, // Padding
+ 1, 2, 3, 4, 5, 6, 7, 8, // ThreadId, SuspendCount
+ 9, 0, 1, 2, 3, 4, 5, 6, // PriorityClass, Priority
+ 7, 8, 9, 0, 1, 2, 3, 4, // EnvironmentBlock
+ // Stack
+ 5, 6, 7, 8, 9, 0, 1, 2, // StartOfMemoryRange
+ 3, 4, 5, 6, 7, 8, 9, 0, // DataSize, RVA
+ // Context
+ 1, 2, 3, 4, 5, 6, 7, 8, // DataSize, RVA
+ };
+
+ for (ArrayRef<uint8_t> Data : {OneThread, PaddedThread}) {
+ auto ExpectedFile = create(Data);
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ const MinidumpFile &File = **ExpectedFile;
+ Expected<ArrayRef<Thread>> ExpectedThread = File.getThreadList();
+ ASSERT_THAT_EXPECTED(ExpectedThread, Succeeded());
+ ASSERT_EQ(1u, ExpectedThread->size());
+ const Thread &T = ExpectedThread.get()[0];
+ EXPECT_EQ(0x04030201u, T.ThreadId);
+ EXPECT_EQ(0x08070605u, T.SuspendCount);
+ EXPECT_EQ(0x02010009u, T.PriorityClass);
+ EXPECT_EQ(0x06050403u, T.Priority);
+ EXPECT_EQ(0x0403020100090807u, T.EnvironmentBlock);
+ EXPECT_EQ(0x0201000908070605u, T.Stack.StartOfMemoryRange);
+ EXPECT_EQ(0x06050403u, T.Stack.Memory.DataSize);
+ EXPECT_EQ(0x00090807u, T.Stack.Memory.RVA);
+ EXPECT_EQ(0x04030201u, T.Context.DataSize);
+ EXPECT_EQ(0x08070605u, T.Context.RVA);
+ }
+}
+
+TEST(MinidumpFile, getMemoryList) {
+ std::vector<uint8_t> OneRange{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 32, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 0, 0, 0, 0, 0, 0, 0, 0, // Flags
+ // Stream Directory
+ 5, 0, 0, 0, 20, 0, 0, 0, // Type, DataSize,
+ 44, 0, 0, 0, // RVA
+ // MemoryDescriptor
+ 1, 0, 0, 0, // NumberOfMemoryRanges
+ 5, 6, 7, 8, 9, 0, 1, 2, // StartOfMemoryRange
+ 3, 4, 5, 6, 7, 8, 9, 0, // DataSize, RVA
+ };
+ // Same as before, but with a padded memory list.
+ std::vector<uint8_t> PaddedRange{
+ // Header
+ 'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+ 1, 0, 0, 0, // NumberOfStreams,
+ 32, 0, 0, 0, // StreamDirectoryRVA
+ 0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+ 0, 0, 0, 0, 0, 0, 0, 0, // Flags
+ // Stream Directory
+ 5, 0, 0, 0, 24, 0, 0, 0, // Type, DataSize,
+ 44, 0, 0, 0, // RVA
+ // MemoryDescriptor
+ 1, 0, 0, 0, // NumberOfMemoryRanges
+ 0, 0, 0, 0, // Padding
+ 5, 6, 7, 8, 9, 0, 1, 2, // StartOfMemoryRange
+ 3, 4, 5, 6, 7, 8, 9, 0, // DataSize, RVA
+ };
+
+ for (ArrayRef<uint8_t> Data : {OneRange, PaddedRange}) {
+ auto ExpectedFile = create(Data);
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ const MinidumpFile &File = **ExpectedFile;
+ Expected<ArrayRef<MemoryDescriptor>> ExpectedRanges = File.getMemoryList();
+ ASSERT_THAT_EXPECTED(ExpectedRanges, Succeeded());
+ ASSERT_EQ(1u, ExpectedRanges->size());
+ const MemoryDescriptor &MD = ExpectedRanges.get()[0];
+ EXPECT_EQ(0x0201000908070605u, MD.StartOfMemoryRange);
+ EXPECT_EQ(0x06050403u, MD.Memory.DataSize);
+ EXPECT_EQ(0x00090807u, MD.Memory.RVA);
+ }
+}
diff --git a/src/llvm-project/llvm/unittests/Object/SymbolSizeTest.cpp b/src/llvm-project/llvm/unittests/Object/SymbolSizeTest.cpp
index ad9c40b..41269a6 100644
--- a/src/llvm-project/llvm/unittests/Object/SymbolSizeTest.cpp
+++ b/src/llvm-project/llvm/unittests/Object/SymbolSizeTest.cpp
@@ -1,9 +1,8 @@
//===- SymbolSizeTest.cpp - Tests for SymbolSize.cpp ----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Object/SymbolicFileTest.cpp b/src/llvm-project/llvm/unittests/Object/SymbolicFileTest.cpp
index ec954e5..3fc5d54 100644
--- a/src/llvm-project/llvm/unittests/Object/SymbolicFileTest.cpp
+++ b/src/llvm-project/llvm/unittests/Object/SymbolicFileTest.cpp
@@ -1,9 +1,8 @@
//===- SymbolicFileTest.cpp - Tests for SymbolicFile.cpp ------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ObjectYAML/CMakeLists.txt b/src/llvm-project/llvm/unittests/ObjectYAML/CMakeLists.txt
index baed10b..7fcc974 100644
--- a/src/llvm-project/llvm/unittests/ObjectYAML/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/ObjectYAML/CMakeLists.txt
@@ -1,8 +1,11 @@
set(LLVM_LINK_COMPONENTS
+ Object
ObjectYAML
)
add_llvm_unittest(ObjectYAMLTests
+ MinidumpYAMLTest.cpp
YAMLTest.cpp
)
+target_link_libraries(ObjectYAMLTests PRIVATE LLVMTestingSupport)
diff --git a/src/llvm-project/llvm/unittests/ObjectYAML/MinidumpYAMLTest.cpp b/src/llvm-project/llvm/unittests/ObjectYAML/MinidumpYAMLTest.cpp
new file mode 100644
index 0000000..66d44e0
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ObjectYAML/MinidumpYAMLTest.cpp
@@ -0,0 +1,139 @@
+//===- MinidumpYAMLTest.cpp - Tests for Minidump<->YAML code --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/MinidumpYAML.h"
+#include "llvm/Object/Minidump.h"
+#include "llvm/ObjectYAML/ObjectYAML.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::minidump;
+
+static Expected<std::unique_ptr<object::MinidumpFile>>
+toBinary(SmallVectorImpl<char> &Storage, StringRef Yaml) {
+ Storage.clear();
+ raw_svector_ostream OS(Storage);
+ if (Error E = MinidumpYAML::writeAsBinary(Yaml, OS))
+ return std::move(E);
+
+ return object::MinidumpFile::create(MemoryBufferRef(OS.str(), "Binary"));
+}
+
+TEST(MinidumpYAML, Basic) {
+ SmallString<0> Storage;
+ auto ExpectedFile = toBinary(Storage, R"(
+--- !minidump
+Streams:
+ - Type: SystemInfo
+ Processor Arch: ARM64
+ Platform ID: Linux
+ CPU:
+ CPUID: 0x05060708
+ - Type: LinuxMaps
+ Text: |
+ 400d9000-400db000 r-xp 00000000 b3:04 227 /system/bin/app_process
+ 400db000-400dc000 r--p 00001000 b3:04 227 /system/bin/app_process
+
+ - Type: LinuxAuxv
+ Content: DEADBEEFBAADF00D)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ object::MinidumpFile &File = **ExpectedFile;
+
+ ASSERT_EQ(3u, File.streams().size());
+
+ EXPECT_EQ(StreamType::SystemInfo, File.streams()[0].Type);
+ auto ExpectedSysInfo = File.getSystemInfo();
+ ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());
+ const SystemInfo &SysInfo = *ExpectedSysInfo;
+ EXPECT_EQ(ProcessorArchitecture::ARM64, SysInfo.ProcessorArch);
+ EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);
+ EXPECT_EQ(0x05060708u, SysInfo.CPU.Arm.CPUID);
+
+ EXPECT_EQ(StreamType::LinuxMaps, File.streams()[1].Type);
+ EXPECT_EQ("400d9000-400db000 r-xp 00000000 b3:04 227 "
+ "/system/bin/app_process\n"
+ "400db000-400dc000 r--p 00001000 b3:04 227 "
+ "/system/bin/app_process\n",
+ toStringRef(*File.getRawStream(StreamType::LinuxMaps)));
+
+ EXPECT_EQ(StreamType::LinuxAuxv, File.streams()[2].Type);
+ EXPECT_EQ((ArrayRef<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D}),
+ File.getRawStream(StreamType::LinuxAuxv));
+}
+
+TEST(MinidumpYAML, RawContent) {
+ SmallString<0> Storage;
+ auto ExpectedFile = toBinary(Storage, R"(
+--- !minidump
+Streams:
+ - Type: LinuxAuxv
+ Size: 9
+ Content: DEADBEEFBAADF00D)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ object::MinidumpFile &File = **ExpectedFile;
+
+ EXPECT_EQ(
+ (ArrayRef<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D, 0x00}),
+ File.getRawStream(StreamType::LinuxAuxv));
+}
+
+TEST(MinidumpYAML, X86SystemInfo) {
+ SmallString<0> Storage;
+ auto ExpectedFile = toBinary(Storage, R"(
+--- !minidump
+Streams:
+ - Type: SystemInfo
+ Processor Arch: X86
+ Platform ID: Linux
+ CPU:
+ Vendor ID: LLVMLLVMLLVM
+ Version Info: 0x01020304
+ Feature Info: 0x05060708
+ AMD Extended Features: 0x09000102)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ object::MinidumpFile &File = **ExpectedFile;
+
+ ASSERT_EQ(1u, File.streams().size());
+
+ auto ExpectedSysInfo = File.getSystemInfo();
+ ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());
+ const SystemInfo &SysInfo = *ExpectedSysInfo;
+ EXPECT_EQ(ProcessorArchitecture::X86, SysInfo.ProcessorArch);
+ EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);
+ EXPECT_EQ("LLVMLLVMLLVM", StringRef(SysInfo.CPU.X86.VendorID,
+ sizeof(SysInfo.CPU.X86.VendorID)));
+ EXPECT_EQ(0x01020304u, SysInfo.CPU.X86.VersionInfo);
+ EXPECT_EQ(0x05060708u, SysInfo.CPU.X86.FeatureInfo);
+ EXPECT_EQ(0x09000102u, SysInfo.CPU.X86.AMDExtendedFeatures);
+}
+
+TEST(MinidumpYAML, OtherSystemInfo) {
+ SmallString<0> Storage;
+ auto ExpectedFile = toBinary(Storage, R"(
+--- !minidump
+Streams:
+ - Type: SystemInfo
+ Processor Arch: PPC
+ Platform ID: Linux
+ CPU:
+ Features: 000102030405060708090a0b0c0d0e0f)");
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+ object::MinidumpFile &File = **ExpectedFile;
+
+ ASSERT_EQ(1u, File.streams().size());
+
+ auto ExpectedSysInfo = File.getSystemInfo();
+ ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());
+ const SystemInfo &SysInfo = *ExpectedSysInfo;
+ EXPECT_EQ(ProcessorArchitecture::PPC, SysInfo.ProcessorArch);
+ EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);
+ EXPECT_EQ(
+ (ArrayRef<uint8_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}),
+ makeArrayRef(SysInfo.CPU.Other.ProcessorFeatures));
+}
diff --git a/src/llvm-project/llvm/unittests/ObjectYAML/YAMLTest.cpp b/src/llvm-project/llvm/unittests/ObjectYAML/YAMLTest.cpp
index 606e160..3d283a0 100644
--- a/src/llvm-project/llvm/unittests/ObjectYAML/YAMLTest.cpp
+++ b/src/llvm-project/llvm/unittests/ObjectYAML/YAMLTest.cpp
@@ -1,9 +1,8 @@
//===- YAMLTest.cpp - Tests for Object YAML -------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/OptRemarks/CMakeLists.txt b/src/llvm-project/llvm/unittests/OptRemarks/CMakeLists.txt
deleted file mode 100644
index 94c7486..0000000
--- a/src/llvm-project/llvm/unittests/OptRemarks/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- OptRemarks
- Support
- )
-
-add_llvm_unittest(OptRemarksTests
- OptRemarksParsingTest.cpp
- )
diff --git a/src/llvm-project/llvm/unittests/OptRemarks/OptRemarksParsingTest.cpp b/src/llvm-project/llvm/unittests/OptRemarks/OptRemarksParsingTest.cpp
deleted file mode 100644
index a3b28f0..0000000
--- a/src/llvm-project/llvm/unittests/OptRemarks/OptRemarksParsingTest.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-//===- unittest/Support/OptRemarksParsingTest.cpp - OptTable tests --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm-c/OptRemarks.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-template <size_t N> bool tryParse(const char (&Buf)[N]) {
- LLVMOptRemarkParserRef Parser = LLVMOptRemarkParserCreate(Buf, N - 1);
- LLVMOptRemarkEntry *Remark = nullptr;
- while (LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser)) {
- EXPECT_TRUE(Remark == nullptr); // Only one remark per test.
- Remark = NewRemark;
- }
- EXPECT_TRUE(Remark != nullptr); // We need *exactly* one remark per test.
- bool HasError = LLVMOptRemarkParserHasError(Parser);
- LLVMOptRemarkParserDispose(Parser);
- return !HasError;
-}
-
-template <size_t N>
-bool parseExpectError(const char (&Buf)[N], const char *Error) {
- LLVMOptRemarkParserRef Parser = LLVMOptRemarkParserCreate(Buf, N - 1);
- LLVMOptRemarkEntry *Remark = nullptr;
- while (LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser)) {
- EXPECT_FALSE(NewRemark);
- }
- EXPECT_TRUE(Remark == nullptr); // We are parsing only one malformed remark.
- EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser));
- bool MatchesError =
- StringRef(LLVMOptRemarkParserGetErrorMessage(Parser)).contains(Error);
- LLVMOptRemarkParserDispose(Parser);
-
- return MatchesError;
-}
-
-TEST(OptRemarks, OptRemarksParsingEmpty) {
- StringRef Buf = "\n"
- "\n";
- LLVMOptRemarkParserRef Parser =
- LLVMOptRemarkParserCreate(Buf.data(), Buf.size());
- LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser);
- EXPECT_TRUE(NewRemark == nullptr); // No remark expected.
- EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser));
- EXPECT_TRUE(StringRef(LLVMOptRemarkParserGetErrorMessage(Parser))
- .contains("document root is not of mapping type."));
- LLVMOptRemarkParserDispose(Parser);
-}
-
-TEST(OptRemarks, OptRemarksParsingGood) {
- EXPECT_TRUE(tryParse("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
-"Function: foo\n"
-"Args:\n"
-" - Callee: bar\n"
-" - String: ' will not be inlined into '\n"
-" - Caller: foo\n"
-" DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
-" - String: ' because its definition is unavailable'\n"
-""));
-
- // No debug loc should also pass.
- EXPECT_TRUE(tryParse("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-" - Callee: bar\n"
-" - String: ' will not be inlined into '\n"
-" - Caller: foo\n"
-" DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
-" - String: ' because its definition is unavailable'\n"
-""));
-
- // No args is also ok.
- EXPECT_TRUE(tryParse("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
-"Function: foo\n"
-""));
-
- // Different order.
- EXPECT_TRUE(tryParse("\n"
-"--- !Missed\n"
-"DebugLoc: { Line: 3, Column: 12, File: file.c }\n"
-"Function: foo\n"
-"Name: NoDefinition\n"
-"Args:\n"
-" - Callee: bar\n"
-" - String: ' will not be inlined into '\n"
-" - Caller: foo\n"
-" DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
-" - String: ' because its definition is unavailable'\n"
-"Pass: inline\n"
-""));
-}
-
-// Mandatory common part of a remark.
-#define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n"
-// Test all the types.
-TEST(OptRemarks, OptRemarksParsingTypes) {
- // Type: Passed
- EXPECT_TRUE(tryParse("--- !Passed" COMMON_REMARK));
- // Type: Missed
- EXPECT_TRUE(tryParse("--- !Missed" COMMON_REMARK));
- // Type: Analysis
- EXPECT_TRUE(tryParse("--- !Analysis" COMMON_REMARK));
- // Type: AnalysisFPCompute
- EXPECT_TRUE(tryParse("--- !AnalysisFPCompute" COMMON_REMARK));
- // Type: AnalysisAliasing
- EXPECT_TRUE(tryParse("--- !AnalysisAliasing" COMMON_REMARK));
- // Type: Failure
- EXPECT_TRUE(tryParse("--- !Failure" COMMON_REMARK));
-}
-#undef COMMON_REMARK
-
-TEST(OptRemarks, OptRemarksParsingMissingFields) {
- // No type.
- EXPECT_TRUE(parseExpectError("\n"
-"---\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"",
- "error: Type, Pass, Name or Function missing."));
- // No pass.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"",
- "error: Type, Pass, Name or Function missing."));
- // No name.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Function: foo\n"
-"",
- "error: Type, Pass, Name or Function missing."));
- // No function.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"",
- "error: Type, Pass, Name or Function missing."));
- // Debug loc but no file.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { Line: 3, Column: 12 }\n"
-"",
- "DebugLoc node incomplete."));
- // Debug loc but no line.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: 12 }\n"
-"",
- "DebugLoc node incomplete."));
- // Debug loc but no column.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Line: 3 }\n"
-"",
- "DebugLoc node incomplete."));
-}
-
-TEST(OptRemarks, OptRemarksParsingWrongTypes) {
- // Wrong debug loc type.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: foo\n"
-"",
- "expected a value of mapping type."));
- // Wrong line type.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Line: b, Column: 12 }\n"
-"",
- "expected a value of integer type."));
- // Wrong column type.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Line: 3, Column: c }\n"
-"",
- "expected a value of integer type."));
- // Wrong args type.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args: foo\n"
-"",
- "wrong value type for key."));
- // Wrong key type.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"{ A: a }: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"",
- "key is not a string."));
- // Debug loc with unknown entry.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n"
-"",
- "unknown entry in DebugLoc map."));
- // Unknown entry.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Unknown: inline\n"
-"",
- "unknown key."));
- // Not a scalar.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: { File: a, Line: 1, Column: 2 }\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"",
- "expected a value of scalar type."));
- // Not a string file in debug loc.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n"
-"",
- "expected a value of scalar type."));
- // Not a integer column in debug loc.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n"
-"",
- "expected a value of scalar type."));
- // Not a integer line in debug loc.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
-"",
- "expected a value of scalar type."));
- // Not a mapping type value for args.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
-"",
- "expected a value of scalar type."));
-}
-
-TEST(OptRemarks, OptRemarksParsingWrongArgs) {
- // Multiple debug locs per arg.
- EXPECT_TRUE(
- parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-" - Str: string\n"
-" DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-" DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-"",
- "only one DebugLoc entry is allowed per argument."));
- // Multiple strings per arg.
- EXPECT_TRUE(
- parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-" - Str: string\n"
-" Str2: string\n"
-" DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-"",
- "only one string entry is allowed per argument."));
- // No arg value.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-" - Callee: ''\n"
-" - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-"",
- "argument value is missing."));
- // No arg value.
- EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-" - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-"",
- "argument key is missing."));
-
-}
-
-TEST(OptRemarks, OptRemarksGoodStruct) {
- StringRef Buf = "\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
-"Function: foo\n"
-"Args:\n"
-" - Callee: bar\n"
-" - String: ' will not be inlined into '\n"
-" - Caller: foo\n"
-" DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
-" - String: ' because its definition is unavailable'\n"
-"\n";
-
- LLVMOptRemarkParserRef Parser =
- LLVMOptRemarkParserCreate(Buf.data(), Buf.size());
- LLVMOptRemarkEntry *Remark = LLVMOptRemarkParserGetNext(Parser);
- EXPECT_FALSE(Remark == nullptr);
- EXPECT_EQ(StringRef(Remark->RemarkType.Str, 7), "!Missed");
- EXPECT_EQ(Remark->RemarkType.Len, 7U);
- EXPECT_EQ(StringRef(Remark->PassName.Str, 6), "inline");
- EXPECT_EQ(Remark->PassName.Len, 6U);
- EXPECT_EQ(StringRef(Remark->RemarkName.Str, 12), "NoDefinition");
- EXPECT_EQ(Remark->RemarkName.Len, 12U);
- EXPECT_EQ(StringRef(Remark->FunctionName.Str, 3), "foo");
- EXPECT_EQ(Remark->FunctionName.Len, 3U);
- EXPECT_EQ(StringRef(Remark->DebugLoc.SourceFile.Str, 6), "file.c");
- EXPECT_EQ(Remark->DebugLoc.SourceFile.Len, 6U);
- EXPECT_EQ(Remark->DebugLoc.SourceLineNumber, 3U);
- EXPECT_EQ(Remark->DebugLoc.SourceColumnNumber, 12U);
- EXPECT_EQ(Remark->Hotness, 0U);
- EXPECT_EQ(Remark->NumArgs, 4U);
- // Arg 0
- {
- LLVMOptRemarkArg &Arg = Remark->Args[0];
- EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Callee");
- EXPECT_EQ(Arg.Key.Len, 6U);
- EXPECT_EQ(StringRef(Arg.Value.Str, 3), "bar");
- EXPECT_EQ(Arg.Value.Len, 3U);
- EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
- EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
- EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
- EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
- }
- // Arg 1
- {
- LLVMOptRemarkArg &Arg = Remark->Args[1];
- EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String");
- EXPECT_EQ(Arg.Key.Len, 6U);
- EXPECT_EQ(StringRef(Arg.Value.Str, 26), " will not be inlined into ");
- EXPECT_EQ(Arg.Value.Len, 26U);
- EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
- EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
- EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
- EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
- }
- // Arg 2
- {
- LLVMOptRemarkArg &Arg = Remark->Args[2];
- EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Caller");
- EXPECT_EQ(Arg.Key.Len, 6U);
- EXPECT_EQ(StringRef(Arg.Value.Str, 3), "foo");
- EXPECT_EQ(Arg.Value.Len, 3U);
- EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 6), "file.c");
- EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 6U);
- EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 2U);
- EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
- }
- // Arg 3
- {
- LLVMOptRemarkArg &Arg = Remark->Args[3];
- EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String");
- EXPECT_EQ(Arg.Key.Len, 6U);
- EXPECT_EQ(StringRef(Arg.Value.Str, 38),
- " because its definition is unavailable");
- EXPECT_EQ(Arg.Value.Len, 38U);
- EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
- EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
- EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
- EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
- }
-
- EXPECT_EQ(LLVMOptRemarkParserGetNext(Parser), nullptr);
-
- EXPECT_FALSE(LLVMOptRemarkParserHasError(Parser));
- LLVMOptRemarkParserDispose(Parser);
-}
diff --git a/src/llvm-project/llvm/unittests/Option/OptionParsingTest.cpp b/src/llvm-project/llvm/unittests/Option/OptionParsingTest.cpp
index 230049c..e1d7a47 100644
--- a/src/llvm-project/llvm/unittests/Option/OptionParsingTest.cpp
+++ b/src/llvm-project/llvm/unittests/Option/OptionParsingTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Support/OptionParsingTest.cpp - OptTable tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -287,6 +286,10 @@
EXPECT_EQ(Nearest, "-blorp");
EXPECT_EQ(1U, T.findNearest("--blorm", Nearest));
EXPECT_EQ(Nearest, "--blorp");
+ EXPECT_EQ(1U, T.findNearest("-blarg", Nearest));
+ EXPECT_EQ(Nearest, "-blarn");
+ EXPECT_EQ(1U, T.findNearest("--blarm", Nearest));
+ EXPECT_EQ(Nearest, "--blarn");
EXPECT_EQ(1U, T.findNearest("-fjormp", Nearest));
EXPECT_EQ(Nearest, "--fjormp");
@@ -295,6 +298,20 @@
EXPECT_EQ(1U, T.findNearest("/framb:foo", Nearest));
EXPECT_EQ(Nearest, "/cramb:foo");
+ // `--glormp` should have an editing distance > 0 from `--glormp=`.
+ EXPECT_GT(T.findNearest("--glorrmp", Nearest), 0U);
+ EXPECT_EQ(Nearest, "--glorrmp=");
+ EXPECT_EQ(0U, T.findNearest("--glorrmp=foo", Nearest));
+
+ // `--blurmps` should correct to `--blurmp`, not `--blurmp=`, even though
+ // both naively have an editing distance of 1.
+ EXPECT_EQ(1U, T.findNearest("--blurmps", Nearest));
+ EXPECT_EQ(Nearest, "--blurmp");
+
+ // ...but `--blurmps=foo` should correct to `--blurmp=foo`.
+ EXPECT_EQ(1U, T.findNearest("--blurmps=foo", Nearest));
+ EXPECT_EQ(Nearest, "--blurmp=foo");
+
// Flags should be included and excluded as specified.
EXPECT_EQ(1U, T.findNearest("-doopf", Nearest, /*FlagsToInclude=*/OptFlag2));
EXPECT_EQ(Nearest, "-doopf2");
diff --git a/src/llvm-project/llvm/unittests/Option/Opts.td b/src/llvm-project/llvm/unittests/Option/Opts.td
index c4544b5..70920a6 100644
--- a/src/llvm-project/llvm/unittests/Option/Opts.td
+++ b/src/llvm-project/llvm/unittests/Option/Opts.td
@@ -30,9 +30,16 @@
def SlurpJoined : Option<["-"], "slurpjoined", KIND_REMAINING_ARGS_JOINED>;
def Blorp : Flag<["-", "--"], "blorp">, HelpText<"The blorp option">, Flags<[OptFlag1]>;
+def Blarn : Flag<["--", "-"], "blarn">, HelpText<"The blarn option">, Flags<[OptFlag1]>;
def Cramb : Joined<["/"], "cramb:">, HelpText<"The cramb option">, MetaVarName<"CRAMB">, Flags<[OptFlag1]>;
def Doopf1 : Flag<["-"], "doopf1">, HelpText<"The doopf1 option">, Flags<[OptFlag1]>;
def Doopf2 : Flag<["-"], "doopf2">, HelpText<"The doopf2 option">, Flags<[OptFlag2]>;
def Ermgh : Joined<["--"], "ermgh">, HelpText<"The ermgh option">, MetaVarName<"ERMGH">, Flags<[OptFlag1]>;
def Fjormp : Flag<["--"], "fjormp">, HelpText<"The fjormp option">, Flags<[OptFlag1]>;
+
+def Glorrmp_eq : Flag<["--"], "glorrmp=">;
+
+def Blurmpq : Flag<["--"], "blurmp">;
+def Blurmpq_eq : Flag<["--"], "blurmp=">;
+
def DashDash : Option<["--"], "", KIND_REMAINING_ARGS>;
diff --git a/src/llvm-project/llvm/unittests/Passes/PluginsTest.cpp b/src/llvm-project/llvm/unittests/Passes/PluginsTest.cpp
index abb7b57..dd889e6 100644
--- a/src/llvm-project/llvm/unittests/Passes/PluginsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Passes/PluginsTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Passes/Plugins/PluginsTest.cpp ---------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Passes/TestPlugin.cpp b/src/llvm-project/llvm/unittests/Passes/TestPlugin.cpp
index 3dc5cdc..e0ae861 100644
--- a/src/llvm-project/llvm/unittests/Passes/TestPlugin.cpp
+++ b/src/llvm-project/llvm/unittests/Passes/TestPlugin.cpp
@@ -1,9 +1,8 @@
//===- unittests/Passes/Plugins/Plugin.cpp --------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp b/src/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp
index 987f676..6b94fa1 100644
--- a/src/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp
+++ b/src/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/ProfileData/CoverageMappingTest.cpp -------------------------=//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/ProfileData/InstrProfTest.cpp b/src/llvm-project/llvm/unittests/ProfileData/InstrProfTest.cpp
index 2d915d4..b1e5159 100644
--- a/src/llvm-project/llvm/unittests/ProfileData/InstrProfTest.cpp
+++ b/src/llvm-project/llvm/unittests/ProfileData/InstrProfTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/ProfileData/InstrProfTest.cpp -------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -176,7 +175,7 @@
ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
};
- ProfileSummary &PS = Reader->getSummary();
+ ProfileSummary &PS = Reader->getSummary(/* IsCS */ false);
VerifySummary(PS);
// Test that conversion of summary to and from Metadata works.
@@ -190,8 +189,8 @@
// Test that summary can be attached to and read back from module.
Module M("my_module", Context);
- M.setProfileSummary(MD);
- MD = M.getProfileSummary();
+ M.setProfileSummary(MD, ProfileSummary::PSK_Instr);
+ MD = M.getProfileSummary(/* IsCS */ false);
ASSERT_TRUE(MD);
PSFromMD = ProfileSummary::getFromMD(MD);
ASSERT_TRUE(PSFromMD);
@@ -802,7 +801,7 @@
auto Profile = Writer.writeBuffer();
readProfile(std::move(Profile));
- ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
+ ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount(/* IsCS */ false));
}
TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
@@ -1045,4 +1044,25 @@
INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest,
::testing::Bool(),);
+#if defined(_LP64) && defined(EXPENSIVE_CHECKS)
+TEST(ProfileReaderTest, ReadsLargeFiles) {
+ const size_t LargeSize = 1ULL << 32; // 4GB
+
+ auto RawProfile = WritableMemoryBuffer::getNewUninitMemBuffer(LargeSize);
+ if (!RawProfile)
+ return;
+ auto RawProfileReaderOrErr = InstrProfReader::create(std::move(RawProfile));
+ ASSERT_TRUE(InstrProfError::take(RawProfileReaderOrErr.takeError()) ==
+ instrprof_error::unrecognized_format);
+
+ auto IndexedProfile = WritableMemoryBuffer::getNewUninitMemBuffer(LargeSize);
+ if (!IndexedProfile)
+ return;
+ auto IndexedReaderOrErr =
+ IndexedInstrProfReader::create(std::move(IndexedProfile), nullptr);
+ ASSERT_TRUE(InstrProfError::take(IndexedReaderOrErr.takeError()) ==
+ instrprof_error::bad_magic);
+}
+#endif
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ProfileData/SampleProfTest.cpp b/src/llvm-project/llvm/unittests/ProfileData/SampleProfTest.cpp
index f75f10b..a9a8b11 100644
--- a/src/llvm-project/llvm/unittests/ProfileData/SampleProfTest.cpp
+++ b/src/llvm-project/llvm/unittests/ProfileData/SampleProfTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/ProfileData/SampleProfTest.cpp ------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -192,14 +191,86 @@
delete PS;
// Test that summary can be attached to and read back from module.
- M.setProfileSummary(MD);
- MD = M.getProfileSummary();
+ M.setProfileSummary(MD, ProfileSummary::PSK_Sample);
+ MD = M.getProfileSummary(/* IsCS */ false);
ASSERT_TRUE(MD);
PS = ProfileSummary::getFromMD(MD);
ASSERT_TRUE(PS);
VerifySummary(*PS);
delete PS;
}
+
+ void addFunctionSamples(StringMap<FunctionSamples> *Smap, const char *Fname,
+ uint64_t TotalSamples, uint64_t HeadSamples) {
+ StringRef Name(Fname);
+ FunctionSamples FcnSamples;
+ FcnSamples.setName(Name);
+ FcnSamples.addTotalSamples(TotalSamples);
+ FcnSamples.addHeadSamples(HeadSamples);
+ FcnSamples.addBodySamples(1, 0, HeadSamples);
+ (*Smap)[Name] = FcnSamples;
+ }
+
+ StringMap<FunctionSamples> setupFcnSamplesForElisionTest(StringRef Policy) {
+ StringMap<FunctionSamples> Smap;
+ addFunctionSamples(&Smap, "foo", uint64_t(20301), uint64_t(1437));
+ if (Policy == "" || Policy == "all")
+ return Smap;
+ addFunctionSamples(&Smap, "foo.bar", uint64_t(20303), uint64_t(1439));
+ if (Policy == "selected")
+ return Smap;
+ addFunctionSamples(&Smap, "foo.llvm.2465", uint64_t(20305), uint64_t(1441));
+ return Smap;
+ }
+
+ void createFunctionWithSampleProfileElisionPolicy(Module *M,
+ const char *Fname,
+ StringRef Policy) {
+ FunctionType *FnType =
+ FunctionType::get(Type::getVoidTy(Context), {}, false);
+ auto Inserted = M->getOrInsertFunction(Fname, FnType);
+ auto Fcn = cast<Function>(Inserted.getCallee());
+ if (Policy != "")
+ Fcn->addFnAttr("sample-profile-suffix-elision-policy", Policy);
+ }
+
+ void setupModuleForElisionTest(Module *M, StringRef Policy) {
+ createFunctionWithSampleProfileElisionPolicy(M, "foo", Policy);
+ createFunctionWithSampleProfileElisionPolicy(M, "foo.bar", Policy);
+ createFunctionWithSampleProfileElisionPolicy(M, "foo.llvm.2465", Policy);
+ }
+
+ void testSuffixElisionPolicy(SampleProfileFormat Format, StringRef Policy,
+ const StringMap<uint64_t> &Expected) {
+ SmallVector<char, 128> ProfilePath;
+ std::error_code EC;
+ EC = llvm::sys::fs::createTemporaryFile("profile", "", ProfilePath);
+ ASSERT_TRUE(NoError(EC));
+ StringRef ProfileFile(ProfilePath.data(), ProfilePath.size());
+
+ Module M("my_module", Context);
+ setupModuleForElisionTest(&M, Policy);
+ StringMap<FunctionSamples> ProfMap = setupFcnSamplesForElisionTest(Policy);
+
+ // write profile
+ createWriter(Format, ProfileFile);
+ EC = Writer->write(ProfMap);
+ ASSERT_TRUE(NoError(EC));
+ Writer->getOutputStream().flush();
+
+ // read profile
+ readProfile(M, ProfileFile);
+ EC = Reader->read();
+ ASSERT_TRUE(NoError(EC));
+
+ for (auto I = Expected.begin(); I != Expected.end(); ++I) {
+ uint64_t Esamples = uint64_t(-1);
+ FunctionSamples *Samples = Reader->getSamplesFor(I->getKey());
+ if (Samples != nullptr)
+ Esamples = Samples->getTotalSamples();
+ ASSERT_EQ(I->getValue(), Esamples);
+ }
+ }
};
TEST_F(SampleProfTest, roundtrip_text_profile) {
@@ -252,4 +323,77 @@
ASSERT_EQ(BodySamples.get(), Max);
}
+TEST_F(SampleProfTest, default_suffix_elision_text) {
+ // Default suffix elision policy: strip everything after first dot.
+ // This implies that all suffix variants will map to "foo", so
+ // we don't expect to see any entries for them in the sample
+ // profile.
+ StringMap<uint64_t> Expected;
+ Expected["foo"] = uint64_t(20301);
+ Expected["foo.bar"] = uint64_t(-1);
+ Expected["foo.llvm.2465"] = uint64_t(-1);
+ testSuffixElisionPolicy(SampleProfileFormat::SPF_Text, "", Expected);
+}
+
+TEST_F(SampleProfTest, default_suffix_elision_compact_binary) {
+ // Default suffix elision policy: strip everything after first dot.
+ // This implies that all suffix variants will map to "foo", so
+ // we don't expect to see any entries for them in the sample
+ // profile.
+ StringMap<uint64_t> Expected;
+ Expected["foo"] = uint64_t(20301);
+ Expected["foo.bar"] = uint64_t(-1);
+ Expected["foo.llvm.2465"] = uint64_t(-1);
+ testSuffixElisionPolicy(SampleProfileFormat::SPF_Compact_Binary, "",
+ Expected);
+}
+
+TEST_F(SampleProfTest, selected_suffix_elision_text) {
+ // Profile is created and searched using the "selected"
+ // suffix elision policy: we only strip a .XXX suffix if
+ // it matches a pattern known to be generated by the compiler
+ // (e.g. ".llvm.<digits>").
+ StringMap<uint64_t> Expected;
+ Expected["foo"] = uint64_t(20301);
+ Expected["foo.bar"] = uint64_t(20303);
+ Expected["foo.llvm.2465"] = uint64_t(-1);
+ testSuffixElisionPolicy(SampleProfileFormat::SPF_Text, "selected", Expected);
+}
+
+TEST_F(SampleProfTest, selected_suffix_elision_compact_binary) {
+ // Profile is created and searched using the "selected"
+ // suffix elision policy: we only strip a .XXX suffix if
+ // it matches a pattern known to be generated by the compiler
+ // (e.g. ".llvm.<digits>").
+ StringMap<uint64_t> Expected;
+ Expected["foo"] = uint64_t(20301);
+ Expected["foo.bar"] = uint64_t(20303);
+ Expected["foo.llvm.2465"] = uint64_t(-1);
+ testSuffixElisionPolicy(SampleProfileFormat::SPF_Compact_Binary, "selected",
+ Expected);
+}
+
+TEST_F(SampleProfTest, none_suffix_elision_text) {
+ // Profile is created and searched using the "none"
+ // suffix elision policy: no stripping of suffixes at all.
+ // Here we expect to see all variants in the profile.
+ StringMap<uint64_t> Expected;
+ Expected["foo"] = uint64_t(20301);
+ Expected["foo.bar"] = uint64_t(20303);
+ Expected["foo.llvm.2465"] = uint64_t(20305);
+ testSuffixElisionPolicy(SampleProfileFormat::SPF_Text, "none", Expected);
+}
+
+TEST_F(SampleProfTest, none_suffix_elision_compact_binary) {
+ // Profile is created and searched using the "none"
+ // suffix elision policy: no stripping of suffixes at all.
+ // Here we expect to see all variants in the profile.
+ StringMap<uint64_t> Expected;
+ Expected["foo"] = uint64_t(20301);
+ Expected["foo.bar"] = uint64_t(20303);
+ Expected["foo.llvm.2465"] = uint64_t(20305);
+ testSuffixElisionPolicy(SampleProfileFormat::SPF_Compact_Binary, "none",
+ Expected);
+}
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Remarks/CMakeLists.txt b/src/llvm-project/llvm/unittests/Remarks/CMakeLists.txt
new file mode 100644
index 0000000..d74960e
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Remarks/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_LINK_COMPONENTS
+ Remarks
+ Support
+ )
+
+add_llvm_unittest(RemarksTests
+ RemarksStrTabParsingTest.cpp
+ YAMLRemarksParsingTest.cpp
+ )
diff --git a/src/llvm-project/llvm/unittests/Remarks/RemarksStrTabParsingTest.cpp b/src/llvm-project/llvm/unittests/Remarks/RemarksStrTabParsingTest.cpp
new file mode 100644
index 0000000..f1e9eb8
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Remarks/RemarksStrTabParsingTest.cpp
@@ -0,0 +1,39 @@
+//===- unittest/Support/RemarksStrTabParsingTest.cpp - StrTab tests -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Remarks/Remark.h"
+#include "llvm/Remarks/RemarkParser.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(RemarksStrTab, ParsingEmpty) {
+ StringRef Empty("", 0);
+ remarks::ParsedStringTable StrTab(Empty);
+ Expected<StringRef> Nothing = StrTab[0];
+ EXPECT_FALSE(static_cast<bool>(Nothing));
+ EXPECT_EQ(toString(Nothing.takeError()),
+ "String with index 0 is out of bounds (size = 0).");
+}
+
+TEST(RemarksStrTab, ParsingGood) {
+ StringRef Strings("str1\0str2\0str3\0str4", 20);
+ remarks::ParsedStringTable StrTab(Strings);
+ Expected<StringRef> Result = StrTab[0];
+ EXPECT_TRUE(static_cast<bool>(Result));
+ EXPECT_EQ(*Result, "str1");
+ Result = StrTab[1];
+ EXPECT_TRUE(static_cast<bool>(Result));
+ EXPECT_EQ(*Result, "str2");
+ Result = StrTab[2];
+ EXPECT_TRUE(static_cast<bool>(Result));
+ EXPECT_EQ(*Result, "str3");
+ Result = StrTab[3];
+ EXPECT_TRUE(static_cast<bool>(Result));
+ EXPECT_EQ(*Result, "str4");
+}
diff --git a/src/llvm-project/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp b/src/llvm-project/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp
new file mode 100644
index 0000000..8b79dfd
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp
@@ -0,0 +1,619 @@
+//===- unittest/Support/YAMLRemarksParsingTest.cpp - OptTable tests -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/Remarks.h"
+#include "llvm/Remarks/Remark.h"
+#include "llvm/Remarks/RemarkParser.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+template <size_t N> void parseGood(const char (&Buf)[N]) {
+ Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+ remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});
+ EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+ EXPECT_TRUE(*MaybeParser != nullptr);
+
+ remarks::Parser &Parser = **MaybeParser;
+ Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();
+ EXPECT_FALSE(errorToBool(Remark.takeError())); // Check for parsing errors.
+ EXPECT_TRUE(*Remark != nullptr); // At least one remark.
+ Remark = Parser.next();
+ Error E = Remark.takeError();
+ EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
+ EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
+}
+
+template <size_t N>
+bool parseExpectError(const char (&Buf)[N], const char *Error) {
+ Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+ remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});
+ EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+ EXPECT_TRUE(*MaybeParser != nullptr);
+
+ remarks::Parser &Parser = **MaybeParser;
+ Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();
+ EXPECT_FALSE(Remark); // Check for parsing errors.
+
+ std::string ErrorStr;
+ raw_string_ostream Stream(ErrorStr);
+ handleAllErrors(Remark.takeError(),
+ [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });
+ return StringRef(Stream.str()).contains(Error);
+}
+
+TEST(YAMLRemarks, ParsingEmpty) {
+ EXPECT_TRUE(parseExpectError("\n\n", "document root is not of mapping type."));
+}
+
+TEST(YAMLRemarks, ParsingNotYAML) {
+ EXPECT_TRUE(
+ parseExpectError("\x01\x02\x03\x04\x05\x06", "Got empty plain scalar"));
+}
+
+TEST(YAMLRemarks, ParsingGood) {
+ parseGood("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
+ "Function: foo\n"
+ "Args:\n"
+ " - Callee: bar\n"
+ " - String: ' will not be inlined into '\n"
+ " - Caller: foo\n"
+ " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+ " - String: ' because its definition is unavailable'\n"
+ "");
+
+ // No debug loc should also pass.
+ parseGood("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "Args:\n"
+ " - Callee: bar\n"
+ " - String: ' will not be inlined into '\n"
+ " - Caller: foo\n"
+ " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+ " - String: ' because its definition is unavailable'\n"
+ "");
+
+ // No args is also ok.
+ parseGood("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
+ "Function: foo\n"
+ "");
+
+ // Different order.
+ parseGood("\n"
+ "--- !Missed\n"
+ "DebugLoc: { Line: 3, Column: 12, File: file.c }\n"
+ "Function: foo\n"
+ "Name: NoDefinition\n"
+ "Args:\n"
+ " - Callee: bar\n"
+ " - String: ' will not be inlined into '\n"
+ " - Caller: foo\n"
+ " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+ " - String: ' because its definition is unavailable'\n"
+ "Pass: inline\n"
+ "");
+}
+
+// Mandatory common part of a remark.
+#define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n"
+// Test all the types.
+TEST(YAMLRemarks, ParsingTypes) {
+ // Type: Passed
+ parseGood("--- !Passed" COMMON_REMARK);
+ // Type: Missed
+ parseGood("--- !Missed" COMMON_REMARK);
+ // Type: Analysis
+ parseGood("--- !Analysis" COMMON_REMARK);
+ // Type: AnalysisFPCommute
+ parseGood("--- !AnalysisFPCommute" COMMON_REMARK);
+ // Type: AnalysisAliasing
+ parseGood("--- !AnalysisAliasing" COMMON_REMARK);
+ // Type: Failure
+ parseGood("--- !Failure" COMMON_REMARK);
+}
+#undef COMMON_REMARK
+
+TEST(YAMLRemarks, ParsingMissingFields) {
+ // No type.
+ EXPECT_TRUE(parseExpectError("\n"
+ "---\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "",
+ "expected a remark tag."));
+ // No pass.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "",
+ "Type, Pass, Name or Function missing."));
+ // No name.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Function: foo\n"
+ "",
+ "Type, Pass, Name or Function missing."));
+ // No function.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "",
+ "Type, Pass, Name or Function missing."));
+ // Debug loc but no file.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { Line: 3, Column: 12 }\n"
+ "",
+ "DebugLoc node incomplete."));
+ // Debug loc but no line.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { File: file.c, Column: 12 }\n"
+ "",
+ "DebugLoc node incomplete."));
+ // Debug loc but no column.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { File: file.c, Line: 3 }\n"
+ "",
+ "DebugLoc node incomplete."));
+}
+
+TEST(YAMLRemarks, ParsingWrongTypes) {
+ // Wrong debug loc type.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: foo\n"
+ "",
+ "expected a value of mapping type."));
+ // Wrong line type.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { File: file.c, Line: b, Column: 12 }\n"
+ "",
+ "expected a value of integer type."));
+ // Wrong column type.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { File: file.c, Line: 3, Column: c }\n"
+ "",
+ "expected a value of integer type."));
+ // Wrong args type.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "Args: foo\n"
+ "",
+ "wrong value type for key."));
+ // Wrong key type.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "{ A: a }: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "",
+ "key is not a string."));
+ // Debug loc with unknown entry.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n"
+ "",
+ "unknown entry in DebugLoc map."));
+ // Unknown entry.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Unknown: inline\n"
+ "",
+ "unknown key."));
+ // Not a scalar.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: { File: a, Line: 1, Column: 2 }\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "",
+ "expected a value of scalar type."));
+ // Not a string file in debug loc.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n"
+ "",
+ "expected a value of scalar type."));
+ // Not a integer column in debug loc.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n"
+ "",
+ "expected a value of scalar type."));
+ // Not a integer line in debug loc.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
+ "",
+ "expected a value of scalar type."));
+ // Not a mapping type value for args.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
+ "",
+ "expected a value of scalar type."));
+}
+
+TEST(YAMLRemarks, ParsingWrongArgs) {
+ // Multiple debug locs per arg.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "Args:\n"
+ " - Str: string\n"
+ " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
+ " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
+ "",
+ "only one DebugLoc entry is allowed per argument."));
+ // Multiple strings per arg.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "Args:\n"
+ " - Str: string\n"
+ " Str2: string\n"
+ " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
+ "",
+ "only one string entry is allowed per argument."));
+ // No arg value.
+ EXPECT_TRUE(parseExpectError("\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "Function: foo\n"
+ "Args:\n"
+ " - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
+ "",
+ "argument key is missing."));
+}
+
+static inline StringRef checkStr(StringRef Str, unsigned ExpectedLen) {
+ const char *StrData = Str.data();
+ unsigned StrLen = Str.size();
+ EXPECT_EQ(StrLen, ExpectedLen);
+ return StringRef(StrData, StrLen);
+}
+
+TEST(YAMLRemarks, Contents) {
+ StringRef Buf = "\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
+ "Function: foo\n"
+ "Hotness: 4\n"
+ "Args:\n"
+ " - Callee: bar\n"
+ " - String: ' will not be inlined into '\n"
+ " - Caller: foo\n"
+ " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+ " - String: ' because its definition is unavailable'\n"
+ "\n";
+
+ Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+ remarks::createRemarkParser(remarks::Format::YAML, Buf);
+ EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+ EXPECT_TRUE(*MaybeParser != nullptr);
+
+ remarks::Parser &Parser = **MaybeParser;
+ Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
+ EXPECT_FALSE(
+ errorToBool(MaybeRemark.takeError())); // Check for parsing errors.
+ EXPECT_TRUE(*MaybeRemark != nullptr); // At least one remark.
+
+ const remarks::Remark &Remark = **MaybeRemark;
+ EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed);
+ EXPECT_EQ(checkStr(Remark.PassName, 6), "inline");
+ EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition");
+ EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo");
+ EXPECT_TRUE(Remark.Loc);
+ const remarks::RemarkLocation &RL = *Remark.Loc;
+ EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
+ EXPECT_EQ(RL.SourceLine, 3U);
+ EXPECT_EQ(RL.SourceColumn, 12U);
+ EXPECT_TRUE(Remark.Hotness);
+ EXPECT_EQ(*Remark.Hotness, 4U);
+ EXPECT_EQ(Remark.Args.size(), 4U);
+
+ unsigned ArgID = 0;
+ for (const remarks::Argument &Arg : Remark.Args) {
+ switch (ArgID) {
+ case 0:
+ EXPECT_EQ(checkStr(Arg.Key, 6), "Callee");
+ EXPECT_EQ(checkStr(Arg.Val, 3), "bar");
+ EXPECT_FALSE(Arg.Loc);
+ break;
+ case 1:
+ EXPECT_EQ(checkStr(Arg.Key, 6), "String");
+ EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into ");
+ EXPECT_FALSE(Arg.Loc);
+ break;
+ case 2: {
+ EXPECT_EQ(checkStr(Arg.Key, 6), "Caller");
+ EXPECT_EQ(checkStr(Arg.Val, 3), "foo");
+ EXPECT_TRUE(Arg.Loc);
+ const remarks::RemarkLocation &RL = *Arg.Loc;
+ EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
+ EXPECT_EQ(RL.SourceLine, 2U);
+ EXPECT_EQ(RL.SourceColumn, 0U);
+ break;
+ }
+ case 3:
+ EXPECT_EQ(checkStr(Arg.Key, 6), "String");
+ EXPECT_EQ(checkStr(Arg.Val, 38),
+ " because its definition is unavailable");
+ EXPECT_FALSE(Arg.Loc);
+ break;
+ default:
+ break;
+ }
+ ++ArgID;
+ }
+
+ MaybeRemark = Parser.next();
+ Error E = MaybeRemark.takeError();
+ EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
+ EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
+}
+
+static inline StringRef checkStr(LLVMRemarkStringRef Str,
+ unsigned ExpectedLen) {
+ const char *StrData = LLVMRemarkStringGetData(Str);
+ unsigned StrLen = LLVMRemarkStringGetLen(Str);
+ EXPECT_EQ(StrLen, ExpectedLen);
+ return StringRef(StrData, StrLen);
+}
+
+TEST(YAMLRemarks, ContentsCAPI) {
+ StringRef Buf = "\n"
+ "--- !Missed\n"
+ "Pass: inline\n"
+ "Name: NoDefinition\n"
+ "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
+ "Function: foo\n"
+ "Args:\n"
+ " - Callee: bar\n"
+ " - String: ' will not be inlined into '\n"
+ " - Caller: foo\n"
+ " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+ " - String: ' because its definition is unavailable'\n"
+ "\n";
+
+ LLVMRemarkParserRef Parser =
+ LLVMRemarkParserCreateYAML(Buf.data(), Buf.size());
+ LLVMRemarkEntryRef Remark = LLVMRemarkParserGetNext(Parser);
+ EXPECT_FALSE(Remark == nullptr);
+ EXPECT_EQ(LLVMRemarkEntryGetType(Remark), LLVMRemarkTypeMissed);
+ EXPECT_EQ(checkStr(LLVMRemarkEntryGetPassName(Remark), 6), "inline");
+ EXPECT_EQ(checkStr(LLVMRemarkEntryGetRemarkName(Remark), 12), "NoDefinition");
+ EXPECT_EQ(checkStr(LLVMRemarkEntryGetFunctionName(Remark), 3), "foo");
+ LLVMRemarkDebugLocRef DL = LLVMRemarkEntryGetDebugLoc(Remark);
+ EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");
+ EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 3U);
+ EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 12U);
+ EXPECT_EQ(LLVMRemarkEntryGetHotness(Remark), 0U);
+ EXPECT_EQ(LLVMRemarkEntryGetNumArgs(Remark), 4U);
+
+ unsigned ArgID = 0;
+ LLVMRemarkArgRef Arg = LLVMRemarkEntryGetFirstArg(Remark);
+ do {
+ switch (ArgID) {
+ case 0:
+ EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Callee");
+ EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "bar");
+ EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
+ break;
+ case 1:
+ EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");
+ EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 26),
+ " will not be inlined into ");
+ EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
+ break;
+ case 2: {
+ EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Caller");
+ EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "foo");
+ LLVMRemarkDebugLocRef DL = LLVMRemarkArgGetDebugLoc(Arg);
+ EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");
+ EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 2U);
+ EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 0U);
+ break;
+ }
+ case 3:
+ EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");
+ EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 38),
+ " because its definition is unavailable");
+ EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
+ break;
+ default:
+ break;
+ }
+ ++ArgID;
+ } while ((Arg = LLVMRemarkEntryGetNextArg(Arg, Remark)));
+
+ LLVMRemarkEntryDispose(Remark);
+
+ EXPECT_EQ(LLVMRemarkParserGetNext(Parser), nullptr);
+
+ EXPECT_FALSE(LLVMRemarkParserHasError(Parser));
+ LLVMRemarkParserDispose(Parser);
+}
+
+TEST(YAMLRemarks, ContentsStrTab) {
+ StringRef Buf = "\n"
+ "--- !Missed\n"
+ "Pass: 0\n"
+ "Name: 1\n"
+ "DebugLoc: { File: 2, Line: 3, Column: 12 }\n"
+ "Function: 3\n"
+ "Hotness: 4\n"
+ "Args:\n"
+ " - Callee: 5\n"
+ " - String: 7\n"
+ " - Caller: 3\n"
+ " DebugLoc: { File: 2, Line: 2, Column: 0 }\n"
+ " - String: 8\n"
+ "\n";
+
+ StringRef StrTabBuf =
+ StringRef("inline\0NoDefinition\0file.c\0foo\0Callee\0bar\0String\0 "
+ "will not be inlined into \0 because its definition is "
+ "unavailable",
+ 115);
+
+ remarks::ParsedStringTable StrTab(StrTabBuf);
+ Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+ remarks::createRemarkParser(remarks::Format::YAML, Buf, &StrTab);
+ EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+ EXPECT_TRUE(*MaybeParser != nullptr);
+
+ remarks::Parser &Parser = **MaybeParser;
+ Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
+ EXPECT_FALSE(
+ errorToBool(MaybeRemark.takeError())); // Check for parsing errors.
+ EXPECT_TRUE(*MaybeRemark != nullptr); // At least one remark.
+
+ const remarks::Remark &Remark = **MaybeRemark;
+ EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed);
+ EXPECT_EQ(checkStr(Remark.PassName, 6), "inline");
+ EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition");
+ EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo");
+ EXPECT_TRUE(Remark.Loc);
+ const remarks::RemarkLocation &RL = *Remark.Loc;
+ EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
+ EXPECT_EQ(RL.SourceLine, 3U);
+ EXPECT_EQ(RL.SourceColumn, 12U);
+ EXPECT_TRUE(Remark.Hotness);
+ EXPECT_EQ(*Remark.Hotness, 4U);
+ EXPECT_EQ(Remark.Args.size(), 4U);
+
+ unsigned ArgID = 0;
+ for (const remarks::Argument &Arg : Remark.Args) {
+ switch (ArgID) {
+ case 0:
+ EXPECT_EQ(checkStr(Arg.Key, 6), "Callee");
+ EXPECT_EQ(checkStr(Arg.Val, 3), "bar");
+ EXPECT_FALSE(Arg.Loc);
+ break;
+ case 1:
+ EXPECT_EQ(checkStr(Arg.Key, 6), "String");
+ EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into ");
+ EXPECT_FALSE(Arg.Loc);
+ break;
+ case 2: {
+ EXPECT_EQ(checkStr(Arg.Key, 6), "Caller");
+ EXPECT_EQ(checkStr(Arg.Val, 3), "foo");
+ EXPECT_TRUE(Arg.Loc);
+ const remarks::RemarkLocation &RL = *Arg.Loc;
+ EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
+ EXPECT_EQ(RL.SourceLine, 2U);
+ EXPECT_EQ(RL.SourceColumn, 0U);
+ break;
+ }
+ case 3:
+ EXPECT_EQ(checkStr(Arg.Key, 6), "String");
+ EXPECT_EQ(checkStr(Arg.Val, 38),
+ " because its definition is unavailable");
+ EXPECT_FALSE(Arg.Loc);
+ break;
+ default:
+ break;
+ }
+ ++ArgID;
+ }
+
+ MaybeRemark = Parser.next();
+ Error E = MaybeRemark.takeError();
+ EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
+ EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
+}
+
+TEST(YAMLRemarks, ParsingBadStringTableIndex) {
+ StringRef Buf = "\n"
+ "--- !Missed\n"
+ "Pass: 50\n"
+ "\n";
+
+ StringRef StrTabBuf = StringRef("inline");
+
+ remarks::ParsedStringTable StrTab(StrTabBuf);
+ Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+ remarks::createRemarkParser(remarks::Format::YAML, Buf, &StrTab);
+ EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+ EXPECT_TRUE(*MaybeParser != nullptr);
+
+ remarks::Parser &Parser = **MaybeParser;
+ Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
+ EXPECT_FALSE(MaybeRemark); // Expect an error here.
+
+ std::string ErrorStr;
+ raw_string_ostream Stream(ErrorStr);
+ handleAllErrors(MaybeRemark.takeError(),
+ [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });
+ EXPECT_TRUE(
+ StringRef(Stream.str())
+ .contains("String with index 50 is out of bounds (size = 1)."));
+}
diff --git a/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp b/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp
index 9940118..6781acc 100644
--- a/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp
@@ -75,6 +75,16 @@
ARMBuildAttrs::v6S_M));
EXPECT_TRUE(testBuildAttr(6, 13, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v7E_M));
+ EXPECT_TRUE(testBuildAttr(6, 14, ARMBuildAttrs::CPU_arch,
+ ARMBuildAttrs::v8_A));
+ EXPECT_TRUE(testBuildAttr(6, 15, ARMBuildAttrs::CPU_arch,
+ ARMBuildAttrs::v8_R));
+ EXPECT_TRUE(testBuildAttr(6, 16, ARMBuildAttrs::CPU_arch,
+ ARMBuildAttrs::v8_M_Base));
+ EXPECT_TRUE(testBuildAttr(6, 17, ARMBuildAttrs::CPU_arch,
+ ARMBuildAttrs::v8_M_Main));
+ EXPECT_TRUE(testBuildAttr(6, 21, ARMBuildAttrs::CPU_arch,
+ ARMBuildAttrs::v8_1_M_Main));
}
TEST(CPUArchProfileBuildAttr, testBuildAttr) {
@@ -159,6 +169,16 @@
ARMBuildAttrs::AllowHPFP));
}
+TEST(MVEBuildAttr, testBuildAttr) {
+ EXPECT_TRUE(testTagString(48, "Tag_MVE_arch"));
+ EXPECT_TRUE(testBuildAttr(48, 0, ARMBuildAttrs::MVE_arch,
+ ARMBuildAttrs::Not_Allowed));
+ EXPECT_TRUE(testBuildAttr(48, 1, ARMBuildAttrs::MVE_arch,
+ ARMBuildAttrs::AllowMVEInteger));
+ EXPECT_TRUE(testBuildAttr(48, 2, ARMBuildAttrs::MVE_arch,
+ ARMBuildAttrs::AllowMVEIntegerAndFloat));
+}
+
TEST(CPUAlignBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(34, "Tag_CPU_unaligned_access"));
EXPECT_TRUE(testBuildAttr(34, 0, ARMBuildAttrs::CPU_unaligned_access,
diff --git a/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp b/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
index 388ca11..94c6f5a 100644
--- a/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
@@ -1,9 +1,8 @@
//=== - llvm/unittest/Support/AlignOfTest.cpp - Alignment utility tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp b/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
index 74b394f..a0223ea 100644
--- a/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/AnnotationsTest.cpp b/src/llvm-project/llvm/unittests/Support/AnnotationsTest.cpp
new file mode 100644
index 0000000..b2970ad
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/AnnotationsTest.cpp
@@ -0,0 +1,112 @@
+//===----- unittests/AnnotationsTest.cpp ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/Testing/Support/Annotations.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+
+namespace {
+llvm::Annotations::Range range(size_t Begin, size_t End) {
+ llvm::Annotations::Range R;
+ R.Begin = Begin;
+ R.End = End;
+ return R;
+}
+
+TEST(AnnotationsTest, CleanedCode) {
+ EXPECT_EQ(llvm::Annotations("foo^bar$nnn[[baz$^[[qux]]]]").code(),
+ "foobarbazqux");
+}
+
+TEST(AnnotationsTest, Points) {
+ // A single point.
+ EXPECT_EQ(llvm::Annotations("^ab").point(), 0u);
+ EXPECT_EQ(llvm::Annotations("a^b").point(), 1u);
+ EXPECT_EQ(llvm::Annotations("ab^").point(), 2u);
+
+ // Multiple points.
+ EXPECT_THAT(llvm::Annotations("^a^bc^d^").points(),
+ ElementsAre(0u, 1u, 3u, 4u));
+
+ // No points.
+ EXPECT_THAT(llvm::Annotations("ab[[cd]]").points(), IsEmpty());
+
+ // Consecutive points.
+ EXPECT_THAT(llvm::Annotations("ab^^^cd").points(), ElementsAre(2u, 2u, 2u));
+}
+
+TEST(AnnotationsTest, Ranges) {
+ // A single range.
+ EXPECT_EQ(llvm::Annotations("[[a]]bc").range(), range(0, 1));
+ EXPECT_EQ(llvm::Annotations("a[[bc]]d").range(), range(1, 3));
+ EXPECT_EQ(llvm::Annotations("ab[[cd]]").range(), range(2, 4));
+
+ // Empty range.
+ EXPECT_EQ(llvm::Annotations("[[]]ab").range(), range(0, 0));
+ EXPECT_EQ(llvm::Annotations("a[[]]b").range(), range(1, 1));
+ EXPECT_EQ(llvm::Annotations("ab[[]]").range(), range(2, 2));
+
+ // Multiple ranges.
+ EXPECT_THAT(llvm::Annotations("[[a]][[b]]cd[[ef]]ef").ranges(),
+ ElementsAre(range(0, 1), range(1, 2), range(4, 6)));
+
+ // No ranges.
+ EXPECT_THAT(llvm::Annotations("ab^c^defef").ranges(), IsEmpty());
+}
+
+TEST(AnnotationsTest, Nested) {
+ llvm::Annotations Annotated("a[[f^oo^bar[[b[[a]]z]]]]bcdef");
+ EXPECT_THAT(Annotated.points(), ElementsAre(2u, 4u));
+ EXPECT_THAT(Annotated.ranges(),
+ ElementsAre(range(8, 9), range(7, 10), range(1, 10)));
+}
+
+TEST(AnnotationsTest, Named) {
+ // A single named point or range.
+ EXPECT_EQ(llvm::Annotations("a$foo^b").point("foo"), 1u);
+ EXPECT_EQ(llvm::Annotations("a$foo[[b]]cdef").range("foo"), range(1, 2));
+
+ // Empty names should also work.
+ EXPECT_EQ(llvm::Annotations("a$^b").point(""), 1u);
+ EXPECT_EQ(llvm::Annotations("a$[[b]]cdef").range(""), range(1, 2));
+
+ // Multiple named points.
+ llvm::Annotations Annotated("a$p1^bcd$p2^123$p1^345");
+ EXPECT_THAT(Annotated.points(), IsEmpty());
+ EXPECT_THAT(Annotated.points("p1"), ElementsAre(1u, 7u));
+ EXPECT_EQ(Annotated.point("p2"), 4u);
+}
+
+TEST(AnnotationsTest, Errors) {
+ // Annotations use llvm_unreachable, it will only crash in debug mode.
+#ifndef NDEBUG
+ // point() and range() crash on zero or multiple ranges.
+ EXPECT_DEATH(llvm::Annotations("ab[[c]]def").point(),
+ "expected exactly one point");
+ EXPECT_DEATH(llvm::Annotations("a^b^cdef").point(),
+ "expected exactly one point");
+
+ EXPECT_DEATH(llvm::Annotations("a^bcdef").range(),
+ "expected exactly one range");
+ EXPECT_DEATH(llvm::Annotations("a[[b]]c[[d]]ef").range(),
+ "expected exactly one range");
+
+ EXPECT_DEATH(llvm::Annotations("$foo^a$foo^a").point("foo"),
+ "expected exactly one point");
+ EXPECT_DEATH(llvm::Annotations("$foo[[a]]bc$foo[[a]]").range("foo"),
+ "expected exactly one range");
+
+ // Parsing failures.
+ EXPECT_DEATH(llvm::Annotations("ff[[fdfd"), "unmatched \\[\\[");
+ EXPECT_DEATH(llvm::Annotations("ff[[fdjsfjd]]xxx]]"), "unmatched \\]\\]");
+ EXPECT_DEATH(llvm::Annotations("ff$fdsfd"), "unterminated \\$name");
+#endif
+}
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp b/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp
index 1ff97ba..264cf97 100644
--- a/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp
@@ -1,9 +1,8 @@
//===--- unittest/Support/ArrayRecyclerTest.cpp ---------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp b/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
index 35a010e..5291a31 100644
--- a/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/BinaryStreamTest.cpp -------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -611,6 +610,77 @@
}
}
+TEST_F(BinaryStreamTest, StreamReaderULEB128) {
+ std::vector<uint64_t> TestValues = {
+ 0, // Zero
+ 0x7F, // One byte
+ 0xFF, // One byte, all-ones
+ 0xAAAA, // Two bytes
+ 0xAAAAAAAA, // Four bytes
+ 0xAAAAAAAAAAAAAAAA, // Eight bytes
+ 0xffffffffffffffff // Eight bytess, all-ones
+ };
+
+ // Conservatively assume a 10-byte encoding for each of our LEB128s, with no
+ // alignment requirement.
+ initializeOutput(10 * TestValues.size(), 1);
+ initializeInputFromOutput(1);
+
+ for (auto &Stream : Streams) {
+ // Write fields.
+ BinaryStreamWriter Writer(*Stream.Output);
+ for (const auto &Value : TestValues)
+ ASSERT_THAT_ERROR(Writer.writeULEB128(Value), Succeeded());
+
+ // Read fields.
+ BinaryStreamReader Reader(*Stream.Input);
+ std::vector<uint64_t> Results;
+ Results.resize(TestValues.size());
+ for (unsigned I = 0; I != TestValues.size(); ++I)
+ ASSERT_THAT_ERROR(Reader.readULEB128(Results[I]), Succeeded());
+
+ for (unsigned I = 0; I != TestValues.size(); ++I)
+ EXPECT_EQ(TestValues[I], Results[I]);
+ }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderSLEB128) {
+ std::vector<int64_t> TestValues = {
+ 0, // Zero
+ 0x7F, // One byte
+ -0x7F, // One byte, negative
+ 0xFF, // One byte, all-ones
+ 0xAAAA, // Two bytes
+ -0xAAAA, // Two bytes, negative
+ 0xAAAAAAAA, // Four bytes
+ -0xAAAAAAAA, // Four bytes, negative
+ 0x2AAAAAAAAAAAAAAA, // Eight bytes
+ -0x7ffffffffffffff // Eight bytess, negative
+ };
+
+ // Conservatively assume a 10-byte encoding for each of our LEB128s, with no
+ // alignment requirement.
+ initializeOutput(10 * TestValues.size(), 1);
+ initializeInputFromOutput(1);
+
+ for (auto &Stream : Streams) {
+ // Write fields.
+ BinaryStreamWriter Writer(*Stream.Output);
+ for (const auto &Value : TestValues)
+ ASSERT_THAT_ERROR(Writer.writeSLEB128(Value), Succeeded());
+
+ // Read fields.
+ BinaryStreamReader Reader(*Stream.Input);
+ std::vector<int64_t> Results;
+ Results.resize(TestValues.size());
+ for (unsigned I = 0; I != TestValues.size(); ++I)
+ ASSERT_THAT_ERROR(Reader.readSLEB128(Results[I]), Succeeded());
+
+ for (unsigned I = 0; I != TestValues.size(); ++I)
+ EXPECT_EQ(TestValues[I], Results[I]);
+ }
+}
+
TEST_F(BinaryStreamTest, StreamReaderObject) {
struct Foo {
int X;
diff --git a/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp b/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp
index c1f5671..cf5cf92 100644
--- a/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Support/BlockFrequencyTest.cpp - BlockFrequency tests ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp b/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp
index 54948ba..94626e7 100644
--- a/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Support/BranchProbabilityTest.cpp - BranchProbability tests -=//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/CMakeLists.txt b/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
index f9c877f..da2b501 100644
--- a/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
@@ -5,6 +5,7 @@
add_llvm_unittest(SupportTests
AlignOfTest.cpp
AllocatorTest.cpp
+ AnnotationsTest.cpp
ARMAttributeParser.cpp
ArrayRecyclerTest.cpp
BinaryStreamTest.cpp
@@ -18,6 +19,7 @@
CommandLineTest.cpp
CompressionTest.cpp
ConvertUTFTest.cpp
+ CRCTest.cpp
DataExtractorTest.cpp
DebugTest.cpp
DebugCounterTest.cpp
@@ -27,15 +29,18 @@
ErrnoTest.cpp
ErrorOrTest.cpp
ErrorTest.cpp
+ FileCheckTest.cpp
FileOutputBufferTest.cpp
FormatVariadicTest.cpp
GlobPatternTest.cpp
Host.cpp
ItaniumManglingCanonicalizerTest.cpp
JSONTest.cpp
+ KnownBitsTest.cpp
LEB128Test.cpp
LineIteratorTest.cpp
LockFileManagerTest.cpp
+ MatchersTest.cpp
MD5Test.cpp
ManagedStatic.cpp
MathExtrasTest.cpp
@@ -83,7 +88,21 @@
# Disable all warning for AlignOfTest.cpp,
# as it does things intentionally, and there is no reliable way of
# disabling all warnings for all the compilers by using pragmas.
-set_source_files_properties(AlignOfTest.cpp PROPERTIES COMPILE_FLAGS -w)
+# Don't disable on MSVC, because all incriminated warnings are already disabled
+# in source; and because we would otherwise see this warning:
+# cl : Command line warning D9025: overriding '/W4' with '/w'
+if(NOT MSVC)
+ set_source_files_properties(AlignOfTest.cpp PROPERTIES COMPILE_FLAGS -w)
+endif()
+if(MSVC)
+ if( CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.14 )
+ # Since VS2017 15.8, the following snippet: Failed<CustomSubError>()
+ # generates a warning:
+ # \svn\llvm\utils\unittest\googlemock\include\gmock\gmock-matchers.h(186):
+ # warning C5046: 'testing::MatcherInterface<T>::~MatcherInterface': Symbol involving type with internal linkage not defined
+ set_source_files_properties(ErrorTest.cpp PROPERTIES COMPILE_FLAGS -wd5046)
+ endif()
+endif()
# ManagedStatic.cpp uses <pthread>.
target_link_libraries(SupportTests PRIVATE LLVMTestingSupport ${LLVM_PTHREAD_LIB})
diff --git a/src/llvm-project/llvm/unittests/Support/CRCTest.cpp b/src/llvm-project/llvm/unittests/Support/CRCTest.cpp
new file mode 100644
index 0000000..71afb0a
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/CRCTest.cpp
@@ -0,0 +1,29 @@
+//===- llvm/unittest/Support/CRCTest.cpp - CRC tests ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unit tests for CRC calculation functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CRC.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(CRCTest, CRC32) {
+ EXPECT_EQ(0x414FA339U,
+ llvm::crc32(
+ 0, StringRef("The quick brown fox jumps over the lazy dog")));
+ // CRC-32/ISO-HDLC test vector
+ // http://reveng.sourceforge.net/crc-catalogue/17plus.htm#crc.cat.crc-32c
+ EXPECT_EQ(0xCBF43926U, llvm::crc32(0, StringRef("123456789")));
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp b/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp
index 4bc2ad1..eeffe21 100644
--- a/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp
@@ -1,9 +1,8 @@
//===- CachePruningTest.cpp -----------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/Casting.cpp b/src/llvm-project/llvm/unittests/Support/Casting.cpp
index 9a818f6..bcdaca9 100644
--- a/src/llvm-project/llvm/unittests/Support/Casting.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Casting.cpp
@@ -1,9 +1,8 @@
//===---------- llvm/unittest/Support/Casting.cpp - Casting tests ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -119,6 +118,12 @@
EXPECT_TRUE(isa<foo>(B4));
}
+TEST(CastingTest, isa_and_nonnull) {
+ EXPECT_TRUE(isa_and_nonnull<foo>(B2));
+ EXPECT_TRUE(isa_and_nonnull<foo>(B4));
+ EXPECT_FALSE(isa_and_nonnull<foo>(fub()));
+}
+
TEST(CastingTest, cast) {
foo &F1 = cast<foo>(B1);
EXPECT_NE(&F1, null_foo);
diff --git a/src/llvm-project/llvm/unittests/Support/Chrono.cpp b/src/llvm-project/llvm/unittests/Support/Chrono.cpp
index a6b76c8..9a08a5c 100644
--- a/src/llvm-project/llvm/unittests/Support/Chrono.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Chrono.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/Chrono.cpp - Time utilities tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp b/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
index 9d06f72..1a1c8a4 100644
--- a/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/CommandLineTest.cpp - CommandLine tests ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -14,6 +13,7 @@
#include "llvm/Config/config.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/StringSaver.h"
@@ -95,12 +95,20 @@
cl::Option *Retrieved = Map["test-option"];
ASSERT_EQ(&TestOption, Retrieved) << "Retrieved wrong option.";
- ASSERT_EQ(&cl::GeneralCategory,Retrieved->Category) <<
- "Incorrect default option category.";
+ ASSERT_NE(Retrieved->Categories.end(),
+ find_if(Retrieved->Categories,
+ [&](const llvm::cl::OptionCategory *Cat) {
+ return Cat == &cl::GeneralCategory;
+ }))
+ << "Incorrect default option category.";
- Retrieved->setCategory(TestCategory);
- ASSERT_EQ(&TestCategory,Retrieved->Category) <<
- "Failed to modify option's option category.";
+ Retrieved->addCategory(TestCategory);
+ ASSERT_NE(Retrieved->Categories.end(),
+ find_if(Retrieved->Categories,
+ [&](const llvm::cl::OptionCategory *Cat) {
+ return Cat == &TestCategory;
+ }))
+ << "Failed to modify option's option category.";
Retrieved->setDescription(Description);
ASSERT_STREQ(Retrieved->HelpStr.data(), Description)
@@ -152,8 +160,56 @@
TEST(CommandLineTest, UseOptionCategory) {
StackOption<int> TestOption2("test-option", cl::cat(TestCategory));
- ASSERT_EQ(&TestCategory,TestOption2.Category) << "Failed to assign Option "
- "Category.";
+ ASSERT_NE(TestOption2.Categories.end(),
+ find_if(TestOption2.Categories,
+ [&](const llvm::cl::OptionCategory *Cat) {
+ return Cat == &TestCategory;
+ }))
+ << "Failed to assign Option Category.";
+}
+
+TEST(CommandLineTest, UseMultipleCategories) {
+ StackOption<int> TestOption2("test-option2", cl::cat(TestCategory),
+ cl::cat(cl::GeneralCategory),
+ cl::cat(cl::GeneralCategory));
+
+ // Make sure cl::GeneralCategory wasn't added twice.
+ ASSERT_EQ(TestOption2.Categories.size(), 2U);
+
+ ASSERT_NE(TestOption2.Categories.end(),
+ find_if(TestOption2.Categories,
+ [&](const llvm::cl::OptionCategory *Cat) {
+ return Cat == &TestCategory;
+ }))
+ << "Failed to assign Option Category.";
+ ASSERT_NE(TestOption2.Categories.end(),
+ find_if(TestOption2.Categories,
+ [&](const llvm::cl::OptionCategory *Cat) {
+ return Cat == &cl::GeneralCategory;
+ }))
+ << "Failed to assign General Category.";
+
+ cl::OptionCategory AnotherCategory("Additional test Options", "Description");
+ StackOption<int> TestOption("test-option", cl::cat(TestCategory),
+ cl::cat(AnotherCategory));
+ ASSERT_EQ(TestOption.Categories.end(),
+ find_if(TestOption.Categories,
+ [&](const llvm::cl::OptionCategory *Cat) {
+ return Cat == &cl::GeneralCategory;
+ }))
+ << "Failed to remove General Category.";
+ ASSERT_NE(TestOption.Categories.end(),
+ find_if(TestOption.Categories,
+ [&](const llvm::cl::OptionCategory *Cat) {
+ return Cat == &TestCategory;
+ }))
+ << "Failed to assign Option Category.";
+ ASSERT_NE(TestOption.Categories.end(),
+ find_if(TestOption.Categories,
+ [&](const llvm::cl::OptionCategory *Cat) {
+ return Cat == &AnotherCategory;
+ }))
+ << "Failed to assign Another Category.";
}
typedef void ParserFunction(StringRef Source, StringSaver &Saver,
@@ -185,7 +241,7 @@
array_lengthof(Output));
}
-TEST(CommandLineTest, TokenizeWindowsCommandLine) {
+TEST(CommandLineTest, TokenizeWindowsCommandLine1) {
const char Input[] = "a\\b c\\\\d e\\\\\"f g\" h\\\"i j\\\\\\\"k \"lmn\" o pqr "
"\"st \\\"u\" \\v";
const char *const Output[] = { "a\\b", "c\\\\d", "e\\f g", "h\"i", "j\\\"k",
@@ -194,6 +250,13 @@
array_lengthof(Output));
}
+TEST(CommandLineTest, TokenizeWindowsCommandLine2) {
+ const char Input[] = "clang -c -DFOO=\"\"\"ABC\"\"\" x.cpp";
+ const char *const Output[] = { "clang", "-c", "-DFOO=\"ABC\"", "x.cpp"};
+ testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input, Output,
+ array_lengthof(Output));
+}
+
TEST(CommandLineTest, TokenizeConfigFile1) {
const char *Input = "\\";
const char *const Output[] = { "\\" };
@@ -613,6 +676,68 @@
}
}
+TEST(CommandLineTest, DefaultOptions) {
+ cl::ResetCommandLineParser();
+
+ StackOption<std::string> Bar("bar", cl::sub(*cl::AllSubCommands),
+ cl::DefaultOption);
+ StackOption<std::string, cl::alias> Bar_Alias(
+ "b", cl::desc("Alias for -bar"), cl::aliasopt(Bar), cl::DefaultOption);
+
+ StackOption<bool> Foo("foo", cl::init(false), cl::sub(*cl::AllSubCommands),
+ cl::DefaultOption);
+ StackOption<bool, cl::alias> Foo_Alias("f", cl::desc("Alias for -foo"),
+ cl::aliasopt(Foo), cl::DefaultOption);
+
+ StackSubCommand SC1("sc1", "First Subcommand");
+ // Override "-b" and change type in sc1 SubCommand.
+ StackOption<bool> SC1_B("b", cl::sub(SC1), cl::init(false));
+ StackSubCommand SC2("sc2", "Second subcommand");
+ // Override "-foo" and change type in sc2 SubCommand. Note that this does not
+ // affect "-f" alias, which continues to work correctly.
+ StackOption<std::string> SC2_Foo("foo", cl::sub(SC2));
+
+ const char *args0[] = {"prog", "-b", "args0 bar string", "-f"};
+ EXPECT_TRUE(cl::ParseCommandLineOptions(sizeof(args0) / sizeof(char *), args0,
+ StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(Bar == "args0 bar string");
+ EXPECT_TRUE(Foo);
+ EXPECT_FALSE(SC1_B);
+ EXPECT_TRUE(SC2_Foo.empty());
+
+ cl::ResetAllOptionOccurrences();
+
+ const char *args1[] = {"prog", "sc1", "-b", "-bar", "args1 bar string", "-f"};
+ EXPECT_TRUE(cl::ParseCommandLineOptions(sizeof(args1) / sizeof(char *), args1,
+ StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(Bar == "args1 bar string");
+ EXPECT_TRUE(Foo);
+ EXPECT_TRUE(SC1_B);
+ EXPECT_TRUE(SC2_Foo.empty());
+ for (auto *S : cl::getRegisteredSubcommands()) {
+ if (*S) {
+ EXPECT_EQ("sc1", S->getName());
+ }
+ }
+
+ cl::ResetAllOptionOccurrences();
+
+ const char *args2[] = {"prog", "sc2", "-b", "args2 bar string",
+ "-f", "-foo", "foo string"};
+ EXPECT_TRUE(cl::ParseCommandLineOptions(sizeof(args2) / sizeof(char *), args2,
+ StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(Bar == "args2 bar string");
+ EXPECT_TRUE(Foo);
+ EXPECT_FALSE(SC1_B);
+ EXPECT_TRUE(SC2_Foo == "foo string");
+ for (auto *S : cl::getRegisteredSubcommands()) {
+ if (*S) {
+ EXPECT_EQ("sc2", S->getName());
+ }
+ }
+ cl::ResetCommandLineParser();
+}
+
TEST(CommandLineTest, ArgumentLimit) {
std::string args(32 * 4096, 'a');
EXPECT_FALSE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args.data()));
@@ -665,7 +790,9 @@
EXPECT_TRUE(IncludedFile.is_open());
IncludedFile << "-option_1 -option_2\n"
"@incdir/resp2\n"
- "-option_3=abcd\n";
+ "-option_3=abcd\n"
+ "@incdir/resp3\n"
+ "-option_4=efjk\n";
IncludedFile.close();
// Directory for included file.
@@ -683,6 +810,15 @@
IncludedFile2 << "-option_23=abcd\n";
IncludedFile2.close();
+ // Create second included response file of second level.
+ llvm::SmallString<128> IncludedFileName3;
+ llvm::sys::path::append(IncludedFileName3, IncDir, "resp3");
+ std::ofstream IncludedFile3(IncludedFileName3.c_str());
+ EXPECT_TRUE(IncludedFile3.is_open());
+ IncludedFile3 << "-option_31 -option_32\n";
+ IncludedFile3 << "-option_33=abcd\n";
+ IncludedFile3.close();
+
// Prepare 'file' with reference to response file.
SmallString<128> IncRef;
IncRef.append(1, '@');
@@ -696,7 +832,7 @@
bool Res = llvm::cl::ExpandResponseFiles(
Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true);
EXPECT_TRUE(Res);
- EXPECT_EQ(Argv.size(), 9U);
+ EXPECT_EQ(Argv.size(), 13U);
EXPECT_STREQ(Argv[0], "test/test");
EXPECT_STREQ(Argv[1], "-flag_1");
EXPECT_STREQ(Argv[2], "-option_1");
@@ -705,14 +841,122 @@
EXPECT_STREQ(Argv[5], "-option_22");
EXPECT_STREQ(Argv[6], "-option_23=abcd");
EXPECT_STREQ(Argv[7], "-option_3=abcd");
- EXPECT_STREQ(Argv[8], "-flag_2");
+ EXPECT_STREQ(Argv[8], "-option_31");
+ EXPECT_STREQ(Argv[9], "-option_32");
+ EXPECT_STREQ(Argv[10], "-option_33=abcd");
+ EXPECT_STREQ(Argv[11], "-option_4=efjk");
+ EXPECT_STREQ(Argv[12], "-flag_2");
+ llvm::sys::fs::remove(IncludedFileName3);
llvm::sys::fs::remove(IncludedFileName2);
llvm::sys::fs::remove(IncDir);
llvm::sys::fs::remove(IncludedFileName);
llvm::sys::fs::remove(TestDir);
}
+TEST(CommandLineTest, RecursiveResponseFiles) {
+ SmallString<128> TestDir;
+ std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir);
+ EXPECT_TRUE(!EC);
+
+ SmallString<128> SelfFilePath;
+ sys::path::append(SelfFilePath, TestDir, "self.rsp");
+ std::string SelfFileRef = std::string("@") + SelfFilePath.c_str();
+
+ SmallString<128> NestedFilePath;
+ sys::path::append(NestedFilePath, TestDir, "nested.rsp");
+ std::string NestedFileRef = std::string("@") + NestedFilePath.c_str();
+
+ SmallString<128> FlagFilePath;
+ sys::path::append(FlagFilePath, TestDir, "flag.rsp");
+ std::string FlagFileRef = std::string("@") + FlagFilePath.c_str();
+
+ std::ofstream SelfFile(SelfFilePath.str());
+ EXPECT_TRUE(SelfFile.is_open());
+ SelfFile << "-option_1\n";
+ SelfFile << FlagFileRef << "\n";
+ SelfFile << NestedFileRef << "\n";
+ SelfFile << SelfFileRef << "\n";
+ SelfFile.close();
+
+ std::ofstream NestedFile(NestedFilePath.str());
+ EXPECT_TRUE(NestedFile.is_open());
+ NestedFile << "-option_2\n";
+ NestedFile << FlagFileRef << "\n";
+ NestedFile << SelfFileRef << "\n";
+ NestedFile << NestedFileRef << "\n";
+ NestedFile.close();
+
+ std::ofstream FlagFile(FlagFilePath.str());
+ EXPECT_TRUE(FlagFile.is_open());
+ FlagFile << "-option_x\n";
+ FlagFile.close();
+
+ // Ensure:
+ // Recursive expansion terminates
+ // Recursive files never expand
+ // Non-recursive repeats are allowed
+ SmallVector<const char *, 4> Argv = {"test/test", SelfFileRef.c_str(),
+ "-option_3"};
+ BumpPtrAllocator A;
+ StringSaver Saver(A);
+#ifdef _WIN32
+ cl::TokenizerCallback Tokenizer = cl::TokenizeWindowsCommandLine;
+#else
+ cl::TokenizerCallback Tokenizer = cl::TokenizeGNUCommandLine;
+#endif
+ bool Res = cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false);
+ EXPECT_FALSE(Res);
+
+ EXPECT_EQ(Argv.size(), 9U);
+ EXPECT_STREQ(Argv[0], "test/test");
+ EXPECT_STREQ(Argv[1], "-option_1");
+ EXPECT_STREQ(Argv[2], "-option_x");
+ EXPECT_STREQ(Argv[3], "-option_2");
+ EXPECT_STREQ(Argv[4], "-option_x");
+ EXPECT_STREQ(Argv[5], SelfFileRef.c_str());
+ EXPECT_STREQ(Argv[6], NestedFileRef.c_str());
+ EXPECT_STREQ(Argv[7], SelfFileRef.c_str());
+ EXPECT_STREQ(Argv[8], "-option_3");
+}
+
+TEST(CommandLineTest, ResponseFilesAtArguments) {
+ SmallString<128> TestDir;
+ std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir);
+ EXPECT_TRUE(!EC);
+
+ SmallString<128> ResponseFilePath;
+ sys::path::append(ResponseFilePath, TestDir, "test.rsp");
+
+ std::ofstream ResponseFile(ResponseFilePath.c_str());
+ EXPECT_TRUE(ResponseFile.is_open());
+ ResponseFile << "-foo" << "\n";
+ ResponseFile << "-bar" << "\n";
+ ResponseFile.close();
+
+ // Ensure we expand rsp files after lots of non-rsp arguments starting with @.
+ constexpr size_t NON_RSP_AT_ARGS = 64;
+ SmallVector<const char *, 4> Argv = {"test/test"};
+ Argv.append(NON_RSP_AT_ARGS, "@non_rsp_at_arg");
+ std::string ResponseFileRef = std::string("@") + ResponseFilePath.c_str();
+ Argv.push_back(ResponseFileRef.c_str());
+
+ BumpPtrAllocator A;
+ StringSaver Saver(A);
+ bool Res = cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
+ false, false);
+ EXPECT_FALSE(Res);
+
+ // ASSERT instead of EXPECT to prevent potential out-of-bounds access.
+ ASSERT_EQ(Argv.size(), 1 + NON_RSP_AT_ARGS + 2);
+ size_t i = 0;
+ EXPECT_STREQ(Argv[i++], "test/test");
+ for (; i < 1 + NON_RSP_AT_ARGS; ++i)
+ EXPECT_STREQ(Argv[i], "@non_rsp_at_arg");
+ EXPECT_STREQ(Argv[i++], "-foo");
+ EXPECT_STREQ(Argv[i++], "-bar");
+}
+
TEST(CommandLineTest, SetDefautValue) {
cl::ResetCommandLineParser();
@@ -804,13 +1048,21 @@
}
TEST(CommandLineTest, PositionalEatArgsError) {
+ cl::ResetCommandLineParser();
+
StackOption<std::string, cl::list<std::string>> PosEatArgs(
"positional-eat-args", cl::Positional, cl::desc("<arguments>..."),
cl::ZeroOrMore, cl::PositionalEatsArgs);
+ StackOption<std::string, cl::list<std::string>> PosEatArgs2(
+ "positional-eat-args2", cl::Positional, cl::desc("Some strings"),
+ cl::ZeroOrMore, cl::PositionalEatsArgs);
const char *args[] = {"prog", "-positional-eat-args=XXXX"};
const char *args2[] = {"prog", "-positional-eat-args=XXXX", "-foo"};
const char *args3[] = {"prog", "-positional-eat-args", "-foo"};
+ const char *args4[] = {"prog", "-positional-eat-args",
+ "-foo", "-positional-eat-args2",
+ "-bar", "foo"};
std::string Errs;
raw_string_ostream OS(Errs);
@@ -819,6 +1071,12 @@
EXPECT_FALSE(cl::ParseCommandLineOptions(3, args2, StringRef(), &OS)); OS.flush();
EXPECT_FALSE(Errs.empty()); Errs.clear();
EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, StringRef(), &OS)); OS.flush();
+ EXPECT_TRUE(Errs.empty()); Errs.clear();
+
+ cl::ResetAllOptionOccurrences();
+ EXPECT_TRUE(cl::ParseCommandLineOptions(6, args4, StringRef(), &OS)); OS.flush();
+ EXPECT_TRUE(PosEatArgs.size() == 1);
+ EXPECT_TRUE(PosEatArgs2.size() == 2);
EXPECT_TRUE(Errs.empty());
}
@@ -840,6 +1098,221 @@
}
#endif
+class OutputRedirector {
+public:
+ OutputRedirector(int RedirectFD)
+ : RedirectFD(RedirectFD), OldFD(dup(RedirectFD)) {
+ if (OldFD == -1 ||
+ sys::fs::createTemporaryFile("unittest-redirect", "", NewFD,
+ FilePath) ||
+ dup2(NewFD, RedirectFD) == -1)
+ Valid = false;
+ }
+
+ ~OutputRedirector() {
+ dup2(OldFD, RedirectFD);
+ close(OldFD);
+ close(NewFD);
+ }
+
+ SmallVector<char, 128> FilePath;
+ bool Valid = true;
+
+private:
+ int RedirectFD;
+ int OldFD;
+ int NewFD;
+};
+
+struct AutoDeleteFile {
+ SmallVector<char, 128> FilePath;
+ ~AutoDeleteFile() {
+ if (!FilePath.empty())
+ sys::fs::remove(std::string(FilePath.data(), FilePath.size()));
+ }
+};
+
+class PrintOptionInfoTest : public ::testing::Test {
+public:
+ // Return std::string because the output of a failing EXPECT check is
+ // unreadable for StringRef. It also avoids any lifetime issues.
+ template <typename... Ts> std::string runTest(Ts... OptionAttributes) {
+ outs().flush(); // flush any output from previous tests
+ AutoDeleteFile File;
+ {
+ OutputRedirector Stdout(fileno(stdout));
+ if (!Stdout.Valid)
+ return "";
+ File.FilePath = Stdout.FilePath;
+
+ StackOption<OptionValue> TestOption(Opt, cl::desc(HelpText),
+ OptionAttributes...);
+ printOptionInfo(TestOption, 26);
+ outs().flush();
+ }
+ auto Buffer = MemoryBuffer::getFile(File.FilePath);
+ if (!Buffer)
+ return "";
+ return Buffer->get()->getBuffer().str();
+ }
+
+ enum class OptionValue { Val };
+ const StringRef Opt = "some-option";
+ const StringRef HelpText = "some help";
+
+private:
+ // This is a workaround for cl::Option sub-classes having their
+ // printOptionInfo functions private.
+ void printOptionInfo(const cl::Option &O, size_t Width) {
+ O.printOptionInfo(Width);
+ }
+};
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithoutSentinel) {
+ std::string Output =
+ runTest(cl::ValueOptional,
+ cl::values(clEnumValN(OptionValue::Val, "v1", "desc1")));
+
+ // clang-format off
+ EXPECT_EQ(Output, (" --" + Opt + "=<value> - " + HelpText + "\n"
+ " =v1 - desc1\n")
+ .str());
+ // clang-format on
+}
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithSentinel) {
+ std::string Output = runTest(
+ cl::ValueOptional, cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"),
+ clEnumValN(OptionValue::Val, "", "")));
+
+ // clang-format off
+ EXPECT_EQ(Output,
+ (" --" + Opt + " - " + HelpText + "\n"
+ " --" + Opt + "=<value> - " + HelpText + "\n"
+ " =v1 - desc1\n")
+ .str());
+ // clang-format on
+}
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithSentinelWithHelp) {
+ std::string Output = runTest(
+ cl::ValueOptional, cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"),
+ clEnumValN(OptionValue::Val, "", "desc2")));
+
+ // clang-format off
+ EXPECT_EQ(Output, (" --" + Opt + " - " + HelpText + "\n"
+ " --" + Opt + "=<value> - " + HelpText + "\n"
+ " =v1 - desc1\n"
+ " =<empty> - desc2\n")
+ .str());
+ // clang-format on
+}
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoValueRequiredWithEmptyValueName) {
+ std::string Output = runTest(
+ cl::ValueRequired, cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"),
+ clEnumValN(OptionValue::Val, "", "")));
+
+ // clang-format off
+ EXPECT_EQ(Output, (" --" + Opt + "=<value> - " + HelpText + "\n"
+ " =v1 - desc1\n"
+ " =<empty>\n")
+ .str());
+ // clang-format on
+}
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoEmptyValueDescription) {
+ std::string Output = runTest(
+ cl::ValueRequired, cl::values(clEnumValN(OptionValue::Val, "v1", "")));
+
+ // clang-format off
+ EXPECT_EQ(Output,
+ (" --" + Opt + "=<value> - " + HelpText + "\n"
+ " =v1\n").str());
+ // clang-format on
+}
+
+class GetOptionWidthTest : public ::testing::Test {
+public:
+ enum class OptionValue { Val };
+
+ template <typename... Ts>
+ size_t runTest(StringRef ArgName, Ts... OptionAttributes) {
+ StackOption<OptionValue> TestOption(ArgName, cl::desc("some help"),
+ OptionAttributes...);
+ return getOptionWidth(TestOption);
+ }
+
+private:
+ // This is a workaround for cl::Option sub-classes having their
+ // printOptionInfo
+ // functions private.
+ size_t getOptionWidth(const cl::Option &O) { return O.getOptionWidth(); }
+};
+
+TEST_F(GetOptionWidthTest, GetOptionWidthArgNameLonger) {
+ StringRef ArgName("a-long-argument-name");
+ size_t ExpectedStrSize = (" --" + ArgName + "=<value> - ").str().size();
+ EXPECT_EQ(
+ runTest(ArgName, cl::values(clEnumValN(OptionValue::Val, "v", "help"))),
+ ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest, GetOptionWidthFirstOptionNameLonger) {
+ StringRef OptName("a-long-option-name");
+ size_t ExpectedStrSize = (" =" + OptName + " - ").str().size();
+ EXPECT_EQ(
+ runTest("a", cl::values(clEnumValN(OptionValue::Val, OptName, "help"),
+ clEnumValN(OptionValue::Val, "b", "help"))),
+ ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest, GetOptionWidthSecondOptionNameLonger) {
+ StringRef OptName("a-long-option-name");
+ size_t ExpectedStrSize = (" =" + OptName + " - ").str().size();
+ EXPECT_EQ(
+ runTest("a", cl::values(clEnumValN(OptionValue::Val, "b", "help"),
+ clEnumValN(OptionValue::Val, OptName, "help"))),
+ ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest, GetOptionWidthEmptyOptionNameLonger) {
+ size_t ExpectedStrSize = StringRef(" =<empty> - ").size();
+ // The length of a=<value> (including indentation) is actually the same as the
+ // =<empty> string, so it is impossible to distinguish via testing the case
+ // where the empty string is picked from where the option name is picked.
+ EXPECT_EQ(runTest("a", cl::values(clEnumValN(OptionValue::Val, "b", "help"),
+ clEnumValN(OptionValue::Val, "", "help"))),
+ ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest,
+ GetOptionWidthValueOptionalEmptyOptionWithNoDescription) {
+ StringRef ArgName("a");
+ // The length of a=<value> (including indentation) is actually the same as the
+ // =<empty> string, so it is impossible to distinguish via testing the case
+ // where the empty string is ignored from where it is not ignored.
+ // The dash will not actually be printed, but the space it would take up is
+ // included to ensure a consistent column width.
+ size_t ExpectedStrSize = (" -" + ArgName + "=<value> - ").str().size();
+ EXPECT_EQ(runTest(ArgName, cl::ValueOptional,
+ cl::values(clEnumValN(OptionValue::Val, "value", "help"),
+ clEnumValN(OptionValue::Val, "", ""))),
+ ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest,
+ GetOptionWidthValueRequiredEmptyOptionWithNoDescription) {
+ // The length of a=<value> (including indentation) is actually the same as the
+ // =<empty> string, so it is impossible to distinguish via testing the case
+ // where the empty string is picked from where the option name is picked
+ size_t ExpectedStrSize = StringRef(" =<empty> - ").size();
+ EXPECT_EQ(runTest("a", cl::ValueRequired,
+ cl::values(clEnumValN(OptionValue::Val, "value", "help"),
+ clEnumValN(OptionValue::Val, "", ""))),
+ ExpectedStrSize);
+}
+
TEST(CommandLineTest, PrefixOptions) {
cl::ResetCommandLineParser();
@@ -914,4 +1387,270 @@
EXPECT_TRUE(MacroDefs.front().compare("HAVE_FOO") == 0);
}
-} // anonymous namespace
+TEST(CommandLineTest, GroupingWithValue) {
+ cl::ResetCommandLineParser();
+
+ StackOption<bool> OptF("f", cl::Grouping, cl::desc("Some flag"));
+ StackOption<bool> OptB("b", cl::Grouping, cl::desc("Another flag"));
+ StackOption<bool> OptD("d", cl::Grouping, cl::ValueDisallowed,
+ cl::desc("ValueDisallowed option"));
+ StackOption<std::string> OptV("v", cl::Grouping,
+ cl::desc("ValueRequired option"));
+ StackOption<std::string> OptO("o", cl::Grouping, cl::ValueOptional,
+ cl::desc("ValueOptional option"));
+
+ // Should be possible to use an option which requires a value
+ // at the end of a group.
+ const char *args1[] = {"prog", "-fv", "val1"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(3, args1, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("val1", OptV.c_str());
+ OptV.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Should not crash if it is accidentally used elsewhere in the group.
+ const char *args2[] = {"prog", "-vf", "val2"};
+ EXPECT_FALSE(
+ cl::ParseCommandLineOptions(3, args2, StringRef(), &llvm::nulls()));
+ OptV.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Should allow the "opt=value" form at the end of the group
+ const char *args3[] = {"prog", "-fv=val3"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args3, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("val3", OptV.c_str());
+ OptV.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Should allow assigning a value for a ValueOptional option
+ // at the end of the group
+ const char *args4[] = {"prog", "-fo=val4"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args4, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("val4", OptO.c_str());
+ OptO.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Should assign an empty value if a ValueOptional option is used elsewhere
+ // in the group.
+ const char *args5[] = {"prog", "-fob"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args5, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_EQ(1, OptO.getNumOccurrences());
+ EXPECT_EQ(1, OptB.getNumOccurrences());
+ EXPECT_TRUE(OptO.empty());
+ cl::ResetAllOptionOccurrences();
+
+ // Should not allow an assignment for a ValueDisallowed option.
+ const char *args6[] = {"prog", "-fd=false"};
+ EXPECT_FALSE(
+ cl::ParseCommandLineOptions(2, args6, StringRef(), &llvm::nulls()));
+}
+
+TEST(CommandLineTest, GroupingAndPrefix) {
+ cl::ResetCommandLineParser();
+
+ StackOption<bool> OptF("f", cl::Grouping, cl::desc("Some flag"));
+ StackOption<bool> OptB("b", cl::Grouping, cl::desc("Another flag"));
+ StackOption<std::string> OptP("p", cl::Prefix, cl::Grouping,
+ cl::desc("Prefix and Grouping"));
+ StackOption<std::string> OptA("a", cl::AlwaysPrefix, cl::Grouping,
+ cl::desc("AlwaysPrefix and Grouping"));
+
+ // Should be possible to use a cl::Prefix option without grouping.
+ const char *args1[] = {"prog", "-pval1"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args1, StringRef(), &llvm::nulls()));
+ EXPECT_STREQ("val1", OptP.c_str());
+ OptP.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Should be possible to pass a value in a separate argument.
+ const char *args2[] = {"prog", "-p", "val2"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(3, args2, StringRef(), &llvm::nulls()));
+ EXPECT_STREQ("val2", OptP.c_str());
+ OptP.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // The "-opt=value" form should work, too.
+ const char *args3[] = {"prog", "-p=val3"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args3, StringRef(), &llvm::nulls()));
+ EXPECT_STREQ("val3", OptP.c_str());
+ OptP.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // All three previous cases should work the same way if an option with both
+ // cl::Prefix and cl::Grouping modifiers is used at the end of a group.
+ const char *args4[] = {"prog", "-fpval4"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args4, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("val4", OptP.c_str());
+ OptP.clear();
+ cl::ResetAllOptionOccurrences();
+
+ const char *args5[] = {"prog", "-fp", "val5"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(3, args5, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("val5", OptP.c_str());
+ OptP.clear();
+ cl::ResetAllOptionOccurrences();
+
+ const char *args6[] = {"prog", "-fp=val6"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args6, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("val6", OptP.c_str());
+ OptP.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Should assign a value even if the part after a cl::Prefix option is equal
+ // to the name of another option.
+ const char *args7[] = {"prog", "-fpb"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args7, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("b", OptP.c_str());
+ EXPECT_FALSE(OptB);
+ OptP.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Should be possible to use a cl::AlwaysPrefix option without grouping.
+ const char *args8[] = {"prog", "-aval8"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args8, StringRef(), &llvm::nulls()));
+ EXPECT_STREQ("val8", OptA.c_str());
+ OptA.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Should not be possible to pass a value in a separate argument.
+ const char *args9[] = {"prog", "-a", "val9"};
+ EXPECT_FALSE(
+ cl::ParseCommandLineOptions(3, args9, StringRef(), &llvm::nulls()));
+ cl::ResetAllOptionOccurrences();
+
+ // With the "-opt=value" form, the "=" symbol should be preserved.
+ const char *args10[] = {"prog", "-a=val10"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args10, StringRef(), &llvm::nulls()));
+ EXPECT_STREQ("=val10", OptA.c_str());
+ OptA.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // All three previous cases should work the same way if an option with both
+ // cl::AlwaysPrefix and cl::Grouping modifiers is used at the end of a group.
+ const char *args11[] = {"prog", "-faval11"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args11, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("val11", OptA.c_str());
+ OptA.clear();
+ cl::ResetAllOptionOccurrences();
+
+ const char *args12[] = {"prog", "-fa", "val12"};
+ EXPECT_FALSE(
+ cl::ParseCommandLineOptions(3, args12, StringRef(), &llvm::nulls()));
+ cl::ResetAllOptionOccurrences();
+
+ const char *args13[] = {"prog", "-fa=val13"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args13, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("=val13", OptA.c_str());
+ OptA.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Should assign a value even if the part after a cl::AlwaysPrefix option
+ // is equal to the name of another option.
+ const char *args14[] = {"prog", "-fab"};
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args14, StringRef(), &llvm::nulls()));
+ EXPECT_TRUE(OptF);
+ EXPECT_STREQ("b", OptA.c_str());
+ EXPECT_FALSE(OptB);
+ OptA.clear();
+ cl::ResetAllOptionOccurrences();
+}
+
+TEST(CommandLineTest, LongOptions) {
+ cl::ResetCommandLineParser();
+
+ StackOption<bool> OptA("a", cl::desc("Some flag"));
+ StackOption<bool> OptBLong("long-flag", cl::desc("Some long flag"));
+ StackOption<bool, cl::alias> OptB("b", cl::desc("Alias to --long-flag"),
+ cl::aliasopt(OptBLong));
+ StackOption<std::string> OptAB("ab", cl::desc("Another long option"));
+
+ std::string Errs;
+ raw_string_ostream OS(Errs);
+
+ const char *args1[] = {"prog", "-a", "-ab", "val1"};
+ const char *args2[] = {"prog", "-a", "--ab", "val1"};
+ const char *args3[] = {"prog", "-ab", "--ab", "val1"};
+
+ //
+ // The following tests treat `-` and `--` the same, and always match the
+ // longest string.
+ //
+
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(4, args1, StringRef(), &OS)); OS.flush();
+ EXPECT_TRUE(OptA);
+ EXPECT_FALSE(OptBLong);
+ EXPECT_STREQ("val1", OptAB.c_str());
+ EXPECT_TRUE(Errs.empty()); Errs.clear();
+ cl::ResetAllOptionOccurrences();
+
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(4, args2, StringRef(), &OS)); OS.flush();
+ EXPECT_TRUE(OptA);
+ EXPECT_FALSE(OptBLong);
+ EXPECT_STREQ("val1", OptAB.c_str());
+ EXPECT_TRUE(Errs.empty()); Errs.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Fails because `-ab` and `--ab` are treated the same and appear more than
+ // once. Also, `val1` is unexpected.
+ EXPECT_FALSE(
+ cl::ParseCommandLineOptions(4, args3, StringRef(), &OS)); OS.flush();
+ outs()<< Errs << "\n";
+ EXPECT_FALSE(Errs.empty()); Errs.clear();
+ cl::ResetAllOptionOccurrences();
+
+ //
+ // The following tests treat `-` and `--` differently, with `-` for short, and
+ // `--` for long options.
+ //
+
+ // Fails because `-ab` is treated as `-a -b`, so `-a` is seen twice, and
+ // `val1` is unexpected.
+ EXPECT_FALSE(cl::ParseCommandLineOptions(4, args1, StringRef(),
+ &OS, nullptr, true)); OS.flush();
+ EXPECT_FALSE(Errs.empty()); Errs.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Works because `-a` is treated differently than `--ab`.
+ EXPECT_TRUE(cl::ParseCommandLineOptions(4, args2, StringRef(),
+ &OS, nullptr, true)); OS.flush();
+ EXPECT_TRUE(Errs.empty()); Errs.clear();
+ cl::ResetAllOptionOccurrences();
+
+ // Works because `-ab` is treated as `-a -b`, and `--ab` is a long option.
+ EXPECT_TRUE(cl::ParseCommandLineOptions(4, args3, StringRef(),
+ &OS, nullptr, true));
+ EXPECT_TRUE(OptA);
+ EXPECT_TRUE(OptBLong);
+ EXPECT_STREQ("val1", OptAB.c_str());
+ OS.flush();
+ EXPECT_TRUE(Errs.empty()); Errs.clear();
+ cl::ResetAllOptionOccurrences();
+}
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp b/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp
index e9f36c5..cc7be43 100644
--- a/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/CompressionTest.cpp - Compression tests ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp b/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp
index dd6e0df..8301972 100644
--- a/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/ConvertUTFTest.cpp - ConvertUTF tests --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp b/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
index ac531b2..d863dd0 100644
--- a/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/CrashRecoveryTest.cpp ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/DJBTest.cpp b/src/llvm-project/llvm/unittests/Support/DJBTest.cpp
index b157b96..c01bbe1 100644
--- a/src/llvm-project/llvm/unittests/Support/DJBTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DJBTest.cpp
@@ -1,9 +1,8 @@
//===---------- llvm/unittest/Support/DJBTest.cpp -------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp b/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
index 8b64552..9726a74 100644
--- a/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/DataExtractorTest.cpp - DataExtractor tests --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -117,4 +116,14 @@
EXPECT_EQ(8U, offset);
}
+TEST(DataExtractorTest, LEB128_error) {
+ DataExtractor DE(StringRef("\x81"), false, 8);
+ uint32_t Offset = 0;
+ EXPECT_EQ(0U, DE.getULEB128(&Offset));
+ EXPECT_EQ(0U, Offset);
+
+ Offset = 0;
+ EXPECT_EQ(0U, DE.getSLEB128(&Offset));
+ EXPECT_EQ(0U, Offset);
+}
}
diff --git a/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp b/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp
index 32bf56c..e7345b1 100644
--- a/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/DebugCounterTest.cpp -------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/DebugTest.cpp b/src/llvm-project/llvm/unittests/Support/DebugTest.cpp
index 7db91ff..e68e376 100644
--- a/src/llvm-project/llvm/unittests/Support/DebugTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DebugTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/DebugTest.cpp --------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
index 50a0f1e..d1afd50 100644
--- a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/DynamicLibrary/DynamicLibraryTest.cpp --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp
index 370c8cb..e1c6596 100644
--- a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/DynamicLibrary/ExportedFuncs.cpp -------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
index e2f1cf7..8ff2c30 100644
--- a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/DynamicLibrary/PipSqueak.cpp -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
index b44c61d..a32c06c 100644
--- a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/DynamicLibrary/PipSqueak.h -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp b/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp
index 9f938ee..1e800ff 100644
--- a/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Support/EndianStreamTest.cpp - EndianStream.h tests ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/EndianTest.cpp b/src/llvm-project/llvm/unittests/Support/EndianTest.cpp
index c2b5572..b5e4a9c 100644
--- a/src/llvm-project/llvm/unittests/Support/EndianTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/EndianTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Support/EndianTest.cpp - Endian.h tests ------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -201,4 +200,13 @@
EXPECT_EQ(*big_val, *little_val);
}
+TEST(Endian, PacketEndianSpecificIntegralAsEnum) {
+ enum class Test : uint16_t { ONETWO = 0x0102, TWOONE = 0x0201 };
+ unsigned char bytes[] = {0x01, 0x02};
+ using LittleTest = little_t<Test>;
+ using BigTest = big_t<Test>;
+ EXPECT_EQ(Test::TWOONE, *reinterpret_cast<LittleTest *>(bytes));
+ EXPECT_EQ(Test::ONETWO, *reinterpret_cast<BigTest *>(bytes));
+}
+
} // end anon namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp
index 701ac96..747d9dd 100644
--- a/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp
@@ -1,9 +1,8 @@
//===- ErrnoTest.cpp - Error handling unit tests --------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp
index 2ffc6e5..6e5bd2e 100644
--- a/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/ErrorOrTest.cpp - ErrorOr.h tests ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
index eee2fe2..c4a9f3e 100644
--- a/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
@@ -1,9 +1,8 @@
//===----- unittests/ErrorTest.cpp - Error.h tests ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp b/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp
new file mode 100644
index 0000000..2275d72
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp
@@ -0,0 +1,573 @@
+//===- llvm/unittest/Support/FileCheckTest.cpp - FileCheck tests --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/FileCheck.h"
+#include "gtest/gtest.h"
+#include <unordered_set>
+
+using namespace llvm;
+namespace {
+
+class FileCheckTest : public ::testing::Test {};
+
+TEST_F(FileCheckTest, Literal) {
+ // Eval returns the literal's value.
+ FileCheckExpressionLiteral Ten(10);
+ Expected<uint64_t> Value = Ten.eval();
+ EXPECT_TRUE(bool(Value));
+ EXPECT_EQ(10U, *Value);
+
+ // Max value can be correctly represented.
+ FileCheckExpressionLiteral Max(std::numeric_limits<uint64_t>::max());
+ Value = Max.eval();
+ EXPECT_TRUE(bool(Value));
+ EXPECT_EQ(std::numeric_limits<uint64_t>::max(), *Value);
+}
+
+static std::string toString(const std::unordered_set<std::string> &Set) {
+ bool First = true;
+ std::string Str;
+ for (StringRef S : Set) {
+ Str += Twine(First ? "{" + S : ", " + S).str();
+ First = false;
+ }
+ Str += '}';
+ return Str;
+}
+
+static void
+expectUndefErrors(std::unordered_set<std::string> ExpectedUndefVarNames,
+ Error Err) {
+ handleAllErrors(std::move(Err), [&](const FileCheckUndefVarError &E) {
+ ExpectedUndefVarNames.erase(E.getVarName());
+ });
+ EXPECT_TRUE(ExpectedUndefVarNames.empty()) << toString(ExpectedUndefVarNames);
+}
+
+static void expectUndefError(const Twine &ExpectedUndefVarName, Error Err) {
+ expectUndefErrors({ExpectedUndefVarName.str()}, std::move(Err));
+}
+
+TEST_F(FileCheckTest, NumericVariable) {
+ // Undefined variable: getValue and eval fail, error returned by eval holds
+ // the name of the undefined variable and setValue does not trigger assert.
+ FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 1);
+ EXPECT_EQ("FOO", FooVar.getName());
+ FileCheckNumericVariableUse FooVarUse =
+ FileCheckNumericVariableUse("FOO", &FooVar);
+ EXPECT_FALSE(FooVar.getValue());
+ Expected<uint64_t> EvalResult = FooVarUse.eval();
+ EXPECT_FALSE(EvalResult);
+ expectUndefError("FOO", EvalResult.takeError());
+ FooVar.setValue(42);
+
+ // Defined variable: getValue and eval return value set.
+ Optional<uint64_t> Value = FooVar.getValue();
+ EXPECT_TRUE(bool(Value));
+ EXPECT_EQ(42U, *Value);
+ EvalResult = FooVarUse.eval();
+ EXPECT_TRUE(bool(EvalResult));
+ EXPECT_EQ(42U, *EvalResult);
+
+ // Clearing variable: getValue and eval fail. Error returned by eval holds
+ // the name of the cleared variable.
+ FooVar.clearValue();
+ Value = FooVar.getValue();
+ EXPECT_FALSE(Value);
+ EvalResult = FooVarUse.eval();
+ EXPECT_FALSE(EvalResult);
+ expectUndefError("FOO", EvalResult.takeError());
+}
+
+uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
+
+TEST_F(FileCheckTest, Binop) {
+ FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO");
+ FooVar.setValue(42);
+ std::unique_ptr<FileCheckNumericVariableUse> FooVarUse =
+ llvm::make_unique<FileCheckNumericVariableUse>("FOO", &FooVar);
+ FileCheckNumericVariable BarVar = FileCheckNumericVariable("BAR");
+ BarVar.setValue(18);
+ std::unique_ptr<FileCheckNumericVariableUse> BarVarUse =
+ llvm::make_unique<FileCheckNumericVariableUse>("BAR", &BarVar);
+ FileCheckASTBinop Binop =
+ FileCheckASTBinop(doAdd, std::move(FooVarUse), std::move(BarVarUse));
+
+ // Defined variable: eval returns right value.
+ Expected<uint64_t> Value = Binop.eval();
+ EXPECT_TRUE(bool(Value));
+ EXPECT_EQ(60U, *Value);
+
+ // 1 undefined variable: eval fails, error contains name of undefined
+ // variable.
+ FooVar.clearValue();
+ Value = Binop.eval();
+ EXPECT_FALSE(Value);
+ expectUndefError("FOO", Value.takeError());
+
+ // 2 undefined variables: eval fails, error contains names of all undefined
+ // variables.
+ BarVar.clearValue();
+ Value = Binop.eval();
+ EXPECT_FALSE(Value);
+ expectUndefErrors({"FOO", "BAR"}, Value.takeError());
+}
+
+TEST_F(FileCheckTest, ValidVarNameStart) {
+ EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('a'));
+ EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('G'));
+ EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('_'));
+ EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('2'));
+ EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('$'));
+ EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('@'));
+ EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('+'));
+ EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('-'));
+ EXPECT_FALSE(FileCheckPattern::isValidVarNameStart(':'));
+}
+
+static StringRef bufferize(SourceMgr &SM, StringRef Str) {
+ std::unique_ptr<MemoryBuffer> Buffer =
+ MemoryBuffer::getMemBufferCopy(Str, "TestBuffer");
+ StringRef StrBufferRef = Buffer->getBuffer();
+ SM.AddNewSourceBuffer(std::move(Buffer), SMLoc());
+ return StrBufferRef;
+}
+
+TEST_F(FileCheckTest, ParseVar) {
+ SourceMgr SM;
+ StringRef OrigVarName = bufferize(SM, "GoodVar42");
+ StringRef VarName = OrigVarName;
+ Expected<FileCheckPattern::VariableProperties> ParsedVarResult =
+ FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(bool(ParsedVarResult));
+ EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
+ EXPECT_TRUE(VarName.empty());
+ EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+ VarName = OrigVarName = bufferize(SM, "$GoodGlobalVar");
+ ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(bool(ParsedVarResult));
+ EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
+ EXPECT_TRUE(VarName.empty());
+ EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+ VarName = OrigVarName = bufferize(SM, "@GoodPseudoVar");
+ ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(bool(ParsedVarResult));
+ EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
+ EXPECT_TRUE(VarName.empty());
+ EXPECT_TRUE(ParsedVarResult->IsPseudo);
+
+ VarName = bufferize(SM, "42BadVar");
+ ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
+
+ VarName = bufferize(SM, "$@");
+ ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
+
+ VarName = OrigVarName = bufferize(SM, "B@dVar");
+ ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(bool(ParsedVarResult));
+ EXPECT_EQ(VarName, OrigVarName.substr(1));
+ EXPECT_EQ(ParsedVarResult->Name, "B");
+ EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+ VarName = OrigVarName = bufferize(SM, "B$dVar");
+ ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(bool(ParsedVarResult));
+ EXPECT_EQ(VarName, OrigVarName.substr(1));
+ EXPECT_EQ(ParsedVarResult->Name, "B");
+ EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+ VarName = bufferize(SM, "BadVar+");
+ ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(bool(ParsedVarResult));
+ EXPECT_EQ(VarName, "+");
+ EXPECT_EQ(ParsedVarResult->Name, "BadVar");
+ EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+ VarName = bufferize(SM, "BadVar-");
+ ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(bool(ParsedVarResult));
+ EXPECT_EQ(VarName, "-");
+ EXPECT_EQ(ParsedVarResult->Name, "BadVar");
+ EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+ VarName = bufferize(SM, "BadVar:");
+ ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+ EXPECT_TRUE(bool(ParsedVarResult));
+ EXPECT_EQ(VarName, ":");
+ EXPECT_EQ(ParsedVarResult->Name, "BadVar");
+ EXPECT_FALSE(ParsedVarResult->IsPseudo);
+}
+
+class PatternTester {
+private:
+ size_t LineNumber = 1;
+ SourceMgr SM;
+ FileCheckRequest Req;
+ FileCheckPatternContext Context;
+ FileCheckPattern P =
+ FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
+
+public:
+ PatternTester() {
+ std::vector<std::string> GlobalDefines;
+ GlobalDefines.emplace_back(std::string("#FOO=42"));
+ GlobalDefines.emplace_back(std::string("BAR=BAZ"));
+ EXPECT_FALSE(
+ errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM)));
+ Context.createLineVariable();
+ // Call parsePattern to have @LINE defined.
+ P.parsePattern("N/A", "CHECK", SM, Req);
+ // parsePattern does not expect to be called twice for the same line and
+ // will set FixedStr and RegExStr incorrectly if it is. Therefore prepare
+ // a pattern for a different line.
+ initNextPattern();
+ }
+
+ void initNextPattern() {
+ P = FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
+ }
+
+ bool parseNumVarDefExpect(StringRef Expr) {
+ StringRef ExprBufferRef = bufferize(SM, Expr);
+ return errorToBool(FileCheckPattern::parseNumericVariableDefinition(
+ ExprBufferRef, &Context, LineNumber, SM)
+ .takeError());
+ }
+
+ bool parseSubstExpect(StringRef Expr) {
+ StringRef ExprBufferRef = bufferize(SM, Expr);
+ Optional<FileCheckNumericVariable *> DefinedNumericVariable;
+ return errorToBool(P.parseNumericSubstitutionBlock(
+ ExprBufferRef, DefinedNumericVariable, false, SM)
+ .takeError());
+ }
+
+ bool parsePatternExpect(StringRef Pattern) {
+ StringRef PatBufferRef = bufferize(SM, Pattern);
+ return P.parsePattern(PatBufferRef, "CHECK", SM, Req);
+ }
+
+ bool matchExpect(StringRef Buffer) {
+ StringRef BufferRef = bufferize(SM, Buffer);
+ size_t MatchLen;
+ return errorToBool(P.match(BufferRef, MatchLen, SM).takeError());
+ }
+};
+
+TEST_F(FileCheckTest, ParseNumericVariableDefinition) {
+ PatternTester Tester;
+
+ // Invalid definition of pseudo.
+ EXPECT_TRUE(Tester.parseNumVarDefExpect("@LINE"));
+
+ // Conflict with pattern variable.
+ EXPECT_TRUE(Tester.parseNumVarDefExpect("BAR"));
+
+ // Defined variable.
+ EXPECT_FALSE(Tester.parseNumVarDefExpect("FOO"));
+}
+
+TEST_F(FileCheckTest, ParseExpr) {
+ PatternTester Tester;
+
+ // Variable definition.
+
+ // Definition of invalid variable.
+ EXPECT_TRUE(Tester.parseSubstExpect("10VAR:"));
+ EXPECT_TRUE(Tester.parseSubstExpect("@FOO:"));
+ EXPECT_TRUE(Tester.parseSubstExpect("@LINE:"));
+
+ // Garbage after name of variable being defined.
+ EXPECT_TRUE(Tester.parseSubstExpect("VAR GARBAGE:"));
+
+ // Variable defined to numeric expression.
+ EXPECT_TRUE(Tester.parseSubstExpect("VAR1: FOO"));
+
+ // Acceptable variable definition.
+ EXPECT_FALSE(Tester.parseSubstExpect("VAR1:"));
+ EXPECT_FALSE(Tester.parseSubstExpect(" VAR2:"));
+ EXPECT_FALSE(Tester.parseSubstExpect("VAR3 :"));
+ EXPECT_FALSE(Tester.parseSubstExpect("VAR3: "));
+
+ // Numeric expression.
+
+ // Unacceptable variable.
+ EXPECT_TRUE(Tester.parseSubstExpect("10VAR"));
+ EXPECT_TRUE(Tester.parseSubstExpect("@FOO"));
+
+ // Only valid variable.
+ EXPECT_FALSE(Tester.parseSubstExpect("@LINE"));
+ EXPECT_FALSE(Tester.parseSubstExpect("FOO"));
+ EXPECT_FALSE(Tester.parseSubstExpect("UNDEF"));
+
+ // Use variable defined on same line.
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]"));
+ EXPECT_TRUE(Tester.parseSubstExpect("LINE1VAR"));
+
+ // Unsupported operator.
+ EXPECT_TRUE(Tester.parseSubstExpect("@LINE/2"));
+
+ // Missing offset operand.
+ EXPECT_TRUE(Tester.parseSubstExpect("@LINE+"));
+
+ // Valid expression.
+ EXPECT_FALSE(Tester.parseSubstExpect("@LINE+5"));
+ EXPECT_FALSE(Tester.parseSubstExpect("FOO+4"));
+ Tester.initNextPattern();
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+FOO]]"));
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+3-FOO]]"));
+}
+
+TEST_F(FileCheckTest, ParsePattern) {
+ PatternTester Tester;
+
+ // Space in pattern variable expression.
+ EXPECT_TRUE(Tester.parsePatternExpect("[[ BAR]]"));
+
+ // Invalid variable name.
+ EXPECT_TRUE(Tester.parsePatternExpect("[[42INVALID]]"));
+
+ // Invalid pattern variable definition.
+ EXPECT_TRUE(Tester.parsePatternExpect("[[@PAT:]]"));
+ EXPECT_TRUE(Tester.parsePatternExpect("[[PAT+2:]]"));
+
+ // Collision with numeric variable.
+ EXPECT_TRUE(Tester.parsePatternExpect("[[FOO:]]"));
+
+ // Valid use of pattern variable.
+ EXPECT_FALSE(Tester.parsePatternExpect("[[BAR]]"));
+
+ // Valid pattern variable definition.
+ EXPECT_FALSE(Tester.parsePatternExpect("[[PAT:[0-9]+]]"));
+
+ // Invalid numeric expressions.
+ EXPECT_TRUE(Tester.parsePatternExpect("[[#42INVALID]]"));
+ EXPECT_TRUE(Tester.parsePatternExpect("[[#@FOO]]"));
+ EXPECT_TRUE(Tester.parsePatternExpect("[[#@LINE/2]]"));
+ EXPECT_TRUE(Tester.parsePatternExpect("[[#YUP:@LINE]]"));
+
+ // Valid numeric expressions and numeric variable definition.
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO]]"));
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE+2]]"));
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#NUMVAR:]]"));
+}
+
+TEST_F(FileCheckTest, Match) {
+ PatternTester Tester;
+
+ // Check matching a definition only matches a number.
+ Tester.parsePatternExpect("[[#NUMVAR:]]");
+ EXPECT_TRUE(Tester.matchExpect("FAIL"));
+ EXPECT_FALSE(Tester.matchExpect("18"));
+
+ // Check matching the variable defined matches the correct number only
+ Tester.initNextPattern();
+ Tester.parsePatternExpect("[[#NUMVAR]] [[#NUMVAR+2]]");
+ EXPECT_TRUE(Tester.matchExpect("19 21"));
+ EXPECT_TRUE(Tester.matchExpect("18 21"));
+ EXPECT_FALSE(Tester.matchExpect("18 20"));
+
+ // Check matching a numeric expression using @LINE after match failure uses
+ // the correct value for @LINE.
+ Tester.initNextPattern();
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
+ // Ok, @LINE is 4 now.
+ EXPECT_FALSE(Tester.matchExpect("4"));
+ Tester.initNextPattern();
+ // @LINE is now 5, match with substitution failure.
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#UNKNOWN]]"));
+ EXPECT_TRUE(Tester.matchExpect("FOO"));
+ Tester.initNextPattern();
+ // Check that @LINE is 6 as expected.
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
+ EXPECT_FALSE(Tester.matchExpect("6"));
+}
+
+TEST_F(FileCheckTest, Substitution) {
+ SourceMgr SM;
+ FileCheckPatternContext Context;
+ std::vector<std::string> GlobalDefines;
+ GlobalDefines.emplace_back(std::string("FOO=BAR"));
+ EXPECT_FALSE(errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM)));
+
+ // Substitution of an undefined string variable fails and error holds that
+ // variable's name.
+ FileCheckStringSubstitution StringSubstitution =
+ FileCheckStringSubstitution(&Context, "VAR404", 42);
+ Expected<std::string> SubstValue = StringSubstitution.getResult();
+ EXPECT_FALSE(bool(SubstValue));
+ expectUndefError("VAR404", SubstValue.takeError());
+
+ // Substitutions of defined pseudo and non-pseudo numeric variables return
+ // the right value.
+ FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE");
+ LineVar.setValue(42);
+ FileCheckNumericVariable NVar = FileCheckNumericVariable("N");
+ NVar.setValue(10);
+ auto LineVarUse =
+ llvm::make_unique<FileCheckNumericVariableUse>("@LINE", &LineVar);
+ auto NVarUse = llvm::make_unique<FileCheckNumericVariableUse>("N", &NVar);
+ FileCheckNumericSubstitution SubstitutionLine = FileCheckNumericSubstitution(
+ &Context, "@LINE", std::move(LineVarUse), 12);
+ FileCheckNumericSubstitution SubstitutionN =
+ FileCheckNumericSubstitution(&Context, "N", std::move(NVarUse), 30);
+ SubstValue = SubstitutionLine.getResult();
+ EXPECT_TRUE(bool(SubstValue));
+ EXPECT_EQ("42", *SubstValue);
+ SubstValue = SubstitutionN.getResult();
+ EXPECT_TRUE(bool(SubstValue));
+ EXPECT_EQ("10", *SubstValue);
+
+ // Substitution of an undefined numeric variable fails, error holds name of
+ // undefined variable.
+ LineVar.clearValue();
+ SubstValue = SubstitutionLine.getResult();
+ EXPECT_FALSE(bool(SubstValue));
+ expectUndefError("@LINE", SubstValue.takeError());
+ NVar.clearValue();
+ SubstValue = SubstitutionN.getResult();
+ EXPECT_FALSE(bool(SubstValue));
+ expectUndefError("N", SubstValue.takeError());
+
+ // Substitution of a defined string variable returns the right value.
+ FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context, 1);
+ StringSubstitution = FileCheckStringSubstitution(&Context, "FOO", 42);
+ SubstValue = StringSubstitution.getResult();
+ EXPECT_TRUE(bool(SubstValue));
+ EXPECT_EQ("BAR", *SubstValue);
+}
+
+TEST_F(FileCheckTest, FileCheckContext) {
+ FileCheckPatternContext Cxt = FileCheckPatternContext();
+ std::vector<std::string> GlobalDefines;
+ SourceMgr SM;
+
+ // Missing equal sign.
+ GlobalDefines.emplace_back(std::string("LocalVar"));
+ EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+ GlobalDefines.clear();
+ GlobalDefines.emplace_back(std::string("#LocalNumVar"));
+ EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+ // Empty variable name.
+ GlobalDefines.clear();
+ GlobalDefines.emplace_back(std::string("=18"));
+ EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+ GlobalDefines.clear();
+ GlobalDefines.emplace_back(std::string("#=18"));
+ EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+ // Invalid variable name.
+ GlobalDefines.clear();
+ GlobalDefines.emplace_back(std::string("18LocalVar=18"));
+ EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+ GlobalDefines.clear();
+ GlobalDefines.emplace_back(std::string("#18LocalNumVar=18"));
+ EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+ // Name conflict between pattern and numeric variable.
+ GlobalDefines.clear();
+ GlobalDefines.emplace_back(std::string("LocalVar=18"));
+ GlobalDefines.emplace_back(std::string("#LocalVar=36"));
+ EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+ Cxt = FileCheckPatternContext();
+ GlobalDefines.clear();
+ GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
+ GlobalDefines.emplace_back(std::string("LocalNumVar=36"));
+ EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+ Cxt = FileCheckPatternContext();
+
+ // Invalid numeric value for numeric variable.
+ GlobalDefines.clear();
+ GlobalDefines.emplace_back(std::string("#LocalNumVar=x"));
+ EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+ // Define local variables from command-line.
+ GlobalDefines.clear();
+ GlobalDefines.emplace_back(std::string("LocalVar=FOO"));
+ GlobalDefines.emplace_back(std::string("EmptyVar="));
+ GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
+ EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+ // Check defined variables are present and undefined is absent.
+ StringRef LocalVarStr = "LocalVar";
+ StringRef LocalNumVarRef = bufferize(SM, "LocalNumVar");
+ StringRef EmptyVarStr = "EmptyVar";
+ StringRef UnknownVarStr = "UnknownVar";
+ Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr);
+ FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt, 1);
+ Optional<FileCheckNumericVariable *> DefinedNumericVariable;
+ Expected<std::unique_ptr<FileCheckExpressionAST>> ExpressionAST =
+ P.parseNumericSubstitutionBlock(LocalNumVarRef, DefinedNumericVariable,
+ /*IsLegacyLineExpr=*/false, SM);
+ EXPECT_TRUE(bool(LocalVar));
+ EXPECT_EQ(*LocalVar, "FOO");
+ Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
+ Expected<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr);
+ EXPECT_TRUE(bool(ExpressionAST));
+ Expected<uint64_t> ExpressionVal = (*ExpressionAST)->eval();
+ EXPECT_TRUE(bool(ExpressionVal));
+ EXPECT_EQ(*ExpressionVal, 18U);
+ EXPECT_TRUE(bool(EmptyVar));
+ EXPECT_EQ(*EmptyVar, "");
+ EXPECT_TRUE(errorToBool(UnknownVar.takeError()));
+
+ // Clear local variables and check they become absent.
+ Cxt.clearLocalVars();
+ LocalVar = Cxt.getPatternVarValue(LocalVarStr);
+ EXPECT_TRUE(errorToBool(LocalVar.takeError()));
+ // Check a numeric expression's evaluation fails if called after clearing of
+ // local variables, if it was created before. This is important because local
+ // variable clearing due to --enable-var-scope happens after numeric
+ // expressions are linked to the numeric variables they use.
+ EXPECT_TRUE(errorToBool((*ExpressionAST)->eval().takeError()));
+ P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
+ ExpressionAST = P.parseNumericSubstitutionBlock(
+ LocalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
+ EXPECT_TRUE(bool(ExpressionAST));
+ ExpressionVal = (*ExpressionAST)->eval();
+ EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
+ EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
+ EXPECT_TRUE(errorToBool(EmptyVar.takeError()));
+ // Clear again because parseNumericSubstitutionBlock would have created a
+ // dummy variable and stored it in GlobalNumericVariableTable.
+ Cxt.clearLocalVars();
+
+ // Redefine global variables and check variables are defined again.
+ GlobalDefines.emplace_back(std::string("$GlobalVar=BAR"));
+ GlobalDefines.emplace_back(std::string("#$GlobalNumVar=36"));
+ EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+ StringRef GlobalVarStr = "$GlobalVar";
+ StringRef GlobalNumVarRef = bufferize(SM, "$GlobalNumVar");
+ Expected<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr);
+ EXPECT_TRUE(bool(GlobalVar));
+ EXPECT_EQ(*GlobalVar, "BAR");
+ P = FileCheckPattern(Check::CheckPlain, &Cxt, 3);
+ ExpressionAST = P.parseNumericSubstitutionBlock(
+ GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
+ EXPECT_TRUE(bool(ExpressionAST));
+ ExpressionVal = (*ExpressionAST)->eval();
+ EXPECT_TRUE(bool(ExpressionVal));
+ EXPECT_EQ(*ExpressionVal, 36U);
+
+ // Clear local variables and check global variables remain defined.
+ Cxt.clearLocalVars();
+ EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError()));
+ P = FileCheckPattern(Check::CheckPlain, &Cxt, 4);
+ ExpressionAST = P.parseNumericSubstitutionBlock(
+ GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
+ EXPECT_TRUE(bool(ExpressionAST));
+ ExpressionVal = (*ExpressionAST)->eval();
+ EXPECT_TRUE(bool(ExpressionVal));
+ EXPECT_EQ(*ExpressionVal, 36U);
+}
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp b/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
index 5548595..8afc212 100644
--- a/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/FileOutputBuffer.cpp - unit tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -122,53 +121,4 @@
// Clean up.
ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
}
-
-TEST(FileOutputBuffer, TestModify) {
- // Create unique temporary directory for these tests
- SmallString<128> TestDirectory;
- {
- ASSERT_NO_ERROR(
- fs::createUniqueDirectory("FileOutputBuffer-modify", TestDirectory));
- }
-
- SmallString<128> File1(TestDirectory);
- File1.append("/file");
- // First write some data.
- {
- Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
- FileOutputBuffer::create(File1, 10);
- ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
- std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
- memcpy(Buffer->getBufferStart(), "AAAAAAAAAA", 10);
- ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
- }
-
- // Then re-open the file for modify and change only some bytes.
- {
- Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
- FileOutputBuffer::create(File1, size_t(-1), FileOutputBuffer::F_modify);
- ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
- std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
- ASSERT_EQ(10U, Buffer->getBufferSize());
- uint8_t *Data = Buffer->getBufferStart();
- Data[0] = 'X';
- Data[9] = 'X';
- ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
- }
-
- // Finally, re-open the file for read and verify that it has the modified
- // contents.
- {
- ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(File1);
- ASSERT_NO_ERROR(BufferOrErr.getError());
- std::unique_ptr<MemoryBuffer> Buffer = std::move(*BufferOrErr);
- ASSERT_EQ(10U, Buffer->getBufferSize());
- EXPECT_EQ(StringRef("XAAAAAAAAX"), Buffer->getBuffer());
- }
-
- // Clean up.
- ASSERT_NO_ERROR(fs::remove(File1));
- ASSERT_NO_ERROR(fs::remove(TestDirectory));
-}
-
} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp b/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp
index 91a44ba..e9565c1 100644
--- a/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp
@@ -1,9 +1,8 @@
//===- FormatVariadicTest.cpp - Unit tests for string formatting ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp b/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
index d7016ab..113b20e 100644
--- a/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/GlobPatternTest.cpp --------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/Host.cpp b/src/llvm-project/llvm/unittests/Support/Host.cpp
index 0d257a7..ec9dd95 100644
--- a/src/llvm-project/llvm/unittests/Support/Host.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Host.cpp
@@ -1,13 +1,13 @@
//========- unittests/Support/Host.cpp - Host.cpp tests --------------========//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Host.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/FileSystem.h"
@@ -249,6 +249,48 @@
"tsv110");
}
+#if defined(__APPLE__) || defined(_AIX)
+static bool runAndGetCommandOutput(
+ const char *ExePath, ArrayRef<llvm::StringRef> argv,
+ std::unique_ptr<char[]> &Buffer, off_t &Size) {
+ bool Success = false;
+ [ExePath, argv, &Buffer, &Size, &Success] {
+ using namespace llvm::sys;
+ SmallString<128> TestDirectory;
+ ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory));
+
+ SmallString<128> OutputFile(TestDirectory);
+ path::append(OutputFile, "out");
+ StringRef OutputPath = OutputFile.str();
+
+ const Optional<StringRef> Redirects[] = {
+ /*STDIN=*/None, /*STDOUT=*/OutputPath, /*STDERR=*/None};
+ int RetCode = ExecuteAndWait(ExePath, argv, /*env=*/llvm::None, Redirects);
+ ASSERT_EQ(0, RetCode);
+
+ int FD = 0;
+ ASSERT_NO_ERROR(fs::openFileForRead(OutputPath, FD));
+ Size = ::lseek(FD, 0, SEEK_END);
+ ASSERT_NE(-1, Size);
+ ::lseek(FD, 0, SEEK_SET);
+ Buffer = llvm::make_unique<char[]>(Size);
+ ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
+ ::close(FD);
+
+ ASSERT_NO_ERROR(fs::remove(OutputPath));
+ ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+ Success = true;
+ }();
+ return Success;
+}
+
+TEST_F(HostTest, DummyRunAndGetCommandOutputUse) {
+ // Suppress defined-but-not-used warnings when the tests using the helper are
+ // disabled.
+ (void) runAndGetCommandOutput;
+}
+#endif
+
#if defined(__APPLE__)
TEST_F(HostTest, getMacOSHostVersion) {
using namespace llvm::sys;
@@ -256,31 +298,14 @@
if (!HostTriple.isMacOSX())
return;
- SmallString<128> TestDirectory;
- ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory));
- SmallString<128> OutputFile(TestDirectory);
- path::append(OutputFile, "out");
-
const char *SwVersPath = "/usr/bin/sw_vers";
StringRef argv[] = {SwVersPath, "-productVersion"};
- StringRef OutputPath = OutputFile.str();
- const Optional<StringRef> Redirects[] = {/*STDIN=*/None,
- /*STDOUT=*/OutputPath,
- /*STDERR=*/None};
- int RetCode = ExecuteAndWait(SwVersPath, argv, /*env=*/llvm::None, Redirects);
- ASSERT_EQ(0, RetCode);
-
- int FD = 0;
- ASSERT_NO_ERROR(fs::openFileForRead(OutputPath, FD));
- off_t Size = ::lseek(FD, 0, SEEK_END);
- ASSERT_NE(-1, Size);
- ::lseek(FD, 0, SEEK_SET);
- std::unique_ptr<char[]> Buffer = llvm::make_unique<char[]>(Size);
- ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
- ::close(FD);
+ std::unique_ptr<char[]> Buffer;
+ off_t Size;
+ ASSERT_EQ(runAndGetCommandOutput(SwVersPath, argv, Buffer, Size), true);
+ StringRef SystemVersion(Buffer.get(), Size);
// Ensure that the two versions match.
- StringRef SystemVersion(Buffer.get(), Size);
unsigned SystemMajor, SystemMinor, SystemMicro;
ASSERT_EQ(llvm::Triple((Twine("x86_64-apple-macos") + SystemVersion))
.getMacOSXVersion(SystemMajor, SystemMinor, SystemMicro),
@@ -291,8 +316,52 @@
// Don't compare the 'Micro' version, as it's always '0' for the 'Darwin'
// triples.
ASSERT_EQ(std::tie(SystemMajor, SystemMinor), std::tie(HostMajor, HostMinor));
+}
+#endif
- ASSERT_NO_ERROR(fs::remove(OutputPath));
- ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+#if defined(_AIX)
+TEST_F(HostTest, AIXVersionDetect) {
+ using namespace llvm::sys;
+
+ llvm::Triple HostTriple(getProcessTriple());
+ ASSERT_EQ(HostTriple.getOS(), Triple::AIX);
+
+ llvm::Triple ConfiguredHostTriple(LLVM_HOST_TRIPLE);
+ ASSERT_EQ(ConfiguredHostTriple.getOS(), Triple::AIX);
+
+ const char *ExePath = "/usr/bin/oslevel";
+ StringRef argv[] = {ExePath};
+ std::unique_ptr<char[]> Buffer;
+ off_t Size;
+ ASSERT_EQ(runAndGetCommandOutput(ExePath, argv, Buffer, Size), true);
+ StringRef SystemVersion(Buffer.get(), Size);
+
+ unsigned SystemMajor, SystemMinor, SystemMicro;
+ llvm::Triple((Twine("powerpc-ibm-aix") + SystemVersion))
+ .getOSVersion(SystemMajor, SystemMinor, SystemMicro);
+
+ // Ensure that the host triple version (major) and release (minor) numbers,
+ // unless explicitly configured, match with those of the current system.
+ if (!ConfiguredHostTriple.getOSMajorVersion()) {
+ unsigned HostMajor, HostMinor, HostMicro;
+ HostTriple.getOSVersion(HostMajor, HostMinor, HostMicro);
+ ASSERT_EQ(std::tie(SystemMajor, SystemMinor),
+ std::tie(HostMajor, HostMinor));
+ }
+
+ llvm::Triple TargetTriple(getDefaultTargetTriple());
+ if (TargetTriple.getOS() != Triple::AIX)
+ return;
+
+ // Ensure that the target triple version (major) and release (minor) numbers
+ // match with those of the current system.
+ llvm::Triple ConfiguredTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
+ if (ConfiguredTargetTriple.getOSMajorVersion())
+ return; // The version was configured explicitly; skip.
+
+ unsigned TargetMajor, TargetMinor, TargetMicro;
+ TargetTriple.getOSVersion(TargetMajor, TargetMinor, TargetMicro);
+ ASSERT_EQ(std::tie(SystemMajor, SystemMinor),
+ std::tie(TargetMajor, TargetMinor));
}
#endif
diff --git a/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp b/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
index 2fd6bd8..9143289 100644
--- a/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
@@ -1,9 +1,8 @@
//===-------------- ItaniumManglingCanonicalizerTest.cpp ------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/JSONTest.cpp b/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
index 9f2d47b..14c11b1 100644
--- a/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
@@ -1,13 +1,13 @@
//===-- JSONTest.cpp - JSON unit tests --------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/JSON.h"
+#include "llvm/Support/raw_ostream.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -384,6 +384,44 @@
<< "Wrong type for Optional<T> " << V;
}
+TEST(JSONTest, Stream) {
+ auto StreamStuff = [](unsigned Indent) {
+ std::string S;
+ llvm::raw_string_ostream OS(S);
+ OStream J(OS, Indent);
+ J.object([&] {
+ J.attributeArray("foo", [&] {
+ J.value(nullptr);
+ J.value(42.5);
+ J.arrayBegin();
+ J.value(43);
+ J.arrayEnd();
+ });
+ J.attributeBegin("bar");
+ J.objectBegin();
+ J.objectEnd();
+ J.attributeEnd();
+ J.attribute("baz", "xyz");
+ });
+ return OS.str();
+ };
+
+ const char *Plain = R"({"foo":[null,42.5,[43]],"bar":{},"baz":"xyz"})";
+ EXPECT_EQ(Plain, StreamStuff(0));
+ const char *Pretty = R"({
+ "foo": [
+ null,
+ 42.5,
+ [
+ 43
+ ]
+ ],
+ "bar": {},
+ "baz": "xyz"
+})";
+ EXPECT_EQ(Pretty, StreamStuff(2));
+}
+
} // namespace
} // namespace json
} // namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp b/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp
new file mode 100644
index 0000000..c2b3b12
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp
@@ -0,0 +1,130 @@
+//===- llvm/unittest/Support/KnownBitsTest.cpp - KnownBits tests ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unit tests for KnownBits functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/KnownBits.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+template<typename FnTy>
+void ForeachKnownBits(unsigned Bits, FnTy Fn) {
+ unsigned Max = 1 << Bits;
+ KnownBits Known(Bits);
+ for (unsigned Zero = 0; Zero < Max; ++Zero) {
+ for (unsigned One = 0; One < Max; ++One) {
+ Known.Zero = Zero;
+ Known.One = One;
+ if (Known.hasConflict())
+ continue;
+
+ Fn(Known);
+ }
+ }
+}
+
+template<typename FnTy>
+void ForeachNumInKnownBits(const KnownBits &Known, FnTy Fn) {
+ unsigned Bits = Known.getBitWidth();
+ unsigned Max = 1 << Bits;
+ for (unsigned N = 0; N < Max; ++N) {
+ APInt Num(Bits, N);
+ if ((Num & Known.Zero) != 0 || (~Num & Known.One) != 0)
+ continue;
+
+ Fn(Num);
+ }
+}
+
+TEST(KnownBitsTest, AddCarryExhaustive) {
+ unsigned Bits = 4;
+ ForeachKnownBits(Bits, [&](const KnownBits &Known1) {
+ ForeachKnownBits(Bits, [&](const KnownBits &Known2) {
+ ForeachKnownBits(1, [&](const KnownBits &KnownCarry) {
+ // Explicitly compute known bits of the addition by trying all
+ // possibilities.
+ KnownBits Known(Bits);
+ Known.Zero.setAllBits();
+ Known.One.setAllBits();
+ ForeachNumInKnownBits(Known1, [&](const APInt &N1) {
+ ForeachNumInKnownBits(Known2, [&](const APInt &N2) {
+ ForeachNumInKnownBits(KnownCarry, [&](const APInt &Carry) {
+ APInt Add = N1 + N2;
+ if (Carry.getBoolValue())
+ ++Add;
+
+ Known.One &= Add;
+ Known.Zero &= ~Add;
+ });
+ });
+ });
+
+ KnownBits KnownComputed = KnownBits::computeForAddCarry(
+ Known1, Known2, KnownCarry);
+ EXPECT_EQ(Known.Zero, KnownComputed.Zero);
+ EXPECT_EQ(Known.One, KnownComputed.One);
+ });
+ });
+ });
+}
+
+static void TestAddSubExhaustive(bool IsAdd) {
+ unsigned Bits = 4;
+ ForeachKnownBits(Bits, [&](const KnownBits &Known1) {
+ ForeachKnownBits(Bits, [&](const KnownBits &Known2) {
+ KnownBits Known(Bits), KnownNSW(Bits);
+ Known.Zero.setAllBits();
+ Known.One.setAllBits();
+ KnownNSW.Zero.setAllBits();
+ KnownNSW.One.setAllBits();
+
+ ForeachNumInKnownBits(Known1, [&](const APInt &N1) {
+ ForeachNumInKnownBits(Known2, [&](const APInt &N2) {
+ bool Overflow;
+ APInt Res;
+ if (IsAdd)
+ Res = N1.sadd_ov(N2, Overflow);
+ else
+ Res = N1.ssub_ov(N2, Overflow);
+
+ Known.One &= Res;
+ Known.Zero &= ~Res;
+
+ if (!Overflow) {
+ KnownNSW.One &= Res;
+ KnownNSW.Zero &= ~Res;
+ }
+ });
+ });
+
+ KnownBits KnownComputed = KnownBits::computeForAddSub(
+ IsAdd, /*NSW*/false, Known1, Known2);
+ EXPECT_EQ(Known.Zero, KnownComputed.Zero);
+ EXPECT_EQ(Known.One, KnownComputed.One);
+
+ // The NSW calculation is not precise, only check that it's
+ // conservatively correct.
+ KnownBits KnownNSWComputed = KnownBits::computeForAddSub(
+ IsAdd, /*NSW*/true, Known1, Known2);
+ EXPECT_TRUE(KnownNSWComputed.Zero.isSubsetOf(KnownNSW.Zero));
+ EXPECT_TRUE(KnownNSWComputed.One.isSubsetOf(KnownNSW.One));
+ });
+ });
+}
+
+TEST(KnownBitsTest, AddSubExhaustive) {
+ TestAddSubExhaustive(true);
+ TestAddSubExhaustive(false);
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp b/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp
index 1c9b5db..e429279 100644
--- a/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/LEB128Test.cpp - LEB128 function tests -------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp b/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp
index 67f9d97..96cf37a 100644
--- a/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp
@@ -1,9 +1,8 @@
//===- LineIterator.cpp - Unit tests --------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp b/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp
index 1775d05..5f1fe0f 100644
--- a/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/LockFileManagerTest.cpp - LockFileManager tests ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/MD5Test.cpp b/src/llvm-project/llvm/unittests/Support/MD5Test.cpp
index bac1ec2..3a24e1f 100644
--- a/src/llvm-project/llvm/unittests/Support/MD5Test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MD5Test.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/MD5Test.cpp - MD5 tests ----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp b/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp
index d3cc80c..3e9e3f5 100644
--- a/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/ManagedStatic.cpp - ManagedStatic tests ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/MatchersTest.cpp b/src/llvm-project/llvm/unittests/Support/MatchersTest.cpp
new file mode 100644
index 0000000..3248686
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/MatchersTest.cpp
@@ -0,0 +1,25 @@
+//===----- unittests/MatchersTest.cpp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
+#include "gmock/gmock-matchers.h"
+
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::Gt;
+using ::testing::Lt;
+using ::testing::Not;
+
+namespace {
+TEST(MatchersTest, Optional) {
+ EXPECT_THAT(llvm::Optional<int>(llvm::None), Not(llvm::ValueIs(_)));
+ EXPECT_THAT(llvm::Optional<int>(10), llvm::ValueIs(10));
+ EXPECT_THAT(llvm::Optional<int>(10), llvm::ValueIs(AllOf(Lt(11), Gt(9))));
+}
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp b/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
index 694a1f2..de87714 100644
--- a/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Support/MathExtrasTest.cpp - math utils tests ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp b/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
index 034b2ea..2f96643 100644
--- a/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/MemoryBufferTest.cpp - MemoryBuffer tests ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -150,11 +149,11 @@
EXPECT_FALSE(sys::fs::openFileForRead(TestPath.c_str(), TestFD));
}
- ErrorOr<OwningBuffer> Buf =
- MemoryBuffer::getOpenFileSlice(TestFD, TestPath.c_str(),
- 40000, // Size
- 80000 // Offset
- );
+ ErrorOr<OwningBuffer> Buf = MemoryBuffer::getOpenFileSlice(
+ sys::fs::convertFDToNativeFile(TestFD), TestPath.c_str(),
+ 40000, // Size
+ 80000 // Offset
+ );
std::error_code EC = Buf.getError();
EXPECT_FALSE(EC);
diff --git a/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp b/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp
index bc2fba0..af33dc3 100644
--- a/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -51,7 +50,7 @@
public:
MappedMemoryTest() {
Flags = GetParam();
- PageSize = sys::Process::getPageSize();
+ PageSize = sys::Process::getPageSizeEstimate();
}
protected:
@@ -77,9 +76,9 @@
return true;
if (M1.base() > M2.base())
- return (unsigned char *)M2.base() + M2.size() > M1.base();
+ return (unsigned char *)M2.base() + M2.allocatedSize() > M1.base();
- return (unsigned char *)M1.base() + M1.size() > M2.base();
+ return (unsigned char *)M1.base() + M1.allocatedSize() > M2.base();
}
unsigned Flags;
@@ -101,7 +100,23 @@
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(sizeof(int), M1.size());
+ EXPECT_LE(sizeof(int), M1.allocatedSize());
+
+ EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+}
+
+TEST_P(MappedMemoryTest, AllocAndReleaseHuge) {
+ CHECK_UNSUPPORTED();
+ std::error_code EC;
+ MemoryBlock M1 = Memory::allocateMappedMemory(
+ sizeof(int), nullptr, Flags | Memory::MF_HUGE_HINT, EC);
+ EXPECT_EQ(std::error_code(), EC);
+
+ // Test large/huge memory pages. In the worst case, 4kb pages should be
+ // returned, if large pages aren't available.
+
+ EXPECT_NE((void *)nullptr, M1.base());
+ EXPECT_LE(sizeof(int), M1.allocatedSize());
EXPECT_FALSE(Memory::releaseMappedMemory(M1));
}
@@ -117,11 +132,11 @@
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(16U, M1.size());
+ EXPECT_LE(16U, M1.allocatedSize());
EXPECT_NE((void*)nullptr, M2.base());
- EXPECT_LE(64U, M2.size());
+ EXPECT_LE(64U, M2.allocatedSize());
EXPECT_NE((void*)nullptr, M3.base());
- EXPECT_LE(32U, M3.size());
+ EXPECT_LE(32U, M3.allocatedSize());
EXPECT_FALSE(doesOverlap(M1, M2));
EXPECT_FALSE(doesOverlap(M2, M3));
@@ -132,7 +147,7 @@
MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M4.base());
- EXPECT_LE(16U, M4.size());
+ EXPECT_LE(16U, M4.allocatedSize());
EXPECT_FALSE(Memory::releaseMappedMemory(M4));
EXPECT_FALSE(Memory::releaseMappedMemory(M2));
}
@@ -149,7 +164,7 @@
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(sizeof(int), M1.size());
+ EXPECT_LE(sizeof(int), M1.allocatedSize());
int *a = (int*)M1.base();
*a = 1;
@@ -181,11 +196,11 @@
EXPECT_FALSE(doesOverlap(M1, M3));
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(1U * sizeof(int), M1.size());
+ EXPECT_LE(1U * sizeof(int), M1.allocatedSize());
EXPECT_NE((void*)nullptr, M2.base());
- EXPECT_LE(8U * sizeof(int), M2.size());
+ EXPECT_LE(8U * sizeof(int), M2.allocatedSize());
EXPECT_NE((void*)nullptr, M3.base());
- EXPECT_LE(4U * sizeof(int), M3.size());
+ EXPECT_LE(4U * sizeof(int), M3.allocatedSize());
int *x = (int*)M1.base();
*x = 1;
@@ -209,7 +224,7 @@
Flags, EC);
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M4.base());
- EXPECT_LE(64U * sizeof(int), M4.size());
+ EXPECT_LE(64U * sizeof(int), M4.allocatedSize());
x = (int*)M4.base();
*x = 4;
EXPECT_EQ(4, *x);
@@ -240,11 +255,11 @@
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(2U * sizeof(int), M1.size());
+ EXPECT_LE(2U * sizeof(int), M1.allocatedSize());
EXPECT_NE((void*)nullptr, M2.base());
- EXPECT_LE(8U * sizeof(int), M2.size());
+ EXPECT_LE(8U * sizeof(int), M2.allocatedSize());
EXPECT_NE((void*)nullptr, M3.base());
- EXPECT_LE(4U * sizeof(int), M3.size());
+ EXPECT_LE(4U * sizeof(int), M3.allocatedSize());
EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
@@ -274,7 +289,7 @@
MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M4.base());
- EXPECT_LE(16U, M4.size());
+ EXPECT_LE(16U, M4.allocatedSize());
EXPECT_EQ(std::error_code(),
Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
x = (int*)M4.base();
@@ -295,11 +310,11 @@
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(16U, M1.size());
+ EXPECT_LE(16U, M1.allocatedSize());
EXPECT_NE((void*)nullptr, M2.base());
- EXPECT_LE(64U, M2.size());
+ EXPECT_LE(64U, M2.allocatedSize());
EXPECT_NE((void*)nullptr, M3.base());
- EXPECT_LE(32U, M3.size());
+ EXPECT_LE(32U, M3.allocatedSize());
EXPECT_FALSE(doesOverlap(M1, M2));
EXPECT_FALSE(doesOverlap(M2, M3));
@@ -322,11 +337,11 @@
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(16U, M1.size());
+ EXPECT_LE(16U, M1.allocatedSize());
EXPECT_NE((void*)nullptr, M2.base());
- EXPECT_LE(64U, M2.size());
+ EXPECT_LE(64U, M2.allocatedSize());
EXPECT_NE((void*)nullptr, M3.base());
- EXPECT_LE(32U, M3.size());
+ EXPECT_LE(32U, M3.allocatedSize());
EXPECT_FALSE(Memory::releaseMappedMemory(M1));
EXPECT_FALSE(Memory::releaseMappedMemory(M3));
@@ -345,11 +360,11 @@
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(16U, M1.size());
+ EXPECT_LE(16U, M1.allocatedSize());
EXPECT_NE((void*)nullptr, M2.base());
- EXPECT_LE(64U, M2.size());
+ EXPECT_LE(64U, M2.allocatedSize());
EXPECT_NE((void*)nullptr, M3.base());
- EXPECT_LE(32U, M3.size());
+ EXPECT_LE(32U, M3.allocatedSize());
EXPECT_FALSE(doesOverlap(M1, M2));
EXPECT_FALSE(doesOverlap(M2, M3));
@@ -372,11 +387,11 @@
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(16U, M1.size());
+ EXPECT_LE(16U, M1.allocatedSize());
EXPECT_NE((void*)nullptr, M2.base());
- EXPECT_LE(64U, M2.size());
+ EXPECT_LE(64U, M2.allocatedSize());
EXPECT_NE((void*)nullptr, M3.base());
- EXPECT_LE(32U, M3.size());
+ EXPECT_LE(32U, M3.allocatedSize());
EXPECT_FALSE(doesOverlap(M1, M2));
EXPECT_FALSE(doesOverlap(M2, M3));
@@ -395,7 +410,7 @@
EXPECT_EQ(std::error_code(), EC);
EXPECT_NE((void*)nullptr, M1.base());
- EXPECT_LE(sizeof(int), M1.size());
+ EXPECT_LE(sizeof(int), M1.allocatedSize());
EXPECT_FALSE(Memory::releaseMappedMemory(M1));
}
diff --git a/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp b/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp
index 52acb6a..bbe9aa6 100644
--- a/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp
+++ b/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/NativeFormatTests.cpp - formatting tests -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp b/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp
index 8779a61..63c7152 100644
--- a/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/ParallelTest.cpp -----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/src/llvm-project/llvm/unittests/Support/Path.cpp b/src/llvm-project/llvm/unittests/Support/Path.cpp
index 97b77e2..ccd72d7 100644
--- a/src/llvm-project/llvm/unittests/Support/Path.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Path.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/Path.cpp - Path tests ------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -579,6 +578,7 @@
auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
ASSERT_TRUE((bool)TempFileOrError);
fs::TempFile File = std::move(*TempFileOrError);
+ ASSERT_EQ(-1, TempFileOrError->FD);
ASSERT_FALSE((bool)File.keep(TestDirectory + "/keep"));
ASSERT_FALSE((bool)File.discard());
ASSERT_TRUE(fs::exists(TestDirectory + "/keep"));
@@ -590,6 +590,7 @@
auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
ASSERT_TRUE((bool)TempFileOrError);
fs::TempFile File = std::move(*TempFileOrError);
+ ASSERT_EQ(-1, TempFileOrError->FD);
ASSERT_FALSE((bool)File.discard());
ASSERT_FALSE((bool)File.discard());
ASSERT_FALSE(fs::exists(TestDirectory + "/keep"));
@@ -701,10 +702,18 @@
}
};
- // We should be able to create exactly 16 temporary files.
- for (int i = 0; i < 16; ++i)
- EXPECT_TRUE(TryCreateTempFile());
- EXPECT_FALSE(TryCreateTempFile());
+ // Our single-character template allows for 16 unique names. Check that
+ // calling TryCreateTempFile repeatedly results in 16 successes.
+ // Because the test depends on random numbers, it could theoretically fail.
+ // However, the probability of this happening is tiny: with 32 calls, each
+ // of which will retry up to 128 times, to not get a given digit we would
+ // have to fail at least 15 + 17 * 128 = 2191 attempts. The probability of
+ // 2191 attempts not producing a given hexadecimal digit is
+ // (1 - 1/16) ** 2191 or 3.88e-62.
+ int Successes = 0;
+ for (int i = 0; i < 32; ++i)
+ if (TryCreateTempFile()) ++Successes;
+ EXPECT_EQ(Successes, 16);
for (fs::TempFile &T : TempFiles)
cantFail(T.discard());
@@ -1075,7 +1084,7 @@
std::error_code EC;
StringRef Val("hello there");
{
- fs::mapped_file_region mfr(FileDescriptor,
+ fs::mapped_file_region mfr(fs::convertFDToNativeFile(FileDescriptor),
fs::mapped_file_region::readwrite, Size, 0, EC);
ASSERT_NO_ERROR(EC);
std::copy(Val.begin(), Val.end(), mfr.data());
@@ -1090,14 +1099,16 @@
int FD;
EC = fs::openFileForRead(Twine(TempPath), FD);
ASSERT_NO_ERROR(EC);
- fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0, EC);
+ fs::mapped_file_region mfr(fs::convertFDToNativeFile(FD),
+ fs::mapped_file_region::readonly, Size, 0, EC);
ASSERT_NO_ERROR(EC);
// Verify content
EXPECT_EQ(StringRef(mfr.const_data()), Val);
// Unmap temp file
- fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0, EC);
+ fs::mapped_file_region m(fs::convertFDToNativeFile(FD),
+ fs::mapped_file_region::readonly, Size, 0, EC);
ASSERT_NO_ERROR(EC);
ASSERT_EQ(close(FD), 0);
}
@@ -1493,6 +1504,85 @@
verifyWrite(FD, "Buzz", true);
}
+TEST_F(FileSystemTest, is_local) {
+ bool TestDirectoryIsLocal;
+ ASSERT_NO_ERROR(fs::is_local(TestDirectory, TestDirectoryIsLocal));
+ EXPECT_EQ(TestDirectoryIsLocal, fs::is_local(TestDirectory));
+
+ int FD;
+ SmallString<128> TempPath;
+ ASSERT_NO_ERROR(
+ fs::createUniqueFile(Twine(TestDirectory) + "/temp", FD, TempPath));
+ FileRemover Cleanup(TempPath);
+
+ // Make sure it exists.
+ ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
+
+ bool TempFileIsLocal;
+ ASSERT_NO_ERROR(fs::is_local(FD, TempFileIsLocal));
+ EXPECT_EQ(TempFileIsLocal, fs::is_local(FD));
+ ::close(FD);
+
+ // Expect that the file and its parent directory are equally local or equally
+ // remote.
+ EXPECT_EQ(TestDirectoryIsLocal, TempFileIsLocal);
+}
+
+TEST_F(FileSystemTest, getUmask) {
+#ifdef _WIN32
+ EXPECT_EQ(fs::getUmask(), 0U) << "Should always be 0 on Windows.";
+#else
+ unsigned OldMask = ::umask(0022);
+ unsigned CurrentMask = fs::getUmask();
+ EXPECT_EQ(CurrentMask, 0022U)
+ << "getUmask() didn't return previously set umask()";
+ EXPECT_EQ(::umask(OldMask), 0022U) << "getUmask() may have changed umask()";
+#endif
+}
+
+TEST_F(FileSystemTest, RespectUmask) {
+#ifndef _WIN32
+ unsigned OldMask = ::umask(0022);
+
+ int FD;
+ SmallString<128> TempPath;
+ ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
+
+ fs::perms AllRWE = static_cast<fs::perms>(0777);
+
+ ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE));
+
+ ErrorOr<fs::perms> Perms = fs::getPermissions(TempPath);
+ ASSERT_TRUE(!!Perms);
+ EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask by default";
+
+ ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE));
+
+ Perms = fs::getPermissions(TempPath);
+ ASSERT_TRUE(!!Perms);
+ EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask";
+
+ ASSERT_NO_ERROR(
+ fs::setPermissions(FD, static_cast<fs::perms>(AllRWE & ~fs::getUmask())));
+ Perms = fs::getPermissions(TempPath);
+ ASSERT_TRUE(!!Perms);
+ EXPECT_EQ(Perms.get(), static_cast<fs::perms>(0755))
+ << "Did not respect umask";
+
+ (void)::umask(0057);
+
+ ASSERT_NO_ERROR(
+ fs::setPermissions(FD, static_cast<fs::perms>(AllRWE & ~fs::getUmask())));
+ Perms = fs::getPermissions(TempPath);
+ ASSERT_TRUE(!!Perms);
+ EXPECT_EQ(Perms.get(), static_cast<fs::perms>(0720))
+ << "Did not respect umask";
+
+ (void)::umask(OldMask);
+ (void)::close(FD);
+#endif
+}
+
TEST_F(FileSystemTest, set_current_path) {
SmallString<128> path;
@@ -1665,9 +1755,10 @@
EXPECT_TRUE(CheckPermissions(fs::set_gid_on_exe));
// Modern BSDs require root to set the sticky bit on files.
- // AIX without root will mask off (i.e., lose) the sticky bit on files.
+ // AIX and Solaris without root will mask off (i.e., lose) the sticky bit
+ // on files.
#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && \
- !defined(_AIX)
+ !defined(_AIX) && !(defined(__sun__) && defined(__svr4__))
EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError);
EXPECT_TRUE(CheckPermissions(fs::sticky_bit));
diff --git a/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp b/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
index 85b1839..dbfaf8e 100644
--- a/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Support/ProcessTest.cpp -----------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp b/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp
index ec1c85a..85a1d53 100644
--- a/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Support/ProgramTest.cpp -----------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/RegexTest.cpp b/src/llvm-project/llvm/unittests/Support/RegexTest.cpp
index 7e44a3c..eb8160e 100644
--- a/src/llvm-project/llvm/unittests/Support/RegexTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/RegexTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/RegexTest.cpp - Regex tests --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp b/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp
index 15143be..d2273d7 100644
--- a/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/ReplaceFileTest.cpp - unit tests -------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -53,7 +52,8 @@
};
bool FDHasContent(int FD, StringRef Content) {
- auto Buffer = MemoryBuffer::getOpenFile(FD, "", -1);
+ auto Buffer =
+ MemoryBuffer::getOpenFile(sys::fs::convertFDToNativeFile(FD), "", -1);
assert(Buffer);
return Buffer.get()->getBuffer() == Content;
}
@@ -147,8 +147,9 @@
std::error_code EC;
ASSERT_NO_ERROR(fs::openFileForRead(TargetFileName, TargetFD));
ScopedFD X(TargetFD);
- sys::fs::mapped_file_region MFR(
- TargetFD, sys::fs::mapped_file_region::readonly, 10, 0, EC);
+ sys::fs::mapped_file_region MFR(sys::fs::convertFDToNativeFile(TargetFD),
+ sys::fs::mapped_file_region::readonly, 10,
+ 0, EC);
ASSERT_FALSE(EC);
ASSERT_NO_ERROR(fs::rename(SourceFileName, TargetFileName));
diff --git a/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp b/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
index 930bd43..05804e6 100644
--- a/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/ReverseIterationTest.cpp ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp b/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp
index 9e3f6de..3fa63b7 100644
--- a/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/ScaledNumberTest.cpp - ScaledPair tests -----==//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -563,4 +562,7 @@
EXPECT_EQ(1u, (n * n).toInt<uint32_t>());
}
+static_assert(is_trivially_copyable<ScaledNumber<uint32_t>>::value,
+ "trivially copyable");
+
} // end namespace
diff --git a/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp b/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp
index 7bb76f5..a3079a4 100644
--- a/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Support/SourceMgrTest.cpp - SourceMgr tests --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp b/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
index 060703e..2245588 100644
--- a/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
@@ -1,9 +1,8 @@
//===- SpecialCaseListTest.cpp - Unit tests for SpecialCaseList -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/StringPool.cpp b/src/llvm-project/llvm/unittests/Support/StringPool.cpp
index ac39fec..0a540e9 100644
--- a/src/llvm-project/llvm/unittests/Support/StringPool.cpp
+++ b/src/llvm-project/llvm/unittests/Support/StringPool.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/StringPoiil.cpp - StringPool tests -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp b/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp
index 474eac6..9581f07 100644
--- a/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Support/SwapByteOrderTest.cpp - swap byte order test -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp b/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp
index 717df62..6db4b2a 100644
--- a/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Support/SymbolRemappingReaderTest.cpp --------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp b/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp
index 901dd90..bd67e03 100644
--- a/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/TarWriterTest.cpp ----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp b/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
index 18bbb6a..04ee379 100644
--- a/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
@@ -1,9 +1,8 @@
//===----------- TargetParser.cpp - Target Parser -------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -28,7 +27,8 @@
"armv8l", "armv8.1-a", "armv8.1a", "armv8.2-a", "armv8.2a",
"armv8.3-a", "armv8.3a", "armv8.4-a", "armv8.4a", "armv8.5-a",
"armv8.5a", "armv8-r", "armv8r", "armv8-m.base", "armv8m.base",
- "armv8-m.main", "armv8m.main", "iwmmxt", "iwmmxt2", "xscale"
+ "armv8-m.main", "armv8m.main", "iwmmxt", "iwmmxt2", "xscale",
+ "armv8.1-m.main",
};
bool testARMCPU(StringRef CPUName, StringRef ExpectedArch,
@@ -245,6 +245,18 @@
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
ARM::AEK_RAS | ARM::AEK_DOTPROD,
"8.2-A"));
+ EXPECT_TRUE(testARMCPU("cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
+ ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+ ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
+ ARM::AEK_RAS | ARM::AEK_DOTPROD,
+ "8.2-A"));
+ EXPECT_TRUE(testARMCPU("cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
+ ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+ ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
+ ARM::AEK_RAS | ARM::AEK_DOTPROD,
+ "8.2-A"));
EXPECT_TRUE(testARMCPU("cyclone", "armv8-a", "crypto-neon-fp-armv8",
ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
@@ -271,10 +283,18 @@
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_DOTPROD |
ARM::AEK_FP16 | ARM::AEK_RAS,
"8.2-A"));
+ EXPECT_TRUE(testARMCPU("exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
+ ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+ ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_DOTPROD |
+ ARM::AEK_FP16 | ARM::AEK_RAS,
+ "8.2-A"));
EXPECT_TRUE(testARMCPU("cortex-m23", "armv8-m.base", "none",
ARM::AEK_HWDIVTHUMB, "8-M.Baseline"));
EXPECT_TRUE(testARMCPU("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"));
+ EXPECT_TRUE(testARMCPU("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"));
EXPECT_TRUE(testARMCPU("iwmmxt", "iwmmxt", "none",
ARM::AEK_NONE, "iwmmxt"));
EXPECT_TRUE(testARMCPU("xscale", "xscale", "none",
@@ -284,7 +304,7 @@
"7-S"));
}
-static constexpr unsigned NumARMCPUArchs = 82;
+static constexpr unsigned NumARMCPUArchs = 86;
TEST(TargetParserTest, testARMCPUArchList) {
SmallVector<StringRef, NumARMCPUArchs> List;
@@ -399,6 +419,9 @@
testARMArch("armv8-m.main", "generic", "v8m.main",
ARMBuildAttrs::CPUArch::v8_M_Main));
EXPECT_TRUE(
+ testARMArch("armv8.1-m.main", "generic", "v8.1m.main",
+ ARMBuildAttrs::CPUArch::v8_1_M_Main));
+ EXPECT_TRUE(
testARMArch("iwmmxt", "iwmmxt", "",
ARMBuildAttrs::CPUArch::v5TE));
EXPECT_TRUE(
@@ -546,15 +569,37 @@
}
TEST(TargetParserTest, ARMExtensionFeatures) {
- std::vector<StringRef> Features;
- unsigned Extensions = ARM::AEK_CRC | ARM::AEK_CRYPTO | ARM::AEK_DSP |
- ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_MP |
- ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_RAS | ARM::AEK_FP16 |
- ARM::AEK_FP16FML;
+ std::map<unsigned, std::vector<StringRef>> Extensions;
- for (unsigned i = 0; i <= Extensions; i++)
- EXPECT_TRUE(i == 0 ? !ARM::getExtensionFeatures(i, Features)
- : ARM::getExtensionFeatures(i, Features));
+ for (auto &Ext : ARM::ARCHExtNames) {
+ if (Ext.Feature && Ext.NegFeature)
+ Extensions[Ext.ID] = { StringRef(Ext.Feature),
+ StringRef(Ext.NegFeature) };
+ }
+
+ Extensions[ARM::AEK_HWDIVARM] = { "+hwdiv-arm", "-hwdiv-arm" };
+ Extensions[ARM::AEK_HWDIVTHUMB] = { "+hwdiv", "-hwdiv" };
+
+ std::vector<StringRef> Features;
+
+ EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID, Features));
+
+ for (auto &E : Extensions) {
+ // test +extension
+ Features.clear();
+ ARM::getExtensionFeatures(E.first, Features);
+ auto Found =
+ std::find(std::begin(Features), std::end(Features), E.second.at(0));
+ EXPECT_TRUE(Found != std::end(Features));
+ EXPECT_TRUE(Extensions.size() == Features.size());
+
+ // test -extension
+ Features.clear();
+ ARM::getExtensionFeatures(~E.first, Features);
+ Found = std::find(std::begin(Features), std::end(Features), E.second.at(1));
+ EXPECT_TRUE(Found != std::end(Features));
+ EXPECT_TRUE(Extensions.size() == Features.size());
+ }
}
TEST(TargetParserTest, ARMFPUFeatures) {
@@ -586,7 +631,9 @@
{"iwmmxt2", "noiwmmxt2", nullptr, nullptr},
{"maverick", "maverick", nullptr, nullptr},
{"xscale", "noxscale", nullptr, nullptr},
- {"sb", "nosb", "+sb", "-sb"}};
+ {"sb", "nosb", "+sb", "-sb"},
+ {"mve", "nomve", "+mve", "-mve"},
+ {"mve.fp", "nomve.fp", "+mve.fp", "-mve.fp"}};
for (unsigned i = 0; i < array_lengthof(ArchExt); i++) {
EXPECT_EQ(StringRef(ArchExt[i][2]), ARM::getArchExtFeature(ArchExt[i][0]));
@@ -609,7 +656,7 @@
"v7", "v7a", "v7ve", "v7hl", "v7l", "v7-r", "v7r", "v7-m",
"v7m", "v7k", "v7s", "v7e-m", "v7em", "v8-a", "v8", "v8a",
"v8l", "v8.1-a", "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8.4-a",
- "v8.4a", "v8.5-a","v8.5a", "v8-r"
+ "v8.4a", "v8.5-a","v8.5a", "v8-r", "v8m.base", "v8m.main", "v8.1m.main"
};
for (unsigned i = 0; i < array_lengthof(Arch); i++) {
@@ -639,12 +686,15 @@
}
EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("aarch64"));
+ EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("arm64_32"));
EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian("aarch64_be"));
EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64"));
EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_be"));
EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64"));
EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_be"));
+ EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_32"));
+ EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_32"));
}
TEST(TargetParserTest, ARMparseArchProfile) {
@@ -655,6 +705,7 @@
case ARM::ArchKind::ARMV7EM:
case ARM::ArchKind::ARMV8MMainline:
case ARM::ArchKind::ARMV8MBaseline:
+ case ARM::ArchKind::ARMV8_1MMainline:
EXPECT_EQ(ARM::ProfileKind::M, ARM::parseArchProfile(ARMArch[i]));
break;
case ARM::ArchKind::ARMV7R:
@@ -745,6 +796,18 @@
AArch64::AEK_RDM | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
AArch64::AEK_RCPC, "8.2-A"));
EXPECT_TRUE(testAArch64CPU(
+ "cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
+ AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+ AArch64::AEK_RDM | AArch64::AEK_SIMD | AArch64::AEK_RAS |
+ AArch64::AEK_LSE | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
+ AArch64::AEK_RCPC| AArch64::AEK_SSBS, "8.2-A"));
+ EXPECT_TRUE(testAArch64CPU(
+ "cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
+ AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+ AArch64::AEK_RDM | AArch64::AEK_SIMD | AArch64::AEK_RAS |
+ AArch64::AEK_LSE | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
+ AArch64::AEK_RCPC| AArch64::AEK_SSBS, "8.2-A"));
+ EXPECT_TRUE(testAArch64CPU(
"cyclone", "armv8-a", "crypto-neon-fp-armv8",
AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD, "8-A"));
EXPECT_TRUE(testAArch64CPU(
@@ -766,6 +829,12 @@
AArch64::AEK_LSE | AArch64::AEK_RAS | AArch64::AEK_RDM |
AArch64::AEK_SIMD, "8.2-A"));
EXPECT_TRUE(testAArch64CPU(
+ "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
+ AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
+ AArch64::AEK_DOTPROD | AArch64::AEK_FP | AArch64::AEK_FP16 |
+ AArch64::AEK_LSE | AArch64::AEK_RAS | AArch64::AEK_RDM |
+ AArch64::AEK_SIMD, "8.2-A"));
+ EXPECT_TRUE(testAArch64CPU(
"falkor", "armv8-a", "crypto-neon-fp-armv8",
AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
AArch64::AEK_SIMD | AArch64::AEK_RDM, "8-A"));
@@ -806,7 +875,7 @@
"8.2-A"));
}
-static constexpr unsigned NumAArch64CPUArchs = 21;
+static constexpr unsigned NumAArch64CPUArchs = 24;
TEST(TargetParserTest, testAArch64CPUArchList) {
SmallVector<StringRef, NumAArch64CPUArchs> List;
@@ -874,15 +943,25 @@
EXPECT_FALSE(testAArch64Extension("exynos-m3",
AArch64::ArchKind::INVALID, "ras"));
EXPECT_TRUE(testAArch64Extension("exynos-m4",
+ AArch64::ArchKind::INVALID, "dotprod"));
+ EXPECT_TRUE(testAArch64Extension("exynos-m4",
+ AArch64::ArchKind::INVALID, "fp16"));
+ EXPECT_TRUE(testAArch64Extension("exynos-m4",
AArch64::ArchKind::INVALID, "lse"));
EXPECT_TRUE(testAArch64Extension("exynos-m4",
- AArch64::ArchKind::INVALID, "rdm"));
- EXPECT_TRUE(testAArch64Extension("exynos-m4",
AArch64::ArchKind::INVALID, "ras"));
- EXPECT_FALSE(testAArch64Extension("exynos-m4",
- AArch64::ArchKind::INVALID, "fullfp16"));
EXPECT_TRUE(testAArch64Extension("exynos-m4",
+ AArch64::ArchKind::INVALID, "rdm"));
+ EXPECT_TRUE(testAArch64Extension("exynos-m5",
AArch64::ArchKind::INVALID, "dotprod"));
+ EXPECT_TRUE(testAArch64Extension("exynos-m5",
+ AArch64::ArchKind::INVALID, "fp16"));
+ EXPECT_TRUE(testAArch64Extension("exynos-m5",
+ AArch64::ArchKind::INVALID, "lse"));
+ EXPECT_TRUE(testAArch64Extension("exynos-m5",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_TRUE(testAArch64Extension("exynos-m5",
+ AArch64::ArchKind::INVALID, "rdm"));
EXPECT_TRUE(testAArch64Extension("falkor",
AArch64::ArchKind::INVALID, "rdm"));
EXPECT_FALSE(testAArch64Extension("kryo",
@@ -961,18 +1040,50 @@
}
TEST(TargetParserTest, AArch64ExtensionFeatures) {
- std::vector<StringRef> Features;
- unsigned Extensions = AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
- AArch64::AEK_FP | AArch64::AEK_SIMD |
- AArch64::AEK_FP16 | AArch64::AEK_PROFILE |
- AArch64::AEK_RAS | AArch64::AEK_LSE |
- AArch64::AEK_RDM | AArch64::AEK_SVE |
- AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
- AArch64::AEK_FP16FML;
+ std::vector<unsigned> Extensions = {
+ AArch64::AEK_CRC, AArch64::AEK_CRYPTO,
+ AArch64::AEK_FP, AArch64::AEK_SIMD,
+ AArch64::AEK_FP16, AArch64::AEK_PROFILE,
+ AArch64::AEK_RAS, AArch64::AEK_LSE,
+ AArch64::AEK_RDM, AArch64::AEK_DOTPROD,
+ AArch64::AEK_SVE, AArch64::AEK_SVE2,
+ AArch64::AEK_SVE2AES, AArch64::AEK_SVE2SM4,
+ AArch64::AEK_SVE2SHA3, AArch64::AEK_SVE2BITPERM,
+ AArch64::AEK_RCPC, AArch64::AEK_FP16FML };
- for (unsigned i = 0; i <= Extensions; i++)
- EXPECT_TRUE(i == 0 ? !AArch64::getExtensionFeatures(i, Features)
- : AArch64::getExtensionFeatures(i, Features));
+ std::vector<StringRef> Features;
+
+ unsigned ExtVal = 0;
+ for (auto Ext : Extensions)
+ ExtVal |= Ext;
+
+ EXPECT_FALSE(AArch64::getExtensionFeatures(AArch64::AEK_INVALID, Features));
+ EXPECT_TRUE(!Features.size());
+
+ AArch64::getExtensionFeatures(ExtVal, Features);
+ EXPECT_TRUE(Extensions.size() == Features.size());
+
+ auto B = std::begin(Features);
+ auto E = std::end(Features);
+
+ EXPECT_TRUE(std::find(B, E, "+crc") != E);
+ EXPECT_TRUE(std::find(B, E, "+crypto") != E);
+ EXPECT_TRUE(std::find(B, E, "+fp-armv8") != E);
+ EXPECT_TRUE(std::find(B, E, "+neon") != E);
+ EXPECT_TRUE(std::find(B, E, "+fullfp16") != E);
+ EXPECT_TRUE(std::find(B, E, "+spe") != E);
+ EXPECT_TRUE(std::find(B, E, "+ras") != E);
+ EXPECT_TRUE(std::find(B, E, "+lse") != E);
+ EXPECT_TRUE(std::find(B, E, "+rdm") != E);
+ EXPECT_TRUE(std::find(B, E, "+dotprod") != E);
+ EXPECT_TRUE(std::find(B, E, "+rcpc") != E);
+ EXPECT_TRUE(std::find(B, E, "+fp16fml") != E);
+ EXPECT_TRUE(std::find(B, E, "+sve") != E);
+ EXPECT_TRUE(std::find(B, E, "+sve2") != E);
+ EXPECT_TRUE(std::find(B, E, "+sve2-aes") != E);
+ EXPECT_TRUE(std::find(B, E, "+sve2-sm4") != E);
+ EXPECT_TRUE(std::find(B, E, "+sve2-sha3") != E);
+ EXPECT_TRUE(std::find(B, E, "+sve2-bitperm") != E);
}
TEST(TargetParserTest, AArch64ArchFeatures) {
@@ -996,6 +1107,15 @@
{"lse", "nolse", "+lse", "-lse"},
{"rdm", "nordm", "+rdm", "-rdm"},
{"sve", "nosve", "+sve", "-sve"},
+ {"sve2", "nosve2", "+sve2", "-sve2"},
+ {"sve2-aes", "nosve2-aes", "+sve2-aes",
+ "-sve2-aes"},
+ {"sve2-sm4", "nosve2-sm4", "+sve2-sm4",
+ "-sve2-sm4"},
+ {"sve2-sha3", "nosve2-sha3", "+sve2-sha3",
+ "-sve2-sha3"},
+ {"sve2-bitperm", "nosve2-bitperm",
+ "+sve2-bitperm", "-sve2-bitperm"},
{"dotprod", "nodotprod", "+dotprod", "-dotprod"},
{"rcpc", "norcpc", "+rcpc", "-rcpc" },
{"rng", "norng", "+rand", "-rand"},
diff --git a/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp b/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp
index 14ca9c0..0a8aeca 100644
--- a/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp
@@ -1,9 +1,8 @@
//========- unittests/Support/TaskQueue.cpp - TaskQueue.h tests ------========//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp b/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp
index e71c7db..075d7d9 100644
--- a/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/ThreadLocalTest.cpp - ThreadLocal tests ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp b/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
index 0da33ad..4755b52 100644
--- a/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
@@ -1,9 +1,8 @@
//========- unittests/Support/ThreadPools.cpp - ThreadPools.h tests --========//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/Threading.cpp b/src/llvm-project/llvm/unittests/Support/Threading.cpp
index be53026..01f1c51 100644
--- a/src/llvm-project/llvm/unittests/Support/Threading.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Threading.cpp
@@ -1,9 +1,8 @@
//===- unittests/Threading.cpp - Thread tests -----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/TimerTest.cpp b/src/llvm-project/llvm/unittests/Support/TimerTest.cpp
index a92ecf1..9a9b67e 100644
--- a/src/llvm-project/llvm/unittests/Support/TimerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TimerTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/TimerTest.cpp - Timer tests ------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp b/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
index 23acc54..967f6f6 100644
--- a/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
@@ -1,9 +1,8 @@
//=== - llvm/unittest/Support/TrailingObjectsTest.cpp ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp b/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
index df42c1e..9b10daa 100644
--- a/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
@@ -1,9 +1,8 @@
//===- TrigramIndexTest.cpp - Unit tests for TrigramIndex -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp b/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp
index 63381d4..c896293 100644
--- a/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp
@@ -1,9 +1,8 @@
//===- TypeNameTest.cpp ---------------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp b/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp
index 7a3ce53..e7a1025 100644
--- a/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp
@@ -1,13 +1,13 @@
//===- TypeTraitsTest.cpp -------------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/type_traits.h"
+#include "gtest/gtest.h"
namespace {
@@ -72,6 +72,26 @@
template void TrivialityTester<A &&, false, true>();
template void TrivialityTester<B &&, false, true>();
+TEST(Triviality, Tester) {
+ TrivialityTester<int, true, true>();
+ TrivialityTester<void *, true, true>();
+ TrivialityTester<int &, true, true>();
+ TrivialityTester<int &&, false, true>();
+
+ TrivialityTester<X, true, true>();
+ TrivialityTester<Y, false, false>();
+ TrivialityTester<Z, false, false>();
+ TrivialityTester<A, true, false>();
+ TrivialityTester<B, false, true>();
+
+ TrivialityTester<Z &, true, true>();
+ TrivialityTester<A &, true, true>();
+ TrivialityTester<B &, true, true>();
+ TrivialityTester<Z &&, false, true>();
+ TrivialityTester<A &&, false, true>();
+ TrivialityTester<B &&, false, true>();
+}
+
} // namespace triviality
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp b/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp
index 0733397..376fbee 100644
--- a/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Support/UnicodeTest.cpp - Unicode.h tests ----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp b/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp
index cd7ecda..af6c0a7 100644
--- a/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp
@@ -1,9 +1,8 @@
//===- VersionTupleTests.cpp - Version Number Handling Tests --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp b/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
index 7b42943..a867bc5 100644
--- a/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Support/VirtualFileSystem.cpp -------------- VFS tests ---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -343,6 +342,57 @@
EXPECT_EQ(0200, Status->getPermissions());
}
+TEST(VirtualFileSystemTest, OverlayIterator) {
+ IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+ Lower->addRegularFile("/foo");
+ IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+
+ IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+ new vfs::OverlayFileSystem(Lower));
+ O->pushOverlay(Upper);
+
+ ErrorOr<vfs::Status> Status((std::error_code()));
+ {
+ auto it = O->overlays_begin();
+ auto end = O->overlays_end();
+
+ EXPECT_NE(it, end);
+
+ Status = (*it)->status("/foo");
+ ASSERT_TRUE(Status.getError());
+
+ it++;
+ EXPECT_NE(it, end);
+
+ Status = (*it)->status("/foo");
+ ASSERT_FALSE(Status.getError());
+ EXPECT_TRUE(Status->exists());
+
+ it++;
+ EXPECT_EQ(it, end);
+ }
+
+ {
+ auto it = O->overlays_rbegin();
+ auto end = O->overlays_rend();
+
+ EXPECT_NE(it, end);
+
+ Status = (*it)->status("/foo");
+ ASSERT_FALSE(Status.getError());
+ EXPECT_TRUE(Status->exists());
+
+ it++;
+ EXPECT_NE(it, end);
+
+ Status = (*it)->status("/foo");
+ ASSERT_TRUE(Status.getError());
+
+ it++;
+ EXPECT_EQ(it, end);
+ }
+}
+
namespace {
struct ScopedDir {
SmallString<128> Path;
@@ -350,13 +400,18 @@
std::error_code EC;
if (Unique) {
EC = llvm::sys::fs::createUniqueDirectory(Name, Path);
+ if (!EC) {
+ // Resolve any symlinks in the new directory.
+ std::string UnresolvedPath = Path.str();
+ EC = llvm::sys::fs::real_path(UnresolvedPath, Path);
+ }
} else {
Path = Name.str();
EC = llvm::sys::fs::create_directory(Twine(Path));
}
if (EC)
Path = "";
- EXPECT_FALSE(EC);
+ EXPECT_FALSE(EC) << EC.message();
}
~ScopedDir() {
if (Path != "") {
@@ -382,6 +437,26 @@
}
operator StringRef() { return Path.str(); }
};
+
+struct ScopedFile {
+ SmallString<128> Path;
+ ScopedFile(const Twine &Path, StringRef Contents) {
+ Path.toVector(this->Path);
+ std::error_code EC;
+ raw_fd_ostream OS(this->Path, EC);
+ EXPECT_FALSE(EC);
+ OS << Contents;
+ OS.flush();
+ EXPECT_FALSE(OS.error());
+ if (EC || OS.error())
+ this->Path = "";
+ }
+ ~ScopedFile() {
+ if (Path != "") {
+ EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+ }
+ }
+};
} // end anonymous namespace
TEST(VirtualFileSystemTest, BasicRealFSIteration) {
@@ -412,6 +487,67 @@
}
#ifdef LLVM_ON_UNIX
+TEST(VirtualFileSystemTest, MultipleWorkingDirs) {
+ // Our root contains a/aa, b/bb, c, where c is a link to a/.
+ // Run tests both in root/b/ and root/c/ (to test "normal" and symlink dirs).
+ // Interleave operations to show the working directories are independent.
+ ScopedDir Root("r", true), ADir(Root.Path + "/a"), BDir(Root.Path + "/b");
+ ScopedLink C(ADir.Path, Root.Path + "/c");
+ ScopedFile AA(ADir.Path + "/aa", "aaaa"), BB(BDir.Path + "/bb", "bbbb");
+ std::unique_ptr<vfs::FileSystem> BFS = vfs::createPhysicalFileSystem(),
+ CFS = vfs::createPhysicalFileSystem();
+
+ ASSERT_FALSE(BFS->setCurrentWorkingDirectory(BDir.Path));
+ ASSERT_FALSE(CFS->setCurrentWorkingDirectory(C.Path));
+ EXPECT_EQ(BDir.Path, *BFS->getCurrentWorkingDirectory());
+ EXPECT_EQ(C.Path, *CFS->getCurrentWorkingDirectory());
+
+ // openFileForRead(), indirectly.
+ auto BBuf = BFS->getBufferForFile("bb");
+ ASSERT_TRUE(BBuf);
+ EXPECT_EQ("bbbb", (*BBuf)->getBuffer());
+
+ auto ABuf = CFS->getBufferForFile("aa");
+ ASSERT_TRUE(ABuf);
+ EXPECT_EQ("aaaa", (*ABuf)->getBuffer());
+
+ // status()
+ auto BStat = BFS->status("bb");
+ ASSERT_TRUE(BStat);
+ EXPECT_EQ("bb", BStat->getName());
+
+ auto AStat = CFS->status("aa");
+ ASSERT_TRUE(AStat);
+ EXPECT_EQ("aa", AStat->getName()); // unresolved name
+
+ // getRealPath()
+ SmallString<128> BPath;
+ ASSERT_FALSE(BFS->getRealPath("bb", BPath));
+ EXPECT_EQ(BB.Path, BPath);
+
+ SmallString<128> APath;
+ ASSERT_FALSE(CFS->getRealPath("aa", APath));
+ EXPECT_EQ(AA.Path, APath); // Reports resolved name.
+
+ // dir_begin
+ std::error_code EC;
+ auto BIt = BFS->dir_begin(".", EC);
+ ASSERT_FALSE(EC);
+ ASSERT_NE(BIt, vfs::directory_iterator());
+ EXPECT_EQ((BDir.Path + "/./bb").str(), BIt->path());
+ BIt.increment(EC);
+ ASSERT_FALSE(EC);
+ ASSERT_EQ(BIt, vfs::directory_iterator());
+
+ auto CIt = CFS->dir_begin(".", EC);
+ ASSERT_FALSE(EC);
+ ASSERT_NE(CIt, vfs::directory_iterator());
+ EXPECT_EQ((ADir.Path + "/./aa").str(), CIt->path()); // Partly resolved name!
+ CIt.increment(EC); // Because likely to read through this path.
+ ASSERT_FALSE(EC);
+ ASSERT_EQ(CIt, vfs::directory_iterator());
+}
+
TEST(VirtualFileSystemTest, BrokenSymlinkRealFSIteration) {
ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
@@ -777,7 +913,7 @@
bool Local = true;
ASSERT_FALSE(PFS.isLocal("/a", Local));
- ASSERT_EQ(false, Local);
+ EXPECT_FALSE(Local);
}
class InMemoryFileSystemTest : public ::testing::Test {
diff --git a/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp b/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
index 17f38f9..e02f68f 100644
--- a/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
@@ -1,12 +1,12 @@
//===- unittest/Support/YAMLIOTest.cpp ------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -580,6 +580,90 @@
}
}
+enum class Enum : uint16_t { One, Two };
+enum class BitsetEnum : uint16_t {
+ ZeroOne = 0x01,
+ OneZero = 0x10,
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ OneZero),
+};
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+struct EndianEnums {
+ llvm::support::little_t<Enum> LittleEnum;
+ llvm::support::big_t<Enum> BigEnum;
+ llvm::support::little_t<BitsetEnum> LittleBitset;
+ llvm::support::big_t<BitsetEnum> BigBitset;
+};
+namespace llvm {
+namespace yaml {
+template <> struct ScalarEnumerationTraits<Enum> {
+ static void enumeration(IO &io, Enum &E) {
+ io.enumCase(E, "One", Enum::One);
+ io.enumCase(E, "Two", Enum::Two);
+ }
+};
+
+template <> struct ScalarBitSetTraits<BitsetEnum> {
+ static void bitset(IO &io, BitsetEnum &E) {
+ io.bitSetCase(E, "ZeroOne", BitsetEnum::ZeroOne);
+ io.bitSetCase(E, "OneZero", BitsetEnum::OneZero);
+ }
+};
+
+template <> struct MappingTraits<EndianEnums> {
+ static void mapping(IO &io, EndianEnums &EE) {
+ io.mapRequired("LittleEnum", EE.LittleEnum);
+ io.mapRequired("BigEnum", EE.BigEnum);
+ io.mapRequired("LittleBitset", EE.LittleBitset);
+ io.mapRequired("BigBitset", EE.BigBitset);
+ }
+};
+} // namespace yaml
+} // namespace llvm
+
+TEST(YAMLIO, TestReadEndianEnums) {
+ EndianEnums map;
+ Input yin("---\n"
+ "LittleEnum: One\n"
+ "BigEnum: Two\n"
+ "LittleBitset: [ ZeroOne ]\n"
+ "BigBitset: [ ZeroOne, OneZero ]\n"
+ "...\n");
+ yin >> map;
+
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(Enum::One, map.LittleEnum);
+ EXPECT_EQ(Enum::Two, map.BigEnum);
+ EXPECT_EQ(BitsetEnum::ZeroOne, map.LittleBitset);
+ EXPECT_EQ(BitsetEnum::ZeroOne | BitsetEnum::OneZero, map.BigBitset);
+}
+
+TEST(YAMLIO, TestReadWriteEndianEnums) {
+ std::string intermediate;
+ {
+ EndianEnums map;
+ map.LittleEnum = Enum::Two;
+ map.BigEnum = Enum::One;
+ map.LittleBitset = BitsetEnum::OneZero | BitsetEnum::ZeroOne;
+ map.BigBitset = BitsetEnum::OneZero;
+
+ llvm::raw_string_ostream ostr(intermediate);
+ Output yout(ostr);
+ yout << map;
+ }
+
+ {
+ Input yin(intermediate);
+ EndianEnums map;
+ yin >> map;
+
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(Enum::Two, map.LittleEnum);
+ EXPECT_EQ(Enum::One, map.BigEnum);
+ EXPECT_EQ(BitsetEnum::OneZero | BitsetEnum::ZeroOne, map.LittleBitset);
+ EXPECT_EQ(BitsetEnum::OneZero, map.BigBitset);
+ }
+}
+
struct StringTypes {
llvm::StringRef str1;
llvm::StringRef str2;
@@ -604,6 +688,7 @@
std::string stdstr10;
std::string stdstr11;
std::string stdstr12;
+ std::string stdstr13;
};
namespace llvm {
@@ -634,6 +719,7 @@
io.mapRequired("stdstr10", st.stdstr10);
io.mapRequired("stdstr11", st.stdstr11);
io.mapRequired("stdstr12", st.stdstr12);
+ io.mapRequired("stdstr13", st.stdstr13);
}
};
}
@@ -666,6 +752,7 @@
map.stdstr10 = "0.2e20";
map.stdstr11 = "0x30";
map.stdstr12 = "- match";
+ map.stdstr13.assign("\0a\0b\0", 5);
llvm::raw_string_ostream ostr(intermediate);
Output yout(ostr);
@@ -691,6 +778,7 @@
EXPECT_NE(std::string::npos, flowOut.find("'@hhh'"));
EXPECT_NE(std::string::npos, flowOut.find("''\n"));
EXPECT_NE(std::string::npos, flowOut.find("'0000000004000000'\n"));
+ EXPECT_NE(std::string::npos, flowOut.find("\"\\0a\\0b\\0\""));
{
Input yin(intermediate);
@@ -710,6 +798,7 @@
EXPECT_TRUE(map.stdstr4 == "@hhh");
EXPECT_TRUE(map.stdstr5 == "");
EXPECT_TRUE(map.stdstr6 == "0000000004000000");
+ EXPECT_EQ(std::string("\0a\0b\0", 5), map.stdstr13);
}
}
@@ -824,7 +913,7 @@
io.mapRequired("f1", c.f1);
io.mapRequired("f2", c.f2);
io.mapRequired("f3", c.f3);
- io.mapOptional("f4", c.f4, MyFlags(flagRound));
+ io.mapOptional("f4", c.f4, flagRound);
}
};
}
@@ -1328,8 +1417,8 @@
static void mapping(IO &io, TotalSeconds &secs) {
MappingNormalization<NormalizedSeconds, TotalSeconds> keys(io, secs);
- io.mapOptional("hours", keys->hours, (uint32_t)0);
- io.mapOptional("minutes", keys->minutes, (uint8_t)0);
+ io.mapOptional("hours", keys->hours, 0);
+ io.mapOptional("minutes", keys->minutes, 0);
io.mapRequired("seconds", keys->seconds);
}
};
@@ -2439,7 +2528,7 @@
ostr.flush();
EXPECT_EQ(1, Context.A);
EXPECT_EQ("---\n"
- "Simple: \n"
+ "Simple:\n"
" B: 0\n"
" C: 0\n"
" Context: 1\n"
@@ -2454,7 +2543,7 @@
ostr.flush();
EXPECT_EQ(2, Context.A);
EXPECT_EQ("---\n"
- "Simple: \n"
+ "Simple:\n"
" B: 2\n"
" C: 3\n"
" Context: 2\n"
@@ -2467,8 +2556,6 @@
TEST(YAMLIO, TestCustomMapping) {
std::map<std::string, int> x;
- x["foo"] = 1;
- x["bar"] = 2;
std::string out;
llvm::raw_string_ostream ostr(out);
@@ -2477,6 +2564,17 @@
xout << x;
ostr.flush();
EXPECT_EQ("---\n"
+ "{}\n"
+ "...\n",
+ out);
+
+ x["foo"] = 1;
+ x["bar"] = 2;
+
+ out.clear();
+ xout << x;
+ ostr.flush();
+ EXPECT_EQ("---\n"
"bar: 2\n"
"foo: 1\n"
"...\n",
@@ -2506,10 +2604,10 @@
xout << x;
ostr.flush();
EXPECT_EQ("---\n"
- "bar: \n"
+ "bar:\n"
" foo: 3\n"
" bar: 4\n"
- "foo: \n"
+ "foo:\n"
" foo: 1\n"
" bar: 2\n"
"...\n",
@@ -2525,6 +2623,38 @@
EXPECT_EQ(4, y["bar"].bar);
}
+struct FooBarMapMap {
+ std::map<std::string, FooBar> fbm;
+};
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<FooBarMapMap> {
+ static void mapping(IO &io, FooBarMapMap &x) {
+ io.mapRequired("fbm", x.fbm);
+ }
+};
+}
+}
+
+TEST(YAMLIO, TestEmptyMapWrite) {
+ FooBarMapMap cont;
+ std::string str;
+ llvm::raw_string_ostream OS(str);
+ Output yout(OS);
+ yout << cont;
+ EXPECT_EQ(OS.str(), "---\nfbm: {}\n...\n");
+}
+
+TEST(YAMLIO, TestEmptySequenceWrite) {
+ FooBarContainer cont;
+ std::string str;
+ llvm::raw_string_ostream OS(str);
+ Output yout(OS);
+ yout << cont;
+ EXPECT_EQ(OS.str(), "---\nfbs: []\n...\n");
+}
+
static void TestEscaped(llvm::StringRef Input, llvm::StringRef Expected) {
std::string out;
llvm::raw_string_ostream ostr(out);
diff --git a/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp b/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
index 7962f3c..06d4b0e 100644
--- a/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Support/YAMLParserTest ------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp
index 2b8f065..0fe0869 100644
--- a/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/formatted_raw_ostream_test.cpp ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
index a75f446..4ce4917 100644
--- a/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/raw_ostream_test.cpp - raw_ostream tests -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp
index a528fd2..459eb940 100644
--- a/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp
@@ -1,9 +1,8 @@
//===- raw_pwrite_stream_test.cpp - raw_pwrite_stream tests ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
index e176f3f..be03536 100644
--- a/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/raw_ostream_test.cpp - raw_ostream tests -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp b/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp
index 6a88a2d..7dc7c40 100644
--- a/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Support/xxhashTest.cpp -------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp b/src/llvm-project/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp
index 095ee06..49a469b 100644
--- a/src/llvm-project/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp
@@ -1,9 +1,8 @@
//=== WebAssemblyExceptionInfoTest.cpp - WebAssebmlyExceptionInfo unit tests =//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -75,7 +74,7 @@
declare i32 @__gxx_wasm_personality_v0(...)
- define hidden void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+ define void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
unreachable
}
@@ -101,14 +100,14 @@
; predecessors: %bb.0
successors: %bb.3, %bb.9
liveins: $value_stack
- CATCH_ALL implicit-def $arguments
+ %0:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.3 (landing-pad):
; predecessors: %bb.2
successors: %bb.4, %bb.6
liveins: $value_stack
- CATCH_ALL implicit-def $arguments
+ %1:exnref = CATCH implicit-def $arguments
BR_IF %bb.4, %58:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
BR %bb.6, implicit-def $arguments
@@ -139,13 +138,13 @@
; predecessors: %bb.4
successors: %bb.9
liveins: $value_stack
- CATCH_ALL implicit-def $arguments
+ %2:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.9 (landing-pad):
; predecessors: %bb.2, %bb.6, %bb.8
liveins: $value_stack
- CATCH_ALL implicit-def $arguments
+ %3:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.10:
@@ -238,7 +237,7 @@
declare i32 @__gxx_wasm_personality_v0(...)
- define hidden void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+ define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
unreachable
}
@@ -258,7 +257,7 @@
; predecessors: %bb.0
successors: %bb.2, %bb.8
liveins: $value_stack
- %52:i32 = CATCH_I32 0, implicit-def dead $arguments
+ %0:exnref = CATCH implicit-def $arguments
BR_IF %bb.2, %32:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
BR %bb.8, implicit-def $arguments
@@ -272,7 +271,7 @@
; predecessors: %bb.2
successors: %bb.4, %bb.6
liveins: $value_stack
- CATCH_ALL implicit-def $arguments
+ %1:exnref = CATCH implicit-def $arguments
BR_IF %bb.4, %43:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
BR %bb.6, implicit-def $arguments
@@ -314,13 +313,13 @@
; predecessors: %bb.4
successors: %bb.11
liveins: $value_stack
- CATCH_ALL implicit-def $arguments
+ %2:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.11 (landing-pad):
; predecessors: %bb.2, %bb.6, %bb.10
liveins: $value_stack
- CATCH_ALL implicit-def $arguments
+ %3:exnref = CATCH implicit-def $arguments
CLEANUPRET implicit-def dead $arguments
bb.12:
@@ -416,135 +415,3 @@
EXPECT_EQ(WE0_1->getParentException(), WE0);
EXPECT_EQ(WE0_1->getExceptionDepth(), (unsigned)2);
}
-
-// Terminate pad test
-TEST(WebAssemblyExceptionInfoTest, TEST2) {
- std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
- ASSERT_TRUE(TM);
-
- StringRef MIRString = R"MIR(
---- |
- target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
- target triple = "wasm32-unknown-unknown"
-
- declare i32 @__gxx_wasm_personality_v0(...)
- declare void @_ZSt9terminatev()
- declare void @__clang_call_terminate(i8*)
-
- define hidden void @test2() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
- unreachable
- }
-
-...
----
-name: test2
-liveins:
- - { reg: '$arguments' }
- - { reg: '$value_stack' }
-body: |
- bb.0:
- successors: %bb.3, %bb.1
- BR %bb.3, implicit-def dead $arguments
-
- bb.1 (landing-pad):
- ; predecessors: %bb.0
- successors: %bb.2, %bb.4
- %3:i32 = CATCH_I32 0, implicit-def dead $arguments
- BR %bb.2, implicit-def dead $arguments
-
- bb.2:
- ; predecessors: %bb.1
- successors: %bb.3(0x80000000); %bb.3(200.00%)
- CATCHRET %bb.3, %bb.0, implicit-def dead $arguments
-
- bb.3:
- ; predecessors: %bb.0, %bb.2
- RETURN_VOID implicit-def $arguments
-
- bb.4 (landing-pad):
- ; predecessors: %bb.1
- successors: %bb.5, %bb.6
- CATCH_ALL implicit-def $arguments
- BR %bb.5, implicit-def dead $arguments
-
- bb.5:
- ; predecessors: %bb.4
- CLEANUPRET implicit-def dead $arguments
-
- bb.6 (landing-pad):
- ; predecessors: %bb.4
- successors: %bb.7(0x80000000); %bb.7(200.00%)
- %6:i32 = CATCH_I32 0, implicit-def dead $arguments
- CALL_VOID @__clang_call_terminate, %7:i32, implicit-def $arguments
- UNREACHABLE implicit-def $arguments
-
- bb.7 (landing-pad):
- ; predecessors: %bb.6
- CATCH_ALL implicit-def $arguments
- CALL_VOID @_ZSt9terminatev, implicit-def $arguments
- UNREACHABLE implicit-def $arguments
-)MIR";
-
- LLVMContext Context;
- std::unique_ptr<MIRParser> MIR;
- MachineModuleInfo MMI(TM.get());
- std::unique_ptr<Module> M =
- parseMIR(Context, MIR, *TM, MIRString, "test2", MMI);
- ASSERT_TRUE(M);
-
- Function *F = M->getFunction("test2");
- auto *MF = MMI.getMachineFunction(*F);
- ASSERT_TRUE(MF);
-
- WebAssemblyExceptionInfo WEI;
- MachineDominatorTree MDT;
- MachineDominanceFrontier MDF;
- MDT.runOnMachineFunction(*MF);
- MDF.getBase().analyze(MDT.getBase());
- WEI.recalculate(MDT, MDF);
-
- // Exception info structure:
- // |- bb1 (ehpad), bb2, bb4, bb5, bb6, bb7
- // |- bb4 (ehpad), bb5, bb6, bb7
- // |- bb6 (ehpad), bb7
- //
- // Here, bb6 is a terminate pad with a 'catch' instruction, and bb7 is a
- // terminate pad with a 'catch_all' instruction, In this case we put bb6 and
- // bb7 into one exception.
-
- auto *MBB1 = MF->getBlockNumbered(1);
- auto *WE0 = WEI.getExceptionFor(MBB1);
- ASSERT_TRUE(WE0);
- EXPECT_EQ(WE0->getEHPad(), MBB1);
- EXPECT_EQ(WE0->getParentException(), nullptr);
- EXPECT_EQ(WE0->getExceptionDepth(), (unsigned)1);
-
- auto *MBB2 = MF->getBlockNumbered(2);
- WE0 = WEI.getExceptionFor(MBB2);
- ASSERT_TRUE(WE0);
- EXPECT_EQ(WE0->getEHPad(), MBB1);
-
- auto *MBB4 = MF->getBlockNumbered(4);
- auto *WE0_0 = WEI.getExceptionFor(MBB4);
- ASSERT_TRUE(WE0_0);
- EXPECT_EQ(WE0_0->getEHPad(), MBB4);
- EXPECT_EQ(WE0_0->getParentException(), WE0);
- EXPECT_EQ(WE0_0->getExceptionDepth(), (unsigned)2);
-
- auto *MBB5 = MF->getBlockNumbered(5);
- WE0_0 = WEI.getExceptionFor(MBB5);
- ASSERT_TRUE(WE0_0);
- EXPECT_EQ(WE0_0->getEHPad(), MBB4);
-
- auto *MBB6 = MF->getBlockNumbered(6);
- auto *WE0_0_0 = WEI.getExceptionFor(MBB6);
- ASSERT_TRUE(WE0_0_0);
- EXPECT_EQ(WE0_0_0->getEHPad(), MBB6);
- EXPECT_EQ(WE0_0_0->getParentException(), WE0_0);
- EXPECT_EQ(WE0_0_0->getExceptionDepth(), (unsigned)3);
-
- auto *MBB7 = MF->getBlockNumbered(7);
- WE0_0_0 = WEI.getExceptionFor(MBB7);
- ASSERT_TRUE(WE0_0_0);
- EXPECT_EQ(WE0_0_0->getEHPad(), MBB6);
-}
diff --git a/src/llvm-project/llvm/unittests/TextAPI/CMakeLists.txt b/src/llvm-project/llvm/unittests/TextAPI/CMakeLists.txt
index d7208b2..924b7a2 100644
--- a/src/llvm-project/llvm/unittests/TextAPI/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/TextAPI/CMakeLists.txt
@@ -4,6 +4,8 @@
add_llvm_unittest(TextAPITests
ELFYAMLTest.cpp
+ TextStubV1Tests.cpp
+ TextStubV2Tests.cpp
)
-target_link_libraries(TextAPITests PRIVATE LLVMTestingSupport)
+target_link_libraries(TextAPITests PRIVATE LLVMTestingSupport)
\ No newline at end of file
diff --git a/src/llvm-project/llvm/unittests/TextAPI/ELFYAMLTest.cpp b/src/llvm-project/llvm/unittests/TextAPI/ELFYAMLTest.cpp
index 1ace819..8217507 100644
--- a/src/llvm-project/llvm/unittests/TextAPI/ELFYAMLTest.cpp
+++ b/src/llvm-project/llvm/unittests/TextAPI/ELFYAMLTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittests/TextAPI/YAMLTest.cpp --------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===-----------------------------------------------------------------------===/
@@ -150,7 +149,7 @@
"--- !tapi-tbe\n"
"TbeVersion: 1.0\n"
"Arch: AArch64\n"
- "Symbols: \n"
+ "Symbols:\n"
" bar: { Type: Func, Weak: true }\n"
" foo: { Type: NoType, Size: 99, Warning: Does nothing }\n"
" nor: { Type: Func, Undefined: true }\n"
@@ -206,7 +205,7 @@
"TbeVersion: 1.0\n"
"SoName: nosyms.so\n"
"Arch: x86_64\n"
- "NeededLibs: \n"
+ "NeededLibs:\n"
" - libc.so\n"
" - libfoo.so\n"
" - libbar.so\n"
diff --git a/src/llvm-project/llvm/unittests/TextAPI/TextStubV1Tests.cpp b/src/llvm-project/llvm/unittests/TextAPI/TextStubV1Tests.cpp
new file mode 100644
index 0000000..165e58f
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/TextAPI/TextStubV1Tests.cpp
@@ -0,0 +1,456 @@
+//===-- TextStubV1Tests.cpp - TBD V1 File Test ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===-----------------------------------------------------------------------===/
+
+#include "llvm/TextAPI/MachO/InterfaceFile.h"
+#include "llvm/TextAPI/MachO/TextAPIReader.h"
+#include "llvm/TextAPI/MachO/TextAPIWriter.h"
+#include "gtest/gtest.h"
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::MachO;
+
+struct ExportedSymbol {
+ SymbolKind Kind;
+ std::string Name;
+ bool WeakDefined;
+ bool ThreadLocalValue;
+};
+using ExportedSymbolSeq = std::vector<ExportedSymbol>;
+
+inline bool operator<(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
+ return std::tie(lhs.Kind, lhs.Name) < std::tie(rhs.Kind, rhs.Name);
+}
+
+inline bool operator==(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
+ return std::tie(lhs.Kind, lhs.Name, lhs.WeakDefined, lhs.ThreadLocalValue) ==
+ std::tie(rhs.Kind, rhs.Name, rhs.WeakDefined, rhs.ThreadLocalValue);
+}
+
+static ExportedSymbol TBDv1Symbols[] = {
+ {SymbolKind::GlobalSymbol, "$ld$hide$os9.0$_sym1", false, false},
+ {SymbolKind::GlobalSymbol, "_sym1", false, false},
+ {SymbolKind::GlobalSymbol, "_sym2", false, false},
+ {SymbolKind::GlobalSymbol, "_sym3", false, false},
+ {SymbolKind::GlobalSymbol, "_sym4", false, false},
+ {SymbolKind::GlobalSymbol, "_sym5", false, false},
+ {SymbolKind::GlobalSymbol, "_tlv1", false, true},
+ {SymbolKind::GlobalSymbol, "_tlv2", false, true},
+ {SymbolKind::GlobalSymbol, "_tlv3", false, true},
+ {SymbolKind::GlobalSymbol, "_weak1", true, false},
+ {SymbolKind::GlobalSymbol, "_weak2", true, false},
+ {SymbolKind::GlobalSymbol, "_weak3", true, false},
+ {SymbolKind::ObjectiveCClass, "class1", false, false},
+ {SymbolKind::ObjectiveCClass, "class2", false, false},
+ {SymbolKind::ObjectiveCClass, "class3", false, false},
+ {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar1", false, false},
+ {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar2", false, false},
+ {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar3", false, false},
+};
+
+namespace TBDv1 {
+
+TEST(TBDv1, ReadFile) {
+ static const char tbd_v1_file1[] =
+ "---\n"
+ "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "current-version: 2.3.4\n"
+ "compatibility-version: 1.0\n"
+ "swift-version: 1.1\n"
+ "exports:\n"
+ " - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+ " allowed-clients: [ clientA ]\n"
+ " re-exports: [ /usr/lib/libfoo.dylib ]\n"
+ " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
+ " objc-classes: [ _class1, _class2 ]\n"
+ " objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"
+ " weak-def-symbols: [ _weak1, _weak2 ]\n"
+ " thread-local-symbols: [ _tlv1, _tlv2 ]\n"
+ " - archs: [ armv7, armv7s, armv7k ]\n"
+ " symbols: [ _sym5 ]\n"
+ " objc-classes: [ _class3 ]\n"
+ " objc-ivars: [ _class1._ivar3 ]\n"
+ " weak-def-symbols: [ _weak3 ]\n"
+ " thread-local-symbols: [ _tlv3 ]\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_file1, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
+ EXPECT_EQ(Archs, File->getArchitectures());
+ EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+ EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
+ EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
+ EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
+ EXPECT_EQ(2U, File->getSwiftABIVersion());
+ EXPECT_EQ(ObjCConstraintType::None, File->getObjCConstraint());
+ EXPECT_TRUE(File->isTwoLevelNamespace());
+ EXPECT_TRUE(File->isApplicationExtensionSafe());
+ EXPECT_FALSE(File->isInstallAPI());
+ InterfaceFileRef client("clientA", Archs);
+ InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Archs);
+ EXPECT_EQ(1U, File->allowableClients().size());
+ EXPECT_EQ(client, File->allowableClients().front());
+ EXPECT_EQ(1U, File->reexportedLibraries().size());
+ EXPECT_EQ(reexport, File->reexportedLibraries().front());
+
+ ExportedSymbolSeq Exports;
+ for (const auto *Sym : File->symbols()) {
+ EXPECT_FALSE(Sym->isWeakReferenced());
+ EXPECT_FALSE(Sym->isUndefined());
+ Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName(),
+ Sym->isWeakDefined(),
+ Sym->isThreadLocalValue()});
+ }
+ llvm::sort(Exports.begin(), Exports.end());
+
+ EXPECT_EQ(sizeof(TBDv1Symbols) / sizeof(ExportedSymbol), Exports.size());
+ EXPECT_TRUE(
+ std::equal(Exports.begin(), Exports.end(), std::begin(TBDv1Symbols)));
+}
+
+TEST(TBDv1, ReadFile2) {
+ static const char tbd_v1_file2[] = "--- !tapi-tbd-v1\n"
+ "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_file2, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
+ EXPECT_EQ(Archs, File->getArchitectures());
+ EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+ EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
+ EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
+ EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
+ EXPECT_EQ(0U, File->getSwiftABIVersion());
+ EXPECT_EQ(ObjCConstraintType::None, File->getObjCConstraint());
+ EXPECT_TRUE(File->isTwoLevelNamespace());
+ EXPECT_TRUE(File->isApplicationExtensionSafe());
+ EXPECT_FALSE(File->isInstallAPI());
+ EXPECT_EQ(0U, File->allowableClients().size());
+ EXPECT_EQ(0U, File->reexportedLibraries().size());
+}
+
+// Disable test for windows.
+#ifndef _WIN32
+TEST(TBDv1, WriteFile) {
+ static const char tbd_v1_file3[] =
+ "---\n"
+ "archs: [ i386, x86_64 ]\n"
+ "platform: macosx\n"
+ "install-name: '/usr/lib/libfoo.dylib'\n"
+ "current-version: 1.2.3\n"
+ "compatibility-version: 0\n"
+ "swift-version: 5\n"
+ "objc-constraint: retain_release\n"
+ "exports:\n"
+ " - archs: [ i386 ]\n"
+ " symbols: [ _sym1 ]\n"
+ " weak-def-symbols: [ _sym2 ]\n"
+ " thread-local-symbols: [ _sym3 ]\n"
+ " - archs: [ x86_64 ]\n"
+ " allowed-clients: [ clientA ]\n"
+ " re-exports: [ '/usr/lib/libfoo.dylib' ]\n"
+ " symbols: [ '_OBJC_EHTYPE_$_Class1' ]\n"
+ " objc-classes: [ _Class1 ]\n"
+ " objc-ivars: [ _Class1._ivar1 ]\n"
+ "...\n";
+
+ InterfaceFile File;
+ File.setPath("libfoo.dylib");
+ File.setInstallName("/usr/lib/libfoo.dylib");
+ File.setFileType(FileType::TBD_V1);
+ File.setArchitectures(AK_i386 | AK_x86_64);
+ File.setPlatform(PlatformKind::macOS);
+ File.setCurrentVersion(PackedVersion(1, 2, 3));
+ File.setSwiftABIVersion(5);
+ File.setObjCConstraint(ObjCConstraintType::Retain_Release);
+ File.addAllowableClient("clientA", AK_x86_64);
+ File.addReexportedLibrary("/usr/lib/libfoo.dylib", AK_x86_64);
+ File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", AK_i386);
+ File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", AK_i386,
+ SymbolFlags::WeakDefined);
+ File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", AK_i386,
+ SymbolFlags::ThreadLocalValue);
+ File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", AK_x86_64);
+ File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", AK_x86_64);
+ File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
+ AK_x86_64);
+
+ SmallString<4096> Buffer;
+ raw_svector_ostream OS(Buffer);
+ auto Result = TextAPIWriter::writeToStream(OS, File);
+ EXPECT_FALSE(Result);
+ EXPECT_STREQ(tbd_v1_file3, Buffer.c_str());
+}
+
+TEST(TBDv1, Platform_macOS) {
+ static const char tbd_v1_platform_macos[] = "---\n"
+ "archs: [ x86_64 ]\n"
+ "platform: macosx\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_macos, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(PlatformKind::macOS, File->getPlatform());
+}
+#endif // _WIN32
+
+TEST(TBDv1, Platform_iOS) {
+ static const char tbd_v1_platform_ios[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_ios, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+}
+
+TEST(TBDv1, Platform_watchOS) {
+ static const char tbd_v1_platform_watchos[] = "---\n"
+ "archs: [ armv7k ]\n"
+ "platform: watchos\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_watchos, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(PlatformKind::watchOS, File->getPlatform());
+}
+
+TEST(TBDv1, Platform_tvOS) {
+ static const char tbd_v1_platform_tvos[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: tvos\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_tvos, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(PlatformKind::tvOS, File->getPlatform());
+}
+
+TEST(TBDv1, Platform_bridgeOS) {
+ static const char tbd_v1_platform_bridgeos[] = "---\n"
+ "archs: [ armv7k ]\n"
+ "platform: bridgeos\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer =
+ MemoryBuffer::getMemBuffer(tbd_v1_platform_bridgeos, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(PlatformKind::bridgeOS, File->getPlatform());
+}
+
+TEST(TBDv1, Swift_1_0) {
+ static const char tbd_v1_swift_1_0[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 1.0\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_0, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(1U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_1_1) {
+ static const char tbd_v1_swift_1_1[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 1.1\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_1, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(2U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_2_0) {
+ static const char tbd_v1_swift_2_0[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 2.0\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_2_0, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(3U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_3_0) {
+ static const char tbd_v1_swift_3_0[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 3.0\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_3_0, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(4U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_4_0) {
+ static const char tbd_v1_swift_4_0[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 4.0\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_4_0, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_FALSE(!!Result);
+ auto errorMessage = toString(Result.takeError());
+ EXPECT_EQ("malformed file\nTest.tbd:5:16: error: invalid Swift ABI "
+ "version.\nswift-version: 4.0\n ^~~\n",
+ errorMessage);
+}
+
+TEST(TBDv1, Swift_5) {
+ static const char tbd_v1_swift_5[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 5\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_5, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(5U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_99) {
+ static const char tbd_v1_swift_99[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 99\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_99, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+ EXPECT_EQ(99U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, UnknownArchitecture) {
+ static const char tbd_v1_file_unknown_architecture[] =
+ "---\n"
+ "archs: [ foo ]\n"
+ "platform: macosx\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer =
+ MemoryBuffer::getMemBuffer(tbd_v1_file_unknown_architecture, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+}
+
+TEST(TBDv1, UnknownPlatform) {
+ static const char tbd_v1_file_unknown_platform[] = "---\n"
+ "archs: [ i386 ]\n"
+ "platform: newOS\n"
+ "...\n";
+
+ auto Buffer =
+ MemoryBuffer::getMemBuffer(tbd_v1_file_unknown_platform, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_FALSE(!!Result);
+ auto errorMessage = toString(Result.takeError());
+ EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "
+ "newOS\n ^~~~~\n",
+ errorMessage);
+}
+
+TEST(TBDv1, MalformedFile1) {
+ static const char malformed_file1[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "foobar: \"Unsupported key\"\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(malformed_file1, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_FALSE(!!Result);
+ auto errorMessage = toString(Result.takeError());
+ ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
+ "'platform'\narchs: [ arm64 ]\n^\n",
+ errorMessage);
+}
+
+TEST(TBDv1, MalformedFile2) {
+ static const char malformed_file2[] = "---\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "foobar: \"Unsupported key\"\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(malformed_file2, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_FALSE(!!Result);
+ auto errorMessage = toString(Result.takeError());
+ ASSERT_EQ(
+ "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: "
+ "\"Unsupported key\"\n ^~~~~~~~~~~~~~~~~\n",
+ errorMessage);
+}
+
+} // end namespace TBDv1.
diff --git a/src/llvm-project/llvm/unittests/TextAPI/TextStubV2Tests.cpp b/src/llvm-project/llvm/unittests/TextAPI/TextStubV2Tests.cpp
new file mode 100644
index 0000000..b4b8ca9
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/TextAPI/TextStubV2Tests.cpp
@@ -0,0 +1,481 @@
+//===-- TextStubV2Tests.cpp - TBD V2 File Test ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===-----------------------------------------------------------------------===/
+
+#include "llvm/TextAPI/MachO/InterfaceFile.h"
+#include "llvm/TextAPI/MachO/TextAPIReader.h"
+#include "llvm/TextAPI/MachO/TextAPIWriter.h"
+#include "gtest/gtest.h"
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::MachO;
+
+struct ExportedSymbol {
+ SymbolKind Kind;
+ std::string Name;
+ bool WeakDefined;
+ bool ThreadLocalValue;
+};
+using ExportedSymbolSeq = std::vector<ExportedSymbol>;
+
+inline bool operator<(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
+ return std::tie(lhs.Kind, lhs.Name) < std::tie(rhs.Kind, rhs.Name);
+}
+
+inline bool operator==(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
+ return std::tie(lhs.Kind, lhs.Name, lhs.WeakDefined, lhs.ThreadLocalValue) ==
+ std::tie(rhs.Kind, rhs.Name, rhs.WeakDefined, rhs.ThreadLocalValue);
+}
+
+static ExportedSymbol TBDv2Symbols[] = {
+ {SymbolKind::GlobalSymbol, "$ld$hide$os9.0$_sym1", false, false},
+ {SymbolKind::GlobalSymbol, "_sym1", false, false},
+ {SymbolKind::GlobalSymbol, "_sym2", false, false},
+ {SymbolKind::GlobalSymbol, "_sym3", false, false},
+ {SymbolKind::GlobalSymbol, "_sym4", false, false},
+ {SymbolKind::GlobalSymbol, "_sym5", false, false},
+ {SymbolKind::GlobalSymbol, "_tlv1", false, true},
+ {SymbolKind::GlobalSymbol, "_tlv2", false, true},
+ {SymbolKind::GlobalSymbol, "_tlv3", false, true},
+ {SymbolKind::GlobalSymbol, "_weak1", true, false},
+ {SymbolKind::GlobalSymbol, "_weak2", true, false},
+ {SymbolKind::GlobalSymbol, "_weak3", true, false},
+ {SymbolKind::ObjectiveCClass, "class1", false, false},
+ {SymbolKind::ObjectiveCClass, "class2", false, false},
+ {SymbolKind::ObjectiveCClass, "class3", false, false},
+ {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar1", false, false},
+ {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar2", false, false},
+ {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar3", false, false},
+};
+
+namespace TBDv2 {
+
+TEST(TBDv2, ReadFile) {
+ static const char tbd_v2_file1[] =
+ "--- !tapi-tbd-v2\n"
+ "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+ "platform: ios\n"
+ "flags: [ installapi ]\n"
+ "install-name: Test.dylib\n"
+ "current-version: 2.3.4\n"
+ "compatibility-version: 1.0\n"
+ "swift-version: 1.1\n"
+ "parent-umbrella: Umbrella.dylib\n"
+ "exports:\n"
+ " - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+ " allowable-clients: [ clientA ]\n"
+ " re-exports: [ /usr/lib/libfoo.dylib ]\n"
+ " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
+ " objc-classes: [ _class1, _class2 ]\n"
+ " objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"
+ " weak-def-symbols: [ _weak1, _weak2 ]\n"
+ " thread-local-symbols: [ _tlv1, _tlv2 ]\n"
+ " - archs: [ armv7, armv7s, armv7k ]\n"
+ " symbols: [ _sym5 ]\n"
+ " objc-classes: [ _class3 ]\n"
+ " objc-ivars: [ _class1._ivar3 ]\n"
+ " weak-def-symbols: [ _weak3 ]\n"
+ " thread-local-symbols: [ _tlv3 ]\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v2_file1, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
+ EXPECT_EQ(Archs, File->getArchitectures());
+ EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+ EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
+ EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
+ EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
+ EXPECT_EQ(2U, File->getSwiftABIVersion());
+ EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());
+ EXPECT_TRUE(File->isTwoLevelNamespace());
+ EXPECT_TRUE(File->isApplicationExtensionSafe());
+ EXPECT_TRUE(File->isInstallAPI());
+ InterfaceFileRef client("clientA", Archs);
+ InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Archs);
+ EXPECT_EQ(1U, File->allowableClients().size());
+ EXPECT_EQ(client, File->allowableClients().front());
+ EXPECT_EQ(1U, File->reexportedLibraries().size());
+ EXPECT_EQ(reexport, File->reexportedLibraries().front());
+
+ ExportedSymbolSeq Exports;
+ for (const auto *Sym : File->symbols()) {
+ EXPECT_FALSE(Sym->isWeakReferenced());
+ EXPECT_FALSE(Sym->isUndefined());
+ Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName(),
+ Sym->isWeakDefined(),
+ Sym->isThreadLocalValue()});
+ }
+ llvm::sort(Exports.begin(), Exports.end());
+
+ EXPECT_EQ(sizeof(TBDv2Symbols) / sizeof(ExportedSymbol), Exports.size());
+ EXPECT_TRUE(
+ std::equal(Exports.begin(), Exports.end(), std::begin(TBDv2Symbols)));
+}
+
+TEST(TBDv2, ReadFile2) {
+ static const char tbd_v2_file2[] =
+ "--- !tapi-tbd-v2\n"
+ "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+ "platform: ios\n"
+ "flags: [ flat_namespace, not_app_extension_safe ]\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 1.1\n"
+ "exports:\n"
+ " - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+ " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
+ " objc-classes: [ _class1, _class2 ]\n"
+ " objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"
+ " weak-def-symbols: [ _weak1, _weak2 ]\n"
+ " thread-local-symbols: [ _tlv1, _tlv2 ]\n"
+ " - archs: [ armv7, armv7s, armv7k ]\n"
+ " symbols: [ _sym5 ]\n"
+ " objc-classes: [ _class3 ]\n"
+ " objc-ivars: [ _class1._ivar3 ]\n"
+ " weak-def-symbols: [ _weak3 ]\n"
+ " thread-local-symbols: [ _tlv3 ]\n"
+ "undefineds:\n"
+ " - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+ " symbols: [ _undefSym1, _undefSym2, _undefSym3 ]\n"
+ " objc-classes: [ _undefClass1, _undefClass2 ]\n"
+ " objc-ivars: [ _undefClass1._ivar1, _undefClass1._ivar2 ]\n"
+ " weak-ref-symbols: [ _undefWeak1, _undefWeak2 ]\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v2_file2, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
+ EXPECT_EQ(Archs, File->getArchitectures());
+ EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+ EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
+ EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
+ EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
+ EXPECT_EQ(2U, File->getSwiftABIVersion());
+ EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());
+ EXPECT_FALSE(File->isTwoLevelNamespace());
+ EXPECT_FALSE(File->isApplicationExtensionSafe());
+ EXPECT_FALSE(File->isInstallAPI());
+ EXPECT_EQ(0U, File->allowableClients().size());
+ EXPECT_EQ(0U, File->reexportedLibraries().size());
+}
+
+// Disable test for windows.
+#ifndef _WIN32
+TEST(TBDv2, WriteFile) {
+ static const char tbd_v2_file3[] =
+ "--- !tapi-tbd-v2\n"
+ "archs: [ i386, x86_64 ]\n"
+ "platform: macosx\n"
+ "install-name: '/usr/lib/libfoo.dylib'\n"
+ "current-version: 1.2.3\n"
+ "compatibility-version: 0\n"
+ "swift-version: 5\n"
+ "exports:\n"
+ " - archs: [ i386 ]\n"
+ " symbols: [ _sym1 ]\n"
+ " weak-def-symbols: [ _sym2 ]\n"
+ " thread-local-symbols: [ _sym3 ]\n"
+ " - archs: [ x86_64 ]\n"
+ " allowable-clients: [ clientA ]\n"
+ " re-exports: [ '/usr/lib/libfoo.dylib' ]\n"
+ " symbols: [ '_OBJC_EHTYPE_$_Class1' ]\n"
+ " objc-classes: [ _Class1 ]\n"
+ " objc-ivars: [ _Class1._ivar1 ]\n"
+ "...\n";
+
+ InterfaceFile File;
+ File.setPath("libfoo.dylib");
+ File.setInstallName("/usr/lib/libfoo.dylib");
+ File.setFileType(FileType::TBD_V2);
+ File.setArchitectures(AK_i386 | AK_x86_64);
+ File.setPlatform(PlatformKind::macOS);
+ File.setCurrentVersion(PackedVersion(1, 2, 3));
+ File.setTwoLevelNamespace();
+ File.setApplicationExtensionSafe();
+ File.setSwiftABIVersion(5);
+ File.setObjCConstraint(ObjCConstraintType::Retain_Release);
+ File.addAllowableClient("clientA", AK_x86_64);
+ File.addReexportedLibrary("/usr/lib/libfoo.dylib", AK_x86_64);
+ File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", AK_i386);
+ File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", AK_i386,
+ SymbolFlags::WeakDefined);
+ File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", AK_i386,
+ SymbolFlags::ThreadLocalValue);
+ File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", AK_x86_64);
+ File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", AK_x86_64);
+ File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
+ AK_x86_64);
+
+ SmallString<4096> Buffer;
+ raw_svector_ostream OS(Buffer);
+ auto Result = TextAPIWriter::writeToStream(OS, File);
+ EXPECT_FALSE(Result);
+ EXPECT_STREQ(tbd_v2_file3, Buffer.c_str());
+}
+#endif // _WIN32
+
+TEST(TBDv2, Platform_macOS) {
+ static const char tbd_v1_platform_macos[] = "--- !tapi-tbd-v2\n"
+ "archs: [ x86_64 ]\n"
+ "platform: macosx\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_macos, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(PlatformKind::macOS, File->getPlatform());
+}
+
+TEST(TBDv2, Platform_iOS) {
+ static const char tbd_v1_platform_ios[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_ios, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+}
+
+TEST(TBDv2, Platform_watchOS) {
+ static const char tbd_v1_platform_watchos[] = "--- !tapi-tbd-v2\n"
+ "archs: [ armv7k ]\n"
+ "platform: watchos\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_watchos, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(PlatformKind::watchOS, File->getPlatform());
+}
+
+TEST(TBDv2, Platform_tvOS) {
+ static const char tbd_v1_platform_tvos[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: tvos\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_tvos, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(PlatformKind::tvOS, File->getPlatform());
+}
+
+TEST(TBDv2, Platform_bridgeOS) {
+ static const char tbd_v1_platform_bridgeos[] = "--- !tapi-tbd-v2\n"
+ "archs: [ armv7k ]\n"
+ "platform: bridgeos\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer =
+ MemoryBuffer::getMemBuffer(tbd_v1_platform_bridgeos, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(PlatformKind::bridgeOS, File->getPlatform());
+}
+
+TEST(TBDv2, Swift_1_0) {
+ static const char tbd_v1_swift_1_0[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 1.0\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_0, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(1U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_1_1) {
+ static const char tbd_v1_swift_1_1[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 1.1\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_1, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(2U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_2_0) {
+ static const char tbd_v1_swift_2_0[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 2.0\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_2_0, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(3U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_3_0) {
+ static const char tbd_v1_swift_3_0[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 3.0\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_3_0, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(4U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_4_0) {
+ static const char tbd_v1_swift_4_0[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 4.0\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_4_0, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_FALSE(!!Result);
+ auto errorMessage = toString(Result.takeError());
+ EXPECT_EQ("malformed file\nTest.tbd:5:16: error: invalid Swift ABI "
+ "version.\nswift-version: 4.0\n ^~~\n",
+ errorMessage);
+}
+
+TEST(TBDv2, Swift_5) {
+ static const char tbd_v1_swift_5[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 5\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_5, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(5U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_99) {
+ static const char tbd_v1_swift_99[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "swift-version: 99\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_99, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+ auto File = std::move(Result.get());
+ EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+ EXPECT_EQ(99U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, UnknownArchitecture) {
+ static const char tbd_v2_file_unknown_architecture[] =
+ "--- !tapi-tbd-v2\n"
+ "archs: [ foo ]\n"
+ "platform: macosx\n"
+ "install-name: Test.dylib\n"
+ "...\n";
+
+ auto Buffer =
+ MemoryBuffer::getMemBuffer(tbd_v2_file_unknown_architecture, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_TRUE(!!Result);
+}
+
+TEST(TBDv2, UnknownPlatform) {
+ static const char tbd_v2_file_unknown_platform[] = "--- !tapi-tbd-v2\n"
+ "archs: [ i386 ]\n"
+ "platform: newOS\n"
+ "...\n";
+
+ auto Buffer =
+ MemoryBuffer::getMemBuffer(tbd_v2_file_unknown_platform, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_FALSE(!!Result);
+ auto errorMessage = toString(Result.takeError());
+ EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "
+ "newOS\n ^~~~~\n",
+ errorMessage);
+}
+
+TEST(TBDv2, MalformedFile1) {
+ static const char malformed_file1[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "foobar: \"Unsupported key\"\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(malformed_file1, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_FALSE(!!Result);
+ auto errorMessage = toString(Result.takeError());
+ ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
+ "'platform'\narchs: [ arm64 ]\n^\n",
+ errorMessage);
+}
+
+TEST(TBDv2, MalformedFile2) {
+ static const char malformed_file2[] = "--- !tapi-tbd-v2\n"
+ "archs: [ arm64 ]\n"
+ "platform: ios\n"
+ "install-name: Test.dylib\n"
+ "foobar: \"Unsupported key\"\n"
+ "...\n";
+
+ auto Buffer = MemoryBuffer::getMemBuffer(malformed_file2, "Test.tbd");
+ auto Result = TextAPIReader::get(std::move(Buffer));
+ EXPECT_FALSE(!!Result);
+ auto errorMessage = toString(Result.takeError());
+ ASSERT_EQ(
+ "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: "
+ "\"Unsupported key\"\n ^~~~~~~~~~~~~~~~~\n",
+ errorMessage);
+}
+
+} // namespace TBDv2
diff --git a/src/llvm-project/llvm/unittests/Transforms/IPO/LowerTypeTests.cpp b/src/llvm-project/llvm/unittests/Transforms/IPO/LowerTypeTests.cpp
index 66c9de6..ba13378 100644
--- a/src/llvm-project/llvm/unittests/Transforms/IPO/LowerTypeTests.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/IPO/LowerTypeTests.cpp
@@ -1,9 +1,8 @@
//===- LowerTypeTests.cpp - Unit tests for type test lowering -------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/IPO/WholeProgramDevirt.cpp b/src/llvm-project/llvm/unittests/Transforms/IPO/WholeProgramDevirt.cpp
index 7e7a6bf..8fae05b 100644
--- a/src/llvm-project/llvm/unittests/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/IPO/WholeProgramDevirt.cpp
@@ -1,9 +1,8 @@
//===- WholeProgramDevirt.cpp - Unit tests for whole-program devirt -------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/Scalar/CMakeLists.txt b/src/llvm-project/llvm/unittests/Transforms/Scalar/CMakeLists.txt
index 2762799..3d01d5c 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Scalar/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Transforms/Scalar/CMakeLists.txt
@@ -10,3 +10,8 @@
add_llvm_unittest(ScalarTests
LoopPassManagerTest.cpp
)
+
+# Workaround for the gcc 6.1 bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80916.
+if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
+ set_source_files_properties(LoopPassManagerTest.cpp PROPERTIES COMPILE_FLAGS -Wno-unused-function)
+endif()
diff --git a/src/llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
index 9f0b6f0..5eb8101 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Analysis/LoopPassManagerTest.cpp - LPM tests ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -21,19 +20,9 @@
#include "llvm/IR/PassManager.h"
#include "llvm/Support/SourceMgr.h"
-// Workaround for the gcc 6.1 bug PR80916.
-#if defined(__GNUC__) && __GNUC__ > 5
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wunused-function"
-#endif
-
#include "gmock/gmock.h"
#include "gtest/gtest.h"
-#if defined(__GNUC__) && __GNUC__ > 5
-# pragma GCC diagnostic pop
-#endif
-
using namespace llvm;
namespace {
@@ -304,6 +293,8 @@
// those.
FAM.registerPass([&] { return AAManager(); });
FAM.registerPass([&] { return AssumptionAnalysis(); });
+ if (EnableMSSALoopDependency)
+ FAM.registerPass([&] { return MemorySSAAnalysis(); });
FAM.registerPass([&] { return ScalarEvolutionAnalysis(); });
FAM.registerPass([&] { return TargetLibraryAnalysis(); });
FAM.registerPass([&] { return TargetIRAnalysis(); });
@@ -405,11 +396,13 @@
// No need to re-run if we require again from a fresh loop pass manager.
FPM.addPass(createFunctionToLoopPassAdaptor(
RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));
-
// For 'f', preserve most things but not the specific loop analyses.
+ auto PA = getLoopPassPreservedAnalyses();
+ if (EnableMSSALoopDependency)
+ PA.preserve<MemorySSAAnalysis>();
EXPECT_CALL(MFPHandle, run(HasName("f"), _))
.InSequence(FSequence)
- .WillOnce(Return(getLoopPassPreservedAnalyses()));
+ .WillOnce(Return(PA));
EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0.0"), _, _))
.InSequence(FSequence)
.WillOnce(DoDefault());
@@ -484,6 +477,8 @@
EXPECT_CALL(MMPHandle, run(_, _)).WillOnce(InvokeWithoutArgs([] {
auto PA = getLoopPassPreservedAnalyses();
PA.preserve<FunctionAnalysisManagerModuleProxy>();
+ if (EnableMSSALoopDependency)
+ PA.preserve<MemorySSAAnalysis>();
return PA;
}));
// All the loop analyses from both functions get invalidated before we
@@ -571,7 +566,6 @@
// invalidation and running.
EXPECT_CALL(MFPHandle, run(HasName("f"), _))
.WillOnce(Return(getLoopPassPreservedAnalyses()));
- EXPECT_CALL(MLAHandle, invalidate(_, _, _)).Times(3);
EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
@@ -813,6 +807,8 @@
// the fact that they were preserved.
EXPECT_CALL(MFPHandle, run(HasName("f"), _)).WillOnce(InvokeWithoutArgs([] {
auto PA = getLoopPassPreservedAnalyses();
+ if (EnableMSSALoopDependency)
+ PA.preserve<MemorySSAAnalysis>();
PA.preserveSet<AllAnalysesOn<Loop>>();
return PA;
}));
@@ -834,6 +830,8 @@
// Which means that no extra invalidation occurs and cached values are used.
EXPECT_CALL(MFPHandle, run(HasName("g"), _)).WillOnce(InvokeWithoutArgs([] {
auto PA = getLoopPassPreservedAnalyses();
+ if (EnableMSSALoopDependency)
+ PA.preserve<MemorySSAAnalysis>();
PA.preserveSet<AllAnalysesOn<Loop>>();
return PA;
}));
@@ -909,7 +907,8 @@
ASSERT_THAT(BBI, F.end());
auto CreateCondBr = [&](BasicBlock *TrueBB, BasicBlock *FalseBB,
const char *Name, BasicBlock *BB) {
- auto *Cond = new LoadInst(&Ptr, Name, /*isVolatile*/ true, BB);
+ auto *Cond = new LoadInst(Type::getInt1Ty(Context), &Ptr, Name,
+ /*isVolatile*/ true, BB);
BranchInst::Create(TrueBB, FalseBB, Cond, BB);
};
@@ -1111,7 +1110,8 @@
ASSERT_THAT(BBI, F.end());
auto CreateCondBr = [&](BasicBlock *TrueBB, BasicBlock *FalseBB,
const char *Name, BasicBlock *BB) {
- auto *Cond = new LoadInst(&Ptr, Name, /*isVolatile*/ true, BB);
+ auto *Cond = new LoadInst(Type::getInt1Ty(Context), &Ptr, Name,
+ /*isVolatile*/ true, BB);
BranchInst::Create(TrueBB, FalseBB, Cond, BB);
};
@@ -1504,8 +1504,9 @@
auto *NewLoop03BB =
BasicBlock::Create(Context, "loop.0.3", &F, &Loop0LatchBB);
BranchInst::Create(NewLoop03BB, NewLoop03PHBB);
- auto *Cond = new LoadInst(&Ptr, "cond.0.3", /*isVolatile*/ true,
- NewLoop03BB);
+ auto *Cond =
+ new LoadInst(Type::getInt1Ty(Context), &Ptr, "cond.0.3",
+ /*isVolatile*/ true, NewLoop03BB);
BranchInst::Create(&Loop0LatchBB, NewLoop03BB, Cond, NewLoop03BB);
Loop02PHBB.getTerminator()->replaceUsesOfWith(&Loop0LatchBB,
NewLoop03PHBB);
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
index 777918e..8af49c6 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
@@ -1,9 +1,8 @@
//===- ASanStackFrameLayoutTest.cpp - Tests for ComputeASanStackFrameLayout===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
index 2d0a930..bf8228e 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
@@ -1,13 +1,13 @@
//===- BasicBlockUtils.cpp - Unit tests for BasicBlockUtils ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Analysis/PostDominators.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Dominators.h"
@@ -25,6 +25,64 @@
return Mod;
}
+TEST(BasicBlockUtils, EliminateUnreachableBlocks) {
+ LLVMContext C;
+
+ std::unique_ptr<Module> M = parseIR(
+ C,
+ "define i32 @has_unreachable(i1 %cond) {\n"
+ "entry:\n"
+ " br i1 %cond, label %bb0, label %bb1\n"
+ "bb0:\n"
+ " br label %bb1\n"
+ "bb1:\n"
+ " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]"
+ " ret i32 %phi\n"
+ "bb2:\n"
+ " ret i32 42\n"
+ "}\n"
+ "\n"
+ );
+
+ auto *F = M->getFunction("has_unreachable");
+ DominatorTree DT(*F);
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+ EXPECT_EQ(F->size(), (size_t)4);
+ bool Result = EliminateUnreachableBlocks(*F, &DTU);
+ EXPECT_TRUE(Result);
+ EXPECT_EQ(F->size(), (size_t)3);
+ EXPECT_TRUE(DT.verify());
+}
+
+TEST(BasicBlockUtils, NoUnreachableBlocksToEliminate) {
+ LLVMContext C;
+
+ std::unique_ptr<Module> M = parseIR(
+ C,
+ "define i32 @no_unreachable(i1 %cond) {\n"
+ "entry:\n"
+ " br i1 %cond, label %bb0, label %bb1\n"
+ "bb0:\n"
+ " br label %bb1\n"
+ "bb1:\n"
+ " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]"
+ " ret i32 %phi\n"
+ "}\n"
+ "\n"
+ );
+
+ auto *F = M->getFunction("no_unreachable");
+ DominatorTree DT(*F);
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+ EXPECT_EQ(F->size(), (size_t)3);
+ bool Result = EliminateUnreachableBlocks(*F, &DTU);
+ EXPECT_FALSE(Result);
+ EXPECT_EQ(F->size(), (size_t)3);
+ EXPECT_TRUE(DT.verify());
+}
+
TEST(BasicBlockUtils, SplitBlockPredecessors) {
LLVMContext C;
@@ -50,3 +108,31 @@
SplitBlockPredecessors(&F->getEntryBlock(), {}, "split.entry", &DT);
EXPECT_TRUE(DT.verify());
}
+
+TEST(BasicBlockUtils, SplitCriticalEdge) {
+ LLVMContext C;
+
+ std::unique_ptr<Module> M = parseIR(
+ C,
+ "define void @crit_edge(i1 %cond0, i1 %cond1) {\n"
+ "entry:\n"
+ " br i1 %cond0, label %bb0, label %bb1\n"
+ "bb0:\n"
+ " br label %bb1\n"
+ "bb1:\n"
+ " br label %bb2\n"
+ "bb2:\n"
+ " ret void\n"
+ "}\n"
+ "\n"
+ );
+
+ auto *F = M->getFunction("crit_edge");
+ DominatorTree DT(*F);
+ PostDominatorTree PDT(*F);
+
+ CriticalEdgeSplittingOptions CESO(&DT, nullptr, nullptr, &PDT);
+ EXPECT_EQ(1u, SplitAllCriticalEdges(*F, CESO));
+ EXPECT_TRUE(DT.verify());
+ EXPECT_TRUE(PDT.verify());
+}
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/CloningTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/CloningTest.cpp
index 9d6bf0a..514a770 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/CloningTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/CloningTest.cpp
@@ -1,20 +1,21 @@
//===- Cloning.cpp - Unit tests for the Cloner ----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/DomTreeUpdater.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
@@ -356,6 +357,91 @@
delete F;
}
+static void runWithLoopInfoAndDominatorTree(
+ Module &M, StringRef FuncName,
+ function_ref<void(Function &F, LoopInfo &LI, DominatorTree &DT)> Test) {
+ auto *F = M.getFunction(FuncName);
+ ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
+
+ DominatorTree DT(*F);
+ LoopInfo LI(DT);
+
+ Test(*F, LI, DT);
+}
+
+static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
+ SMDiagnostic Err;
+ std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
+ if (!Mod)
+ Err.print("CloneLoop", errs());
+ return Mod;
+}
+
+TEST(CloneLoop, CloneLoopNest) {
+ // Parse the module.
+ LLVMContext Context;
+
+ std::unique_ptr<Module> M = parseIR(
+ Context,
+ R"(define void @foo(i32* %A, i32 %ub) {
+entry:
+ %guardcmp = icmp slt i32 0, %ub
+ br i1 %guardcmp, label %for.outer.preheader, label %for.end
+for.outer.preheader:
+ br label %for.outer
+for.outer:
+ %j = phi i32 [ 0, %for.outer.preheader ], [ %inc.outer, %for.outer.latch ]
+ br i1 %guardcmp, label %for.inner.preheader, label %for.outer.latch
+for.inner.preheader:
+ br label %for.inner
+for.inner:
+ %i = phi i32 [ 0, %for.inner.preheader ], [ %inc, %for.inner ]
+ %idxprom = sext i32 %i to i64
+ %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
+ store i32 %i, i32* %arrayidx, align 4
+ %inc = add nsw i32 %i, 1
+ %cmp = icmp slt i32 %inc, %ub
+ br i1 %cmp, label %for.inner, label %for.inner.exit
+for.inner.exit:
+ br label %for.outer.latch
+for.outer.latch:
+ %inc.outer = add nsw i32 %j, 1
+ %cmp.outer = icmp slt i32 %inc.outer, %ub
+ br i1 %cmp.outer, label %for.outer, label %for.outer.exit
+for.outer.exit:
+ br label %for.end
+for.end:
+ ret void
+})"
+ );
+
+ runWithLoopInfoAndDominatorTree(
+ *M, "foo", [&](Function &F, LoopInfo &LI, DominatorTree &DT) {
+ Function::iterator FI = F.begin();
+ // First basic block is entry - skip it.
+ BasicBlock *Preheader = &*(++FI);
+ BasicBlock *Header = &*(++FI);
+ assert(Header->getName() == "for.outer");
+ Loop *L = LI.getLoopFor(Header);
+ EXPECT_NE(L, nullptr);
+ EXPECT_EQ(Header, L->getHeader());
+ EXPECT_EQ(Preheader, L->getLoopPreheader());
+
+ ValueToValueMapTy VMap;
+ SmallVector<BasicBlock *, 4> ClonedLoopBlocks;
+ Loop *NewLoop = cloneLoopWithPreheader(Preheader, Preheader, L, VMap,
+ "", &LI, &DT, ClonedLoopBlocks);
+ EXPECT_NE(NewLoop, nullptr);
+ EXPECT_EQ(NewLoop->getSubLoops().size(), 1u);
+ Loop::block_iterator BI = NewLoop->block_begin();
+ EXPECT_TRUE((*BI)->getName().startswith("for.outer"));
+ EXPECT_TRUE((*(++BI))->getName().startswith("for.inner.preheader"));
+ EXPECT_TRUE((*(++BI))->getName().startswith("for.inner"));
+ EXPECT_TRUE((*(++BI))->getName().startswith("for.inner.exit"));
+ EXPECT_TRUE((*(++BI))->getName().startswith("for.outer.latch"));
+ });
+}
+
class CloneFunc : public ::testing::Test {
protected:
void SetUp() override {
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp
index 7e3512f..8b86951 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp
@@ -1,9 +1,8 @@
//===- CodeExtractor.cpp - Unit tests for CodeExtractor -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -59,8 +58,7 @@
getBlockByName(Func, "body1"),
getBlockByName(Func, "body2") };
- DominatorTree DT(*Func);
- CodeExtractor CE(Candidates, &DT);
+ CodeExtractor CE(Candidates);
EXPECT_TRUE(CE.isEligible());
Function *Outlined = CE.extractCodeRegion();
@@ -110,8 +108,7 @@
getBlockByName(Func, "extracted2")
};
- DominatorTree DT(*Func);
- CodeExtractor CE(ExtractedBlocks, &DT);
+ CodeExtractor CE(ExtractedBlocks);
EXPECT_TRUE(CE.isEligible());
Function *Outlined = CE.extractCodeRegion();
@@ -185,8 +182,7 @@
getBlockByName(Func, "lpad2")
};
- DominatorTree DT(*Func);
- CodeExtractor CE(ExtractedBlocks, &DT);
+ CodeExtractor CE(ExtractedBlocks);
EXPECT_TRUE(CE.isEligible());
Function *Outlined = CE.extractCodeRegion();
@@ -195,4 +191,38 @@
EXPECT_FALSE(verifyFunction(*Func, &errs()));
}
+TEST(CodeExtractor, StoreOutputInvokeResultInExitStub) {
+ LLVMContext Ctx;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M(parseAssemblyString(R"invalid(
+ declare i32 @bar()
+
+ define i32 @foo() personality i8* null {
+ entry:
+ %0 = invoke i32 @bar() to label %exit unwind label %lpad
+
+ exit:
+ ret i32 %0
+
+ lpad:
+ %1 = landingpad { i8*, i32 }
+ cleanup
+ resume { i8*, i32 } %1
+ }
+ )invalid",
+ Err, Ctx));
+
+ Function *Func = M->getFunction("foo");
+ SmallVector<BasicBlock *, 1> Blocks{ getBlockByName(Func, "entry"),
+ getBlockByName(Func, "lpad") };
+
+ CodeExtractor CE(Blocks);
+ EXPECT_TRUE(CE.isEligible());
+
+ Function *Outlined = CE.extractCodeRegion();
+ EXPECT_TRUE(Outlined);
+ EXPECT_FALSE(verifyFunction(*Outlined));
+ EXPECT_FALSE(verifyFunction(*Func));
+}
+
} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/FunctionComparatorTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/FunctionComparatorTest.cpp
index 26e20cd..42f9fb3 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/FunctionComparatorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/FunctionComparatorTest.cpp
@@ -1,9 +1,8 @@
//===- FunctionComparator.cpp - Unit tests for FunctionComparator ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/FunctionComparator.h"
@@ -32,7 +31,7 @@
BB = BasicBlock::Create(Ctx, "", F);
B.SetInsertPoint(BB);
Argument *PointerArg = &*F->arg_begin();
- LoadInst *LoadInst = B.CreateLoad(PointerArg);
+ LoadInst *LoadInst = B.CreateLoad(T, PointerArg);
C = B.getInt8(addVal);
I = cast<Instruction>(B.CreateAdd(LoadInst, C));
B.CreateRet(I);
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/IntegerDivisionTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/IntegerDivisionTest.cpp
index e337b9f..7994673 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/IntegerDivisionTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/IntegerDivisionTest.cpp
@@ -1,9 +1,8 @@
//===- IntegerDivision.cpp - Unit tests for the integer division code -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/LocalTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/LocalTest.cpp
index 3868bfb..55f04e9 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/LocalTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/LocalTest.cpp
@@ -1,18 +1,17 @@
//===- Local.cpp - Unit tests for Local -----------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DomTreeUpdater.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -154,8 +153,7 @@
ASSERT_TRUE(DII);
Value *NewBase = Constant::getNullValue(Type::getInt32PtrTy(C));
DIBuilder DIB(*M);
- replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::NoDeref, 0,
- DIExpression::NoDeref);
+ replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::ApplyOffset, 0);
// There should be exactly two dbg.declares.
int Declares = 0;
@@ -789,31 +787,35 @@
};
// Case 1: The original expr is empty, so no deref is needed.
- EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0,
- DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value}));
+ EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
+ DW_OP_LLVM_convert, 64, DW_ATE_signed,
+ DW_OP_stack_value}));
// Case 2: Perform an address calculation with the original expr, deref it,
// then sign-extend the result.
- EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup,
- DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0, DW_OP_not,
- DW_OP_mul, DW_OP_or, DW_OP_stack_value}));
+ EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
+ DW_OP_LLVM_convert, 32, DW_ATE_signed,
+ DW_OP_LLVM_convert, 64, DW_ATE_signed,
+ DW_OP_stack_value}));
// Case 3: Insert the sign-extension logic before the DW_OP_stack_value.
- EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31,
- DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
- DW_OP_stack_value}));
+ EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
+ DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
+ DW_OP_stack_value}));
// Cases 4-6: Just like cases 1-3, but preserve the fragment at the end.
- EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0,
- DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value,
- DW_OP_LLVM_fragment, 0, 8}));
- EXPECT_TRUE(
- hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup, DW_OP_constu,
- 31, DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
- DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
- EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31,
- DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
- DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
+ EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
+ DW_OP_LLVM_convert, 64, DW_ATE_signed,
+ DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
+
+ EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
+ DW_OP_LLVM_convert, 32, DW_ATE_signed,
+ DW_OP_LLVM_convert, 64, DW_ATE_signed,
+ DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
+
+ EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
+ DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
+ DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
verifyModule(*M, &errs(), &BrokenDebugInfo);
ASSERT_FALSE(BrokenDebugInfo);
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp
index 61cbcb7..b75a492 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp
@@ -1,9 +1,8 @@
//===- SSAUpdaterBulk.cpp - Unit tests for SSAUpdaterBulk -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp
index 5f7c2d6..fba21a7 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp
@@ -1,9 +1,8 @@
//===- UnrollLoopTest.cpp - Unit tests for UnrollLoop ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -71,6 +70,7 @@
bool PreserveLCSSA = L->isRecursivelyLCSSAForm(DT,LI);
- bool ret = UnrollRuntimeLoopRemainder(L, 4, true, false, false, &LI, &SE, &DT, &AC, PreserveLCSSA);
+ bool ret = UnrollRuntimeLoopRemainder(L, 4, true, false, false, false, &LI,
+ &SE, &DT, &AC, PreserveLCSSA);
EXPECT_FALSE(ret);
}
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp
index 94ac76b..690f434 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp
@@ -1,9 +1,8 @@
//===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/CMakeLists.txt b/src/llvm-project/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
index 6e886bb..74fc5ed 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
@@ -8,6 +8,7 @@
add_llvm_unittest(VectorizeTests
VPlanDominatorTreeTest.cpp
VPlanLoopInfoTest.cpp
+ VPlanPredicatorTest.cpp
VPlanTest.cpp
VPlanHCFGTest.cpp
VPlanSlpTest.cpp
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp
index 57f07392..6f39790 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp
index 215c3ef..f5894a4 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Transforms/Vectorize/VPlanHCFGTest.cpp ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
index 55486ba..0bb4599 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp
new file mode 100644
index 0000000..81ed3ce
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp
@@ -0,0 +1,229 @@
+//===- llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../lib/Transforms/Vectorize/VPlanPredicator.h"
+#include "VPlanTestBase.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+class VPlanPredicatorTest : public VPlanTestBase {};
+
+TEST_F(VPlanPredicatorTest, BasicPredicatorTest) {
+ const char *ModuleString =
+ "@arr = common global [8 x [8 x i64]] "
+ "zeroinitializer, align 16\n"
+ "@arr2 = common global [8 x [8 x i64]] "
+ "zeroinitializer, align 16\n"
+ "@arr3 = common global [8 x [8 x i64]] "
+ "zeroinitializer, align 16\n"
+ "define void @f(i64 %n1) {\n"
+ "entry:\n"
+ " br label %for.cond1.preheader\n"
+ "for.cond1.preheader: \n"
+ " %i1.029 = phi i64 [ 0, %entry ], [ %inc14, %for.inc13 ]\n"
+ " br label %for.body3\n"
+ "for.body3: \n"
+ " %i2.028 = phi i64 [ 0, %for.cond1.preheader ], [ %inc, %for.inc ]\n"
+ " %arrayidx4 = getelementptr inbounds [8 x [8 x i64]], [8 x [8 x i64]]* "
+ "@arr, i64 0, i64 %i2.028, i64 %i1.029\n"
+ " %0 = load i64, i64* %arrayidx4, align 8\n"
+ " %cmp5 = icmp ugt i64 %0, 10\n"
+ " br i1 %cmp5, label %if.then, label %for.inc\n"
+ "if.then: \n"
+ " %arrayidx7 = getelementptr inbounds [8 x [8 x i64]], [8 x [8 x i64]]* "
+ "@arr2, i64 0, i64 %i2.028, i64 %i1.029\n"
+ " %1 = load i64, i64* %arrayidx7, align 8\n"
+ " %cmp8 = icmp ugt i64 %1, 100\n"
+ " br i1 %cmp8, label %if.then9, label %for.inc\n"
+ "if.then9: \n"
+ " %add = add nuw nsw i64 %i2.028, %i1.029\n"
+ " %arrayidx11 = getelementptr inbounds [8 x [8 x i64]], [8 x [8 x "
+ "i64]]* @arr3, i64 0, i64 %i2.028, i64 %i1.029\n"
+ " store i64 %add, i64* %arrayidx11, align 8\n"
+ " br label %for.inc\n"
+ "for.inc: \n"
+ " %inc = add nuw nsw i64 %i2.028, 1\n"
+ " %exitcond = icmp eq i64 %inc, 8\n"
+ " br i1 %exitcond, label %for.inc13, label %for.body3\n"
+ "for.inc13: \n"
+ " %inc14 = add nuw nsw i64 %i1.029, 1\n"
+ " %exitcond30 = icmp eq i64 %inc14, 8\n"
+ " br i1 %exitcond30, label %for.end15, label %for.cond1.preheader\n"
+ "for.end15: \n"
+ " ret void\n"
+ "}\n";
+
+ Module &M = parseModule(ModuleString);
+
+ Function *F = M.getFunction("f");
+ BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor();
+ auto Plan = buildHCFG(LoopHeader);
+
+ VPRegionBlock *TopRegion = cast<VPRegionBlock>(Plan->getEntry());
+ VPBlockBase *PH = TopRegion->getEntry();
+ VPBlockBase *H = PH->getSingleSuccessor();
+ VPBlockBase *InnerLoopH = H->getSingleSuccessor();
+ VPBlockBase *OuterIf = InnerLoopH->getSuccessors()[0];
+ VPBlockBase *InnerLoopLatch = InnerLoopH->getSuccessors()[1];
+ VPBlockBase *InnerIf = OuterIf->getSuccessors()[0];
+ VPValue *CBV1 = InnerLoopH->getCondBit();
+ VPValue *CBV2 = OuterIf->getCondBit();
+
+ // Apply predication.
+ VPlanPredicator VPP(*Plan);
+ VPP.predicate();
+
+ VPBlockBase *InnerLoopLinSucc = InnerLoopH->getSingleSuccessor();
+ VPBlockBase *OuterIfLinSucc = OuterIf->getSingleSuccessor();
+ VPBlockBase *InnerIfLinSucc = InnerIf->getSingleSuccessor();
+ VPValue *OuterIfPred = OuterIf->getPredicate();
+ VPInstruction *InnerAnd =
+ cast<VPInstruction>(InnerIf->getEntryBasicBlock()->begin());
+ VPValue *InnerIfPred = InnerIf->getPredicate();
+
+ // Test block predicates
+ EXPECT_NE(nullptr, CBV1);
+ EXPECT_NE(nullptr, CBV2);
+ EXPECT_NE(nullptr, InnerAnd);
+ EXPECT_EQ(CBV1, OuterIfPred);
+ EXPECT_EQ(InnerAnd->getOpcode(), Instruction::And);
+ EXPECT_EQ(InnerAnd->getOperand(0), CBV1);
+ EXPECT_EQ(InnerAnd->getOperand(1), CBV2);
+ EXPECT_EQ(InnerIfPred, InnerAnd);
+
+ // Test Linearization
+ EXPECT_EQ(InnerLoopLinSucc, OuterIf);
+ EXPECT_EQ(OuterIfLinSucc, InnerIf);
+ EXPECT_EQ(InnerIfLinSucc, InnerLoopLatch);
+}
+
+// Test generation of Not and Or during predication.
+TEST_F(VPlanPredicatorTest, PredicatorNegOrTest) {
+ const char *ModuleString =
+ "@arr = common global [100 x [100 x i32]] zeroinitializer, align 16\n"
+ "@arr2 = common global [100 x [100 x i32]] zeroinitializer, align 16\n"
+ "@arr3 = common global [100 x [100 x i32]] zeroinitializer, align 16\n"
+ "define void @foo() {\n"
+ "entry:\n"
+ " br label %for.cond1.preheader\n"
+ "for.cond1.preheader: \n"
+ " %indvars.iv42 = phi i64 [ 0, %entry ], [ %indvars.iv.next43, "
+ "%for.inc22 ]\n"
+ " br label %for.body3\n"
+ "for.body3: \n"
+ " %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ "
+ "%indvars.iv.next, %if.end21 ]\n"
+ " %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 "
+ "x i32]]* @arr, i64 0, i64 %indvars.iv, i64 %indvars.iv42\n"
+ " %0 = load i32, i32* %arrayidx5, align 4\n"
+ " %cmp6 = icmp slt i32 %0, 100\n"
+ " br i1 %cmp6, label %if.then, label %if.end21\n"
+ "if.then: \n"
+ " %cmp7 = icmp sgt i32 %0, 10\n"
+ " br i1 %cmp7, label %if.then8, label %if.else\n"
+ "if.then8: \n"
+ " %add = add nsw i32 %0, 10\n"
+ " %arrayidx12 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 "
+ "x i32]]* @arr2, i64 0, i64 %indvars.iv, i64 %indvars.iv42\n"
+ " store i32 %add, i32* %arrayidx12, align 4\n"
+ " br label %if.end\n"
+ "if.else: \n"
+ " %sub = add nsw i32 %0, -10\n"
+ " %arrayidx16 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 "
+ "x i32]]* @arr3, i64 0, i64 %indvars.iv, i64 %indvars.iv42\n"
+ " store i32 %sub, i32* %arrayidx16, align 4\n"
+ " br label %if.end\n"
+ "if.end: \n"
+ " store i32 222, i32* %arrayidx5, align 4\n"
+ " br label %if.end21\n"
+ "if.end21: \n"
+ " %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n"
+ " %exitcond = icmp eq i64 %indvars.iv.next, 100\n"
+ " br i1 %exitcond, label %for.inc22, label %for.body3\n"
+ "for.inc22: \n"
+ " %indvars.iv.next43 = add nuw nsw i64 %indvars.iv42, 1\n"
+ " %exitcond44 = icmp eq i64 %indvars.iv.next43, 100\n"
+ " br i1 %exitcond44, label %for.end24, label %for.cond1.preheader\n"
+ "for.end24: \n"
+ " ret void\n"
+ "}\n";
+
+ Module &M = parseModule(ModuleString);
+ Function *F = M.getFunction("foo");
+ BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor();
+ auto Plan = buildHCFG(LoopHeader);
+
+ VPRegionBlock *TopRegion = cast<VPRegionBlock>(Plan->getEntry());
+ VPBlockBase *PH = TopRegion->getEntry();
+ VPBlockBase *H = PH->getSingleSuccessor();
+ VPBlockBase *OuterIfCmpBlk = H->getSingleSuccessor();
+ VPBlockBase *InnerIfCmpBlk = OuterIfCmpBlk->getSuccessors()[0];
+ VPBlockBase *InnerIfTSucc = InnerIfCmpBlk->getSuccessors()[0];
+ VPBlockBase *InnerIfFSucc = InnerIfCmpBlk->getSuccessors()[1];
+ VPBlockBase *TSuccSucc = InnerIfTSucc->getSingleSuccessor();
+ VPBlockBase *FSuccSucc = InnerIfFSucc->getSingleSuccessor();
+
+ VPValue *OuterCBV = OuterIfCmpBlk->getCondBit();
+ VPValue *InnerCBV = InnerIfCmpBlk->getCondBit();
+
+ // Apply predication.
+ VPlanPredicator VPP(*Plan);
+ VPP.predicate();
+
+ VPInstruction *And =
+ cast<VPInstruction>(InnerIfTSucc->getEntryBasicBlock()->begin());
+ VPInstruction *Not =
+ cast<VPInstruction>(InnerIfFSucc->getEntryBasicBlock()->begin());
+ VPInstruction *NotAnd = cast<VPInstruction>(
+ &*std::next(InnerIfFSucc->getEntryBasicBlock()->begin(), 1));
+ VPInstruction *Or =
+ cast<VPInstruction>(TSuccSucc->getEntryBasicBlock()->begin());
+
+ // Test block predicates
+ EXPECT_NE(nullptr, OuterCBV);
+ EXPECT_NE(nullptr, InnerCBV);
+ EXPECT_NE(nullptr, And);
+ EXPECT_NE(nullptr, Not);
+ EXPECT_NE(nullptr, NotAnd);
+
+ EXPECT_EQ(And->getOpcode(), Instruction::And);
+ EXPECT_EQ(NotAnd->getOpcode(), Instruction::And);
+ EXPECT_EQ(Not->getOpcode(), VPInstruction::Not);
+
+ EXPECT_EQ(And->getOperand(0), OuterCBV);
+ EXPECT_EQ(And->getOperand(1), InnerCBV);
+
+ EXPECT_EQ(Not->getOperand(0), InnerCBV);
+
+ EXPECT_EQ(NotAnd->getOperand(0), OuterCBV);
+ EXPECT_EQ(NotAnd->getOperand(1), Not);
+
+ EXPECT_EQ(InnerIfTSucc->getPredicate(), And);
+ EXPECT_EQ(InnerIfFSucc->getPredicate(), NotAnd);
+
+ EXPECT_EQ(TSuccSucc, FSuccSucc);
+ EXPECT_EQ(Or->getOpcode(), Instruction::Or);
+ EXPECT_EQ(TSuccSucc->getPredicate(), Or);
+
+ // Test operands of the Or - account for differences in predecessor block
+ // ordering.
+ VPInstruction *OrOp0Inst = cast<VPInstruction>(Or->getOperand(0));
+ VPInstruction *OrOp1Inst = cast<VPInstruction>(Or->getOperand(1));
+
+ bool ValidOrOperands = false;
+ if (((OrOp0Inst == And) && (OrOp1Inst == NotAnd)) ||
+ ((OrOp0Inst == NotAnd) && (OrOp1Inst == And)))
+ ValidOrOperands = true;
+
+ EXPECT_TRUE(ValidOrOperands);
+}
+
+} // namespace
+} // namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanSlpTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanSlpTest.cpp
index 0381925..403ffb1 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanSlpTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanSlpTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/Transforms/Vectorize/VPlanSlpTest.cpp ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index 67712a7..90f79a3 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -1,10 +1,9 @@
//===- llvm/unittests/Transforms/Vectorize/VPlanTest.cpp - VPlan tests ----===//
//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
index 0fc4a9a..3ee811a 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
@@ -1,9 +1,8 @@
//===- llvm/unittest/Transforms/Vectorize/VPlanTestBase.h -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRBlockIndexerTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRBlockIndexerTest.cpp
index 558840b..f2fab2f 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRBlockIndexerTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRBlockIndexerTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/XRay/FDRTraceWriterTest.cpp ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/XRay/BlockIndexer.h"
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRBlockVerifierTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRBlockVerifierTest.cpp
index a6e0a8c..5af2745 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRBlockVerifierTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRBlockVerifierTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/XRay/FDRBlockVerifierTest.cpp --------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Testing/Support/Error.h"
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRProducerConsumerTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRProducerConsumerTest.cpp
index 03fabdf..bbc15be 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRProducerConsumerTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRProducerConsumerTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/XRay/FDRProducerConsumerTest.cpp -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRRecordPrinterTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRRecordPrinterTest.cpp
index a0ec3f2..39c1e86 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRRecordPrinterTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRRecordPrinterTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/XRay/FDRRecordPrinterTest.cpp --------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/raw_ostream.h"
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRRecordsTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRRecordsTest.cpp
index 86b478a..aac3c86 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRRecordsTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRRecordsTest.cpp
@@ -1,9 +1,8 @@
//===- FDRRecords.cpp - Unit Tests for XRay FDR Record Loading ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "gmock/gmock.h"
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRTraceWriterTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRTraceWriterTest.cpp
index e78b71d..4f2f06e4 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRTraceWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRTraceWriterTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/XRay/FDRTraceWriterTest.cpp ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/src/llvm-project/llvm/unittests/XRay/GraphTest.cpp b/src/llvm-project/llvm/unittests/XRay/GraphTest.cpp
index b17858f..3c82d53 100644
--- a/src/llvm-project/llvm/unittests/XRay/GraphTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/GraphTest.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittest/XRay/GraphTest.cpp - XRay Graph unit tests -*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/XRay/ProfileTest.cpp b/src/llvm-project/llvm/unittests/XRay/ProfileTest.cpp
index 8486b7b..7eb848f 100644
--- a/src/llvm-project/llvm/unittests/XRay/ProfileTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/ProfileTest.cpp
@@ -1,9 +1,8 @@
//===- ProfileTest.cpp - XRay Profile unit tests ----------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/XRay/Profile.h"
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp b/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
index 05880fc..e38ac92 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -52,8 +51,8 @@
// Expose this method publicly for testing.
void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
- uint64_t SectionAddress) {
- FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
+ object::SectionedAddress Address) {
+ FileAnalysis::parseSectionContents(SectionBytes, Address);
}
Error initialiseDisassemblyMembers() {
@@ -107,7 +106,7 @@
0x41, 0x0e, // 21: rex.B (bad)
0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
EXPECT_EQ(nullptr, Analysis.getInstruction(0x0));
EXPECT_EQ(nullptr, Analysis.getInstruction(0x1000));
@@ -211,7 +210,7 @@
0x2f, // 1: (bad)
0x90 // 2: nop
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
const auto &BadInstrMeta = Analysis.getInstructionOrDie(0xDEADBEEF + 1);
const auto *GoodInstrMeta =
Analysis.getPrevInstructionSequential(BadInstrMeta);
@@ -241,7 +240,7 @@
0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
0x0f, 0x0b // 28: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
EXPECT_FALSE(Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF)));
EXPECT_FALSE(
@@ -276,7 +275,7 @@
0x75, 0x00, // 17: jne +0
0xc3, // 19: retq
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
EXPECT_TRUE(
Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF)));
@@ -323,7 +322,7 @@
0xeb, 0xdd, // 36: jmp 3 [-35]
0xeb, 0xdc, // 38: jmp 4 [-36]
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
const auto *Current = Analysis.getInstruction(0xDEADBEEF);
const auto *Next = Analysis.getDefiniteNextInstruction(*Current);
@@ -413,7 +412,7 @@
0xeb, 0xdd, // 36: jmp 3 [-35]
0xeb, 0xdc, // 38: jmp 4 [-36]
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
const auto *InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF);
std::set<const Instr *> XRefs =
Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
@@ -504,17 +503,18 @@
0x0f, 0x0b, // 1: ud2
0x75, 0x00, // 3: jne 5 [+0]
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
Analysis.validateCFIProtection(Result));
- Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1);
+ Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
Analysis.validateCFIProtection(Result));
- Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
Analysis.validateCFIProtection(Result));
- Result = GraphBuilder::buildFlowGraph(Analysis, 0x12345678);
+ Result = GraphBuilder::buildFlowGraph(Analysis, {0x12345678, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_INVALID_INSTRUCTION,
Analysis.validateCFIProtection(Result));
}
@@ -528,8 +528,9 @@
0x0f, 0x0b, // 2: ud2
0xff, 0x10, // 4: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -543,8 +544,9 @@
0xff, 0x10, // 2: callq *(%rax)
0x0f, 0x0b, // 4: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -561,8 +563,9 @@
0x75, 0xf9, // 7: jne 2 [-7]
0x0f, 0x0b, // 9: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -578,8 +581,9 @@
0x75, 0xfb, // 5: jne 2 [-5]
0x0f, 0x0b, // 7: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -597,12 +601,13 @@
0xff, 0x10, // 6: callq *(%rax)
0x0f, 0x0b, // 8: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
uint64_t PrevSearchLengthForConditionalBranch =
SearchLengthForConditionalBranch;
SearchLengthForConditionalBranch = 2;
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6);
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
Analysis.validateCFIProtection(Result));
@@ -622,11 +627,12 @@
0x90, // 7: nop
0x0f, 0x0b, // 8: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
SearchLengthForUndef = 2;
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
Analysis.validateCFIProtection(Result));
@@ -643,8 +649,9 @@
0xff, 0x10, // 4: callq *(%rax)
0x0f, 0x0b, // 6: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
Analysis.validateCFIProtection(Result));
}
@@ -659,8 +666,9 @@
0xff, 0x10, // 4: callq *(%rax)
0x0f, 0x0b, // 6: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -686,10 +694,11 @@
0x90, // 21: nop
0x0f, 0x0b, // 22: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
SearchLengthForUndef = 5;
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9);
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
Analysis.validateCFIProtection(Result));
SearchLengthForUndef = PrevSearchLengthForUndef;
@@ -705,10 +714,10 @@
0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130
0x0f, 0x0b, // 0x688127: ud2
},
- 0x688118);
+ {0x688118, 0x0});
uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
SearchLengthForUndef = 1;
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x68811d);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x68811d, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
SearchLengthForUndef = PrevSearchLengthForUndef;
@@ -720,7 +729,7 @@
0x74, 0x73, // 0x7759eb: je 0x775a60
0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e
},
- 0x7759eb);
+ {0x7759eb, 0x0});
Analysis.parseSectionContents(
{
@@ -730,24 +739,24 @@
0x48, 0x89, 0xde, // 0x775a65: mov %rbx,%rsi
0xff, 0xd1, // 0x775a68: callq *%rcx
},
- 0x775a56);
+ {0x775a56, 0x0});
Analysis.parseSectionContents(
{
0x0f, 0x0b, // 0x775e0e: ud2
},
- 0x775e0e);
+ {0x775e0e, 0x0});
uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
SearchLengthForUndef = 1;
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
Analysis.validateCFIProtection(Result));
SearchLengthForUndef = 2;
- Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
+ Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
SearchLengthForUndef = 3;
- Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
+ Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
SearchLengthForUndef = PrevSearchLengthForUndef;
@@ -763,8 +772,9 @@
0x48, 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %rax
0xff, 0x10, // 10: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 10);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 10, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -779,8 +789,9 @@
0x48, 0x83, 0xc0, 0x00, // 4: add $0x0, %rax
0xff, 0x10, // 8: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -795,8 +806,9 @@
0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %eax
0xff, 0x10, // 9: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -813,8 +825,9 @@
0x75, 0xf9, // 8: jne 2 [-7]
0x0f, 0x0b, // 10: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -826,8 +839,9 @@
{
0x00, 0x01, 0x3f, 0xd6, // 0: blr x8
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
Analysis.validateCFIProtection(Result));
}
@@ -841,8 +855,9 @@
0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
0x00, 0x01, 0x3f, 0xd6, // 8: blr x8
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -857,8 +872,9 @@
0x08, 0x05, 0x00, 0x91, // 8: add x8, x8, #1
0x00, 0x01, 0x3f, 0xd6, // 12: blr x8
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -873,8 +889,9 @@
0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
0x20, 0x00, 0x1f, 0xd6, // 12: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -890,8 +907,9 @@
0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -907,8 +925,9 @@
0x21, 0x04, 0x00, 0x91, // 12: add x1, x1, #1
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -924,8 +943,9 @@
0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -941,8 +961,9 @@
0x21, 0x08, 0x40, 0xf9, // 12: ldr x1, [x1,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -958,8 +979,9 @@
0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -975,8 +997,9 @@
0x22, 0x08, 0x40, 0xf9, // 12: ldr x2, [x1,#16]
0x20, 0x00, 0x1f, 0xd6, // 16: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -991,8 +1014,9 @@
0x20, 0x00, 0x20, 0xd4, // 8: brk #0x1
0x20, 0x00, 0x1f, 0xd6, // 12: br x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
Analysis.validateCFIProtection(Result));
}
@@ -1010,8 +1034,9 @@
0x20, 0x00, 0x1f, 0xd6, // 20: br x1
0x20, 0x00, 0x20, 0xd4, // 24: brk #0x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 20);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 20, 0x0});
EXPECT_EQ(CFIProtectionStatus::PROTECTED,
Analysis.validateCFIProtection(Result));
}
@@ -1030,8 +1055,9 @@
0x20, 0x00, 0x1f, 0xd6, // 24: br x1
0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
@@ -1050,8 +1076,9 @@
0x20, 0x00, 0x1f, 0xd6, // 24: br x1
0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
Analysis.validateCFIProtection(Result));
}
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp b/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp
index a7d09b5..a57958d 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp
@@ -1,9 +1,8 @@
//===- llvm/unittests/llvm-cfi-verify/GraphBuilder.cpp --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -114,8 +113,8 @@
// Expose this method publicly for testing.
void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
- uint64_t SectionAddress) {
- FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
+ object::SectionedAddress Address) {
+ FileAnalysis::parseSectionContents(SectionBytes, Address);
}
Error initialiseDisassemblyMembers() {
@@ -157,8 +156,9 @@
0x0f, 0x0b, // 2: ud2
0xff, 0x10, // 4: callq *(%rax)
},
- 0xDEADBEEF);
- const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ const auto Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
@@ -183,8 +183,9 @@
0xff, 0x10, // 2: callq *(%rax)
0x0f, 0x0b, // 4: ud2
},
- 0xDEADBEEF);
- const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ {0xDEADBEEF, 0x0});
+ const auto Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
@@ -212,8 +213,9 @@
0x75, 0xf9, // 7: jne 2 [-7]
0x0f, 0x0b, // 9: ud2
},
- 0xDEADBEEF);
- const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ const auto Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
@@ -250,8 +252,9 @@
0x75, 0xfb, // 5: jne 2 [-5]
0x0f, 0x0b, // 7: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
@@ -285,16 +288,17 @@
0x90, // 0: nop
0x75, 0xfe, // 1: jne 1 [-2]
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
- Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1);
+ Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
- Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADC0DE);
+ Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADC0DE, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
}
@@ -307,8 +311,9 @@
0xeb, 0xfe, // 0: jmp 0 [-2]
0xff, 0x10, // 2: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 2));
EXPECT_THAT(Result.IntermediateNodes, IsEmpty());
@@ -322,8 +327,9 @@
0x75, 0xfe, // 0: jne 0 [-2]
0xff, 0x10, // 2: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
EXPECT_THAT(
@@ -345,8 +351,9 @@
0xeb, 0xfc, // 2: jmp 0 [-4]
0xff, 0x10, // 4: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
EXPECT_THAT(
@@ -369,8 +376,9 @@
0xeb, 0xfc, // 2: jmp 0 [-4]
0xff, 0x10, // 4: callq *(%rax)
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 4));
EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
}
@@ -388,12 +396,13 @@
0xff, 0x10, // 6: callq *(%rax)
0x0f, 0x0b, // 8: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
uint64_t PrevSearchLengthForConditionalBranch =
SearchLengthForConditionalBranch;
SearchLengthForConditionalBranch = 2;
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6);
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0});
EXPECT_THAT(Result.OrphanedNodes, SizeIs(1));
EXPECT_THAT(Result.OrphanedNodes,
Each(HasPath(Result, ElementsAre(0xDEADBEEF + 4, 0xDEADBEEF + 5,
@@ -417,11 +426,12 @@
0x90, // 7: nop
0x0f, 0x0b, // 8: ud2
},
- 0xDEADBEEF);
+ {0xDEADBEEF, 0x0});
uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
SearchLengthForUndef = 2;
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(
Result.ConditionalBranchNodes,
@@ -451,8 +461,9 @@
0x75, 0xfb, // 5: jne 2 [-5]
0x0f, 0x0b, // 7: ud2
},
- 0xDEADBEEF);
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+ {0xDEADBEEF, 0x0});
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
EXPECT_THAT(
@@ -530,11 +541,12 @@
0x90, // 21: nop
0x0f, 0x0b, // 22: ud2
},
- 0x1000);
+ {0x1000, 0x0});
uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
SearchLengthForUndef = 5;
- GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x1000 + 9);
+ GraphResult Result =
+ GraphBuilder::buildFlowGraph(Analysis, {0x1000 + 9, 0x0});
EXPECT_THAT(Result.OrphanedNodes, SizeIs(1));
EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(3));
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp
index 6dd5305..4a68541 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp
@@ -1,9 +1,8 @@
//===-- TargetTest.cpp ------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp
index a20fa55..70ad487 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp
@@ -1,9 +1,8 @@
//===-- AssemblerTest.cpp ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/BenchmarkRunnerTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/BenchmarkRunnerTest.cpp
index c518491..9414a48 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/BenchmarkRunnerTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/BenchmarkRunnerTest.cpp
@@ -1,9 +1,8 @@
//===-- BenchmarkRunnerTest.cpp ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ClusteringTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ClusteringTest.cpp
index 8ea77dc..b23938a 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ClusteringTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ClusteringTest.cpp
@@ -1,9 +1,8 @@
//===-- ClusteringTest.cpp --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -23,6 +22,11 @@
using testing::UnorderedElementsAre;
using testing::UnorderedElementsAreArray;
+static const auto HasPoints = [](const std::vector<int> &Indices) {
+ return Field(&InstructionBenchmarkClustering::Cluster::PointIndices,
+ UnorderedElementsAreArray(Indices));
+};
+
TEST(ClusteringTest, Clusters3D) {
std::vector<InstructionBenchmark> Points(6);
@@ -42,12 +46,8 @@
// Error cluster: points {2}
Points[2].Error = "oops";
- auto HasPoints = [](const std::vector<int> &Indices) {
- return Field(&InstructionBenchmarkClustering::Cluster::PointIndices,
- UnorderedElementsAreArray(Indices));
- };
-
- auto Clustering = InstructionBenchmarkClustering::create(Points, 2, 0.25);
+ auto Clustering = InstructionBenchmarkClustering::create(
+ Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 0.25);
ASSERT_TRUE((bool)Clustering);
EXPECT_THAT(Clustering.get().getValidClusters(),
UnorderedElementsAre(HasPoints({0, 3}), HasPoints({1, 4})));
@@ -74,7 +74,9 @@
{"x", 0.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
Points[1].Measurements = {{"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
auto Error =
- InstructionBenchmarkClustering::create(Points, 2, 0.25).takeError();
+ InstructionBenchmarkClustering::create(
+ Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 0.25)
+ .takeError();
ASSERT_TRUE((bool)Error);
consumeError(std::move(Error));
}
@@ -84,7 +86,9 @@
Points[0].Measurements = {{"x", 0.01, 0.0}, {"y", 1.02, 0.0}};
Points[1].Measurements = {{"y", 1.02, 0.0}, {"x", 1.98, 0.0}};
auto Error =
- InstructionBenchmarkClustering::create(Points, 2, 0.25).takeError();
+ InstructionBenchmarkClustering::create(
+ Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 0.25)
+ .takeError();
ASSERT_TRUE((bool)Error);
consumeError(std::move(Error));
}
@@ -103,6 +107,40 @@
InstructionBenchmarkClustering::ClusterId::error());
}
+TEST(ClusteringTest, Ordering1) {
+ std::vector<InstructionBenchmark> Points(3);
+
+ Points[0].Measurements = {
+ {"x", 0.0, 0.0}};
+ Points[1].Measurements = {
+ {"x", 1.0, 0.0}};
+ Points[2].Measurements = {
+ {"x", 2.0, 0.0}};
+
+ auto Clustering = InstructionBenchmarkClustering::create(
+ Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 1.1);
+ ASSERT_TRUE((bool)Clustering);
+ EXPECT_THAT(Clustering.get().getValidClusters(),
+ UnorderedElementsAre(HasPoints({0, 1, 2})));
+}
+
+TEST(ClusteringTest, Ordering2) {
+ std::vector<InstructionBenchmark> Points(3);
+
+ Points[0].Measurements = {
+ {"x", 0.0, 0.0}};
+ Points[1].Measurements = {
+ {"x", 2.0, 0.0}};
+ Points[2].Measurements = {
+ {"x", 1.0, 0.0}};
+
+ auto Clustering = InstructionBenchmarkClustering::create(
+ Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 1.1);
+ ASSERT_TRUE((bool)Clustering);
+ EXPECT_THAT(Clustering.get().getValidClusters(),
+ UnorderedElementsAre(HasPoints({0, 1, 2})));
+}
+
} // namespace
} // namespace exegesis
} // namespace llvm
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
index 8a144e5..fcbff94 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
@@ -1,9 +1,8 @@
//===-- AssemblerUtils.h ----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PerfHelperTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PerfHelperTest.cpp
index 91ed4a6..39942af 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PerfHelperTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PerfHelperTest.cpp
@@ -1,9 +1,8 @@
//===-- PerfHelperTest.cpp --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/AnalysisTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/AnalysisTest.cpp
index 15d81ca..a7d2c6d 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/AnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/AnalysisTest.cpp
@@ -1,9 +1,8 @@
//===-- AnalysisTest.cpp ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp
index 0e34a15..3f6c5b6d 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp
@@ -1,9 +1,8 @@
//===-- TargetTest.cpp ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/RegisterValueTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/RegisterValueTest.cpp
index 8453720..a7c8ba6 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/RegisterValueTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/RegisterValueTest.cpp
@@ -1,9 +1,8 @@
//===-- RegisterValueTest.cpp -----------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp
index 451c3f6..ce7d9be 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp
@@ -1,9 +1,8 @@
//===-- AssemblerTest.cpp ---------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/BenchmarkResultTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/BenchmarkResultTest.cpp
index f069c21..56cbe31 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/BenchmarkResultTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/BenchmarkResultTest.cpp
@@ -1,9 +1,8 @@
//===-- BenchmarkResultTest.cpp ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/CMakeLists.txt b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/CMakeLists.txt
index 5078e7b..88c38d0 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/CMakeLists.txt
@@ -15,10 +15,10 @@
add_llvm_unittest(LLVMExegesisX86Tests
AssemblerTest.cpp
- AnalysisTest.cpp
BenchmarkResultTest.cpp
- SnippetGeneratorTest.cpp
RegisterAliasingTest.cpp
+ SchedClassResolutionTest.cpp
+ SnippetGeneratorTest.cpp
TargetTest.cpp
)
target_link_libraries(LLVMExegesisX86Tests PRIVATE
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp
index c85c99c2..b65b2a9 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp
@@ -1,9 +1,8 @@
//===-- RegisterAliasingTest.cpp --------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AnalysisTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp
similarity index 79%
rename from src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AnalysisTest.cpp
rename to src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp
index c893918..9e74546 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp
@@ -1,13 +1,12 @@
-//===-- AnalysisTest.cpp ---------------------------------------*- C++ -*-===//
+//===-- SchedClassResolutionTest.cpp ----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-#include "Analysis.h"
+#include "SchedClassResolution.h"
#include <cassert>
#include <memory>
@@ -24,9 +23,9 @@
using testing::Pair;
using testing::UnorderedElementsAre;
-class AnalysisTest : public ::testing::Test {
+class SchedClassResolutionTest : public ::testing::Test {
protected:
- AnalysisTest() {
+ SchedClassResolutionTest() {
const std::string TT = "x86_64-unknown-linux";
std::string error;
const llvm::Target *const TheTarget =
@@ -79,20 +78,20 @@
uint16_t P0156Idx = 0;
};
-TEST_F(AnalysisTest, ComputeIdealizedProcResPressure_2P0) {
+TEST_F(SchedClassResolutionTest, ComputeIdealizedProcResPressure_2P0) {
const auto Pressure =
computeIdealizedProcResPressure(STI->getSchedModel(), {{P0Idx, 2}});
EXPECT_THAT(Pressure, UnorderedElementsAre(Pair(P0Idx, 2.0)));
}
-TEST_F(AnalysisTest, ComputeIdealizedProcResPressure_2P05) {
+TEST_F(SchedClassResolutionTest, ComputeIdealizedProcResPressure_2P05) {
const auto Pressure =
computeIdealizedProcResPressure(STI->getSchedModel(), {{P05Idx, 2}});
EXPECT_THAT(Pressure,
UnorderedElementsAre(Pair(P0Idx, 1.0), Pair(P5Idx, 1.0)));
}
-TEST_F(AnalysisTest, ComputeIdealizedProcResPressure_2P05_2P0156) {
+TEST_F(SchedClassResolutionTest, ComputeIdealizedProcResPressure_2P05_2P0156) {
const auto Pressure = computeIdealizedProcResPressure(
STI->getSchedModel(), {{P05Idx, 2}, {P0156Idx, 2}});
EXPECT_THAT(Pressure,
@@ -100,7 +99,8 @@
Pair(P5Idx, 1.0), Pair(P6Idx, 1.0)));
}
-TEST_F(AnalysisTest, ComputeIdealizedProcResPressure_1P1_1P05_2P0156) {
+TEST_F(SchedClassResolutionTest,
+ ComputeIdealizedProcResPressure_1P1_1P05_2P0156) {
const auto Pressure = computeIdealizedProcResPressure(
STI->getSchedModel(), {{P1Idx, 1}, {P05Idx, 1}, {P0156Idx, 2}});
EXPECT_THAT(Pressure,
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
index 1689def..8b110f8 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
@@ -1,9 +1,8 @@
//===-- SnippetGeneratorTest.cpp --------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -228,19 +227,20 @@
}
TEST_F(UopsSnippetGeneratorTest, StaticRenaming) {
- // CMOVA32rr has tied variables, we enumerate the possible values to execute
+ // CMOV32rr has tied variables, we enumerate the possible values to execute
// as many in parallel as possible.
- // - CMOVA32rr
+ // - CMOV32rr
// - Op0 Explicit Def RegClass(GR32)
// - Op1 Explicit Use RegClass(GR32) TiedToOp0
// - Op2 Explicit Use RegClass(GR32)
+ // - Op3 Explicit Use Immediate
// - Op3 Implicit Use Reg(EFLAGS)
// - Var0 [Op0,Op1]
// - Var1 [Op2]
// - hasTiedRegisters (execution is always serial)
// - hasAliasingRegisters
- const unsigned Opcode = llvm::X86::CMOVA32rr;
+ const unsigned Opcode = llvm::X86::CMOV32rr;
const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
ASSERT_THAT(CodeTemplates, SizeIs(1));
const auto &CT = CodeTemplates[0];
@@ -250,7 +250,7 @@
ASSERT_THAT(CT.Instructions, SizeIs(kInstructionCount));
std::unordered_set<unsigned> AllDefRegisters;
for (const auto &IT : CT.Instructions) {
- ASSERT_THAT(IT.VariableValues, SizeIs(2));
+ ASSERT_THAT(IT.VariableValues, SizeIs(3));
AllDefRegisters.insert(IT.VariableValues[0].getReg());
}
EXPECT_THAT(AllDefRegisters, SizeIs(kInstructionCount))
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
index b1ccb48..344ec60 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
@@ -1,9 +1,8 @@
//===-- TargetTest.cpp -----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -145,6 +144,10 @@
Core2Avx512TargetTest() : X86TargetTest("+avx512vl") {}
};
+TEST_F(Core2TargetTest, NoHighByteRegs) {
+ EXPECT_TRUE(State.getRATC().reservedRegisters().test(X86::AH));
+}
+
TEST_F(Core2TargetTest, SetFlags) {
const unsigned Reg = llvm::X86::EFLAGS;
EXPECT_THAT(