diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h --- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h @@ -488,6 +488,10 @@ /// the value \p Val contains a true value. bool isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector, bool IsFP); +/// \returns true if given the TargetLowering's boolean contents information, +/// the value \p Val contains a false value. +bool isConstFalseVal(const TargetLowering &TLI, int64_t Val, bool IsVector, + bool IsFP); /// Returns an integer representing true, as defined by the /// TargetBooleanContents. diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp --- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -1278,6 +1278,18 @@ llvm_unreachable("Invalid boolean contents"); } +bool llvm::isConstFalseVal(const TargetLowering &TLI, int64_t Val, + bool IsVector, bool IsFP) { + switch (TLI.getBooleanContents(IsVector, IsFP)) { + case TargetLowering::UndefinedBooleanContent: + return ~Val & 0x1; + case TargetLowering::ZeroOrOneBooleanContent: + case TargetLowering::ZeroOrNegativeOneBooleanContent: + return Val == 0; + } + llvm_unreachable("Invalid boolean contents"); +} + int64_t llvm::getICmpTrueVal(const TargetLowering &TLI, bool IsVector, bool IsFP) { switch (TLI.getBooleanContents(IsVector, IsFP)) { diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelUtilsTest.cpp b/llvm/unittests/CodeGen/GlobalISel/GISelUtilsTest.cpp --- a/llvm/unittests/CodeGen/GlobalISel/GISelUtilsTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/GISelUtilsTest.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "GISelMITest.h" #include "llvm/CodeGen/GlobalISel/Utils.h" #include "gtest/gtest.h" @@ -245,4 +246,23 @@ EXPECT_EQ(V4P1, getLCMType(P1, V2S64)); } +TEST_F(AArch64GISelMITest, ConstFalseTest) { + setUp(); + if (!TM) + return; + const auto &TLI = *B.getMF().getSubtarget().getTargetLowering(); + bool BooleanChoices[2] = {true, false}; + + // AArch64 uses ZeroOrOneBooleanContent for scalars, and + // ZeroOrNegativeOneBooleanContent for vectors. + for (auto IsVec : BooleanChoices) { + for (auto IsFP : BooleanChoices) { + EXPECT_TRUE(isConstFalseVal(TLI, 0, IsVec, IsFP)); + EXPECT_FALSE(isConstFalseVal(TLI, 1, IsVec, IsFP)); + + // This would be true with UndefinedBooleanContent. + EXPECT_FALSE(isConstFalseVal(TLI, 2, IsVec, IsFP)); + } + } +} }