[globalisel][knownbits] Account for missing type constraints
authorDaniel Sanders <daniel_l_sanders@apple.com>
Thu, 5 Sep 2019 20:26:02 +0000 (20:26 +0000)
committerDaniel Sanders <daniel_l_sanders@apple.com>
Thu, 5 Sep 2019 20:26:02 +0000 (20:26 +0000)
Now that we look through copies, it's possible to visit registers that
have a register class constraint but not a type constraint. Avoid looking
through copies when this occurs as the SrcReg won't be able to determine
it's bit width or any known bits.

Along the same lines, if the initial query is on a register that doesn't
have a type constraint then the result is a default-constructed KnownBits,
that is, a 1-bit fully-unknown value.

llvm-svn: 371116

llvm/lib/CodeGen/GlobalISel/GISelKnownBits.cpp
llvm/unittests/CodeGen/GlobalISel/KnownBitsTest.cpp

index 72ffd44..7db6465 100644 (file)
@@ -94,6 +94,15 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
   unsigned Opcode = MI.getOpcode();
   LLT DstTy = MRI.getType(R);
 
+  // Handle the case where this is called on a register that does not have a
+  // type constraint (i.e. it has a register class constraint instead). This is
+  // unlikely to occur except by looking through copies but it is possible for
+  // the initial register being queried to be in this state.
+  if (!DstTy.isValid()) {
+    Known = KnownBits();
+    return;
+  }
+
   unsigned BitWidth = DstTy.getSizeInBits();
   Known = KnownBits(BitWidth); // Don't know anything
 
@@ -115,11 +124,15 @@ void GISelKnownBits::computeKnownBitsImpl(Register R, KnownBits &Known,
   case TargetOpcode::COPY: {
     MachineOperand Dst = MI.getOperand(0);
     MachineOperand Src = MI.getOperand(1);
-    // Look through trivial copies.
+    // Look through trivial copies but don't look through trivial copies of the
+    // form `%1:(s32) = OP %0:gpr32` known-bits analysis is currently unable to
+    // determine the bit width of a register class.
+    //
     // We can't use NoSubRegister by name as it's defined by each target but
     // it's always defined to be 0 by tablegen.
     if (Dst.getSubReg() == 0 /*NoSubRegister*/ && Src.getReg().isVirtual() &&
-        Src.getSubReg() == 0 /*NoSubRegister*/) {
+        Src.getSubReg() == 0 /*NoSubRegister*/ &&
+        MRI.getType(Src.getReg()).isValid()) {
       // Don't increment Depth for this one since we didn't do any work.
       computeKnownBitsImpl(Src.getReg(), Known, DemandedElts, Depth);
     }
index 62d763b..863a0a7 100644 (file)
@@ -30,6 +30,32 @@ TEST_F(GISelMITest, TestKnownBitsCst) {
   EXPECT_EQ(Res.Zero.getZExtValue(), Res2.Zero.getZExtValue());
 }
 
+TEST_F(GISelMITest, TestKnownBitsCstWithClass) {
+  StringRef MIRString = "  %10:gpr32 = MOVi32imm 1\n"
+                        "  %4:_(s32) = COPY %10\n";
+  setUp(MIRString);
+  if (!TM)
+    return;
+  unsigned CopyReg = Copies[Copies.size() - 1];
+  MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg);
+  unsigned SrcReg = FinalCopy->getOperand(1).getReg();
+  unsigned DstReg = FinalCopy->getOperand(0).getReg();
+  GISelKnownBits Info(*MF);
+  KnownBits Res = Info.getKnownBits(SrcReg);
+  // We can't analyze %3 due to the register class constraint. We will get a
+  // default-constructed KnownBits back.
+  EXPECT_EQ((uint64_t)1, Res.getBitWidth());
+  EXPECT_EQ((uint64_t)0, Res.One.getZExtValue());
+  EXPECT_EQ((uint64_t)0, Res.Zero.getZExtValue());
+
+  KnownBits Res2 = Info.getKnownBits(DstReg);
+  // We still don't know the values due to the register class constraint but %4
+  // did reveal the size of %3.
+  EXPECT_EQ((uint64_t)32, Res2.getBitWidth());
+  EXPECT_EQ(Res.One.getZExtValue(), Res2.One.getZExtValue());
+  EXPECT_EQ(Res.Zero.getZExtValue(), Res2.Zero.getZExtValue());
+}
+
 TEST_F(GISelMITest, TestKnownBitsPtrToIntViceVersa) {
   StringRef MIRString = "  %3:_(s16) = G_CONSTANT i16 256\n"
                         "  %4:_(p0) = G_INTTOPTR %3\n"