[llvm] [SLP]Make the instruction-count check loop-aware (PR #210074)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 07:42:12 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Alexey Bataev (alexey-bataev)
<details>
<summary>Changes</summary>
Raw getNum{Scalar,Vector}Insts() counted one-time, LICM-hoisted
broadcasts/buildvectors against the loop body, rejecting profitable loop
trees (508.namd_r). Weight each entry by its loop-nest trip
count and drop nest-invariant ones; flat code is unchanged (scale 1).
Fixes #<!-- -->207572
---
Patch is 29.47 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/210074.diff
5 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+54-33)
- (modified) llvm/test/Transforms/SLPVectorizer/X86/deleted-instructions-clear.ll (+5-5)
- (modified) llvm/test/Transforms/SLPVectorizer/X86/loop-invariant-gather-inst-count.ll (+64-64)
- (modified) llvm/test/Transforms/SLPVectorizer/X86/phi-removed-on-operand-vectorization.ll (+8-7)
- (modified) llvm/test/Transforms/SLPVectorizer/X86/rgb_phi.ll (+9-9)
``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index b76cb80426456..22dfe1cf4f933 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -3747,12 +3747,15 @@ class slpvectorizer::BoUpSLP {
Instruction *I,
const SmallDenseSet<Value *> *VectorizedVals = nullptr) const;
- /// Estimates the number of scalar instructions in the tree.
- unsigned getNumScalarInsts() const;
+ /// Estimates the number of scalar instructions in the tree, each weighted by
+ /// its loop-nest trip count (nest-invariant entries are dropped when
+ /// \p TreeLoop is non-null).
+ uint64_t getNumScalarInsts(const Loop *TreeLoop);
/// Estimates the number of vector instructions (including buildvectors,
- /// shuffles, and extracts) that the tree will produce.
- unsigned getNumVectorInsts() const;
+ /// shuffles, and extracts) the tree produces, weighted like
+ /// getNumScalarInsts().
+ uint64_t getNumVectorInsts(const Loop *TreeLoop);
/// Return information about the vector formed for the specified index
/// of a vector of (the same) instruction.
@@ -3802,6 +3805,10 @@ class slpvectorizer::BoUpSLP {
uint64_t getGatherNodeEffectiveScale(const TreeEntry &TE,
Instruction *U = nullptr);
+ /// \returns the loop-nest execution scale of \p TE.
+ uint64_t getEntryEffectiveScale(const TreeEntry &TE,
+ Instruction *U = nullptr);
+
/// Get the loop nest for the given loop \p L.
ArrayRef<const Loop *> getLoopNest(const Loop *L);
@@ -13824,12 +13831,16 @@ static InstructionCost canConvertToFMA(ArrayRef<Value *> VL,
TargetTransformInfo &TTI,
const TargetLibraryInfo &TLI);
-unsigned BoUpSLP::getNumScalarInsts() const {
- unsigned Count = 0;
+uint64_t BoUpSLP::getNumScalarInsts(const Loop *TreeLoop) {
+ uint64_t Total = 0;
for (const std::unique_ptr<TreeEntry> &Ptr : VectorizableTree) {
const TreeEntry &TE = *Ptr;
if (DeletedNodes.contains(&TE))
continue;
+ uint64_t Scale = getEntryEffectiveScale(TE);
+ if (TreeLoop && Scale <= 1)
+ continue;
+ unsigned Count = 0;
if (TE.isGather() || TransformedToGatherNodes.contains(&TE)) {
// Count extractelement scalars in gathers - they exist in the scalar
// code regardless of vectorization. ExtractElement instructions
@@ -13837,12 +13848,13 @@ unsigned BoUpSLP::getNumScalarInsts() const {
for (Value *V : TE.Scalars)
if (isa<ExtractElementInst>(V))
++Count;
+ Total = SaturatingMultiplyAdd<uint64_t>(Count, Scale, Total);
continue;
}
// CombinedVectorize entries (e.g. the fmul child of an FMulAdd, or the
// cmp child of a MinMax select) are absorbed into the parent on both
- // scalar and vector sides. The backend fuses fadd+fmul → fma and
- // select+cmp → smin/smax even for scalar code, so skip to avoid
+ // scalar and vector sides. The backend fuses fadd+fmul -> fma and
+ // select+cmp -> smin/smax even for scalar code, so skip to avoid
// double-counting.
if (TE.State == TreeEntry::CombinedVectorize)
continue;
@@ -13867,7 +13879,7 @@ unsigned BoUpSLP::getNumScalarInsts() const {
}
// Even when the whole node is not combined, individual scalar
// instructions may be fused by the backend. Each fused pair (e.g.
- // fadd+fmul → fma, select+cmp → smin/smax) becomes a single scalar
+ // fadd+fmul -> fma, select+cmp -> smin/smax) becomes a single scalar
// instruction, absorbing the operand instruction. Subtract 1 for each
// such match to avoid over-counting the scalar side.
if (TE.CombinedOp == TreeEntry::NotCombinedOp && TE.hasState()) {
@@ -13901,12 +13913,13 @@ unsigned BoUpSLP::getNumScalarInsts() const {
}
}
}
+ Total = SaturatingMultiplyAdd<uint64_t>(Count, Scale, Total);
}
- return Count;
+ return Total;
}
-unsigned BoUpSLP::getNumVectorInsts() const {
- unsigned Count = 0;
+uint64_t BoUpSLP::getNumVectorInsts(const Loop *TreeLoop) {
+ uint64_t Total = 0;
SmallPtrSet<Value *, 4> GatherExtractSourceVecs;
for (const std::unique_ptr<TreeEntry> &Ptr : VectorizableTree) {
const TreeEntry &TE = *Ptr;
@@ -13914,9 +13927,11 @@ unsigned BoUpSLP::getNumVectorInsts() const {
continue;
if (TE.State == TreeEntry::CombinedVectorize)
continue;
- bool IsGatherOrTransformed =
- TE.isGather() || TransformedToGatherNodes.contains(&TE);
- if (IsGatherOrTransformed) {
+ uint64_t Scale = getEntryEffectiveScale(TE);
+ if (TreeLoop && Scale <= 1)
+ continue;
+ unsigned Count = 0;
+ if (TE.isGather() || TransformedToGatherNodes.contains(&TE)) {
if (TE.hasState()) {
if (const TreeEntry *E =
getSameValuesTreeEntry(TE.getMainOp(), TE.Scalars);
@@ -13926,7 +13941,7 @@ unsigned BoUpSLP::getNumVectorInsts() const {
if (const TreeEntry *E =
getSameValuesTreeEntry(TE.getMainOp(), RevScalars);
E && E->getVectorFactor() == TE.getVectorFactor()) {
- ++Count;
+ Total = SaturatingAdd(Total, Scale);
continue;
}
}
@@ -13944,6 +13959,7 @@ unsigned BoUpSLP::getNumVectorInsts() const {
++Count;
}
}
+ Total = SaturatingMultiplyAdd<uint64_t>(Count, Scale, Total);
continue;
}
// InsertElement/ExtractElement vectorize entries don't produce real
@@ -13959,6 +13975,7 @@ unsigned BoUpSLP::getNumVectorInsts() const {
Count += 2;
if (!TE.ReorderIndices.empty() || !TE.ReuseShuffleIndices.empty())
++Count;
+ Total = SaturatingMultiplyAdd<uint64_t>(Count, Scale, Total);
continue;
}
if (TE.State == TreeEntry::SplitVectorize)
@@ -13967,8 +13984,9 @@ unsigned BoUpSLP::getNumVectorInsts() const {
++Count;
if (!TE.ReorderIndices.empty() || !TE.ReuseShuffleIndices.empty())
++Count;
+ Total = SaturatingMultiplyAdd<uint64_t>(Count, Scale, Total);
}
- Count += GatherExtractSourceVecs.size();
+ Total += GatherExtractSourceVecs.size();
// Count extract instructions from ExternalUses, skipping insertelements
// (those get folded into shuffles, not real extracts).
SmallPtrSet<Value *, 8> CountedExtracts;
@@ -13981,9 +13999,9 @@ unsigned BoUpSLP::getNumVectorInsts() const {
continue;
if (!CountedExtracts.insert(EU.Scalar).second)
continue;
- ++Count;
+ ++Total;
}
- return Count;
+ return Total;
}
void BoUpSLP::TreeEntry::buildAltOpShuffleMask(
@@ -16844,6 +16862,12 @@ uint64_t BoUpSLP::getGatherNodeEffectiveScale(const TreeEntry &TE,
return std::clamp<uint64_t>(Avg, 1, BaseScale);
}
+uint64_t BoUpSLP::getEntryEffectiveScale(const TreeEntry &TE, Instruction *U) {
+ if (TE.isGather() || TE.State == TreeEntry::SplitVectorize)
+ return getGatherNodeEffectiveScale(TE, U);
+ return getScaleToLoopIterations(TE);
+}
+
InstructionCost
BoUpSLP::getVectorSpillReloadCost(const TreeEntry *E, Type *ScalarTy,
Type *VecTy, Type *FinalVecTy,
@@ -19376,8 +19400,6 @@ BoUpSLP::calculateTreeCostAndTrimNonProfitable(ArrayRef<Value *> VectorizedVals,
// per-lane refined scale that accounts for LICM-hoistable insertelements
// when an operand is invariant in the current loop nest but defined in
// an outer loop. This prevents over-costing cross-loop-nest buildvectors.
- const bool IsGatherLike =
- TE.isGather() || TE.State == TreeEntry::SplitVectorize;
if (!CostIsFree && !TE.isGather() && TE.hasState()) {
if (PrevVecParent == TE.getMainOp()->getParent()) {
Scale = PrevScale;
@@ -19386,10 +19408,7 @@ BoUpSLP::calculateTreeCostAndTrimNonProfitable(ArrayRef<Value *> VectorizedVals,
}
}
if (!CostIsFree && !Scale) {
- Scale =
- IsGatherLike
- ? getGatherNodeEffectiveScale(TE, TE.Idx == 0 ? RdxRoot : nullptr)
- : getScaleToLoopIterations(TE);
+ Scale = getEntryEffectiveScale(TE, TE.Idx == 0 ? RdxRoot : nullptr);
C *= Scale;
EntryToScale.try_emplace(&TE, Scale);
if (!TE.isGather() && TE.hasState()) {
@@ -19768,12 +19787,8 @@ BoUpSLP::calculateTreeCostAndTrimNonProfitable(ArrayRef<Value *> VectorizedVals,
continue;
}
uint64_t Scale = EntryToScale.lookup(TE.get());
- if (!Scale) {
- const bool IsGatherLike =
- TE->isGather() || TE->State == TreeEntry::SplitVectorize;
- Scale = IsGatherLike ? getGatherNodeEffectiveScale(*TE.get())
- : getScaleToLoopIterations(*TE.get());
- }
+ if (!Scale)
+ Scale = getEntryEffectiveScale(*TE);
C *= Scale;
NodesCosts.try_emplace(TE.get(), C);
}
@@ -19857,8 +19872,14 @@ InstructionCost BoUpSLP::getTreeCost(InstructionCost TreeCost,
(!SLPReVec ||
!isa<VectorType>(
VectorizableTree.front()->Scalars.front()->getType()))) {
- unsigned NumScalar = getNumScalarInsts();
- unsigned NumVector = getNumVectorInsts();
+ // Loop containing the tree root; null for flat code or disabled
+ // loop-aware modeling. Shared by both calls below.
+ const Loop *TreeLoop = nullptr;
+ if (LoopAwareTripCount != 0 && VectorizableTree.front()->hasState())
+ TreeLoop =
+ LI->getLoopFor(VectorizableTree.front()->getMainOp()->getParent());
+ uint64_t NumScalar = getNumScalarInsts(TreeLoop);
+ uint64_t NumVector = getNumVectorInsts(TreeLoop);
LLVM_DEBUG(dbgs() << "SLP: Inst count check: vector=" << NumVector
<< " scalar=" << NumScalar << "\n");
if (NumVector > NumScalar && !BypassesInstCountCheck()) {
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/deleted-instructions-clear.ll b/llvm/test/Transforms/SLPVectorizer/X86/deleted-instructions-clear.ll
index ae6da0913cc24..94631869b15fe 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/deleted-instructions-clear.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/deleted-instructions-clear.ll
@@ -7,7 +7,7 @@ define void @test(i32 %arg, i32 %arg1, i64 %arg2) {
; CHECK-NEXT: [[BB:.*]]:
; CHECK-NEXT: [[TMP11:%.*]] = insertelement <4 x i32> <i32 0, i32 0, i32 0, i32 poison>, i32 [[ARG]], i64 3
; CHECK-NEXT: [[TMP27:%.*]] = insertelement <2 x i32> poison, i32 [[ARG1]], i64 0
-; CHECK-NEXT: [[TMP28:%.*]] = shufflevector <2 x i32> [[TMP27]], <2 x i32> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP29:%.*]] = insertelement <2 x i32> <i32 0, i32 poison>, i32 [[ARG]], i64 1
; CHECK-NEXT: br label %[[BB3:.*]]
; CHECK: [[BB3]]:
; CHECK-NEXT: [[TMP3:%.*]] = phi i64 [ 0, %[[BB3]] ], [ 0, %[[BB]] ]
@@ -28,9 +28,9 @@ define void @test(i32 %arg, i32 %arg1, i64 %arg2) {
; CHECK-NEXT: [[OR11:%.*]] = or i32 [[TRUNC27]], 0
; CHECK-NEXT: [[TMP8:%.*]] = or <4 x i32> zeroinitializer, [[TMP2]]
; CHECK-NEXT: [[TMP9:%.*]] = mul <4 x i32> [[TMP5]], [[TMP8]]
-; CHECK-NEXT: [[XOR38:%.*]] = xor i32 [[ARG]], [[TRUNC28]]
-; CHECK-NEXT: [[TMP29:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[TRUNC19]], i64 0
+; CHECK-NEXT: [[TMP28:%.*]] = insertelement <2 x i32> [[TMP27]], i32 [[TRUNC28]], i64 1
; CHECK-NEXT: [[TMP14:%.*]] = xor <2 x i32> [[TMP28]], [[TMP29]]
+; CHECK-NEXT: [[XOR31:%.*]] = xor i32 [[ARG1]], [[TRUNC19]]
; CHECK-NEXT: [[SHL:%.*]] = shl i32 0, 1
; CHECK-NEXT: [[TMP23:%.*]] = insertelement <4 x i32> poison, i32 [[SHL]], i64 0
; CHECK-NEXT: [[TMP31:%.*]] = insertelement <4 x i32> [[TMP23]], i32 [[TRUNC10]], i64 1
@@ -38,9 +38,9 @@ define void @test(i32 %arg, i32 %arg1, i64 %arg2) {
; CHECK-NEXT: [[TMP25:%.*]] = shufflevector <4 x i32> [[TMP13]], <4 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 3>
; CHECK-NEXT: [[TMP26:%.*]] = xor <4 x i32> [[TMP11]], [[TMP25]]
; CHECK-NEXT: [[TMP24:%.*]] = shufflevector <4 x i32> [[TMP26]], <4 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP32:%.*]] = insertelement <8 x i32> [[TMP24]], i32 [[XOR31]], i64 5
; CHECK-NEXT: [[TMP30:%.*]] = shufflevector <2 x i32> [[TMP14]], <2 x i32> poison, <8 x i32> <i32 0, i32 1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
-; CHECK-NEXT: [[TMP15:%.*]] = shufflevector <8 x i32> [[TMP24]], <8 x i32> [[TMP30]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 8, i32 9, i32 7>
-; CHECK-NEXT: [[TMP16:%.*]] = insertelement <8 x i32> [[TMP15]], i32 [[XOR38]], i64 7
+; CHECK-NEXT: [[TMP16:%.*]] = shufflevector <8 x i32> [[TMP32]], <8 x i32> [[TMP30]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 8, i32 9>
; CHECK-NEXT: [[TMP17:%.*]] = shufflevector <8 x i32> [[TMP16]], <8 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 0, i32 5, i32 6, i32 7>
; CHECK-NEXT: [[TMP18:%.*]] = shufflevector <8 x i32> [[TMP17]], <8 x i32> poison, <12 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison>
; CHECK-NEXT: [[TMP19:%.*]] = shufflevector <4 x i32> [[TMP9]], <4 x i32> poison, <12 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/loop-invariant-gather-inst-count.ll b/llvm/test/Transforms/SLPVectorizer/X86/loop-invariant-gather-inst-count.ll
index 923af5efa5d2e..9c7849d0de123 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/loop-invariant-gather-inst-count.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/loop-invariant-gather-inst-count.ll
@@ -25,70 +25,70 @@ define void @test(ptr noalias readonly %0, ptr noalias readonly %1, i32 %2, doub
; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [32 x i8], ptr [[TMP0]], i64 [[TMP19]]
; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP20]], i64 16
; CHECK-NEXT: [[TMP22:%.*]] = load double, ptr [[TMP21]], align 8
-; CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP15]], i64 8
-; CHECK-NEXT: [[TMP24:%.*]] = load double, ptr [[TMP23]], align 8
-; CHECK-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP20]], i64 8
-; CHECK-NEXT: [[TMP26:%.*]] = load double, ptr [[TMP25]], align 8
-; CHECK-NEXT: [[TMP27:%.*]] = load double, ptr [[TMP15]], align 8
-; CHECK-NEXT: [[TMP28:%.*]] = load double, ptr [[TMP20]], align 8
-; CHECK-NEXT: [[TMP29:%.*]] = zext nneg i32 [[TMP11]] to i64
-; CHECK-NEXT: br label %[[BB30:.*]]
-; CHECK: [[BB30]]:
-; CHECK-NEXT: [[TMP31:%.*]] = phi i64 [ 2, %[[BB10]] ], [ [[TMP81:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP32:%.*]] = phi i32 [ 0, %[[BB10]] ], [ [[TMP80:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP33:%.*]] = phi i32 [ [[TMP18]], %[[BB10]] ], [ [[TMP54:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP34:%.*]] = phi i32 [ [[TMP13]], %[[BB10]] ], [ [[TMP56:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP35:%.*]] = phi double [ [[TMP28]], %[[BB10]] ], [ [[TMP59:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP36:%.*]] = phi double [ [[TMP27]], %[[BB10]] ], [ [[TMP62:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP37:%.*]] = phi double [ [[TMP17]], %[[BB10]] ], [ [[TMP70:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP38:%.*]] = phi double [ [[TMP22]], %[[BB10]] ], [ [[TMP68:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP39:%.*]] = phi double [ [[TMP24]], %[[BB10]] ], [ [[TMP66:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP40:%.*]] = phi double [ [[TMP26]], %[[BB10]] ], [ [[TMP64:%.*]], %[[BB30]] ]
-; CHECK-NEXT: [[TMP41:%.*]] = fsub double [[TMP3]], [[TMP35]]
-; CHECK-NEXT: [[TMP42:%.*]] = fsub double [[TMP3]], [[TMP36]]
-; CHECK-NEXT: [[TMP43:%.*]] = fmul double [[TMP41]], [[TMP41]]
-; CHECK-NEXT: [[TMP44:%.*]] = fmul double [[TMP42]], [[TMP42]]
-; CHECK-NEXT: [[TMP45:%.*]] = fsub double [[TMP4]], [[TMP40]]
-; CHECK-NEXT: [[TMP46:%.*]] = fsub double [[TMP4]], [[TMP39]]
-; CHECK-NEXT: [[TMP47:%.*]] = tail call double @llvm.fmuladd.f64(double [[TMP45]], double [[TMP45]], double [[TMP43]])
-; CHECK-NEXT: [[TMP48:%.*]] = tail call double @llvm.fmuladd.f64(double [[TMP46]], double [[TMP46]], double [[TMP44]])
-; CHECK-NEXT: [[TMP49:%.*]] = fsub double [[TMP5]], [[TMP38]]
-; CHECK-NEXT: [[TMP50:%.*]] = fsub double [[TMP5]], [[TMP37]]
-; CHECK-NEXT: [[TMP51:%.*]] = tail call double @llvm.fmuladd.f64(double [[TMP49]], double [[TMP49]], double [[TMP47]])
-; CHECK-NEXT: [[TMP52:%.*]] = tail call double @llvm.fmuladd.f64(double [[TMP50]], double [[TMP50]], double [[TMP48]])
-; CHECK-NEXT: [[TMP53:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[TMP1]], i64 [[TMP31]]
-; CHECK-NEXT: [[TMP54]] = load i32, ptr [[TMP53]], align 4
-; CHECK-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP53]], i64 4
-; CHECK-NEXT: [[TMP56]] = load i32, ptr [[TMP55]], align 4
-; CHECK-NEXT: [[TMP57:%.*]] = sext i32 [[TMP54]] to i64
-; CHECK-NEXT: [[TMP58:%.*]] = getelementptr inbounds [32 x i8], ptr [[TMP0]], i64 [[TMP57]]
-; CHECK-NEXT: [[TMP59]] = load double, ptr [[TMP58]], align 8
-; CHECK-NEXT: [[TMP60:%.*]] = sext i32 [[TMP56]] to i64
-; CHECK-NEXT: [[TMP61:%.*]] = getelementptr inbounds [32 x i8], ptr [[TMP0]], i64 [[TMP60]]
-; CHECK-NEXT: [[TMP62]] = load double, ptr [[TMP61]], align 8
-; CHECK-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP58]], i64 8
-; CHECK-NEXT: [[TMP64]] = load double, ptr [[TMP63]], align 8
-; CHECK-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP61]], i64 8
-; CHECK-NEXT: [[TMP66]] = load double, ptr [[TMP65]], align 8
-; CHECK-NEXT: [[TMP67:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP58]], i64 16
-; CHECK-NEXT: [[TMP68]] = load double, ptr [[TMP67]], align 8
-; CHECK-NEXT: [[TMP69:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP61]], i64 16
-; CHECK-NEXT: [[TMP70]] = load double, ptr [[TMP69]], align 8
-; CHECK-NEXT: [[TMP71:%.*]] = fcmp olt double [[TMP51]], [[TMP6]]
-; CHECK-NEXT: [[TMP72:%.*]] = fcmp olt double [[TMP52]], [[TMP6]]
-; CHECK-NEXT: [[TMP73:%.*]] = zext nneg i32 [[TMP32]] to i64
-; CHECK-NEXT: [[TMP74:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[TMP7]], i64 [[TMP73]]
-; CHECK-NEXT: store i32 [[TMP33]], ptr [[TMP74]], align 4
-; CHECK-NEXT: [[TMP75:%.*]] = zext i1 [[TMP71]] to i32
-; CHECK-NEXT: [[TMP76:%.*]] = add nuw nsw i32 [[TMP32]], [[TMP75]]
-; CHECK-NEXT: [[TMP77:%.*]] = zext nneg i32 [[TMP76]] to i64
-; CHECK-NEXT: [[TMP78:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[TMP7]], i64 [[TMP77]]
-; CHECK-NEXT: store i32 [[TMP34]], ptr [[TMP78]], align 4
-; CHECK-NEXT: [[TMP79:%.*]] = zext i1 [[TMP72]] to i32
-; CHECK-NEXT: [[TMP80]] = add nuw nsw i32 [[TMP76]], [[TMP79]]
-; CHECK-NEXT: [[TMP81]] = add nuw nsw i64 [[TMP31]], 2
-; CHECK-NEXT: [[TMP82:%.*]] = icmp samesign ult i64 [[TMP81]], [[TMP29]]
-; CHECK-NEXT: br i1 [[TMP82]], label %[[BB30]], label %[[BB83]]
+; CHECK-NEXT: [[TMP23:%.*]] = load <2 x double>, ptr [[TMP15]], align 8
+; CHECK-NEXT: [[TMP24:%.*]] = load <2 x double>, ptr [[TMP20]], align 8
+; CHECK-NEXT: [[TMP25:%.*]] = zext nneg i32 [[TMP11]] to i64
+; CHECK-NEXT: [[TMP26:%.*]] = insertelement <2 x double> poison, double [[TMP17]], i64 0
+; CHECK-NEXT: [[TMP27:%.*]] = insertelement <2 x double> [[TMP26]], double [[TMP22]], i64 1
+; CHECK-NEXT: [[TMP28:%.*]] = shufflevector <2 x double> [[TMP23]], <2 x double> [[TMP24]], <2 x i32> <i32 1, i32 3>
+; CHECK-NEXT: [[TMP29:%.*]] = shufflevector <2 x double> [[TMP23]], <2 x double> [[TMP24]], <2 x i32> <i32 0, i32 2>
+; CHECK-NEXT: [[TMP30:%.*]] = insertelement <2 x double> poison, double [[TMP5]], i64 0
+; CHECK-NEXT: [[TMP31:%.*]] = shufflevector <2 x double> [[TMP30]], <2 x double> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP32:%.*]] = insertelement <2 x double> poison, double [[TMP4]], i64 0
+; CHECK-NEXT: [[TMP33:%.*]] = shufflevector <2 x double> [[TMP32]], <2 x double> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP34:%.*]] = insertelement <2 x double> poison, double [[TMP3]], i64 0
+; CHECK-NEXT: [[TMP35:%.*]] = shufflevector <2 x double> [[TMP34]], <2 x double> poison, <2 x i3...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/210074
More information about the llvm-commits
mailing list