[PATCH] D72423: [DemandedBits] Improve accuracy of Add propagator

Erika via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 8 15:37:42 PST 2020


rrika created this revision.
rrika added a reviewer: jmolloy.
rrika added a project: LLVM.
Herald added subscribers: llvm-commits, hiraditya.

The current demand propagator for addition will mark all input bits at and right of the alive output bit as alive. But carry won't propagate beyond a bit for which both operands are zero (or one/zero in the case of subtraction) so a more accurate answer is possible given known bits.

I derived a propagator by working through truth tables and using a bit-reversed addition to make demand ripple to the right, but I'm not sure how to make a convincing argument for its correctness in the comments yet. Nevertheless, here's a minimal implementation and test to get feedback.

This would help in a situation where, for example, four bytes (<128) packed into an int are added with four others SIMD-style but only one of the four results is actually read.

  Known A:     0_______0_______0_______0_______
  Known B:     0_______0_______0_______0_______
  AOut:        00000000001000000000000000000000
  AB, current: 00000000001111111111111111111111
  AB, patch:   00000000001111111000000000000000


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72423

Files:
  llvm/lib/Analysis/DemandedBits.cpp
  llvm/test/Analysis/DemandedBits/add.ll


Index: llvm/test/Analysis/DemandedBits/add.ll
===================================================================
--- /dev/null
+++ llvm/test/Analysis/DemandedBits/add.ll
@@ -0,0 +1,18 @@
+; RUN: opt -S -demanded-bits -analyze < %s | FileCheck %s
+; RUN: opt -S -disable-output -passes="print<demanded-bits>" < %s 2>&1 | FileCheck %s
+ 
+; CHECK-DAG: DemandedBits: 0x1e for   %1 = and i32 %a, 9
+; CHECK-DAG: DemandedBits: 0x1a for   %2 = and i32 %b, 9
+; CHECK-DAG: DemandedBits: 0x1a for   %3 = and i32 %c, 13
+; CHECK-DAG: DemandedBits: 0x1a for   %4 = and i32 %d, 4
+define i32 @test_add(i32 %a, i32 %b, i32 %c, i32 %d) {
+  %1 = and i32 %a, 9
+  %2 = and i32 %b, 9
+  %3 = and i32 %c, 13
+  %4 = and i32 %d, 4 ; dead
+  %5 = or i32 %2, %3
+  %6 = or i32 %4, %5
+  %7 = add i32 %1, %6
+  %8 = and i32 %7, 16
+  ret i32 %8
+}
Index: llvm/lib/Analysis/DemandedBits.cpp
===================================================================
--- llvm/lib/Analysis/DemandedBits.cpp
+++ llvm/lib/Analysis/DemandedBits.cpp
@@ -173,7 +173,30 @@
       }
     break;
   case Instruction::Add:
-  case Instruction::Sub:
+  case Instruction::Sub: {
+    ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
+    // When Bound == 0, this should behave just like
+    // AB = APInt::getLowBitsSet(BitWidth, AOut.getActiveBits());
+    APInt Bound1;
+    if (UserI->getOpcode() == Instruction::Add)
+      Bound1 = Known.Zero;
+    else
+      Bound1 = Known.One;
+    APInt Bound2 = Known2.Zero;
+    APInt Bound = Bound1 & Bound2;
+    APInt RBound = Bound.reverseBits();
+    APInt RAOut = AOut.reverseBits();
+    APInt RProp = RAOut + (RAOut | ~RBound);
+    APInt RQ = (RProp ^ ~(RAOut | RBound));
+    APInt Q = RQ.reverseBits();
+    APInt U;
+    if (OperandNo == 0)
+      U = Bound1 | ~Bound2;
+    else
+      U = Bound2 | ~Bound1;
+    AB = AOut | (Q & (U | (Bound1 + Bound2 + 1)));
+    break;
+  }
   case Instruction::Mul:
     // Find the highest live output bit. We don't need any more input
     // bits than that (adds, and thus subtracts, ripple only to the


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72423.236910.patch
Type: text/x-patch
Size: 2085 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200108/c697107f/attachment.bin>


More information about the llvm-commits mailing list