[llvm] [InstCombine] Allow folding cross-lane operations into PHIs/selects (PR #164388)

Benjamin Maxwell via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 21 06:00:14 PDT 2025


================
@@ -4003,18 +4003,29 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
 
   // Try to fold intrinsic into select/phi operands. This is legal if:
   //  * The intrinsic is speculatable.
-  //  * The select condition is not a vector, or the intrinsic does not
-  //    perform cross-lane operations.
-  if (isSafeToSpeculativelyExecuteWithVariableReplaced(&CI) &&
-      isNotCrossLaneOperation(II))
+  //  * The operand is one of the following:
+  //    - a phi.
+  //    - a select with a scalar condition.
+  //    - a select with a vector condition and II is not a cross lane operation.
+  if (isSafeToSpeculativelyExecuteWithVariableReplaced(&CI)) {
     for (Value *Op : II->args()) {
-      if (auto *Sel = dyn_cast<SelectInst>(Op))
-        if (Instruction *R = FoldOpIntoSelect(*II, Sel))
+      if (auto *Sel = dyn_cast<SelectInst>(Op)) {
+        bool IsVectorCond = Sel->getCondition()->getType()->isVectorTy();
+        if (IsVectorCond && !isNotCrossLaneOperation(II))
+          continue;
+        // Don't replace a scalar select with a more expensive vector select if
+        // we can't simplify both arms of the select.
+        bool SimplifyBothArms =
+            !Op->getType()->isVectorTy() && II->getType()->isVectorTy();
----------------
MacDue wrote:

It was due to regressions in `LoopVectorize/AArch64` as a `get.active.lane.mask(%base, select %cond, %n, 0)` was replaced with select between the mask and `zeroinitializer`, which is a more expensive operation. 

I'll add a negative test in `intrinsic-select.ll`. 

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


More information about the llvm-commits mailing list