Commit f36007e8 authored by Jessica Paquette's avatar Jessica Paquette
Browse files

[GlobalISel] Implement computeKnownBits for G_SEXT_INREG

Just use the existing `Known.sextInReg` implementation.

- Update KnownBitsTest.cpp.
- Update combine-redundant-and.mir for a more concrete example.

Differential Revision: https://reviews.llvm.org/D95484
parent 0554541b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -347,6 +347,12 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
    Known = Known.sext(BitWidth);
    break;
  }
  case TargetOpcode::G_SEXT_INREG: {
    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
                         Depth + 1);
    Known = Known.sextInReg(MI.getOperand(2).getImm());
    break;
  }
  case TargetOpcode::G_ANYEXT: {
    computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts,
                         Depth + 1);
+21 −0
Original line number Diff line number Diff line
@@ -142,3 +142,24 @@ body: |
    $sgpr0 = COPY %6(s32)
    SI_RETURN_TO_EPILOG implicit $sgpr0
...
---
name:            test_sext_inreg
tracksRegLiveness: true
body:             |
  bb.0:
    ; CHECK-LABEL: name: test_sext_inreg
    ; CHECK: %cst_1:_(s32) = G_CONSTANT i32 -5
    ; CHECK: $sgpr0 = COPY %cst_1(s32)
    ; CHECK: SI_RETURN_TO_EPILOG implicit $sgpr0
    %cst_1:_(s32) = G_CONSTANT i32 -5

    ; 000 ... 1011
    %cst_11:_(s32) = G_CONSTANT i32 11

    ; Sext from the 4th bit -> 111 ... 1011 = -5
    %sext_inreg_11:_(s32) = G_SEXT_INREG %cst_11, 4

    %and:_(s32) = G_AND %cst_1(s32), %sext_inreg_11(s32)
    $sgpr0 = COPY %and(s32)
    SI_RETURN_TO_EPILOG implicit $sgpr0
...
+72 −0
Original line number Diff line number Diff line
@@ -701,6 +701,78 @@ TEST_F(AArch64GISelMITest, TestKnownBitsExt) {
  EXPECT_EQ((uint64_t)0xfffffffe, Res.Zero.getZExtValue());
}

TEST_F(AArch64GISelMITest, TestKnownBitsSextInReg) {
  StringRef MIRString = R"(
   ; 000...0001
   %one:_(s32) = G_CONSTANT i32 1

   ; 000...0010
   %two:_(s32) = G_CONSTANT i32 2

   ; 000...1010
   %ten:_(s32) = G_CONSTANT i32 10

   ; ???...????
   %w0:_(s32) = COPY $w0

   ; ???...?1?
   %or:_(s32) = G_OR %w0, %two

   ; All bits are known.
   %inreg1:_(s32) = G_SEXT_INREG %one, 1
   %copy_inreg1:_(s32) = COPY %inreg1

   ; All bits unknown
   %inreg2:_(s32) = G_SEXT_INREG %or, 1
   %copy_inreg2:_(s32) = COPY %inreg2

   ; Extending from the only (known) set bit
   ; 111...11?
   %inreg3:_(s32) = G_SEXT_INREG %or, 2
   %copy_inreg3:_(s32) = COPY %inreg3

   ; Extending from a known set bit, overwriting all of the high set bits.
   ; 111...1110
   %inreg4:_(s32) = G_SEXT_INREG %ten, 2
   %copy_inreg4:_(s32) = COPY %inreg4

)";
  setUp(MIRString);
  if (!TM)
    return;
  GISelKnownBits Info(*MF);
  KnownBits Res;
  auto GetKB = [&](unsigned Idx) {
    Register CopyReg = Copies[Idx];
    auto *Copy = MRI->getVRegDef(CopyReg);
    return Info.getKnownBits(Copy->getOperand(1).getReg());
  };

  // Every bit is known to be a 1.
  Res = GetKB(Copies.size() - 4);
  EXPECT_EQ(32u, Res.getBitWidth());
  EXPECT_TRUE(Res.isAllOnes());

  // All bits are unknown
  Res = GetKB(Copies.size() - 3);
  EXPECT_EQ(32u, Res.getBitWidth());
  EXPECT_TRUE(Res.isUnknown());

  // Extending from the only known set bit
  // 111...11?
  Res = GetKB(Copies.size() - 2);
  EXPECT_EQ(32u, Res.getBitWidth());
  EXPECT_EQ(0xFFFFFFFEu, Res.One.getZExtValue());
  EXPECT_EQ(0u, Res.Zero.getZExtValue());

  // Extending from a known set bit, overwriting all of the high set bits.
  // 111...1110
  Res = GetKB(Copies.size() - 1);
  EXPECT_EQ(32u, Res.getBitWidth());
  EXPECT_EQ(0xFFFFFFFEu, Res.One.getZExtValue());
  EXPECT_EQ(1u, Res.Zero.getZExtValue());
}

TEST_F(AArch64GISelMITest, TestKnownBitsMergeValues) {
  StringRef MIRString = R"(
   %val0:_(s16) = G_CONSTANT i16 35224