GlobalISel: Implement computeKnownBits for G_BSWAP and G_BITREVERSE
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Thu, 27 Aug 2020 21:55:35 +0000 (17:55 -0400)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 1 Sep 2020 16:49:57 +0000 (12:49 -0400)
llvm/include/llvm/Support/KnownBits.h
llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp

index 760f3cd..5b3de63 100644 (file)
@@ -261,6 +261,14 @@ public:
 
   /// Update known bits based on XORing with RHS.
   KnownBits &operator^=(const KnownBits &RHS);
+
+  KnownBits byteSwap() {
+    return KnownBits(Zero.byteSwap(), One.byteSwap());
+  }
+
+  KnownBits reverseBits() {
+    return KnownBits(Zero.reverseBits(), One.reverseBits());
+  }
 };
 
 inline KnownBits operator&(KnownBits LHS, const KnownBits &RHS) {
index f284582..acd8204 100644 (file)
@@ -437,6 +437,18 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
     Known = SrcOpKnown.extractBits(BitWidth, BitWidth * DstIdx);
     break;
   }
+  case TargetOpcode::G_BSWAP: {
+    Register SrcReg = MI.getOperand(1).getReg();
+    computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
+    Known.byteSwap();
+    break;
+  }
+  case TargetOpcode::G_BITREVERSE: {
+    Register SrcReg = MI.getOperand(1).getReg();
+    computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
+    Known.reverseBits();
+    break;
+  }
   }
 
   assert(!Known.hasConflict() && "Bits known to be one AND zero?");
index 463d8a0..82850f1 100644 (file)
@@ -3357,14 +3357,12 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
   }
   case ISD::BITREVERSE: {
     Known2 = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
-    Known.Zero = Known2.Zero.reverseBits();
-    Known.One = Known2.One.reverseBits();
+    Known = Known2.reverseBits();
     break;
   }
   case ISD::BSWAP: {
     Known2 = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
-    Known.Zero = Known2.Zero.byteSwap();
-    Known.One = Known2.One.byteSwap();
+    Known = Known2.byteSwap();
     break;
   }
   case ISD::ABS: {
index ad30ccd..92dc57b 100644 (file)
@@ -671,3 +671,33 @@ TEST_F(AArch64GISelMITest, TestKnownBitsUnmergeValues) {
     EXPECT_EQ(static_cast<uint16_t>(~PartTestVal), PartKnown.Zero.getZExtValue());
   }
 }
+
+TEST_F(AArch64GISelMITest, TestKnownBitsBSwapBitReverse) {
+  StringRef MIRString = R"(
+   %const:_(s32) = G_CONSTANT i32 287454020
+   %bswap:_(s32) = G_BSWAP %const
+   %bitreverse:_(s32) = G_BITREVERSE %const
+   %copy_bswap:_(s32) = COPY %bswap
+   %copy_bitreverse:_(s32) = COPY %bitreverse
+)";
+  setUp(MIRString);
+  if (!TM)
+    return;
+
+  const uint32_t TestVal = 0x11223344;
+
+  Register CopyBSwap = Copies[Copies.size() - 2];
+  Register CopyBitReverse = Copies[Copies.size() - 1];
+
+  GISelKnownBits Info(*MF);
+
+  KnownBits BSwapKnown = Info.getKnownBits(CopyBSwap);
+  EXPECT_EQ(32u, BSwapKnown.getBitWidth());
+  EXPECT_EQ(TestVal, BSwapKnown.One.getZExtValue());
+  EXPECT_EQ(~TestVal, BSwapKnown.Zero.getZExtValue());
+
+  KnownBits BitReverseKnown = Info.getKnownBits(CopyBitReverse);
+  EXPECT_EQ(32u, BitReverseKnown.getBitWidth());
+  EXPECT_EQ(TestVal, BitReverseKnown.One.getZExtValue());
+  EXPECT_EQ(~TestVal, BitReverseKnown.Zero.getZExtValue());
+}