Index: llvm/include/llvm/CodeGen/GlobalISel/Utils.h =================================================================== --- llvm/include/llvm/CodeGen/GlobalISel/Utils.h +++ llvm/include/llvm/CodeGen/GlobalISel/Utils.h @@ -258,6 +258,11 @@ 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 true if \p Val is a true value extended from \p OrigTy to \p ExtTy. /// \p IsFP is true if the value is floating point. /// \p IsSignExtended is true if the extension should be signed. Index: llvm/lib/CodeGen/GlobalISel/Utils.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -734,6 +734,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"); +} + bool llvm::isExtendedTrueVal(const TargetLowering &TLI, int64_t Val, const LLT &ExtTy, const LLT &OrigTy, bool IsFP, bool IsSignExtended) { Index: llvm/unittests/CodeGen/GlobalISel/GISelUtilsTest.cpp =================================================================== --- llvm/unittests/CodeGen/GlobalISel/GISelUtilsTest.cpp +++ llvm/unittests/CodeGen/GlobalISel/GISelUtilsTest.cpp @@ -294,4 +294,24 @@ } } +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)); + } + } +} + } // namespace