[llvm] [SLP]Improve minbitwidth analysis for shifts. (PR #84356)

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 14 13:17:14 PDT 2024


================
@@ -14039,6 +14039,84 @@ bool BoUpSLP::collectValuesToDemote(
     MaxDepthLevel = std::max(Level1, Level2);
     break;
   }
+  case Instruction::Shl: {
+    // Several vectorized uses? Check if we can truncate it, otherwise - exit.
+    if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth))
+      return false;
+    // If we are truncating the result of this SHL, and if it's a shift of an
+    // inrange amount, we can always perform a SHL in a smaller type.
+    unsigned Level1, Level2;
+    KnownBits AmtKnownBits = computeKnownBits(I->getOperand(1), *DL);
+    if (AmtKnownBits.getMaxValue().uge(BitWidth))
+      return IsProfitableToDemote && IsPotentiallyTruncated(I, BitWidth);
+    bool Res1 = collectValuesToDemote(
+        I->getOperand(0), IsProfitableToDemoteRoot, BitWidth, ToDemote,
+        DemotedConsts, Visited, Level1, IsProfitableToDemote, IsTruncRoot);
+    bool Res2 = collectValuesToDemote(
+        I->getOperand(1), IsProfitableToDemoteRoot, BitWidth, ToDemote,
+        DemotedConsts, Visited, Level2, IsProfitableToDemote, IsTruncRoot);
+    if (!Res1 || !Res2) {
+      MaxDepthLevel = Res1 ? Level1 : (Res2 ? Level2 : 1);
+      return IsProfitableToDemote && IsPotentiallyTruncated(I, BitWidth);
+    }
+    MaxDepthLevel = std::max(Level1, Level2);
+    break;
+  }
+  case Instruction::LShr: {
+    // Several vectorized uses? Check if we can truncate it, otherwise - exit.
+    if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth))
+      return false;
+    // If this is a truncate of a logical shr, we can truncate it to a smaller
+    // lshr iff we know that the bits we would otherwise be shifting in are
+    // already zeros.
+    uint32_t OrigBitWidth = DL->getTypeSizeInBits(V->getType());
+    unsigned Level1, Level2;
+    KnownBits AmtKnownBits = computeKnownBits(I->getOperand(1), *DL);
+    APInt ShiftedBits = APInt::getBitsSetFrom(OrigBitWidth, BitWidth);
+    if (AmtKnownBits.getMaxValue().uge(BitWidth) ||
+        !MaskedValueIsZero(I->getOperand(0), ShiftedBits, SimplifyQuery(*DL)))
+      return IsProfitableToDemote && IsPotentiallyTruncated(I, BitWidth);
+    bool Res1 = collectValuesToDemote(
+        I->getOperand(0), IsProfitableToDemoteRoot, BitWidth, ToDemote,
+        DemotedConsts, Visited, Level1, IsProfitableToDemote, IsTruncRoot);
+    bool Res2 = collectValuesToDemote(
+        I->getOperand(1), IsProfitableToDemoteRoot, BitWidth, ToDemote,
+        DemotedConsts, Visited, Level2, IsProfitableToDemote, IsTruncRoot);
+    if (!Res1 || !Res2) {
+      MaxDepthLevel = Res1 ? Level1 : (Res2 ? Level2 : 1);
+      return IsProfitableToDemote && IsPotentiallyTruncated(I, BitWidth);
+    }
+    MaxDepthLevel = std::max(Level1, Level2);
+    break;
+  }
+  case Instruction::AShr: {
+    // Several vectorized uses? Check if we can truncate it, otherwise - exit.
+    if (ITE->UserTreeIndices.size() > 1 && !IsPotentiallyTruncated(I, BitWidth))
+      return false;
+    // If this is a truncate of an arithmetic shr, we can truncate it to a
+    // smaller ashr iff we know that all the bits from the sign bit of the
+    // original type and the sign bit of the truncate type are similar.
+    uint32_t OrigBitWidth = DL->getTypeSizeInBits(V->getType());
+    unsigned Level1, Level2;
+    KnownBits AmtKnownBits = computeKnownBits(I->getOperand(1), *DL);
+    unsigned ShiftedBits = OrigBitWidth - BitWidth;
+    if (AmtKnownBits.getMaxValue().uge(BitWidth) ||
+        ShiftedBits >=
+            ComputeNumSignBits(I->getOperand(0), *DL, 0, AC, nullptr, DT))
+      return IsProfitableToDemote && IsPotentiallyTruncated(I, BitWidth);
----------------
alexey-bataev wrote:

Will try to reduce this code

https://github.com/llvm/llvm-project/pull/84356


More information about the llvm-commits mailing list