[llvm] [AMDGPU] Add folding ISD::SELECT from vXiY into vZi32 with X * Y = Z * 32 (PR #173328)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 14 00:19:09 PDT 2026


================
@@ -6983,6 +6983,82 @@ static SDValue combineSelectAsExtAnd(SDValue Cond, SDValue T, SDValue F,
   return DAG.getNode(ISD::AND, DL, OpVT, CondMask, T.getOperand(0));
 }
 
+// Widen int vector is not power of 2 in length.
+static SDValue widenIntVectorSelect(SDNode *N, SelectionDAG &DAG,
+                                    const TargetLowering &TLI, SDValue Cond,
+                                    SDValue TrueVal, SDValue FalseVal) {
+  EVT ResultVT = N->getValueType(0);
+  if (ResultVT.isSimple() || ResultVT.isPow2VectorType() ||
+      TLI.getTypeAction(*DAG.getContext(), ResultVT) !=
+          TargetLowering::TypeWidenVector)
+    return SDValue();
+
+  EVT EltVT = ResultVT.getVectorElementType();
+  if (!EltVT.isInteger())
+    return SDValue();
+
+  SDValue WidenTrue = DAG.WidenVector(TrueVal, SDLoc(TrueVal));
+  SDValue WidenFalse = DAG.WidenVector(FalseVal, SDLoc(FalseVal));
+
+  EVT WidenVT = WidenTrue.getValueType();
+  SDValue WidenSelect =
+      DAG.getNode(ISD::SELECT, SDLoc(N), WidenVT, Cond, WidenTrue, WidenFalse);
+  return DAG.getExtractSubvector(SDLoc(N), ResultVT, WidenSelect, 0);
+}
+
+// Try to convert vXiY into vPiQ with:
+// 1. vXiY is not legal type
+// 2. vPiQ is legal type
+// 3. X * Y = P * Q
+// This prevent promotion of integer vectors like v32i4 to v32i16
+// which can create extra operations on type casting.
+static SDValue castIntVectorSelect(SDNode *N, SelectionDAG &DAG,
+                                   const TargetLowering &TLI, SDValue Cond,
+                                   SDValue TrueVal, SDValue FalseVal) {
+  EVT ResultVT = N->getValueType(0);
+  if (ResultVT.isScalableVector() ||
+      TLI.getTypeAction(*DAG.getContext(), ResultVT) ==
+          TargetLowering::TypeLegal)
+    return SDValue();
+
+  EVT EltVT = ResultVT.getVectorElementType();
+  if (!EltVT.isInteger())
+    return SDValue();
+
+  TypeSize NewEltBitSize = EltVT.getSizeInBits() * 2;
+  EVT NewVT = ResultVT.getIntegerVectorWithElementWidth(*DAG.getContext(),
+                                                        NewEltBitSize);
+
+  while (true) {
----------------
Shoreshen wrote:

Hi @arsenm , let me try to explain with this example:
```llvm
define void @v32i4(i1 %cond, ptr addrspace(1) %x, ptr addrspace(3) %y) {
  %v = load <32 x i4>, ptr addrspace(1) %x, align 16
  %vMasked = select i1 %cond, <32 x i4> %v, <32 x i4> zeroinitializer
  store <32 x i4> %vMasked, ptr addrspace(3) %y, align 16
  ret void
}
```
It will create `t16: v32i4 = select # D:1 t3, t13, t15` node and the if we run `TLI.getLegalTypeToTransformTo(*DAG.getContext(), v32i4)`, I will get type of `v32i32`, which does not equal in bit size and cannot bitcast:
<img width="1553" height="557" alt="image" src="https://github.com/user-attachments/assets/1dcd05b3-8b0e-48c6-be0c-bbbb68a8b154" />

So the outer loop is needed and also with the bitsize check.

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


More information about the llvm-commits mailing list