[GlobalISel] Implement computeKnownBits for G_SEXT_INREG
authorJessica Paquette <jpaquette@apple.com>
Tue, 26 Jan 2021 22:39:39 +0000 (14:39 -0800)
committerJessica Paquette <jpaquette@apple.com>
Tue, 26 Jan 2021 23:01:38 +0000 (15:01 -0800)
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

llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
llvm/test/CodeGen/AMDGPU/GlobalISel/combine-redundant-and.mir
llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp

index aac7a73..2de2048 100644 (file)
@@ -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);
index 0f30123..d6d3a22 100644 (file)
@@ -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
+...
index b1e0548..1616f30 100644 (file)
@@ -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