From b2b9a2375848d37f6104ce01bd34bf2a3ddc9d2e Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 29 Aug 2019 17:24:36 +0000 Subject: [PATCH] GlobalISel: Add maskedValueIsZero and signBitIsZero to known bits I dropped the DemandedElts since it seems to be missing from some of the new interfaces, but not others. llvm-svn: 370389 --- .../llvm/CodeGen/GlobalISel/GISelKnownBits.h | 11 +++++++++++ llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp | 6 ++++++ .../CodeGen/GlobalISel/KnownBitsTest.cpp | 16 ++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h b/llvm/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h index f7b804b3a21169..e2a088f9217644 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h @@ -47,6 +47,17 @@ class GISelKnownBits : public GISelChangeObserver { APInt getKnownZeroes(Register R); APInt getKnownOnes(Register R); + /// \return true if 'V & Mask' is known to be zero in DemandedElts. We use + /// this predicate to simplify operations downstream. + /// Mask is known to be zero for bits that V cannot have. + bool maskedValueIsZero(Register Val, const APInt &Mask) { + return Mask.isSubsetOf(getKnownBits(Val).Zero); + } + + /// \return true if the sign bit of Op is known to be zero. We use this + /// predicate to simplify operations downstream. + bool signBitIsZero(Register Op); + // FIXME: Is this the right place for G_FRAME_INDEX? Should it be in // TargetLowering? void computeKnownBitsForFrameIndex(Register R, KnownBits &Known, diff --git a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp index 31e28f5ed5c64d..0870aa3812fe9b 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -75,6 +75,12 @@ KnownBits GISelKnownBits::getKnownBits(Register R) { return Known; } +bool GISelKnownBits::signBitIsZero(Register R) { + LLT Ty = MRI.getType(R); + unsigned BitWidth = Ty.getScalarSizeInBits(); + return maskedValueIsZero(R, APInt::getSignMask(BitWidth)); +} + APInt GISelKnownBits::getKnownZeroes(Register R) { return getKnownBits(R).Zero; } diff --git a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp index f67184fc2081d7..42d676f4a00e59 100644 --- a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp @@ -86,3 +86,19 @@ TEST_F(GISelMITest, TestKnownBits) { APInt Zeroes = Info.getKnownZeroes(SrcReg); EXPECT_EQ(Known.Zero, Zeroes); } + +TEST_F(GISelMITest, TestSignBitIsZero) { + if (!TM) + return; + + const LLT S32 = LLT::scalar(32); + auto SignBit = B.buildConstant(S32, 0x8000000); + auto Zero = B.buildConstant(S32, 0); + + GISelKnownBits KnownBits(*MF); + + EXPECT_TRUE(KnownBits.signBitIsZero(Zero.getReg(0))); + EXPECT_FALSE(KnownBits.signBitIsZero(Zero.getReg(0))); + EXPECT_FALSE(KnownBits.signBitIsZero(SignBit.getReg(0))); + EXPECT_TRUE(KnownBits.signBitIsZero(SignBit.getReg(0))); +}