[llvm] Revert "[VectorCombine] Fold scalar selects from bitcast into vector select" (PR #174758)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 7 04:15:49 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Pankaj Dwivedi (PankajDwivedi-25)

<details>
<summary>Changes</summary>

Reverts llvm/llvm-project#<!-- -->173990

---

Patch is 190.94 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/174758.diff


3 Files Affected:

- (modified) llvm/lib/Transforms/Vectorize/VectorCombine.cpp (-118) 
- (removed) llvm/test/CodeGen/AMDGPU/combine-scalar-selects-asm.ll (-1372) 
- (removed) llvm/test/CodeGen/AMDGPU/combine-scalar-selects.ll (-1874) 


``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 6fc5ca155d57a..3e06f74fa5c65 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -127,7 +127,6 @@ class VectorCombine {
   bool scalarizeOpOrCmp(Instruction &I);
   bool scalarizeVPIntrinsic(Instruction &I);
   bool foldExtractedCmps(Instruction &I);
-  bool foldSelectsFromBitcast(Instruction &I);
   bool foldBinopOfReductions(Instruction &I);
   bool foldSingleElementStore(Instruction &I);
   bool scalarizeLoad(Instruction &I);
@@ -1547,121 +1546,6 @@ bool VectorCombine::foldExtractedCmps(Instruction &I) {
   return true;
 }
 
-/// Try to fold scalar selects that select between extracted elements and zero
-/// into extracting from a vector select. This is rooted at the bitcast.
-///
-/// This pattern arises when a vector is bitcast to a smaller element type,
-/// elements are extracted, and then conditionally selected with zero:
-///
-///   %bc = bitcast <4 x i32> %src to <16 x i8>
-///   %e0 = extractelement <16 x i8> %bc, i32 0
-///   %s0 = select i1 %cond, i8 %e0, i8 0
-///   %e1 = extractelement <16 x i8> %bc, i32 1
-///   %s1 = select i1 %cond, i8 %e1, i8 0
-///   ...
-///
-/// Transforms to:
-///   %sel = select i1 %cond, <4 x i32> %src, <4 x i32> zeroinitializer
-///   %bc = bitcast <4 x i32> %sel to <16 x i8>
-///   %e0 = extractelement <16 x i8> %bc, i32 0
-///   %e1 = extractelement <16 x i8> %bc, i32 1
-///   ...
-///
-/// This is profitable because vector select on wider types produces fewer
-/// select/cndmask instructions than scalar selects on each element.
-bool VectorCombine::foldSelectsFromBitcast(Instruction &I) {
-  auto *BC = dyn_cast<BitCastInst>(&I);
-  if (!BC)
-    return false;
-
-  auto *SrcVecTy = dyn_cast<FixedVectorType>(BC->getSrcTy());
-  auto *DstVecTy = dyn_cast<FixedVectorType>(BC->getDestTy());
-  if (!SrcVecTy || !DstVecTy)
-    return false;
-
-  // Source must be 32-bit or 64-bit elements, destination must be smaller
-  // integer elements. Zero in all these types is all-bits-zero.
-  Type *SrcEltTy = SrcVecTy->getElementType();
-  Type *DstEltTy = DstVecTy->getElementType();
-  unsigned SrcEltBits = SrcEltTy->getPrimitiveSizeInBits();
-  unsigned DstEltBits = DstEltTy->getPrimitiveSizeInBits();
-
-  if (SrcEltBits != 32 && SrcEltBits != 64)
-    return false;
-
-  if (!DstEltTy->isIntegerTy() || DstEltBits >= SrcEltBits)
-    return false;
-
-  // Collect all select users that match the pattern, grouped by condition.
-  // Pattern: select i1 %cond, (extractelement %bc, idx), 0
-  DenseMap<Value *, SmallVector<SelectInst *, 8>> CondToSelects;
-
-  for (User *U : BC->users()) {
-    auto *Ext = dyn_cast<ExtractElementInst>(U);
-    if (!Ext)
-      continue;
-
-    for (User *ExtUser : Ext->users()) {
-      Value *Cond;
-      // Match: select i1 %cond, %ext, 0
-      if (match(ExtUser, m_Select(m_Value(Cond), m_Specific(Ext), m_Zero())) &&
-          Cond->getType()->isIntegerTy(1))
-        CondToSelects[Cond].push_back(cast<SelectInst>(ExtUser));
-    }
-  }
-
-  if (CondToSelects.empty())
-    return false;
-
-  // Check profitability using TTI.
-  auto *CondTy = CmpInst::makeCmpResultType(DstEltTy);
-  auto *VecCondTy = CmpInst::makeCmpResultType(SrcVecTy);
-
-  InstructionCost ScalarSelCost =
-      TTI.getCmpSelInstrCost(Instruction::Select, DstEltTy, CondTy,
-                             CmpInst::BAD_ICMP_PREDICATE, CostKind);
-  InstructionCost VecSelCost =
-      TTI.getCmpSelInstrCost(Instruction::Select, SrcVecTy, VecCondTy,
-                             CmpInst::BAD_ICMP_PREDICATE, CostKind);
-
-  bool MadeChange = false;
-  Value *SrcVec = BC->getOperand(0);
-
-  // Process each group of selects with the same condition.
-  for (auto &[Cond, Selects] : CondToSelects) {
-    // Only profitable if vector select cost < total scalar select cost.
-    if (VecSelCost >= ScalarSelCost * Selects.size()) {
-      LLVM_DEBUG(dbgs() << "VectorCombine: foldSelectsFromBitcast not "
-                        << "profitable (VecCost=" << VecSelCost
-                        << ", ScalarCost=" << ScalarSelCost
-                        << ", NumSelects=" << Selects.size() << ")\n");
-      continue;
-    }
-
-    // Create the vector select and bitcast once for this condition.
-    Builder.SetInsertPoint(BC->getNextNode());
-    Value *VecSel =
-        Builder.CreateSelect(Cond, SrcVec, Constant::getNullValue(SrcVecTy));
-    Value *NewBC = Builder.CreateBitCast(VecSel, DstVecTy);
-
-    // Replace each scalar select with an extract from the new bitcast.
-    for (SelectInst *Sel : Selects) {
-      auto *Ext = cast<ExtractElementInst>(Sel->getTrueValue());
-      Value *Idx = Ext->getIndexOperand();
-
-      Builder.SetInsertPoint(Sel);
-      Value *NewExt = Builder.CreateExtractElement(NewBC, Idx);
-      replaceValue(*Sel, *NewExt);
-      MadeChange = true;
-    }
-
-    LLVM_DEBUG(dbgs() << "VectorCombine: folded " << Selects.size()
-                      << " selects into vector select\n");
-  }
-
-  return MadeChange;
-}
-
 static void analyzeCostOfVecReduction(const IntrinsicInst &II,
                                       TTI::TargetCostKind CostKind,
                                       const TargetTransformInfo &TTI,
@@ -5158,8 +5042,6 @@ bool VectorCombine::run() {
       case Instruction::BitCast:
         if (foldBitcastShuffle(I))
           return true;
-        if (foldSelectsFromBitcast(I))
-          return true;
         break;
       case Instruction::And:
       case Instruction::Or:
diff --git a/llvm/test/CodeGen/AMDGPU/combine-scalar-selects-asm.ll b/llvm/test/CodeGen/AMDGPU/combine-scalar-selects-asm.ll
deleted file mode 100644
index 7ad2bf9c8f557..0000000000000
--- a/llvm/test/CodeGen/AMDGPU/combine-scalar-selects-asm.ll
+++ /dev/null
@@ -1,1372 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 -passes=vector-combine -S < %s | llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 | FileCheck %s --check-prefixes=CHECK,CHECK-OPT
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-NOOPT
-
-define amdgpu_kernel void @combine_scalar_selects_v16i8(
-; CHECK-OPT-LABEL: combine_scalar_selects_v16i8:
-; CHECK-OPT:       ; %bb.0: ; %entry
-; CHECK-OPT-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x0
-; CHECK-OPT-NEXT:    s_load_dword s6, s[4:5], 0x10
-; CHECK-OPT-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
-; CHECK-OPT-NEXT:    v_lshlrev_b32_e32 v0, 4, v0
-; CHECK-OPT-NEXT:    v_mov_b32_e32 v4, 0
-; CHECK-OPT-NEXT:    s_waitcnt lgkmcnt(0)
-; CHECK-OPT-NEXT:    global_load_dwordx4 v[0:3], v0, s[0:1]
-; CHECK-OPT-NEXT:    s_bitcmp1_b32 s6, 0
-; CHECK-OPT-NEXT:    s_cselect_b64 vcc, -1, 0
-; CHECK-OPT-NEXT:    s_waitcnt vmcnt(0)
-; CHECK-OPT-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
-; CHECK-OPT-NEXT:    v_cndmask_b32_e32 v2, 0, v2, vcc
-; CHECK-OPT-NEXT:    v_cndmask_b32_e32 v1, 0, v1, vcc
-; CHECK-OPT-NEXT:    v_cndmask_b32_e32 v0, 0, v0, vcc
-; CHECK-OPT-NEXT:    global_store_dwordx4 v4, v[0:3], s[2:3]
-; CHECK-OPT-NEXT:    s_endpgm
-;
-; CHECK-NOOPT-LABEL: combine_scalar_selects_v16i8:
-; CHECK-NOOPT:       ; %bb.0: ; %entry
-; CHECK-NOOPT-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x0
-; CHECK-NOOPT-NEXT:    s_load_dword s6, s[4:5], 0x10
-; CHECK-NOOPT-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
-; CHECK-NOOPT-NEXT:    v_lshlrev_b32_e32 v0, 4, v0
-; CHECK-NOOPT-NEXT:    v_mov_b32_e32 v4, 0
-; CHECK-NOOPT-NEXT:    s_waitcnt lgkmcnt(0)
-; CHECK-NOOPT-NEXT:    global_load_dwordx4 v[0:3], v0, s[0:1]
-; CHECK-NOOPT-NEXT:    s_bitcmp1_b32 s6, 0
-; CHECK-NOOPT-NEXT:    s_cselect_b64 vcc, -1, 0
-; CHECK-NOOPT-NEXT:    s_waitcnt vmcnt(0)
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v5, 8, v0
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v7, 24, v0
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v8, 8, v1
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v10, 24, v1
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v11, 8, v2
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v13, 24, v2
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v14, 8, v3
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v16, 24, v3
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v6, 16, v0
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v9, 16, v1
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v12, 16, v2
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v15, 16, v3
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v7, 0, v7, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v8, 0, v8, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v10, 0, v10, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v11, 0, v11, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v13, 0, v13, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v14, 0, v14, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v16, 0, v16, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v0, 0, v0, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v1, 0, v1, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v2, 0, v2, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v9, 0, v9, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v12, 0, v12, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v15, 0, v15, vcc
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v14, 8, v14
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v16, 8, v16
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v11, 8, v11
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v13, 8, v13
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v8, 8, v8
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v10, 8, v10
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v5, 8, v5
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v7, 8, v7
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v3, v3, v14 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v14, v15, v16 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v2, v2, v11 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v11, v12, v13 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v1, v1, v8 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v8, v9, v10 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v0, v0, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v5, v6, v7 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v3, v3, v14 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v2, v2, v11 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v1, v1, v8 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v0, v0, v5 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    global_store_dwordx4 v4, v[0:3], s[2:3]
-; CHECK-NOOPT-NEXT:    s_endpgm
-  ptr addrspace(1) %in,
-  ptr addrspace(1) %out,
-  i1 %valid
-) {
-entry:
-  %tid = call i32 @llvm.amdgcn.workitem.id.x()
-  %tid.ext = zext i32 %tid to i64
-  %gep = getelementptr <4 x i32>, ptr addrspace(1) %in, i64 %tid.ext
-  %loaded = load <4 x i32>, ptr addrspace(1) %gep, align 16
-  %bytes = bitcast <4 x i32> %loaded to <16 x i8>
-
-  %e0 = extractelement <16 x i8> %bytes, i64 0
-  %e1 = extractelement <16 x i8> %bytes, i64 1
-  %e2 = extractelement <16 x i8> %bytes, i64 2
-  %e3 = extractelement <16 x i8> %bytes, i64 3
-  %e4 = extractelement <16 x i8> %bytes, i64 4
-  %e5 = extractelement <16 x i8> %bytes, i64 5
-  %e6 = extractelement <16 x i8> %bytes, i64 6
-  %e7 = extractelement <16 x i8> %bytes, i64 7
-  %e8 = extractelement <16 x i8> %bytes, i64 8
-  %e9 = extractelement <16 x i8> %bytes, i64 9
-  %e10 = extractelement <16 x i8> %bytes, i64 10
-  %e11 = extractelement <16 x i8> %bytes, i64 11
-  %e12 = extractelement <16 x i8> %bytes, i64 12
-  %e13 = extractelement <16 x i8> %bytes, i64 13
-  %e14 = extractelement <16 x i8> %bytes, i64 14
-  %e15 = extractelement <16 x i8> %bytes, i64 15
-
-  %s0 = select i1 %valid, i8 %e0, i8 0
-  %s1 = select i1 %valid, i8 %e1, i8 0
-  %s2 = select i1 %valid, i8 %e2, i8 0
-  %s3 = select i1 %valid, i8 %e3, i8 0
-  %s4 = select i1 %valid, i8 %e4, i8 0
-  %s5 = select i1 %valid, i8 %e5, i8 0
-  %s6 = select i1 %valid, i8 %e6, i8 0
-  %s7 = select i1 %valid, i8 %e7, i8 0
-  %s8 = select i1 %valid, i8 %e8, i8 0
-  %s9 = select i1 %valid, i8 %e9, i8 0
-  %s10 = select i1 %valid, i8 %e10, i8 0
-  %s11 = select i1 %valid, i8 %e11, i8 0
-  %s12 = select i1 %valid, i8 %e12, i8 0
-  %s13 = select i1 %valid, i8 %e13, i8 0
-  %s14 = select i1 %valid, i8 %e14, i8 0
-  %s15 = select i1 %valid, i8 %e15, i8 0
-
-  store i8 %s0, ptr addrspace(1) %out, align 1
-  %ptr1 = getelementptr i8, ptr addrspace(1) %out, i64 1
-  store i8 %s1, ptr addrspace(1) %ptr1, align 1
-  %ptr2 = getelementptr i8, ptr addrspace(1) %out, i64 2
-  store i8 %s2, ptr addrspace(1) %ptr2, align 1
-  %ptr3 = getelementptr i8, ptr addrspace(1) %out, i64 3
-  store i8 %s3, ptr addrspace(1) %ptr3, align 1
-  %ptr4 = getelementptr i8, ptr addrspace(1) %out, i64 4
-  store i8 %s4, ptr addrspace(1) %ptr4, align 1
-  %ptr5 = getelementptr i8, ptr addrspace(1) %out, i64 5
-  store i8 %s5, ptr addrspace(1) %ptr5, align 1
-  %ptr6 = getelementptr i8, ptr addrspace(1) %out, i64 6
-  store i8 %s6, ptr addrspace(1) %ptr6, align 1
-  %ptr7 = getelementptr i8, ptr addrspace(1) %out, i64 7
-  store i8 %s7, ptr addrspace(1) %ptr7, align 1
-  %ptr8 = getelementptr i8, ptr addrspace(1) %out, i64 8
-  store i8 %s8, ptr addrspace(1) %ptr8, align 1
-  %ptr9 = getelementptr i8, ptr addrspace(1) %out, i64 9
-  store i8 %s9, ptr addrspace(1) %ptr9, align 1
-  %ptr10 = getelementptr i8, ptr addrspace(1) %out, i64 10
-  store i8 %s10, ptr addrspace(1) %ptr10, align 1
-  %ptr11 = getelementptr i8, ptr addrspace(1) %out, i64 11
-  store i8 %s11, ptr addrspace(1) %ptr11, align 1
-  %ptr12 = getelementptr i8, ptr addrspace(1) %out, i64 12
-  store i8 %s12, ptr addrspace(1) %ptr12, align 1
-  %ptr13 = getelementptr i8, ptr addrspace(1) %out, i64 13
-  store i8 %s13, ptr addrspace(1) %ptr13, align 1
-  %ptr14 = getelementptr i8, ptr addrspace(1) %out, i64 14
-  store i8 %s14, ptr addrspace(1) %ptr14, align 1
-  %ptr15 = getelementptr i8, ptr addrspace(1) %out, i64 15
-  store i8 %s15, ptr addrspace(1) %ptr15, align 1
-
-  ret void
-}
-
-; Test with v8i8 from v2i32 (smaller vector)
-define amdgpu_kernel void @combine_scalar_selects_v8i8(
-; CHECK-OPT-LABEL: combine_scalar_selects_v8i8:
-; CHECK-OPT:       ; %bb.0: ; %entry
-; CHECK-OPT-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x0
-; CHECK-OPT-NEXT:    s_load_dword s6, s[4:5], 0x10
-; CHECK-OPT-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
-; CHECK-OPT-NEXT:    v_lshlrev_b32_e32 v0, 3, v0
-; CHECK-OPT-NEXT:    v_mov_b32_e32 v2, 0
-; CHECK-OPT-NEXT:    s_waitcnt lgkmcnt(0)
-; CHECK-OPT-NEXT:    global_load_dwordx2 v[0:1], v0, s[0:1]
-; CHECK-OPT-NEXT:    s_bitcmp1_b32 s6, 0
-; CHECK-OPT-NEXT:    s_cselect_b64 vcc, -1, 0
-; CHECK-OPT-NEXT:    s_waitcnt vmcnt(0)
-; CHECK-OPT-NEXT:    v_cndmask_b32_e32 v1, 0, v1, vcc
-; CHECK-OPT-NEXT:    v_cndmask_b32_e32 v0, 0, v0, vcc
-; CHECK-OPT-NEXT:    global_store_dwordx2 v2, v[0:1], s[2:3]
-; CHECK-OPT-NEXT:    s_endpgm
-;
-; CHECK-NOOPT-LABEL: combine_scalar_selects_v8i8:
-; CHECK-NOOPT:       ; %bb.0: ; %entry
-; CHECK-NOOPT-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x0
-; CHECK-NOOPT-NEXT:    s_load_dword s6, s[4:5], 0x10
-; CHECK-NOOPT-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
-; CHECK-NOOPT-NEXT:    v_lshlrev_b32_e32 v0, 3, v0
-; CHECK-NOOPT-NEXT:    v_mov_b32_e32 v2, 0
-; CHECK-NOOPT-NEXT:    s_waitcnt lgkmcnt(0)
-; CHECK-NOOPT-NEXT:    global_load_dwordx2 v[0:1], v0, s[0:1]
-; CHECK-NOOPT-NEXT:    s_bitcmp1_b32 s6, 0
-; CHECK-NOOPT-NEXT:    s_cselect_b64 vcc, -1, 0
-; CHECK-NOOPT-NEXT:    s_waitcnt vmcnt(0)
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v3, 8, v0
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v5, 24, v0
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v6, 8, v1
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v8, 24, v1
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v4, 16, v0
-; CHECK-NOOPT-NEXT:    v_lshrrev_b32_e32 v7, 16, v1
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v3, 0, v3, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v5, 0, v5, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v6, 0, v6, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v8, 0, v8, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v0, 0, v0, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v1, 0, v1, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v4, 0, v4, vcc
-; CHECK-NOOPT-NEXT:    v_cndmask_b32_e32 v7, 0, v7, vcc
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v6, 8, v6
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v8, 8, v8
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v3, 8, v3
-; CHECK-NOOPT-NEXT:    v_lshlrev_b16_e32 v5, 8, v5
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v1, v1, v6 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v6, v7, v8 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v0, v0, v3 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v3, v4, v5 dst_sel:WORD_1 dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v1, v1, v6 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    v_or_b32_sdwa v0, v0, v3 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_0 src1_sel:DWORD
-; CHECK-NOOPT-NEXT:    global_store_dwordx2 v2, v[0:1], s[2:3]
-; CHECK-NOOPT-NEXT:    s_endpgm
-  ptr addrspace(1) %in,
-  ptr addrspace(1) %out,
-  i1 %cond
-) {
-entry:
-  %tid = call i32 @llvm.amdgcn.workitem.id.x()
-  %tid.ext = zext i32 %tid to i64
-  %gep = getelementptr <2 x i32>, ptr addrspace(1) %in, i64 %tid.ext
-  %loaded = load <2 x i32>, ptr addrspace(1) %gep, align 8
-  %bytes = bitcast <2 x i32> %loaded to <8 x i8>
-  %e0 = extractelement <8 x i8> %bytes, i64 0
-  %e1 = extractelement <8 x i8> %bytes, i64 1
-  %e2 = extractelement <8 x i8> %bytes, i64 2
-  %e3 = extractelement <8 x i8> %bytes, i64 3
-  %e4 = extractelement <8 x i8> %bytes, i64 4
-  %e5 = extractelement <8 x i8> %bytes, i64 5
-  %e6 = extractelement <8 x i8> %bytes, i64 6
-  %e7 = extractelement <8 x i8> %bytes, i64 7
-  %s0 = select i1 %cond, i8 %e0, i8 0
-  %s1 = select i1 %cond, i8 %e1, i8 0
-  %s2 = select i1 %cond, i8 %e2, i8 0
-  %s3 = select i1 %cond, i8 %e3, i8 0
-  %s4 = select i1 %cond, i8 %e4, i8 0
-  %s5 = select i1 %cond, i8 %e5, i8 0
-  %s6 = select i1 %cond, i8 %e6, i8 0
-  %s7 = select i1 %cond, i8 %e7, i8 0
-  store i8 %s0, ptr addrspace(1) %out, align 1
-  %ptr1 = getelementptr i8, ptr addrspace(1) %out, i64 1
-  store i8 %s1, ptr addrspace(1) %ptr1, align 1
-  %ptr2 = getelementptr i8, ptr addrspace(1) %out, i64 2
-  store i8 %s2, ptr addrspace(1) %ptr2, align 1
-  %ptr3 = getelementptr i8, ptr addrspace(1) %out, i64 3
-  store i8 %s3, ptr addrspace(1) %ptr3, align 1
-  %ptr4 = getelementptr i8, ptr addrspace(1) %out, i64 4
-  store i8 %s4, ptr addrspace(1) %ptr4, align 1
-  %ptr5 = getelementptr i8, ptr addrspace(1) %out, i64 5
-  store i8 %s5, ptr addrspace(1) %ptr5, align 1
-  %ptr6 = getelementptr i8, ptr addrspace(1) %out, i64 6
-  store i8 %s6, ptr addrspace(1) %ptr6, align 1
-  %ptr7 = getelementptr i8, ptr addrspace(1) %out, i64 7
-  store i8 %s7, ptr addrspace(1) %ptr7, align 1
-  ret void
-}
-
-; Test: extracts have additional unrelated uses (extracts can't be removed)
-; The transformation should still be profitable as we reduce v_cndmask count
-define amdgpu_kernel void @combine_with_extract_other_uses_asm(
-; CHECK-OPT-LABEL: combine_with_extract_other_uses_asm:
-; CHECK-OPT:       ; %bb.0: ; %entry
-; CHECK-OPT-NEXT:    s_load_dwordx4 s[0:3], s[4:5], 0x0
-; CHECK-OPT-NEXT:    s_load_dwordx2 s[6:7], s[4:5], 0x10
-; CHECK-OPT-NEXT:    v_and_b32_e32 v0, 0x3ff, v0
-; CHECK-OPT-NEXT:    v_lshlrev_b32_e32 v0, 3, v0
-; CHECK-OPT-NEXT:    v_mov_b32_e32 v4, 0
-; CHE...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list