[llvm] cbde248 - Add getDemandedBits for uses.

Joseph Tremoulet via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 2 07:08:04 PDT 2021


Author: Qunyan Mangus
Date: 2021-06-02T10:07:40-04:00
New Revision: cbde2487367a54355329c5fb942914627e01e598

URL: https://github.com/llvm/llvm-project/commit/cbde2487367a54355329c5fb942914627e01e598
DIFF: https://github.com/llvm/llvm-project/commit/cbde2487367a54355329c5fb942914627e01e598.diff

LOG: Add getDemandedBits for uses.

Add getDemandedBits method for uses so we can query demanded bits for each use.  This can help getting better use information. For example, for the code below
define i32 @test_use(i32 %a) {
  %1 = and i32 %a, -256
  %2 = or i32 %1, 1
  %3 = trunc i32 %2 to i8 (didn't optimize this to 1 for illustration purpose)
  ... some use of %3
  ret %2
}
if we look at the demanded bit of %2 (which is all 32 bits because of the return), we would conclude that %a is used regardless of how its return is used. However, if we look at each use separately, we will see that the demanded bit of %2 in trunc only uses the lower 8 bits of %a which is redefined, therefore %a's usage depends on how the function return is used.

Reviewed By: RKSimon

Differential Revision: https://reviews.llvm.org/D97074

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/DemandedBits.h
    llvm/lib/Analysis/DemandedBits.cpp
    llvm/test/Analysis/DemandedBits/basic.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/DemandedBits.h b/llvm/include/llvm/Analysis/DemandedBits.h
index 66623fbdcdc12..5a68fcbebfea7 100644
--- a/llvm/include/llvm/Analysis/DemandedBits.h
+++ b/llvm/include/llvm/Analysis/DemandedBits.h
@@ -53,6 +53,9 @@ class DemandedBits {
   /// accepted, but will always produce a mask with all bits set.
   APInt getDemandedBits(Instruction *I);
 
+  /// Return the bits demanded from use U.
+  APInt getDemandedBits(Use *U);
+
   /// Return true if, during analysis, I could not be reached.
   bool isInstructionDead(Instruction *I);
 

diff  --git a/llvm/lib/Analysis/DemandedBits.cpp b/llvm/lib/Analysis/DemandedBits.cpp
index dd11b0b02bf8c..467dea9c02366 100644
--- a/llvm/lib/Analysis/DemandedBits.cpp
+++ b/llvm/lib/Analysis/DemandedBits.cpp
@@ -452,6 +452,33 @@ APInt DemandedBits::getDemandedBits(Instruction *I) {
       DL.getTypeSizeInBits(I->getType()->getScalarType()));
 }
 
+APInt DemandedBits::getDemandedBits(Use *U) {
+  Type *T = (*U)->getType();
+  Instruction *UserI = cast<Instruction>(U->getUser());
+  const DataLayout &DL = UserI->getModule()->getDataLayout();
+  unsigned BitWidth = DL.getTypeSizeInBits(T->getScalarType());
+
+  // We only track integer uses, everything else produces a mask with all bits
+  // set
+  if (!T->isIntOrIntVectorTy())
+    return APInt::getAllOnesValue(BitWidth);
+
+  if (isUseDead(U))
+    return APInt(BitWidth, 0);
+
+  performAnalysis();
+
+  APInt AOut = getDemandedBits(UserI);
+  APInt AB = APInt::getAllOnesValue(BitWidth);
+  KnownBits Known, Known2;
+  bool KnownBitsComputed = false;
+
+  determineLiveOperandBits(UserI, *U, U->getOperandNo(), AOut, AB, Known,
+                           Known2, KnownBitsComputed);
+
+  return AB;
+}
+
 bool DemandedBits::isInstructionDead(Instruction *I) {
   performAnalysis();
 
@@ -485,10 +512,24 @@ bool DemandedBits::isUseDead(Use *U) {
 }
 
 void DemandedBits::print(raw_ostream &OS) {
+  auto PrintDB = [&](const Instruction *I, const APInt &A, Value *V = nullptr) {
+    OS << "DemandedBits: 0x" << Twine::utohexstr(A.getLimitedValue())
+       << " for ";
+    if (V) {
+      V->printAsOperand(OS, false);
+      OS << " in ";
+    }
+    OS << *I << '\n';
+  };
+
   performAnalysis();
   for (auto &KV : AliveBits) {
-    OS << "DemandedBits: 0x" << Twine::utohexstr(KV.second.getLimitedValue())
-       << " for " << *KV.first << '\n';
+    Instruction *I = KV.first;
+    PrintDB(I, KV.second);
+
+    for (Use &OI : I->operands()) {
+      PrintDB(I, getDemandedBits(&OI), OI);
+    }
   }
 }
 

diff  --git a/llvm/test/Analysis/DemandedBits/basic.ll b/llvm/test/Analysis/DemandedBits/basic.ll
index a05d3804156a3..8895b27031013 100644
--- a/llvm/test/Analysis/DemandedBits/basic.ll
+++ b/llvm/test/Analysis/DemandedBits/basic.ll
@@ -4,9 +4,24 @@
 ; CHECK-DAG: DemandedBits: 0xff for   %1 = add nsw i32 %a, 5
 ; CHECK-DAG: DemandedBits: 0xff for   %3 = trunc i32 %2 to i8
 ; CHECK-DAG: DemandedBits: 0xff for   %2 = mul nsw i32 %1, %b
+; CHECK-DAG: DemandedBits: 0x1 for   %4 = trunc i32 %2 to i1
+; CHECK-DAG: DemandedBits: 0xff for   %5 = zext i1 %4 to i8
+; CHECK-DAG: DemandedBits: 0xff for   %6 = add nsw i8 %3, %5
+; CHECK-DAG: DemandedBits: 0xff for %a in   %1 = add nsw i32 %a, 5
+; CHECK-DAG: DemandedBits: 0xff for 5 in   %1 = add nsw i32 %a, 5
+; CHECK-DAG: DemandedBits: 0xff for %1 in   %2 = mul nsw i32 %1, %b
+; CHECK-DAG: DemandedBits: 0xff for %b in   %2 = mul nsw i32 %1, %b
+; CHECK-DAG: DemandedBits: 0xff for %2 in   %3 = trunc i32 %2 to i8
+; CHECK-DAG: DemandedBits: 0x1 for %2 in   %4 = trunc i32 %2 to i1
+; CHECK-DAG: DemandedBits: 0x1 for %4 in   %5 = zext i1 %4 to i8
+; CHECK-DAG: DemandedBits: 0xff for %3 in   %6 = add nsw i8 %3, %5
+; CHECK-DAG: DemandedBits: 0xff for %5 in   %6 = add nsw i8 %3, %5
 define i8 @test_mul(i32 %a, i32 %b) {
   %1 = add nsw i32 %a, 5
   %2 = mul nsw i32 %1, %b
   %3 = trunc i32 %2 to i8
-  ret i8 %3
+  %4 = trunc i32 %2 to i1
+  %5 = zext i1 %4 to i8
+  %6 = add nsw i8 %3, %5
+  ret i8 %6
 }


        


More information about the llvm-commits mailing list