[llvm] [VectorCombine] Handle widening/narrowing bitcasts in foldShuffleToIdentity (PR #187870)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 1 02:14:09 PDT 2026


================
@@ -3553,6 +3553,53 @@ generateNewInstTree(ArrayRef<InstLane> Item, Use *From, FixedVectorType *Ty,
   }
 
   auto *I = cast<Instruction>(FrontV);
+
+  // Handle vector bitcasts that change element count. We cannot use
+  // generateInstLaneVectorFromOperand for these because the lane indices
+  // don't map 1:1 through the bitcast.
+  if (auto *BitCast = dyn_cast<BitCastInst>(I)) {
+    auto *BCDstTy = dyn_cast<FixedVectorType>(BitCast->getDestTy());
+    auto *BCSrcTy = dyn_cast<FixedVectorType>(BitCast->getSrcTy());
+    if (BCDstTy && BCSrcTy &&
+        BCDstTy->getNumElements() != BCSrcTy->getNumElements()) {
+      unsigned DstElts = BCDstTy->getNumElements();
+      unsigned SrcElts = BCSrcTy->getNumElements();
+      SmallVector<InstLane> NewItem;
+      if (DstElts > SrcElts) {
+        // Widening: compress operand Item.
+        unsigned R = DstElts / SrcElts;
+        if (Item.size() % R != 0)
+          return nullptr;
+        for (unsigned Idx = 0, E = Item.size(); Idx < E; Idx += R) {
+          auto [V, Lane] = Item[Idx];
+          if (!V)
+            NewItem.push_back({nullptr, PoisonMaskElem});
+          else {
+            NewItem.push_back(lookThroughShuffles(
+                cast<Instruction>(V)->getOperand(0), Lane / R));
+          }
+        }
+      } else {
+        // Narrowing: expand operand Item.
+        unsigned R = SrcElts / DstElts;
+        for (auto [V, Lane] : Item) {
+          if (!V) {
+            for (unsigned J = 0; J < R; ++J)
+              NewItem.push_back({nullptr, PoisonMaskElem});
+          } else {
+            Value *Op = cast<Instruction>(V)->getOperand(0);
+            for (unsigned J = 0; J < R; ++J)
+              NewItem.push_back(lookThroughShuffles(Op, Lane * R + J));
+          }
----------------
RKSimon wrote:

(style)
```
          if (!V) {
            NewItem.append(R, {nullptr, PoisonMaskElem});
            continue;
          }

          Value *Op = cast<Instruction>(V)->getOperand(0);
          for (unsigned J = 0; J < R; ++J)
            NewItem.push_back(lookThroughShuffles(Op, Lane * R + J));
```
(similar for above as well)

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


More information about the llvm-commits mailing list