[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
Mon Apr 13 20:11:43 PDT 2026


================
@@ -12982,6 +13058,15 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
   if (SDValue R = combineSelectAsExtAnd(N0, N1, N2, DL, DAG))
     return R;
 
+  EVT ResultVT = N->getValueType(0);
+  if (ResultVT.isVector()) {
+    if (SDValue R = widenIntVectorSelect(N, DAG, TLI, N0, N1, N2))
+      return R;
----------------
Shoreshen wrote:

Hi @arsenm , this is for odd vector cases like the following:
```
define void @v_select_v15i4(i1 %cond, ptr addrspace(1) %x, ptr addrspace(3) %y) {
  %v = load <15 x i4>, ptr addrspace(1) %x, align 16
  %vMasked = select i1 %cond, <15 x i4> %v, <15 x i4> zeroinitializer
  store <15 x i4> %vMasked, ptr addrspace(3) %y, align 16
  ret void
}
```

Without this optimization, the select will not apply for odd vectors in the first combine and split right after type legalizer:
```
Optimized lowered selection DAG: %bb.0 'v_select_v7i4:'
SelectionDAG has 20 nodes:
  t0: ch,glue = EntryToken
      t5: i32,ch = CopyFromReg # D:1 t0, Register:i32 %9
      t7: i32,ch = CopyFromReg # D:1 t0, Register:i32 %10
    t10: i64 = build_pair # D:1 t5, t7
  t13: v7i4,ch = load<(load (s32) from %ir.x, align 16, addrspace 1)> # D:1 t0, t10, undef:i64
            t2: i32,ch = CopyFromReg # D:1 t0, Register:i32 %8
          t3: i1 = truncate # D:1 t2
          t15: v7i4 = BUILD_VECTOR Constant:i4<0>, Constant:i4<0>, Constant:i4<0>, Constant:i4<0>, Constant:i4<0>, Constant:i4<0>, Constant:i4<0>
        t16: v7i4 = select # D:1 t3, t13, t15
        t9: i32,ch = CopyFromReg # D:1 t0, Register:i32 %11
      t22: ch = store<(store (s32) into %ir.y, align 16, addrspace 3)> # D:1 t0, t16, t9, undef:i32
    t23: ch = TokenFactor t13:1, t22
  t21: ch = AMDGPUISD::RET_GLUE t23



Type-legalized selection DAG: %bb.0 'v_select_v7i4:'
SelectionDAG has 72 nodes:
  t0: ch,glue = EntryToken
      t5: i32,ch = CopyFromReg # D:1 t0, Register:i32 %9
      t7: i32,ch = CopyFromReg # D:1 t0, Register:i32 %10
    t10: i64 = build_pair # D:1 t5, t7
  t29: i32,ch = load<(load (s32) from %ir.x, align 16, addrspace 1), anyext from i28> # D:1 t0, t10, undef:i64
      t2: i32,ch = CopyFromReg # D:1 t0, Register:i32 %8
    t3: i1 = truncate # D:1 t2
      t30: i32 = and # D:1 t29, Constant:i32<15>
        t33: i32 = srl # D:1 t29, Constant:i32<4>
      t34: i32 = and # D:1 t33, Constant:i32<15>
        t37: i32 = srl # D:1 t29, Constant:i32<8>
      t38: i32 = and # D:1 t37, Constant:i32<15>
        t41: i32 = srl # D:1 t29, Constant:i32<12>
      t42: i32 = and # D:1 t41, Constant:i32<15>
        t45: i32 = srl # D:1 t29, Constant:i32<16>
      t46: i32 = and # D:1 t45, Constant:i32<15>
        t49: i32 = srl # D:1 t29, Constant:i32<20>
      t50: i32 = and # D:1 t49, Constant:i32<15>
        t53: i32 = srl # D:1 t29, Constant:i32<24>
      t54: i32 = and # D:1 t53, Constant:i32<15>
    t59: v8i32 = BUILD_VECTOR # D:1 t30, t34, t38, t42, t46, t50, t54, undef:i32
    t27: v8i32 = BUILD_VECTOR Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, undef:i32
  t60: v8i32 = select # D:1 t3, t59, t27
                      t141: i32 = extract_vector_elt # D:1 t60, Constant:i32<0>
                    t132: i32 = and # D:1 t141, Constant:i32<15>
                        t130: i32 = extract_vector_elt # D:1 t60, Constant:i32<1>
                      t127: i32 = and # D:1 t130, Constant:i32<15>
                    t128: i32 = shl # D:1 t127, Constant:i32<4>
                  t133: i32 = or # D:1 t132, t128
                      t125: i32 = extract_vector_elt # D:1 t60, Constant:i32<2>
                    t122: i32 = and # D:1 t125, Constant:i32<15>
                  t123: i32 = shl # D:1 t122, Constant:i32<8>
                t134: i32 = or # D:1 t133, t123
                    t120: i32 = extract_vector_elt # D:1 t60, Constant:i32<3>
                  t117: i32 = and # D:1 t120, Constant:i32<15>
                t118: i32 = shl # D:1 t117, Constant:i32<12>
              t135: i32 = or # D:1 t134, t118
                  t115: i32 = extract_vector_elt # D:1 t60, Constant:i32<4>
                t112: i32 = and # D:1 t115, Constant:i32<15>
              t113: i32 = shl # D:1 t112, Constant:i32<16>
            t136: i32 = or # D:1 t135, t113
                t110: i32 = extract_vector_elt # D:1 t60, Constant:i32<5>
              t107: i32 = and # D:1 t110, Constant:i32<15>
            t108: i32 = shl # D:1 t107, Constant:i32<20>
          t137: i32 = or # D:1 t136, t108
              t105: i32 = extract_vector_elt # D:1 t60, Constant:i32<6>
            t101: i32 = and # D:1 t105, Constant:i32<15>
          t103: i32 = shl # D:1 t101, Constant:i32<24>
        t138: i32 = or # D:1 t137, t103
        t9: i32,ch = CopyFromReg # D:1 t0, Register:i32 %11
      t139: ch = store<(store (s32) into %ir.y, align 16, addrspace 3), trunc to i28> # D:1 t0, t138, t9, undef:i32
    t23: ch = TokenFactor t29:1, t139
  t21: ch = AMDGPUISD::RET_GLUE t23
```

In this case the select will not combine at all...

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


More information about the llvm-commits mailing list