Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LV] Ignore some costs when loop gets fully unrolled #106699

Merged
merged 9 commits into from
Dec 9, 2024

Conversation

igogo-x86
Copy link
Contributor

When fixed-width VF equals the number of iterations, comparison instruction and induction operation will be DCEed later. Ignoring the costs of these instructions improves the cost model.

I have one benchmark that significantly improves when vectorised with fixed VF instead of scalable on AArch64 due to full unrolling. But I am not sure how to ignore the costs properly. This patch, as it is, makes new and legacy cost models out of sync and compiler fails with assertion error on this line:

assert((BestFactor.Width == LegacyVF.Width ||
 planContainsAdditionalSimplifications(getPlanFor(BestFactor.Width),
 BestFactor.Width, CostCtx,
 OrigLoop, CM)) &&
 " VPlan cost model and legacy cost model disagreed");

Identifying variables to ignore in LoopVectorizationCostModel::getInstructionCost is much more challenging.

Is the approach shown in the patch ok, and can I wait for the legacy cost model to be removed? If not, how can it be done differently?

@llvmbot
Copy link
Member

llvmbot commented Aug 30, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Igor Kirillov (igogo-x86)

Changes

When fixed-width VF equals the number of iterations, comparison instruction and induction operation will be DCEed later. Ignoring the costs of these instructions improves the cost model.

I have one benchmark that significantly improves when vectorised with fixed VF instead of scalable on AArch64 due to full unrolling. But I am not sure how to ignore the costs properly. This patch, as it is, makes new and legacy cost models out of sync and compiler fails with assertion error on this line:

assert((BestFactor.Width == LegacyVF.Width ||
 planContainsAdditionalSimplifications(getPlanFor(BestFactor.Width),
 BestFactor.Width, CostCtx,
 OrigLoop, CM)) &&
 " VPlan cost model and legacy cost model disagreed");

Identifying variables to ignore in LoopVectorizationCostModel::getInstructionCost is much more challenging.

Is the approach shown in the patch ok, and can I wait for the legacy cost model to be removed? If not, how can it be done differently?


Full diff: https://github.com/llvm/llvm-project/pull/106699.diff

1 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+20)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 6babfd1eee9108..7dc9a60cb0f034 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -7112,6 +7112,26 @@ LoopVectorizationPlanner::precomputeCosts(VPlan &Plan, ElementCount VF,
         continue;
       IVInsts.push_back(CI);
     }
+
+    // If the given VF loop gets fully unrolled, ignore the costs of comparison
+    // and increment instruction, as they'll get simplified away
+    auto TC = CM.PSE.getSE()->getSmallConstantTripCount(OrigLoop);
+    auto *Cmp = OrigLoop->getLatchCmpInst();
+    if (Cmp && VF.isFixed() && VF.getFixedValue() == TC) {
+      CostCtx.SkipCostComputation.insert(Cmp);
+      for (Instruction *IVInst : IVInsts) {
+        bool IsSimplifiedAway = true;
+        for (auto *UIV : IVInst->users()) {
+          if (!Legal->isInductionVariable(UIV) && UIV != Cmp) {
+            IsSimplifiedAway = false;
+            break;
+          }
+        }
+        if (IsSimplifiedAway)
+          CostCtx.SkipCostComputation.insert(IVInst);
+      }
+    }
+
     for (Instruction *IVInst : IVInsts) {
       if (CostCtx.skipCostComputation(IVInst, VF.isVector()))
         continue;

@igogo-x86
Copy link
Contributor Author

Ping

@fhahn
Copy link
Contributor

fhahn commented Sep 12, 2024

IIUC this should catch cases where the vector loop only executes a single iteration, right?

Ideally we would first remove the redundant compare-and-branch and induction recipes, and then rely on the VPlan-based cost model to consider this difference.

For the former, I just shared #108378 to do that. For the latter, I think we first need to change the cost of the exit condition to be computed by the VPlan-based cost model, instead of pre-computing it.

As you mentioned, this is leading to divergences between legacy and VPlan-based cost model. Ideally we would first migrate computing costs for all recipes to the VPlan-based cost model, ensuring the don't regress vs the legacy cost model, which is still in the works.

@igogo-x86
Copy link
Contributor Author

As far as I understand, optimizeForVFAndUF runs after the cost model is calculated and taken into account to choose the best vectorisation factor:

  VPlanTransforms::optimizeForVFAndUF(BestVPlan, BestVF, BestUF, PSE);

Is optimizeForVFAndUF eventually going to be run for all VFs before the cost model decision? If so, now VPlan implies all possible VF. So, will it generate new VPLans if optimizeForVFAndUF changes something?

@igogo-x86 igogo-x86 force-pushed the lv-ignore-some-costs-fully-unrolled branch from 9a5cbbc to 5bff837 Compare October 21, 2024 14:05
@igogo-x86 igogo-x86 changed the title [WIP][LV] Ignore some costs when loop gets fully unrolled [LV] Ignore some costs when loop gets fully unrolled Oct 21, 2024
@igogo-x86
Copy link
Contributor Author

@fhahn I updated the patch to synchronise both models. Also, ping on my previous questions

Copy link
Contributor

@david-arm david-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea is good, i.e. teach the vectoriser about exit costs when the branch and compare will be removed. However, I think you've assumed that the induction variables have no other uses and so have almost certainly underestimated the costs in some loops. Also, I noticed that this patch doesn't remove the branch cost either. It's possible that removing the branch and comparison costs are enough to get what you want? It might be easier than analysing the users of all the incremented induction variables.

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp Outdated Show resolved Hide resolved
SmallPtrSet<const Value *, 16> ValuesToIgnoreForVF;
auto TC = PSE.getSE()->getSmallConstantTripCount(TheLoop);
auto *Cmp = TheLoop->getLatchCmpInst();
if (Cmp && TC == VF.getKnownMinValue()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment you're also including scalable VFs here and I think the only way we can remove the compare, branch and increment for a scalable VF is if:

  1. We are not tail-folding. Have you checked that we still remove the branch and compare for scalable VFs?
  2. We are tail-folding. In this case you can actually check if TC <= VF.getKnownMinValue(). If you still want to enable this optimisation for tail-folding too then it makes sense to try <= instead for fixed-width and scalable VFs and see if we also remove the branch and compare.

It might be worth pulling out some of the common code in both expectedCost and precomputeCosts to move into a static function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out scalable VF isn't that simple. Branch, next-iteration-induction, and comparison are simplified but only with tail-folding. So, I assume we have to keep only fixed-width FV, as I don't see how I can check the type of prediction here. Branch cost is zero, so I don't do anything about it.

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp Outdated Show resolved Hide resolved
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp Outdated Show resolved Hide resolved
@igogo-x86 igogo-x86 force-pushed the lv-ignore-some-costs-fully-unrolled branch from 5bff837 to a9b9cad Compare November 13, 2024 14:39
Copy link
Contributor

@david-arm david-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing previous comments @igogo-x86! I have a few more comments - I'm most worried about the changes to the RISCV tail-folding tests.

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp Outdated Show resolved Hide resolved
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp Outdated Show resolved Hide resolved
entry:
br label %for.body

for.cond.cleanup: ; preds = %for.body
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename the exit block name here to something more readable? For example, for.cond.cleanup -> ext and it would be nice to move this after the loop, i.e.

entry:
  br label %for.body

for.body:
...

exit:
...

Also, I think in the exit block you should be able to write:

exit:
  ret i64 %add

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it would be good to pre-commit the test or move it into it's own commit within this branch. That way we can see the effect your code changes have on the test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll pre-commit them once I'll be more sure that the patch will go through :)

; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP7]]
; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i32 0
; CHECK-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8.p0(ptr [[TMP9]], i32 1, <vscale x 4 x i1> [[ACTIVE_LANE_MASK]], <vscale x 4 x i8> poison)
; CHECK-NEXT: [[TMP10:%.*]] = shl <vscale x 4 x i8> [[WIDE_MASKED_LOAD]], shufflevector (<vscale x 4 x i8> insertelement (<vscale x 4 x i8> poison, i8 1, i64 0), <vscale x 4 x i8> poison, <vscale x 4 x i32> zeroinitializer)
; CHECK-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <8 x i8> @llvm.masked.load.v8i8.p0(ptr [[TMP9]], i32 1, <8 x i1> [[ACTIVE_LANE_MASK]], <8 x i8> poison)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't have expected this test to be changed by your patch. I think your code changes need an extra check that we're not tail-folding.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that's also bothering me. But where I'm adding this code, I can't see how to understand if scalable vectorisation is available and whether it would be tail-folded or not.

Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand, optimizeForVFAndUF runs after the cost model is calculated and taken into account to choose the best vectorisation factor:

  VPlanTransforms::optimizeForVFAndUF(BestVPlan, BestVF, BestUF, PSE);

Is optimizeForVFAndUF eventually going to be run for all VFs before the cost model decision? If so, now VPlan implies all possible VF. So, will it generate new VPLans if optimizeForVFAndUF changes something?

Eventually yes, eventually there should be no need to special case this. VPlans are valid for a range, that could be split. I guess for now doing it as workaround in precomputeCosts seems OK, even though it is not really intended for that (ideally we only remove stuff from there at this point). Could you add a comment to make sure this is not seen as encouragement to add more code that's not directly related to the transition to the VPlan-based cost model?

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp Outdated Show resolved Hide resolved
@@ -7224,6 +7259,14 @@ LoopVectorizationPlanner::precomputeCosts(VPlan &Plan, ElementCount VF,
continue;
IVInsts.push_back(CI);
}

// If with the given VF loop gets fully unrolled, ignore the costs of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// If with the given VF loop gets fully unrolled, ignore the costs of
// If the vector loop gets executed exactly once with the given VF ....

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp Outdated Show resolved Hide resolved
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp Outdated Show resolved Hide resolved
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp Outdated Show resolved Hide resolved
Comment on lines 2673 to 2674
if (!Cmp)
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the early return here, IV's could still be simplified?

Would be good to have a test case for this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See test_two_ivs test

Comment on lines 2676 to 2696
for (const auto &[IV, IndDesc] : IL) {
// Get next iteration value of the induction variable
Instruction *IVInst =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we completely ignore any IV and update instruction, if the start is a constant? All uses of the update will be replaced by a constant for fixed VFs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which instructions could that be? We have only PHINodes in the IV chain unprocessed, but they already have zero cost

// Check that this value used only to exit the loop
for (auto *UIV : IVInst->users()) {
if (UIV != IV && UIV != Cmp) {
IsSimplifiedAway = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to have a test case for this

Copy link
Contributor Author

@igogo-x86 igogo-x86 Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See test_external_iv_user test

@igogo-x86 igogo-x86 force-pushed the lv-ignore-some-costs-fully-unrolled branch from a9b9cad to fbb939a Compare November 15, 2024 16:42
@igogo-x86 igogo-x86 force-pushed the lv-ignore-some-costs-fully-unrolled branch from fbb939a to 166f376 Compare November 19, 2024 12:56
Copy link
Contributor

@david-arm david-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but can you address the nit for the tests before landing? Also, I think it would be good to change the commit message to reflect what you've done in the patch.

; This test shows that comparison and next iteration IV have zero cost if the
; vector loop gets executed exactly once with the given VF.
define i64 @test(ptr %a, ptr %b) #0 {
; CHECK: LV: Checking a loop in 'test'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the first CHECK line in every function I think it's worth changing to CHECK-LABEL, since this divides the CHECK lines into blocks per function. It also makes error reporting more accurate when something does go wrong.

// away.
SmallPtrSet<Instruction *, 2> ValuesToIgnoreForVF;
auto TC = PSE.getSE()->getSmallConstantTripCount(TheLoop);
if (VF.isFixed() && TC == VF.getFixedValue() && !foldTailByMasking())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If TC == VF, no tail should remain, so we shouldn't try to fold the tail by masking. Could you make this an assert instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course you're right! There is code in computeMaxVF that disables tail-folding. In that case an assert does make sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fhahn Well, if I make it as assert, these tests fail:

  LLVM :: Transforms/LoopVectorize/AArch64/clamped-trip-count.ll
  LLVM :: Transforms/LoopVectorize/RISCV/low-trip-count.ll
  LLVM :: Transforms/LoopVectorize/RISCV/short-trip-count.ll
  LLVM :: Transforms/LoopVectorize/RISCV/truncate-to-minimal-bitwidth-cost.ll

Without assert two RISCV tests show different output (that's why I added this check in the first place)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because in computeMaxVF the variable MaxPowerOf2RuntimeVF is bigger than the trip count and so the remainder of MaxPowerOf2RuntimeVF/TC is non-zero. Basically we only disable tail-folding if we can prove for every single possible VF there will not be a tail. So I believe @igogo-x86 is right and we need an explicit check.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, suppose TC=8 and the max VF=16. In this case we could choose a VF of 16 and there will be a remainder, but the cost model may prefer VF=8 where there isn't a remainder.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for checking, that makes sense.

@igogo-x86 igogo-x86 force-pushed the lv-ignore-some-costs-fully-unrolled branch from 166f376 to b494e64 Compare December 3, 2024 17:21
SmallPtrSet<Instruction *, 2> ValuesToIgnoreForVF;
auto TC = PSE.getSE()->getSmallConstantTripCount(TheLoop);
if (VF.isFixed() && TC == VF.getFixedValue()) {
assert(!foldTailByMasking());
Copy link
Contributor

@fhahn fhahn Dec 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this intentionally added in the latest version? IIUC this is causing crashes as per the earlier comment thread (which seems to have been dropped by Github here)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, no. I was checking the behaviour and forgot to undo the changes

@igogo-x86 igogo-x86 force-pushed the lv-ignore-some-costs-fully-unrolled branch from b494e64 to 86b9f1e Compare December 5, 2024 11:29
Copy link
Contributor

@david-arm david-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just about to accept this @igogo-x86, but I suddenly spotted something. Sorry I didn't see this until now, although it's easily fixed. :(

Loop *L, const LoopVectorizationLegality::InductionList &IL,
SmallPtrSetImpl<Instruction *> &InstsToIgnore) {
auto *Cmp = L->getLatchCmpInst();
if (Cmp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I just thought of something. What if there is an additional use of Cmp outside the loop? Should we also be checking that there is only a single use?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it is the only latch instruction, its value would be simplified to false when the control flow leaves the loop. So, we shouldn't worry about that

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may be right, but have you tried this out with real IR? There would be more than one use of the cmp so I wasn't sure if InstCombine would apply the fold in this case. In any case, adding an extra one use check wouldn't affect the loops you care about I think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean getLatchCmpInst ensures there is only a single user? Would be good to make sure we have a test (and maybe assert that there's a single user)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it doesn't check the number of users but checks that there's only one latch in the loop. The latch is something that makes a loop to be a loop. If there is a single latch and we don't jump to the loop header, then we are exiting the loop, and the value of the condition is constant.

See, it simplifies this condition outside away (pre LV):

https://godbolt.org/z/s9q1558zY

And if the compiler couldn't do it, we should've better taught him to do it rather than adding unnecessary checks

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually thinking about something else @igogo-x86:

define i1 @foo(ptr nocapture noundef %dst, ptr nocapture noundef readonly %src) {
entry:
  br label %for.body

for.body:
  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  %arrayidx = getelementptr inbounds nuw i32, ptr %src, i64 %indvars.iv
  %0 = load i32, ptr %arrayidx, align 4
  %arrayidx2 = getelementptr inbounds nuw i32, ptr %dst, i64 %indvars.iv
  %1 = load i32, ptr %arrayidx2, align 4
  %add = add nsw i32 %1, %0
  store i32 %add, ptr %arrayidx2, align 4
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  %exitcond.not = icmp eq i64 %indvars.iv.next, 16
  br i1 %exitcond.not, label %exit, label %for.body

exit:
  ret i1 %exitcond.not
}

This is a case where in theory the final comparison is used after the loop. That's what I was hoping you could try out. Anyway, I ran this with the following command:

opt -mcpu=neoverse-v1 -p loop-vectorize,loop-unroll -force-vector-width=4 -force-vector-interleave=1 -S -debug-only=loop-vectorize < foo.ll

and it looks like we do indeed unroll the loop and the comparison disappears. Similary we unroll this and the comparison disappears:

define i1 @foo(ptr nocapture noundef %dst, ptr nocapture noundef %p, ptr nocapture noundef readonly %src) {
entry:
  br label %for.body

for.body:
  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  %arrayidx = getelementptr inbounds nuw i32, ptr %src, i64 %indvars.iv
  %0 = load i32, ptr %arrayidx, align 4
  %arrayidx2 = getelementptr inbounds nuw i32, ptr %dst, i64 %indvars.iv
  %1 = load i32, ptr %arrayidx2, align 4
  %add = add nsw i32 %1, %0
  store i32 %add, ptr %arrayidx2, align 4
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  %exitcond.not = icmp eq i64 %indvars.iv.next, 16
  %arrayidx3 = getelementptr inbounds nuw i1, ptr %p, i64 %indvars.iv
  store i1 %exitcond.not, ptr %arrayidx3, align 4
  br i1 %exitcond.not, label %exit, label %for.body

exit:
  ret i1 false
}

In this case I'm happy that the comparison disappears, although I don't think an extra use check would have done any harm.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to add a test case ,if possible

Copy link
Contributor

@david-arm david-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Loop *L, const LoopVectorizationLegality::InductionList &IL,
SmallPtrSetImpl<Instruction *> &InstsToIgnore) {
auto *Cmp = L->getLatchCmpInst();
if (Cmp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually thinking about something else @igogo-x86:

define i1 @foo(ptr nocapture noundef %dst, ptr nocapture noundef readonly %src) {
entry:
  br label %for.body

for.body:
  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  %arrayidx = getelementptr inbounds nuw i32, ptr %src, i64 %indvars.iv
  %0 = load i32, ptr %arrayidx, align 4
  %arrayidx2 = getelementptr inbounds nuw i32, ptr %dst, i64 %indvars.iv
  %1 = load i32, ptr %arrayidx2, align 4
  %add = add nsw i32 %1, %0
  store i32 %add, ptr %arrayidx2, align 4
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  %exitcond.not = icmp eq i64 %indvars.iv.next, 16
  br i1 %exitcond.not, label %exit, label %for.body

exit:
  ret i1 %exitcond.not
}

This is a case where in theory the final comparison is used after the loop. That's what I was hoping you could try out. Anyway, I ran this with the following command:

opt -mcpu=neoverse-v1 -p loop-vectorize,loop-unroll -force-vector-width=4 -force-vector-interleave=1 -S -debug-only=loop-vectorize < foo.ll

and it looks like we do indeed unroll the loop and the comparison disappears. Similary we unroll this and the comparison disappears:

define i1 @foo(ptr nocapture noundef %dst, ptr nocapture noundef %p, ptr nocapture noundef readonly %src) {
entry:
  br label %for.body

for.body:
  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
  %arrayidx = getelementptr inbounds nuw i32, ptr %src, i64 %indvars.iv
  %0 = load i32, ptr %arrayidx, align 4
  %arrayidx2 = getelementptr inbounds nuw i32, ptr %dst, i64 %indvars.iv
  %1 = load i32, ptr %arrayidx2, align 4
  %add = add nsw i32 %1, %0
  store i32 %add, ptr %arrayidx2, align 4
  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
  %exitcond.not = icmp eq i64 %indvars.iv.next, 16
  %arrayidx3 = getelementptr inbounds nuw i1, ptr %p, i64 %indvars.iv
  store i1 %exitcond.not, ptr %arrayidx3, align 4
  br i1 %exitcond.not, label %exit, label %for.body

exit:
  ret i1 false
}

In this case I'm happy that the comparison disappears, although I don't think an extra use check would have done any harm.

@igogo-x86 igogo-x86 force-pushed the lv-ignore-some-costs-fully-unrolled branch from 86b9f1e to a380b34 Compare December 9, 2024 14:37
Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks. would be good to add @david-arm 's test case

Loop *L, const LoopVectorizationLegality::InductionList &IL,
SmallPtrSetImpl<Instruction *> &InstsToIgnore) {
auto *Cmp = L->getLatchCmpInst();
if (Cmp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to add a test case ,if possible

When VF has a fixed width and equals the number of iterations, and we are not
tail folding by masking, comparison instruction and induction operation will
be DCEed later.
Ignoring the costs of these instructions improves the cost model.
@igogo-x86 igogo-x86 force-pushed the lv-ignore-some-costs-fully-unrolled branch from a380b34 to 7417e08 Compare December 9, 2024 16:02
@igogo-x86 igogo-x86 merged commit 337936a into llvm:main Dec 9, 2024
8 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 9, 2024

LLVM Buildbot has detected a new failure on builder lldb-x86_64-debian running on lldb-x86_64-debian while building llvm at step 4 "build".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/12190

Here is the relevant piece of the build log for the reference
Step 4 (build) failure: build (failure)
...
4.321 [57/12/69] Linking CXX executable bin/llvm-debuginfo-analyzer
4.584 [57/11/70] Linking CXX shared module lib/CheckerDependencyHandlingAnalyzerPlugin.so
4.616 [57/10/71] Linking CXX executable bin/diagtool
4.634 [57/9/72] Linking CXX shared module lib/CheckerOptionHandlingAnalyzerPlugin.so
4.728 [57/8/73] Linking CXX shared module lib/SampleAnalyzerPlugin.so
5.061 [57/7/74] Linking CXX executable bin/clang-diff
5.126 [57/6/75] Linking CXX executable bin/clang-installapi
5.137 [57/5/76] Linking CXX executable bin/clang-refactor
5.139 [57/4/77] Linking CXX executable bin/arcmt-test
6.246 [57/3/78] Building CXX object lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o
FAILED: lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o 
/usr/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/worker/2.0.1/lldb-x86_64-debian/build/lib/Transforms/Vectorize -I/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/lib/Transforms/Vectorize -I/home/worker/2.0.1/lldb-x86_64-debian/build/include -I/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -std=c++17 -MD -MT lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -MF lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o.d -o lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -c /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2699:49: error: reference to local binding 'IV' declared in enclosing function 'addFullyUnrolledInstructionsToIgnore'
               [&](const User *U) { return U == IV || U == Cmp; }))
                                                ^
/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2694:21: note: 'IV' declared here
  for (const auto &[IV, IndDesc] : IL) {
                    ^
1 error generated.
11.513 [57/2/79] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
12.648 [57/1/80] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
ninja: build stopped: subcommand failed.

@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 9, 2024

LLVM Buildbot has detected a new failure on builder libc-x86_64-debian-dbg-runtimes-build running on libc-x86_64-debian while building llvm at step 4 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/78/builds/11135

Here is the relevant piece of the build log for the reference
Step 4 (annotate) failure: 'python ../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py ...' (failure)
...
Running: ninja libc
[1/38] Generating VCSRevision.h
[2/38] Generating VCSVersion.inc
[3/38] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/Version.cpp.o
[4/38] Building CXX object tools/llvm-config/CMakeFiles/llvm-config.dir/llvm-config.cpp.o
[5/38] Linking CXX executable bin/llvm-config
[6/38] Building CXX object lib/Object/CMakeFiles/LLVMObject.dir/IRSymtab.cpp.o
[7/38] Linking CXX static library lib/libLLVMObject.a
[8/38] Linking CXX static library lib/libclangBasic.a
[9/38] Building CXX object lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o
FAILED: lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o 
/usr/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/lib/Transforms/Vectorize -I/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize -I/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/include -I/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -g  -fno-exceptions -funwind-tables -fno-rtti -std=c++17 -MD -MT lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -MF lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o.d -o lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -c /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2699:49: error: reference to local binding 'IV' declared in enclosing function 'addFullyUnrolledInstructionsToIgnore'
               [&](const User *U) { return U == IV || U == Cmp; }))
                                                ^
/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2694:21: note: 'IV' declared here
  for (const auto &[IV, IndDesc] : IL) {
                    ^
1 error generated.
[10/38] Linking CXX executable bin/llvm-size
[11/38] Linking CXX executable bin/llvm-objcopy
[12/38] Linking CXX executable bin/llvm-readobj
[13/38] Linking CXX executable bin/sanstats
[14/38] Linking CXX executable bin/llvm-symbolizer
[15/38] Linking CXX executable bin/llvm-cov
[16/38] Linking CXX executable bin/llvm-xray
[17/38] Linking CXX executable bin/obj2yaml
[18/38] Linking CXX executable bin/llvm-ar
[19/38] Linking CXX executable bin/llvm-profdata
[20/38] Linking CXX executable bin/sancov
[21/38] Linking CXX executable bin/llvm-objdump
[22/38] Linking CXX executable bin/llvm-nm
[23/38] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
[24/38] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
ninja: build stopped: subcommand failed.
['ninja', 'libc'] exited with return code 1.
The build step threw an exception...
Traceback (most recent call last):
  File "/home/llvm-libc-buildbot/home/sivachandra/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py", line 160, in step
    yield
  File "/home/llvm-libc-buildbot/home/sivachandra/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py", line 124, in main
    run_command(['ninja', 'libc'])
  File "/home/llvm-libc-buildbot/home/sivachandra/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py", line 175, in run_command
    util.report_run_cmd(cmd, cwd=directory)
  File "/home/llvm-libc-buildbot/home/sivachandra/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-zorg/zorg/buildbot/builders/annotated/util.py", line 49, in report_run_cmd
    subprocess.check_call(cmd, shell=shell, *args, **kwargs)
  File "/usr/lib/python3.11/subprocess.py", line 413, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['ninja', 'libc']' returned non-zero exit status 1.
Step 6 (build libc) failure: build libc (failure)
...
Running: ninja libc
[1/38] Generating VCSRevision.h
[2/38] Generating VCSVersion.inc
[3/38] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/Version.cpp.o
[4/38] Building CXX object tools/llvm-config/CMakeFiles/llvm-config.dir/llvm-config.cpp.o
[5/38] Linking CXX executable bin/llvm-config
[6/38] Building CXX object lib/Object/CMakeFiles/LLVMObject.dir/IRSymtab.cpp.o
[7/38] Linking CXX static library lib/libLLVMObject.a
[8/38] Linking CXX static library lib/libclangBasic.a
[9/38] Building CXX object lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o
FAILED: lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o 
/usr/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/lib/Transforms/Vectorize -I/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize -I/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/include -I/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -g  -fno-exceptions -funwind-tables -fno-rtti -std=c++17 -MD -MT lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -MF lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o.d -o lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -c /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2699:49: error: reference to local binding 'IV' declared in enclosing function 'addFullyUnrolledInstructionsToIgnore'
               [&](const User *U) { return U == IV || U == Cmp; }))
                                                ^
/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2694:21: note: 'IV' declared here
  for (const auto &[IV, IndDesc] : IL) {
                    ^
1 error generated.
[10/38] Linking CXX executable bin/llvm-size
[11/38] Linking CXX executable bin/llvm-objcopy
[12/38] Linking CXX executable bin/llvm-readobj
[13/38] Linking CXX executable bin/sanstats
[14/38] Linking CXX executable bin/llvm-symbolizer
[15/38] Linking CXX executable bin/llvm-cov
[16/38] Linking CXX executable bin/llvm-xray
[17/38] Linking CXX executable bin/obj2yaml
[18/38] Linking CXX executable bin/llvm-ar
[19/38] Linking CXX executable bin/llvm-profdata
[20/38] Linking CXX executable bin/sancov
[21/38] Linking CXX executable bin/llvm-objdump
[22/38] Linking CXX executable bin/llvm-nm
[23/38] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
[24/38] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
ninja: build stopped: subcommand failed.
['ninja', 'libc'] exited with return code 1.
The build step threw an exception...
Traceback (most recent call last):
  File "/home/llvm-libc-buildbot/home/sivachandra/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py", line 160, in step
    yield
  File "/home/llvm-libc-buildbot/home/sivachandra/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py", line 124, in main
    run_command(['ninja', 'libc'])
  File "/home/llvm-libc-buildbot/home/sivachandra/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/build/../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py", line 175, in run_command
    util.report_run_cmd(cmd, cwd=directory)
  File "/home/llvm-libc-buildbot/home/sivachandra/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-zorg/zorg/buildbot/builders/annotated/util.py", line 49, in report_run_cmd
    subprocess.check_call(cmd, shell=shell, *args, **kwargs)
  File "/usr/lib/python3.11/subprocess.py", line 413, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['ninja', 'libc']' returned non-zero exit status 1.

@kazutakahirata
Copy link
Contributor

I've fixed a warning from this PR with: 9099d69

@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 9, 2024

LLVM Buildbot has detected a new failure on builder mlir-nvidia running on mlir-nvidia while building llvm at step 6 "build-check-mlir-build-only".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/138/builds/7515

Here is the relevant piece of the build log for the reference
Step 6 (build-check-mlir-build-only) failure: build (failure)
...
23.343 [439/10/4581] Building CXX object tools/llc/CMakeFiles/llc.dir/llc.cpp.o
23.348 [439/9/4582] Building CXX object tools/mlir/examples/toy/Ch7/CMakeFiles/toyc-ch7.dir/mlir/LowerToLLVM.cpp.o
23.356 [439/8/4583] Building CXX object tools/llc/CMakeFiles/llc.dir/NewPMDriver.cpp.o
23.357 [439/7/4584] Building CXX object tools/lli/CMakeFiles/lli.dir/lli.cpp.o
23.373 [439/6/4585] Linking CXX shared library lib/libLLVMX86Disassembler.so.20.0git
23.380 [438/6/4586] Creating library symlink lib/libLLVMX86Disassembler.so
23.382 [438/5/4587] Building CXX object tools/mlir/examples/toy/Ch7/CMakeFiles/toyc-ch7.dir/toyc.cpp.o
23.440 [438/4/4588] Linking CXX shared library lib/libLLVMX86Desc.so.20.0git
23.447 [437/4/4589] Creating library symlink lib/libLLVMX86Desc.so
23.934 [437/3/4590] Building CXX object lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o
FAILED: lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o 
CCACHE_CPP2=yes CCACHE_HASHDIR=yes /usr/bin/ccache /usr/bin/clang++ -DGTEST_HAS_RTTI=0 -DLLVM_EXPORTS -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/vol/worker/mlir-nvidia/mlir-nvidia/llvm.obj/lib/Transforms/Vectorize -I/vol/worker/mlir-nvidia/mlir-nvidia/llvm.src/llvm/lib/Transforms/Vectorize -I/vol/worker/mlir-nvidia/mlir-nvidia/llvm.obj/include -I/vol/worker/mlir-nvidia/mlir-nvidia/llvm.src/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -fPIC  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -std=c++17 -MD -MT lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -MF lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o.d -o lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -c /vol/worker/mlir-nvidia/mlir-nvidia/llvm.src/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
/vol/worker/mlir-nvidia/mlir-nvidia/llvm.src/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2699:49: error: reference to local binding 'IV' declared in enclosing function 'addFullyUnrolledInstructionsToIgnore'
               [&](const User *U) { return U == IV || U == Cmp; }))
                                                ^
/vol/worker/mlir-nvidia/mlir-nvidia/llvm.src/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2694:21: note: 'IV' declared here
  for (const auto &[IV, IndDesc] : IL) {
                    ^
1 error generated.
24.067 [437/2/4591] Building CXX object lib/MC/MCParser/CMakeFiles/LLVMMCParser.dir/AsmParser.cpp.o
30.282 [437/1/4592] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
ninja: build stopped: subcommand failed.

Instruction *IVInst =
cast<Instruction>(IV->getIncomingValueForBlock(L->getLoopLatch()));
if (all_of(IVInst->users(),
[&](const User *U) { return U == IV || U == Cmp; }))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://lab.llvm.org/buildbot/#/builders/78/builds/11135:

/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2699:49: error: reference to local binding 'IV' declared in enclosing function 'addFullyUnrolledInstructionsToIgnore'
               [&](const User *U) { return U == IV || U == Cmp; }))
                                                ^
/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian/libc-x86_64-debian-dbg-runtimes-build/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2694:21: note: 'IV' declared here
  for (const auto &[IV, IndDesc] : IL) {
                    ^

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@kazutakahirata kazutakahirata Dec 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've fixed the warning with: 9099d69

@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 9, 2024

LLVM Buildbot has detected a new failure on builder clang-x86_64-debian-fast running on gribozavr4 while building llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/56/builds/14076

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
17.214 [881/51/5129] Copying llvm_bitwriter.mli to build area
17.214 [881/50/5130] Copying bitwriter_ocaml.c to build area
17.218 [880/50/5131] Linking CXX static library lib/libLLVMExecutionEngine.a
17.220 [879/50/5132] Linking CXX static library lib/libLLVMCGData.a
17.222 [879/49/5133] Linking CXX static library lib/libLLVMSandboxIR.a
17.223 [879/48/5134] Linking CXX static library lib/libLLVMMCJIT.a
17.262 [879/47/5135] Building OCaml stub object file analysis_ocaml.o
17.263 [878/47/5136] Linking CXX static library lib/libLLVMTransformUtils.a
17.265 [868/56/5137] Building OCaml stub object file bitwriter_ocaml.o
17.267 [867/56/5138] Building CXX object lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o
FAILED: lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o 
CCACHE_CPP2=yes CCACHE_HASHDIR=yes /usr/bin/ccache /usr/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/1/clang-x86_64-debian-fast/llvm.obj/lib/Transforms/Vectorize -I/b/1/clang-x86_64-debian-fast/llvm.src/llvm/lib/Transforms/Vectorize -I/b/1/clang-x86_64-debian-fast/llvm.obj/include -I/b/1/clang-x86_64-debian-fast/llvm.src/llvm/include -std=c++11 -Wdocumentation -Wno-documentation-deprecated-sync -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -std=c++17 -MD -MT lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -MF lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o.d -o lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -c /b/1/clang-x86_64-debian-fast/llvm.src/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
In file included from /b/1/clang-x86_64-debian-fast/llvm.src/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:117:
/b/1/clang-x86_64-debian-fast/llvm.src/llvm/include/llvm/IR/MDBuilder.h:64:14: warning: parameter 'Do' not found in the function declaration [-Wdocumentation]
  /// @param Do these weights come from __builtin_expect*
             ^~
/b/1/clang-x86_64-debian-fast/llvm.src/llvm/include/llvm/IR/MDBuilder.h:64:14: note: did you mean 'IsExpected'?
  /// @param Do these weights come from __builtin_expect*
             ^~
             IsExpected
/b/1/clang-x86_64-debian-fast/llvm.src/llvm/include/llvm/IR/MDBuilder.h:78:14: warning: parameter 'Do' not found in the function declaration [-Wdocumentation]
  /// @param Do these weights come from __builtin_expect*
             ^~
/b/1/clang-x86_64-debian-fast/llvm.src/llvm/include/llvm/IR/MDBuilder.h:78:14: note: did you mean 'IsExpected'?
  /// @param Do these weights come from __builtin_expect*
             ^~
             IsExpected
/b/1/clang-x86_64-debian-fast/llvm.src/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2699:49: error: reference to local binding 'IV' declared in enclosing function 'addFullyUnrolledInstructionsToIgnore'
               [&](const User *U) { return U == IV || U == Cmp; }))
                                                ^
/b/1/clang-x86_64-debian-fast/llvm.src/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2694:21: note: 'IV' declared here
  for (const auto &[IV, IndDesc] : IL) {
                    ^
2 warnings and 1 error generated.
17.267 [867/55/5139] Copying llvm_transform_utils.ml to build area
17.267 [867/54/5140] Copying llvm_transform_utils.mli to build area
17.267 [867/53/5141] Copying transform_utils_ocaml.c to build area
17.269 [867/52/5142] Linking CXX static library lib/libLLVMFrontendOffloading.a
17.270 [867/51/5143] Linking CXX static library lib/libLLVMAggressiveInstCombine.a
17.270 [867/50/5144] Linking CXX static library lib/libLLVMHipStdPar.a
17.272 [867/49/5145] Linking CXX static library lib/libLLVMLinker.a
17.274 [867/48/5146] Linking CXX static library lib/libLLVMObjCARCOpts.a
17.278 [867/47/5147] Linking CXX executable bin/llvm-size
17.280 [867/46/5148] Linking CXX executable bin/llvm-debuginfod-find
17.289 [867/45/5149] Linking CXX static library lib/libLLVMInstCombine.a
17.292 [867/44/5150] Linking CXX static library lib/libLLVMInstrumentation.a
17.305 [867/43/5151] Building OCaml library llvm_analysis
17.312 [867/42/5152] Building OCaml library llvm_bitwriter
17.320 [867/41/5153] Building OCaml stub object file target_ocaml.o

@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 9, 2024

LLVM Buildbot has detected a new failure on builder llvm-x86_64-debian-dylib running on gribozavr4 while building llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/60/builds/14747

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
18.877 [2660/29/4365] Building CXX object lib/Target/X86/MCTargetDesc/CMakeFiles/LLVMX86Desc.dir/X86WinCOFFStreamer.cpp.o
18.877 [2660/28/4366] Building CXX object lib/Target/X86/MCTargetDesc/CMakeFiles/LLVMX86Desc.dir/X86WinCOFFTargetStreamer.cpp.o
18.877 [2660/27/4367] Linking CXX static library lib/libLLVMX86Info.a
18.878 [2659/27/4368] Building CXX object lib/Target/X86/AsmParser/CMakeFiles/LLVMX86AsmParser.dir/X86AsmParser.cpp.o
18.878 [2659/26/4369] Building CXX object lib/Target/X86/MCTargetDesc/CMakeFiles/LLVMX86Desc.dir/X86AsmBackend.cpp.o
18.878 [2659/25/4370] Building CXX object lib/Target/X86/MCTargetDesc/CMakeFiles/LLVMX86Desc.dir/X86MCTargetDesc.cpp.o
18.879 [2658/25/4371] Building CXX object tools/llvm-exegesis/lib/X86/CMakeFiles/LLVMExegesisX86.dir/Target.cpp.o
18.889 [2658/24/4372] Linking CXX static library lib/libLLVMX86Disassembler.a
18.898 [2658/23/4373] Linking CXX static library lib/libLLVMX86Desc.a
18.936 [2658/22/4374] Building CXX object lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o
FAILED: lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o 
CCACHE_CPP2=yes CCACHE_HASHDIR=yes /usr/bin/ccache /usr/bin/clang++ -DGTEST_HAS_RTTI=0 -DLLVM_EXPORTS -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/1/llvm-x86_64-debian-dylib/build/lib/Transforms/Vectorize -I/b/1/llvm-x86_64-debian-dylib/llvm-project/llvm/lib/Transforms/Vectorize -I/b/1/llvm-x86_64-debian-dylib/build/include -I/b/1/llvm-x86_64-debian-dylib/llvm-project/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -std=c++17 -MD -MT lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -MF lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o.d -o lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -c /b/1/llvm-x86_64-debian-dylib/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
/b/1/llvm-x86_64-debian-dylib/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2699:49: error: reference to local binding 'IV' declared in enclosing function 'addFullyUnrolledInstructionsToIgnore'
               [&](const User *U) { return U == IV || U == Cmp; }))
                                                ^
/b/1/llvm-x86_64-debian-dylib/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2694:21: note: 'IV' declared here
  for (const auto &[IV, IndDesc] : IL) {
                    ^
1 error generated.
19.128 [2658/21/4375] Building CXX object lib/MC/MCParser/CMakeFiles/LLVMMCParser.dir/AsmParser.cpp.o
19.305 [2658/20/4376] Building AMDGPUGenCallingConv.inc...
19.628 [2658/19/4377] Building RISCVGenGlobalISel.inc...
19.758 [2658/18/4378] Building AMDGPUGenRegBankGICombiner.inc...
20.367 [2658/17/4379] Building AMDGPUGenPreLegalizeGICombiner.inc...
20.594 [2658/16/4380] Building AMDGPUGenPostLegalizeGICombiner.inc...
20.687 [2658/15/4381] Building AMDGPUGenDisassemblerTables.inc...
20.805 [2658/14/4382] Building AMDGPUGenSubtargetInfo.inc...
20.845 [2658/13/4383] Building RISCVGenDAGISel.inc...
21.192 [2658/12/4384] Building AMDGPUGenMCCodeEmitter.inc...
21.649 [2658/11/4385] Building AMDGPUGenSearchableTables.inc...
24.600 [2658/10/4386] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
25.787 [2658/9/4387] Building RISCVGenSubtargetInfo.inc...
26.724 [2658/8/4388] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
28.117 [2658/7/4389] Building AMDGPUGenAsmWriter.inc...
28.801 [2658/6/4390] Building AMDGPUGenGlobalISel.inc...
29.873 [2658/5/4391] Building AMDGPUGenDAGISel.inc...
29.995 [2658/4/4392] Building AMDGPUGenAsmMatcher.inc...
31.224 [2658/3/4393] Building AMDGPUGenInstrInfo.inc...
33.390 [2658/2/4394] Building AMDGPUGenRegisterInfo.inc...
33.637 [2658/1/4395] Building AMDGPUGenRegisterBank.inc...
ninja: build stopped: subcommand failed.

@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 9, 2024

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-expensive-checks-debian running on gribozavr4 while building llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/16/builds/10362

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
18.434 [906/26/3076] Building OCaml library llvm_debuginfo
18.600 [905/26/3077] Building OCaml documentation for llvm_debuginfo
18.609 [904/26/3078] Running utility command for ocaml_llvm_debuginfo
19.367 [904/25/3079] Building AMDGPUGenCallingConv.inc...
19.561 [904/24/3080] Building AMDGPUGenMCPseudoLowering.inc...
19.659 [904/23/3081] Building X86GenInstrInfo.inc...
19.724 [904/22/3082] Building RISCVGenGlobalISel.inc...
21.087 [904/21/3083] Building AMDGPUGenRegBankGICombiner.inc...
21.523 [904/20/3084] Building AMDGPUGenPostLegalizeGICombiner.inc...
21.539 [904/19/3085] Building CXX object lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o
FAILED: lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o 
CCACHE_CPP2=yes CCACHE_HASHDIR=yes /usr/bin/ccache /usr/bin/clang++ -DEXPENSIVE_CHECKS -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/1/llvm-clang-x86_64-expensive-checks-debian/build/lib/Transforms/Vectorize -I/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/lib/Transforms/Vectorize -I/b/1/llvm-clang-x86_64-expensive-checks-debian/build/include -I/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/include -U_GLIBCXX_DEBUG -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -std=c++17 -MD -MT lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -MF lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o.d -o lib/Transforms/Vectorize/CMakeFiles/LLVMVectorize.dir/LoopVectorize.cpp.o -c /b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2699:49: error: reference to local binding 'IV' declared in enclosing function 'addFullyUnrolledInstructionsToIgnore'
               [&](const User *U) { return U == IV || U == Cmp; }))
                                                ^
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:2694:21: note: 'IV' declared here
  for (const auto &[IV, IndDesc] : IL) {
                    ^
1 error generated.
21.667 [904/18/3086] Building AMDGPUGenPreLegalizeGICombiner.inc...
21.887 [904/17/3087] Building AMDGPUGenSubtargetInfo.inc...
22.166 [904/16/3088] Building AMDGPUGenDisassemblerTables.inc...
22.183 [904/15/3089] Building RISCVGenDAGISel.inc...
22.186 [904/14/3090] Building AMDGPUGenMCCodeEmitter.inc...
22.389 [904/13/3091] Building CXX object lib/MC/MCParser/CMakeFiles/LLVMMCParser.dir/AsmParser.cpp.o
22.558 [904/12/3092] Building AMDGPUGenSearchableTables.inc...
27.455 [904/11/3093] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
28.295 [904/10/3094] Building RISCVGenSubtargetInfo.inc...
30.030 [904/9/3095] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
30.987 [904/8/3096] Building X86GenAsmMatcher.inc...
31.586 [904/7/3097] Building AMDGPUGenAsmWriter.inc...
32.236 [904/6/3098] Building AMDGPUGenGlobalISel.inc...
32.801 [904/5/3099] Building AMDGPUGenDAGISel.inc...
33.840 [904/4/3100] Building AMDGPUGenInstrInfo.inc...
35.848 [904/3/3101] Building AMDGPUGenRegisterBank.inc...
38.333 [904/2/3102] Building AMDGPUGenRegisterInfo.inc...
45.085 [904/1/3103] Building AMDGPUGenAsmMatcher.inc...
ninja: build stopped: subcommand failed.

broxigarchen pushed a commit to broxigarchen/llvm-project that referenced this pull request Dec 10, 2024
When VF has a fixed width and equals the number of iterations, and we are not
tail folding by masking, comparison instruction and induction operation will be DCEed later.
Ignoring the costs of these instructions improves the cost model.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants