[llvm] [WASM] Fold bitselect with splat zero (PR #147305)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 8 04:17:09 PDT 2025


================
@@ -3210,6 +3213,56 @@ static SDValue performTruncateCombine(SDNode *N,
   return truncateVectorWithNARROW(OutVT, In, DL, DAG);
 }
 
+static SDValue performVSelectCombine(SDNode *N,
+                                     TargetLowering::DAGCombinerInfo &DCI) {
+  // In the tablegen.td, vselect A B C -> bitselect B C A
+
+  // SCENARIO 1
+  // vselect Y, <0>, X
+  // -> bitselect <0>, X, Y
+  // -> or (AND(<0>, Y), AND(<X>, !<Y>))
+  // -> or (0, AND(<X>, !<Y>))
+  // -> AND(<X>, !<Y>)
+
+  // SCENARIO 2
+  // vselect X, Y, <0>
+  // -> bitselect Y, <0>, X
+  // -> or (AND(Y, X), AND(<0>, !X))
+  // -> or (AND(Y, X), <0>)
+  // -> AND(Y, X)
----------------
lukel97 wrote:

I'm just noticing: We have these exact combines in `combineVSelectWithAllOnesOrZeros` in DAGCombiner.cpp.

I think they might not be kicking in because they only check for build_vectors:

https://github.com/llvm/llvm-project/blob/d1fe7a29a6c2617de0b3ab7b06b3d22a8509ae41/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp#L13091-L13094

And during the first dag combiner run the build vectors get canonicalized to splats:

```
Initial selection DAG: %bb.0 'bitselect_second_zero:start'
SelectionDAG has 18 nodes:
  t12: v4i32 = BUILD_VECTOR Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0>
            t9: v4i32 = BUILD_VECTOR Constant:i32<2139095040>, Constant:i32<2139095040>, Constant:i32<2139095040>, Constant:i32<2139095040>


Optimized lowered selection DAG: %bb.0 'bitselect_second_zero:start'
SelectionDAG has 17 nodes:
  t19: v4i32 = splat_vector Constant:i32<0>
            t21: v4i32 = splat_vector Constant:i32<2139095040>
```

I think we should try fixing it in DAGCombiner instead, to also detect splat_vector nodes. It'll probably benefit a bunch of other targets too

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


More information about the llvm-commits mailing list