[llvm] Extend narrow interleave group (PR #206305)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 27 22:13:35 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Kamlesh Kumar (kamleshbhalui)
<details>
<summary>Changes</summary>
1. Extend narrow interleave group to intrinsics.
2. Generalise the conditions on VF and vector register size
---
Patch is 569.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/206305.diff
27 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp (+63-28)
- (modified) llvm/lib/Transforms/Vectorize/VPlanUtils.cpp (+21-17)
- (modified) llvm/test/CodeGen/WebAssembly/memory-interleave.ll (+1576-1286)
- (added) llvm/test/Transforms/LoopVectorize/AArch64/foldshuffleidentity.ll (+259)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/interleave-with-runtime-checks.ll (+4-4)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/interleaved_cost.ll (+177-45)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/max-vf-for-interleaved.ll (+26-3)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/transform-narrow-interleave-to-widen-memory-cost.ll (+9-23)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/transform-narrow-interleave-to-widen-memory-derived-ivs.ll (+21-34)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/transform-narrow-interleave-to-widen-memory-epilogue-vec.ll (+180-6)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/transform-narrow-interleave-to-widen-memory-remove-loop-region.ll (+16-17)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/transform-narrow-interleave-to-widen-memory-with-live-outs.ll (+3-3)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/transform-narrow-interleave-to-widen-memory-with-wide-ops-and-casts.ll (+20-20)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/transform-narrow-interleave-to-widen-memory-with-wide-ops.ll (+30-51)
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/transform-narrow-interleave-to-widen-memory.ll (+179-32)
- (modified) llvm/test/Transforms/LoopVectorize/ARM/interleaved_cost.ll (+103-33)
- (modified) llvm/test/Transforms/LoopVectorize/ARM/mve-interleaved-cost.ll (+1337-490)
- (modified) llvm/test/Transforms/LoopVectorize/RISCV/interleaved-accesses.ll (+8-18)
- (modified) llvm/test/Transforms/LoopVectorize/RISCV/interleaved-cost.ll (+1185-276)
- (modified) llvm/test/Transforms/LoopVectorize/RISCV/transform-narrow-interleave-to-widen-memory.ll (+33-33)
- (modified) llvm/test/Transforms/LoopVectorize/WebAssembly/memory-interleave.ll (+14-166)
- (modified) llvm/test/Transforms/LoopVectorize/X86/CostModel/interleaved-load-half.ll (-4)
- (modified) llvm/test/Transforms/LoopVectorize/X86/transform-narrow-interleave-to-widen-memory-epilogue-vec.ll (+25-15)
- (modified) llvm/test/Transforms/LoopVectorize/X86/transform-narrow-interleave-to-widen-memory.ll (+109-53)
- (modified) llvm/test/Transforms/LoopVectorize/interleaved-accesses-metadata.ll (+4-9)
- (modified) llvm/test/Transforms/LoopVectorize/pr31098.ll (+1-1)
- (modified) llvm/test/Transforms/PhaseOrdering/AArch64/interleavevectorization.ll (+30-13)
``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index adcfe30ff9561..1c6cc9d3d0168 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -5779,13 +5779,14 @@ static bool canNarrowLoad(VPSingleDefRecipe *WideMember0, unsigned OpIdx,
return false;
}
-static bool canNarrowOps(ArrayRef<VPValue *> Ops, bool IsScalable) {
+static bool canNarrowOps(ArrayRef<VPValue *> Ops, bool IsScalable,
+ const TargetTransformInfo &TTI) {
SmallVector<VPValue *> Ops0;
auto *WideMember0 = dyn_cast<VPRecipeWithIRFlags>(Ops[0]);
if (!WideMember0)
return false;
for (VPValue *V : Ops) {
- if (!isa<VPWidenRecipe, VPWidenCastRecipe>(V))
+ if (!isa<VPWidenRecipe, VPWidenCastRecipe, VPWidenIntrinsicRecipe>(V))
return false;
auto *R = cast<VPRecipeWithIRFlags>(V);
if (getOpcodeOrIntrinsicID(R) != getOpcodeOrIntrinsicID(WideMember0))
@@ -5801,7 +5802,16 @@ static bool canNarrowOps(ArrayRef<VPValue *> Ops, bool IsScalable) {
for (VPValue *Op : Ops)
OpsI.push_back(Op->getDefiningRecipe()->getOperand(Idx));
- if (canNarrowOps(OpsI, IsScalable))
+ auto *WideIntrinsic0 = dyn_cast<VPWidenIntrinsicRecipe>(WideMember0);
+ if (WideIntrinsic0 &&
+ isVectorIntrinsicWithScalarOpAtArg(
+ WideIntrinsic0->getVectorIntrinsicID(), Idx, &TTI)) {
+ if (!all_of(OpsI, equal_to(OpsI.front())))
+ return false;
+ continue;
+ }
+
+ if (canNarrowOps(OpsI, IsScalable, TTI))
continue;
if (any_of(enumerate(OpsI), [WideMember0, Idx, IsScalable](const auto &P) {
@@ -5854,8 +5864,10 @@ isConsecutiveInterleaveGroup(VPInterleaveRecipe *InterleaveR,
for (ElementCount VF : VFs) {
unsigned MinVal = VF.getKnownMinValue();
+
unsigned GroupSize = GroupElementTy->getScalarSizeInBits() * MinVal;
- if (IG->getFactor() == MinVal && GroupSize == GetVectorBitWidthForVF(VF))
+ if (MinVal % IG->getFactor() == 0 &&
+ GroupSize % GetVectorBitWidthForVF(VF) == 0)
return {VF};
}
return std::nullopt;
@@ -5872,10 +5884,14 @@ static bool isAlreadyNarrow(VPValue *VPV) {
// Convert the wide recipes defining the VPValues in \p Members feeding an
// interleave group to a single narrow variant. The first member is reused as
// the narrowed recipe. BuildVectors for live-in operands are inserted into \p
-// Preheader.
+// Preheader. \p RepeatFactor is the number of original iterations the narrowed
+// plan processes at once (VF / interleave factor); per-field live-ins are
+// repeated this many times so the assembled BuildVector spans all VF lanes.
static VPValue *narrowInterleaveGroupOp(ArrayRef<VPValue *> Members,
SmallPtrSetImpl<VPValue *> &NarrowedOps,
- VPBasicBlock *Preheader) {
+ VPBasicBlock *Preheader,
+ const TargetTransformInfo &TTI,
+ unsigned RepeatFactor) {
VPValue *V = Members.front();
auto *R = V->getDefiningRecipe();
if (NarrowedOps.contains(V))
@@ -5888,7 +5904,11 @@ static VPValue *narrowInterleaveGroupOp(ArrayRef<VPValue *> Members,
M->getScalarType() == V->getScalarType();
}) &&
"expected distinct live-ins of matching scalar type");
- auto *BV = new VPInstruction(VPInstruction::BuildVector, Members);
+ SmallVector<VPValue *> Vals;
+ Vals.reserve(Members.size() * RepeatFactor);
+ for (unsigned I = 0; I != RepeatFactor; ++I)
+ Vals.append(Members.begin(), Members.end());
+ auto *BV = new VPInstruction(VPInstruction::BuildVector, Vals);
Preheader->appendRecipe(BV);
NarrowedOps.insert(BV);
return BV;
@@ -5897,7 +5917,7 @@ static VPValue *narrowInterleaveGroupOp(ArrayRef<VPValue *> Members,
if (isAlreadyNarrow(V))
return V;
- if (isa<VPWidenRecipe, VPWidenCastRecipe>(R)) {
+ if (isa<VPWidenRecipe, VPWidenCastRecipe, VPWidenIntrinsicRecipe>(R)) {
auto *WideMember0 = cast<VPRecipeWithIRFlags>(R);
for (VPValue *Member : Members.drop_front())
WideMember0->intersectFlags(*cast<VPRecipeWithIRFlags>(Member));
@@ -5905,8 +5925,18 @@ static VPValue *narrowInterleaveGroupOp(ArrayRef<VPValue *> Members,
SmallVector<VPValue *> OpsI;
for (VPValue *Member : Members)
OpsI.push_back(Member->getDefiningRecipe()->getOperand(Idx));
- WideMember0->setOperand(
- Idx, narrowInterleaveGroupOp(OpsI, NarrowedOps, Preheader));
+ auto *WideIntrinsic0 = dyn_cast<VPWidenIntrinsicRecipe>(WideMember0);
+ if (WideIntrinsic0 &&
+ isVectorIntrinsicWithScalarOpAtArg(
+ WideIntrinsic0->getVectorIntrinsicID(), Idx, &TTI)) {
+ assert(all_of(OpsI, equal_to(OpsI.front())) &&
+ "scalar intrinsic operands must match");
+ WideMember0->setOperand(Idx, OpsI.front());
+ continue;
+ }
+ WideMember0->setOperand(Idx, narrowInterleaveGroupOp(OpsI, NarrowedOps,
+ Preheader, TTI,
+ RepeatFactor));
}
return V;
}
@@ -5998,7 +6028,9 @@ VPlanTransforms::narrowInterleaveGroups(VPlan &Plan,
// when checking all allowed consumers (store interleave groups) below.
if (!InterleaveR)
continue;
-
+ // Skip read interleave groups.
+ if (InterleaveR->getStoredValues().empty())
+ continue;
// Try to find a single VF, where all interleave groups are consecutive and
// saturate the full vector width. If we already have a candidate VF, check
// if it is applicable for the current InterleaveR, otherwise look for a
@@ -6012,10 +6044,6 @@ VPlanTransforms::narrowInterleaveGroups(VPlan &Plan,
return nullptr;
VFToOptimize = NarrowedVF;
- // Skip read interleave groups.
- if (InterleaveR->getStoredValues().empty())
- continue;
-
// Narrow interleave groups, if all operands are already matching narrow
// ops.
auto *Member0 = InterleaveR->getStoredValues()[0];
@@ -6042,7 +6070,7 @@ VPlanTransforms::narrowInterleaveGroups(VPlan &Plan,
// Check if all values feeding InterleaveR are matching wide recipes, which
// operands that can be narrowed.
if (!canNarrowOps(InterleaveR->getStoredValues(),
- VFToOptimize->isScalable()))
+ VFToOptimize->isScalable(), TTI))
return nullptr;
StoreGroups.push_back(InterleaveR);
}
@@ -6050,6 +6078,12 @@ VPlanTransforms::narrowInterleaveGroups(VPlan &Plan,
if (StoreGroups.empty())
return nullptr;
+ unsigned CommonInterleaveFactor =
+ StoreGroups.front()->getInterleaveGroup()->getFactor();
+ if (any_of(StoreGroups, [CommonInterleaveFactor](auto *R) {
+ return R->getInterleaveGroup()->getFactor() != CommonInterleaveFactor;
+ }))
+ return nullptr;
VPBasicBlock *MiddleVPBB = Plan.getMiddleBlock();
bool RequiresScalarEpilogue =
MiddleVPBB->getNumSuccessors() == 1 &&
@@ -6072,10 +6106,16 @@ VPlanTransforms::narrowInterleaveGroups(VPlan &Plan,
// Convert InterleaveGroup \p R to a single VPWidenLoadRecipe.
SmallPtrSet<VPValue *, 4> NarrowedOps;
VPBasicBlock *Preheader = Plan.getVectorPreheader();
+ // The narrowed plan processes VF / factor original iterations per vector
+ // iteration; per-field live-ins are repeated this many times when assembled
+ // into BuildVectors.
+ unsigned RepeatFactor =
+ VFToOptimize->getKnownMinValue() / CommonInterleaveFactor;
// Narrow operation tree rooted at store groups.
for (auto *StoreGroup : StoreGroups) {
- VPValue *Res = narrowInterleaveGroupOp(StoreGroup->getStoredValues(),
- NarrowedOps, Preheader);
+ VPValue *Res =
+ narrowInterleaveGroupOp(StoreGroup->getStoredValues(), NarrowedOps,
+ Preheader, TTI, RepeatFactor);
auto *SI =
cast<StoreInst>(StoreGroup->getInterleaveGroup()->getInsertPos());
auto *S = new VPWidenStoreRecipe(*SI, StoreGroup->getAddr(), Res, nullptr,
@@ -6094,16 +6134,11 @@ VPlanTransforms::narrowInterleaveGroups(VPlan &Plan,
VPValue *UF = &Plan.getUF();
VPValue *Step;
- if (VFToOptimize->isScalable()) {
- VPValue *VScale =
- PHBuilder.createElementCount(CanIVTy, ElementCount::getScalable(1));
- Step = PHBuilder.createOverflowingOp(Instruction::Mul, {VScale, UF},
- {true, false});
- Plan.getVF().replaceAllUsesWith(VScale);
- } else {
- Step = UF;
- Plan.getVF().replaceAllUsesWith(Plan.getConstantInt(CanIVTy, 1));
- }
+ VPValue *ScaleStep = PHBuilder.createElementCount(
+ CanIVTy, ElementCount::get(RepeatFactor, VFToOptimize->isScalable()));
+ Step = PHBuilder.createOverflowingOp(Instruction::Mul, {ScaleStep, UF},
+ {true, false});
+ Plan.getVF().replaceAllUsesWith(ScaleStep);
// Materialize vector trip count with the narrowed step.
materializeVectorTripCount(Plan, VectorPH, /*TailByMasking=*/false,
RequiresScalarEpilogue, Step);
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index 7e0f536a63a83..410c9d63f4435 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -684,33 +684,37 @@ VPInstruction *vputils::findCanonicalIVIncrement(VPlan &Plan) {
if (!VFxUF.isMaterialized())
return Step == &VFxUF;
+ // After narrowing interleave groups, the step is
+ // ScaleStep * UF, with ScaleStep = VF / InterleaveFactor.
VPSymbolicValue &UF = Plan.getUF();
if (!UF.isMaterialized())
- return Step == &UF ||
- match(Step, m_c_Mul(m_Specific(&Plan.getUF()),
- m_VPInstruction<VPInstruction::VScale>()));
+ return Step == &UF || match(Step, m_c_Mul(m_Specific(&UF), m_VPValue()));
// Alias masking: step is number of active lanes of a dependence mask.
if (match(Step, m_ZExtOrTruncOrSelf(
m_VPInstruction<VPInstruction::NumActiveLanes>())))
return true;
+ // UF is now concrete, so the step has folded to ScaleStep * ConcreteUF.
+ // Extract its constant coefficient, treating fixed and scalable VF
+ // uniformly by ignoring any vscale factor (present only for scalable VF).
unsigned ConcreteUF = Plan.getConcreteUF();
- // Fixed VF: step is just the concrete UF.
- if (match(Step, m_SpecificInt(ConcreteUF)))
- return true;
+ uint64_t Coeff = 0;
+ if (match(Step, m_Shl(m_VPInstruction<VPInstruction::VScale>(),
+ m_ConstantInt(Coeff))))
+ // mul(vscale, Coeff) may have been simplified to shl(vscale, log2(Coeff))
+ // when Coeff is a power of 2.
+ Coeff = uint64_t(1) << Coeff;
+ else if (match(Step, m_VPInstruction<VPInstruction::VScale>()))
+ // Bare vscale: coefficient is 1.
+ Coeff = 1;
+ else if (!match(Step, m_ConstantInt(Coeff)) &&
+ !match(Step, m_c_Mul(m_ConstantInt(Coeff),
+ m_VPInstruction<VPInstruction::VScale>())))
+ return false;
- // Scalable VF: step involves VScale.
- if (ConcreteUF == 1)
- return match(Step, m_VPInstruction<VPInstruction::VScale>());
- if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF),
- m_VPInstruction<VPInstruction::VScale>())))
- return true;
- // mul(VScale, ConcreteUF) may have been simplified to
- // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
- return isPowerOf2_32(ConcreteUF) &&
- match(Step, m_Shl(m_VPInstruction<VPInstruction::VScale>(),
- m_SpecificInt(Log2_32(ConcreteUF))));
+ // The step is ScaleStep * ConcreteUF.
+ return Coeff != 0 && Coeff % ConcreteUF == 0;
};
VPInstruction *Increment = nullptr;
diff --git a/llvm/test/CodeGen/WebAssembly/memory-interleave.ll b/llvm/test/CodeGen/WebAssembly/memory-interleave.ll
index 63cee30414a7c..281d98d702cfb 100644
--- a/llvm/test/CodeGen/WebAssembly/memory-interleave.ll
+++ b/llvm/test/CodeGen/WebAssembly/memory-interleave.ll
@@ -1,4 +1,5 @@
-; RUN: opt -mtriple=wasm32 -mattr=+simd128 -passes=loop-vectorize %s | llc -mtriple=wasm32 -mattr=+simd128 -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --filter "loop|v128\.|shuffle|i8x16|i16x8|i32x4|i64x2|f32x4|f64x2|i32\.(load|store)" --version 6
+; RUN: opt -mtriple=wasm32 -mattr=+simd128 -passes=loop-vectorize %s | llc -mtriple=wasm32 -mattr=+simd128 -disable-wasm-fallthrough-return-opt | FileCheck %s
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
@@ -18,23 +19,22 @@ target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20
%struct.TwoLongLongs = type { i64, i64 }
%struct.FourLongLongs = type { i64, i64, i64, i64 }
-; CHECK-LABEL: two_ints_same_op:
-; CHECK: loop
-; CHECK: v128.load
-; CHECK: v128.load
-; CHECK: i8x16.shuffle 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
-; CHECK: v128.load
-; CHECK: v128.load
-; CHECK: i8x16.shuffle 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
-; CHECK: i32x4.add
-; CHECK: i8x16.shuffle 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
-; CHECK: i8x16.shuffle 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
-; CHECK: i32x4.add
-; CHECK: i8x16.shuffle 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31
-; CHECK: v128.store
-; CHECK: i8x16.shuffle 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23
-; CHECK: v128.store
define hidden void @two_ints_same_op(ptr noalias nocapture noundef writeonly %0, ptr nocapture noundef readonly %1, ptr nocapture noundef readonly %2, i32 noundef %3) {
+; CHECK-LABEL: two_ints_same_op:
+; CHECK: loop # label2:
+; CHECK: i32.load 0
+; CHECK: i32.load 0
+; CHECK: i32.store 0
+; CHECK: i32.load 0
+; CHECK: i32.load 0
+; CHECK: i32.store 0
+; CHECK: end_loop
+; CHECK: loop # label3:
+; CHECK: v128.load64_zero 0:p2align=2
+; CHECK: v128.load64_zero 0:p2align=2
+; CHECK: i32x4.add
+; CHECK: v128.store64_lane 0:p2align=2, 0
+; CHECK: end_loop
%5 = icmp eq i32 %3, 0
br i1 %5, label %6, label %7
@@ -62,23 +62,32 @@ define hidden void @two_ints_same_op(ptr noalias nocapture noundef writeonly %0,
br i1 %22, label %6, label %7
}
-; CHECK-LABEL: two_ints_vary_op:
-; CHECK: loop
-; CHECK: v128.load
-; CHECK: v128.load
-; CHECK: i8x16.shuffle 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
-; CHECK: v128.load
-; CHECK: v128.load
-; CHECK: i8x16.shuffle 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
-; CHECK: i32x4.add
-; CHECK: i8x16.shuffle 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
-; CHECK: i8x16.shuffle 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
-; CHECK: i32x4.sub
-; CHECK: i8x16.shuffle 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31
-; CHECK: v128.store
-; CHECK: i8x16.shuffle 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23
-; CHECK: v128.store
define hidden void @two_ints_vary_op(ptr noalias nocapture noundef writeonly %0, ptr nocapture noundef readonly %1, ptr nocapture noundef readonly %2, i32 noundef %3) {
+; CHECK-LABEL: two_ints_vary_op:
+; CHECK: loop # label6:
+; CHECK: v128.load 0:p2align=2
+; CHECK: v128.load 16:p2align=2
+; CHECK: i8x16.shuffle 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
+; CHECK: v128.load 0:p2align=2
+; CHECK: v128.load 16:p2align=2
+; CHECK: i8x16.shuffle 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27
+; CHECK: i32x4.add
+; CHECK: i8x16.shuffle 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
+; CHECK: i8x16.shuffle 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31
+; CHECK: i32x4.sub
+; CHECK: i8x16.shuffle 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31
+; CHECK: v128.store 16:p2align=2
+; CHECK: i8x16.shuffle 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23
+; CHECK: v128.store 0:p2align=2
+; CHECK: end_loop
+; CHECK: loop # label7:
+; CHECK: i32.load 0
+; CHECK: i32.load 0
+; CHECK: i32.store 0
+; CHECK: i32.load 0
+; CHECK: i32.load 0
+; CHECK: i32.store 0
+; CHECK: end_loop
%5 = icmp eq i32 %3, 0
br i1 %5, label %6, label %7
@@ -106,22 +115,19 @@ define hidden void @two_ints_vary_op(ptr noalias nocapture noundef writeonly %0,
br i1 %22, label %6, label %7
}
-; CHECK-LABEL: three_ints:
-; CHECK: loop
-; CHECK-NOT: v128.load
-; CHECK: i32.load
-; CHECK: i32.load
-; CHECK: i32.add
-; CHECK: i32.store
-; CHECK: i32.load
-; CHECK: i32.load
-; CHECK: i32.add
-; CHECK: i32.store
-; CHECK: i32.load
-; CHECK: i32.load
-; CHECK: i32.add
-; CHECK: i32.store
define hidden void @three_ints(ptr noalias nocapture noundef writeonly %0, ptr nocapture noundef readonly %1, ptr nocapture noundef readonly %2, i32 noundef %3) {
+; CHECK-LABEL: three_ints:
+; CHECK: loop # label9:
+; CHECK: i32.load 0
+; CHECK: i32.load 0
+; CHECK: i32.store 0
+; CHECK: i32.load 0
+; CHECK: i32.load 0
+; CHECK: i32.store 0
+; CHECK: i32.load 0
+; CHECK: i32.load 0
+; CHECK: i32.store 0
+; CHECK: end_loop
%5 = icmp eq i32 %3, 0
br i1 %5, label %6, label %7
@@ -156,22 +162,19 @@ define hidden void @three_ints(ptr noalias nocapture noundef writeonly %0, ptr n
br i1 %28, label %6, label %7
}
-; CHECK-LABEL: three_shorts:
-; CHECK: loop
-; CHECK-NOT: v128.load
-; CHECK: i32.load16_u
-; CHECK: i32.load16_u
-; CHECK: i32.mul
-; CHECK: i32.store16
-; CHECK: i32.load16_u
-; CHECK: i32.load16_u
-; CHECK: i32.mul
-; CHECK: i32.store16
-; CHECK: i32.load16_u
-; CHECK: i32.load16_u
-; CHECK: i32.mul
-; CHECK: i32.store16
define hidden void @three_shorts(ptr noalias nocapture noundef writeonly %0, ptr nocapture noundef readonly %1, ptr nocapture noundef readonly %2, i32 noundef %3) {
+; CHECK-LABEL: three_shorts:
+; CHECK: loop # label11:
+; CHECK: i32.load16_u 0
+; CHECK: i32.load16_u 0
+; CHECK: i32.store16 0
+; CHECK: i32.load16_u 0
+; CHECK: i32.load16_u 0
+; CHECK: i32.store16 0
+; CHECK: i32.load16_u 0
+; CHECK: i32.load16_u 0
+; CHECK: i32.store16 0
+; CHECK: end_loop
%5 = icmp eq i32 %3, 0
br i1 %5, label %6, label %7
@@ -206,33 +209,28 @@ define hidden void @three_shorts(ptr noalias nocapture noundef writeonly %0, ptr
br i1 %28, label %6, label %7
}
-; CHECK-LABEL: four_shorts_same_op:
-; CHECK: loop
-; CHECK: v128.load
-; CHECK: v128.load
-; CHECK: i8x16.shuffle 0, 1, 8, 9, 16, 17, 24, 25, 0, 1, 0, 1, 0, 1, 0, 1
-; CHECK: v128.load
-; CHECK: v128.load
-; CHECK: i8x16.shuffle 0, 1, 8, 9, 16, 17, 24, 25, 0, 1, 0, 1, 0, 1, 0, 1
-; CHECK: i16x8.sub
-; CHECK: i8x16.shuffle 2, 3, 10, 11, 18, 19, 26, 27, 0, 1, 0, 1, 0, 1, 0, 1
-; CHECK: i8x16.shuffle 2, 3, 10, 11, 18, 19, 26, 27, 0, 1, 0, 1, 0, 1, 0, 1
-; CHECK: i16x8.sub
-; CHECK: i8x16.shuffle 4, 5, 20, 21, 0, 1, 0, 1, 6, 7, 22, 23, 0, 1, 0, 1
-; CHECK: i8x16.shuffle 4, 5, 12, 13, 20, 21, 28, 29, 0, 1, 0, 1, 0, 1, 0, 1
-; CHECK: i8x16.shuffle 4, 5, 12, 13, 20, 21, 28, 29, 0, 1, 0, 1, 0, 1, 0, 1
-; CHECK: i16x8.sub
-; CHECK: i8x16.shuffle 6, 7, 14, 15, 22, 23, 30, 31, 0, 1, 0, 1, 0, 1, 0, 1
-; CHECK: i8x16.shuffle 6, 7, 14, 15, 22, 23, 30, 31, 0, 1, 0, 1, 0, 1, 0, 1
-; CHECK: i16x8.sub
-; CHECK: i8x16.shuffle 0, 1, 0, 1, 4, 5, 20, 21, 0, 1, 0, 1, 6, 7, 22, 23
-; CHECK: i8x16.shuffle 0, 1, 2, 3, 20, 21, 22, 23, 8, 9, 10, 11, 28, 29, 30, 31
-; CHECK: v128.store
-; CHECK: i8x16.shuffle 0, 1, 16, 17, 0, 1, 0, 1, 2, 3, 18, 19, 0, 1, 0, 1
-; CHECK: i8x16.shuffle 0, 1, 0, 1, 0, 1, 16, 17, 0, 1, 0, 1, 2, 3, 18, 19
-; CHECK: i8x16.shuffle 0, 1, 2, 3, 20, 21, 22, 23, 8, 9, 10, 11, 28, 29, 30, 31
-; CHECK: v128.store
define hidden void @four_shorts_same_op(ptr noalias nocapture noundef writeonly %0, ptr nocapture noundef readonly %1, ptr nocapture noundef readonly %2, i32 noundef %3) {
+; CHECK-LABEL...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/206305
More information about the llvm-commits
mailing list