diff --git a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp index 51ab7b6262c62..529e50c8ebe05 100644 --- a/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp +++ b/llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp @@ -694,6 +694,20 @@ unsigned GISelKnownBits::computeNumSignBits(Register R, const MachineMemOperand *MMO = *MI.memoperands_begin(); return TyBits - MMO->getSizeInBits().getValue(); } + case TargetOpcode::G_AND: + case TargetOpcode::G_OR: + case TargetOpcode::G_XOR: { + Register Src1 = MI.getOperand(1).getReg(); + unsigned Src1NumSignBits = + computeNumSignBits(Src1, DemandedElts, Depth + 1); + if (Src1NumSignBits != 1) { + Register Src2 = MI.getOperand(2).getReg(); + unsigned Src2NumSignBits = + computeNumSignBits(Src2, DemandedElts, Depth + 1); + FirstAnswer = std::min(Src1NumSignBits, Src2NumSignBits); + } + break; + } case TargetOpcode::G_TRUNC: { Register Src = MI.getOperand(1).getReg(); LLT SrcTy = MRI.getType(Src); diff --git a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp index ef80eed8d1802..34a36ba68d7c0 100644 --- a/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp @@ -745,6 +745,120 @@ TEST_F(AArch64GISelMITest, TestNumSignBitsConstant) { EXPECT_EQ(3u, Info.computeNumSignBits(CopyRegNeg32)); } +TEST_F(AArch64GISelMITest, TestNumSignBitsXOR) { + StringRef MIRString = " %c1:_(s8) = G_CONSTANT i8 1\n" + " %cn1:_(s8) = G_CONSTANT i8 -1\n" + " %c127:_(s8) = G_CONSTANT i8 127\n" + " %c32:_(s8) = G_CONSTANT i8 32\n" + " %cn32:_(s8) = G_CONSTANT i8 -32\n" + + " %xor1:_(s8) = G_XOR %c1, %cn1\n" + " %Copy1:_(s8) = COPY %xor1\n" + + " %xor2:_(s8) = G_XOR %c1, %c32\n" + " %Copy2:_(s8) = COPY %xor2\n" + + " %xor3:_(s8) = G_XOR %c32, %c127\n" + " %Copy3:_(s8) = COPY %xor3\n" + + " %xor4:_(s8) = G_XOR %cn32, %c127\n" + " %Copy4:_(s8) = COPY %xor4\n" + + " %xor5:_(s8) = G_XOR %c127, %cn32\n" + " %Copy5:_(s8) = COPY %xor5\n"; + setUp(MIRString); + if (!TM) + GTEST_SKIP(); + Register Copy1 = Copies[Copies.size() - 5]; + Register Copy2 = Copies[Copies.size() - 4]; + Register Copy3 = Copies[Copies.size() - 3]; + Register Copy4 = Copies[Copies.size() - 2]; + Register Copy5 = Copies[Copies.size() - 1]; + + GISelKnownBits Info(*MF); + EXPECT_EQ(7u, Info.computeNumSignBits(Copy1)); + EXPECT_EQ(2u, Info.computeNumSignBits(Copy2)); + EXPECT_EQ(1u, Info.computeNumSignBits(Copy3)); + EXPECT_EQ(1u, Info.computeNumSignBits(Copy4)); + EXPECT_EQ(1u, Info.computeNumSignBits(Copy5)); +} + +TEST_F(AArch64GISelMITest, TestNumSignBitsOR) { + StringRef MIRString = " %c1:_(s8) = G_CONSTANT i8 1\n" + " %cn1:_(s8) = G_CONSTANT i8 -1\n" + " %c127:_(s8) = G_CONSTANT i8 127\n" + " %c32:_(s8) = G_CONSTANT i8 32\n" + " %cn32:_(s8) = G_CONSTANT i8 -32\n" + + " %or1:_(s8) = G_OR %c1, %cn1\n" + " %Copy1:_(s8) = COPY %or1\n" + + " %or2:_(s8) = G_OR %c1, %c32\n" + " %Copy2:_(s8) = COPY %or2\n" + + " %or3:_(s8) = G_OR %c32, %c127\n" + " %Copy3:_(s8) = COPY %or3\n" + + " %or4:_(s8) = G_OR %cn32, %c127\n" + " %Copy4:_(s8) = COPY %or4\n" + + " %or5:_(s8) = G_OR %c127, %cn32\n" + " %Copy5:_(s8) = COPY %or5\n"; + setUp(MIRString); + if (!TM) + GTEST_SKIP(); + Register Copy1 = Copies[Copies.size() - 5]; + Register Copy2 = Copies[Copies.size() - 4]; + Register Copy3 = Copies[Copies.size() - 3]; + Register Copy4 = Copies[Copies.size() - 2]; + Register Copy5 = Copies[Copies.size() - 1]; + + GISelKnownBits Info(*MF); + EXPECT_EQ(8u, Info.computeNumSignBits(Copy1)); + EXPECT_EQ(2u, Info.computeNumSignBits(Copy2)); + EXPECT_EQ(1u, Info.computeNumSignBits(Copy3)); + EXPECT_EQ(8u, Info.computeNumSignBits(Copy4)); + EXPECT_EQ(8u, Info.computeNumSignBits(Copy5)); +} + +TEST_F(AArch64GISelMITest, TestNumSignBitsAND) { + StringRef MIRString = " %c1:_(s8) = G_CONSTANT i8 1\n" + " %cn1:_(s8) = G_CONSTANT i8 -1\n" + " %c127:_(s8) = G_CONSTANT i8 127\n" + " %c32:_(s8) = G_CONSTANT i8 32\n" + " %cn32:_(s8) = G_CONSTANT i8 -32\n" + + " %and1:_(s8) = G_AND %c1, %cn1\n" + " %Copy1:_(s8) = COPY %and1\n" + + " %and2:_(s8) = G_AND %c1, %c32\n" + " %Copy2:_(s8) = COPY %and2\n" + + " %and3:_(s8) = G_AND %c32, %c127\n" + " %Copy3:_(s8) = COPY %and3\n" + + " %and4:_(s8) = G_AND %cn32, %c127\n" + " %Copy4:_(s8) = COPY %and4\n" + + " %and5:_(s8) = G_AND %c127, %cn32\n" + " %Copy5:_(s8) = COPY %and5\n"; + setUp(MIRString); + if (!TM) + GTEST_SKIP(); + Register Copy1 = Copies[Copies.size() - 5]; + Register Copy2 = Copies[Copies.size() - 4]; + Register Copy3 = Copies[Copies.size() - 3]; + Register Copy4 = Copies[Copies.size() - 2]; + Register Copy5 = Copies[Copies.size() - 1]; + + GISelKnownBits Info(*MF); + EXPECT_EQ(7u, Info.computeNumSignBits(Copy1)); + EXPECT_EQ(8u, Info.computeNumSignBits(Copy2)); + EXPECT_EQ(2u, Info.computeNumSignBits(Copy3)); + EXPECT_EQ(1u, Info.computeNumSignBits(Copy4)); + EXPECT_EQ(1u, Info.computeNumSignBits(Copy5)); +} + TEST_F(AArch64GISelMITest, TestNumSignBitsSext) { StringRef MIRString = " %3:_(p0) = G_IMPLICIT_DEF\n" " %4:_(s8) = G_LOAD %3 :: (load (s8))\n"