[llvm] [LoopVectorize] Fix nondeterminism in loop-vectorize (PR #200833)
Orlando Cazalet-Hyams via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 02:59:21 PDT 2026
https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/200833
>From 9f1e24769b41b03c9f7016be30848aae1c82c463 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Mon, 1 Jun 2026 14:43:28 +0100
Subject: [PATCH 1/6] [LoopVectorize] Fix nondeterminism in loop-vectorizer
The nondeterministic iteration over AddrDefs (SmallPtrSet) causes
nondeterministic output for the test case in this patch (reduced from a C
codebase). One of two different outputs is generated arbitrarily, chosen roughly
equally.
Between the two different outputs sometimes the instruction
`%3 = load i64, ptr %2, align 8`
has an associated cost of 4 and othertimes 9. The instruction is visited twice
in `setCostBasedWideningDecision` in the `AddrDefs` loop: once directly as an
elemement of `AddrDefs`, and the other time indirectly in the lambda
`UpdateMemOpUserCost` as a User of another `AddrDefs` element. Each of those
times `setWideningDecision` is called with a different cost value; the final of
the two calls sets the final value (previous is overwritten). Because `AddrDefs`
iteration is nondeterministic, the order of those two calls to
`setWideningDecision` is also nondeterministic, hence we see two different costs
arbitrarily between runs.
This patch fixes the nondeterministic iteration order. The fact that two costs
for the same instruction are arbitrarily chosen between may (or may not) be a
deeper issue worth addressing, but that falls outside my expertise.
Some additional info:
We observe the issue reproducing (frequently) in llvm-22 but not llvm-21.
With the test case in this patch we observe the nondeterminism frequently
reproduces (< 3 tries) from 1f331e453fa9c328c165c739f61e17a2815ece82 building on
and targeting x86_64 linux. Before that we haven't observed the nondeterminism
(> 500 tries), but can't rule out that it may be observed with different inputs
based on the fact the SmallPtrSet has been in use since 2017. N.B. Building on
Windows bisects to a different commit.
---
.../Transforms/Vectorize/LoopVectorize.cpp | 4 +-
.../nondetermisitic-widening-cost.ll | 128 ++++++++++++++++++
2 files changed, 130 insertions(+), 2 deletions(-)
create mode 100644 llvm/lib/Transforms/Vectorize/nondetermisitic-widening-cost.ll
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 30456819602b2..d27973eb003b8 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -4831,7 +4831,7 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
return;
// Start with all scalar pointer uses.
- SmallPtrSet<Instruction *, 8> AddrDefs;
+ SmallSetVector<Instruction *, 8> AddrDefs;
for (BasicBlock *BB : TheLoop->blocks())
for (Instruction &I : *BB) {
Instruction *PtrDef =
@@ -4849,7 +4849,7 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
for (auto &Op : I->operands())
if (auto *InstOp = dyn_cast<Instruction>(Op))
if (TheLoop->contains(InstOp) && !isa<PHINode>(InstOp) &&
- AddrDefs.insert(InstOp).second)
+ AddrDefs.insert(InstOp))
Worklist.push_back(InstOp);
}
diff --git a/llvm/lib/Transforms/Vectorize/nondetermisitic-widening-cost.ll b/llvm/lib/Transforms/Vectorize/nondetermisitic-widening-cost.ll
new file mode 100644
index 0000000000000..938f177c37854
--- /dev/null
+++ b/llvm/lib/Transforms/Vectorize/nondetermisitic-widening-cost.ll
@@ -0,0 +1,128 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt --passes=loop-vectorize %s -S | FileCheck %s
+
+; Check that we see expected deterministic (over multiple test runs) output.
+; NOTE: Beware, if this test fails it may be due to non-determinism.
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux"
+
+define i32 @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
+; CHECK-LABEL: define i32 @fun(
+; CHECK-SAME: i64 [[TMP0:%.*]], float [[TMP1:%.*]], ptr [[A:%.*]], ptr [[B:%.*]], i64 [[LEN:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[VLA:%.*]] = alloca float, i64 [[LEN]], align 16
+; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP0]], 1
+; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 4
+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_MEMCHECK:.*]]
+; CHECK: [[VECTOR_MEMCHECK]]:
+; CHECK-NEXT: [[TMP3:%.*]] = shl i64 [[TMP0]], 2
+; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP3]], 16
+; CHECK-NEXT: br i1 [[DIFF_CHECK]], label %[[SCALAR_PH]], label %[[VECTOR_PH:.*]]
+; CHECK: [[VECTOR_PH]]:
+; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 4
+; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[TMP0]]
+; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[TMP1]], i64 0
+; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer
+; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
+; CHECK: [[VECTOR_BODY]]:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[INDEX]], 0
+; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 1
+; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[INDEX]], 2
+; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDEX]], 3
+; CHECK-NEXT: [[TMP9:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP5]]
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP6]]
+; CHECK-NEXT: [[TMP11:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP7]]
+; CHECK-NEXT: [[TMP12:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP8]]
+; CHECK-NEXT: [[TMP13:%.*]] = load ptr, ptr [[TMP9]], align 8
+; CHECK-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP10]], align 8
+; CHECK-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP11]], align 8
+; CHECK-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP12]], align 8
+; CHECK-NEXT: [[TMP17:%.*]] = load i64, ptr [[TMP13]], align 8
+; CHECK-NEXT: [[TMP18:%.*]] = load i64, ptr [[TMP14]], align 8
+; CHECK-NEXT: [[TMP19:%.*]] = load i64, ptr [[TMP15]], align 8
+; CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr [[TMP16]], align 8
+; CHECK-NEXT: [[TMP21:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP17]]
+; CHECK-NEXT: [[TMP22:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP18]]
+; CHECK-NEXT: [[TMP23:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP19]]
+; CHECK-NEXT: [[TMP24:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP20]]
+; CHECK-NEXT: [[TMP25:%.*]] = load float, ptr [[TMP21]], align 4
+; CHECK-NEXT: [[TMP26:%.*]] = load float, ptr [[TMP22]], align 4
+; CHECK-NEXT: [[TMP27:%.*]] = load float, ptr [[TMP23]], align 4
+; CHECK-NEXT: [[TMP28:%.*]] = load float, ptr [[TMP24]], align 4
+; CHECK-NEXT: [[TMP29:%.*]] = insertelement <4 x float> poison, float [[TMP25]], i32 0
+; CHECK-NEXT: [[TMP30:%.*]] = insertelement <4 x float> [[TMP29]], float [[TMP26]], i32 1
+; CHECK-NEXT: [[TMP31:%.*]] = insertelement <4 x float> [[TMP30]], float [[TMP27]], i32 2
+; CHECK-NEXT: [[TMP32:%.*]] = insertelement <4 x float> [[TMP31]], float [[TMP28]], i32 3
+; CHECK-NEXT: [[TMP33:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[TMP5]]
+; CHECK-NEXT: [[TMP34:%.*]] = getelementptr float, ptr [[TMP33]], i32 0
+; CHECK-NEXT: store <4 x float> [[TMP32]], ptr [[TMP34]], align 4
+; CHECK-NEXT: [[TMP35:%.*]] = getelementptr [4 x i8], ptr [[TMP4]], i64 [[TMP5]]
+; CHECK-NEXT: [[TMP36:%.*]] = getelementptr float, ptr [[TMP35]], i32 0
+; CHECK-NEXT: store <4 x float> [[BROADCAST_SPLAT]], ptr [[TMP36]], align 4
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; CHECK-NEXT: [[TMP37:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP37]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK: [[MIDDLE_BLOCK]]:
+; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[CMP_N]], label %[[FOR_END_LOOPEXIT:.*]], label %[[SCALAR_PH]]
+; CHECK: [[SCALAR_PH]]:
+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ], [ 0, %[[VECTOR_MEMCHECK]] ]
+; CHECK-NEXT: br label %[[FOR_BODY:.*]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY]] ]
+; CHECK-NEXT: [[ARRAYIDX16:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: [[TMP38:%.*]] = load ptr, ptr [[ARRAYIDX16]], align 8
+; CHECK-NEXT: [[TMP39:%.*]] = load i64, ptr [[TMP38]], align 8
+; CHECK-NEXT: [[ARRAYIDX18:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP39]]
+; CHECK-NEXT: [[TMP40:%.*]] = load float, ptr [[ARRAYIDX18]], align 4
+; CHECK-NEXT: [[ARRAYIDX21:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store float [[TMP40]], ptr [[ARRAYIDX21]], align 4
+; CHECK-NEXT: [[TMP41:%.*]] = load i64, ptr [[B]], align 8
+; CHECK-NEXT: [[ARRAYIDX27:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP41]]
+; CHECK-NEXT: [[TMP42:%.*]] = load float, ptr [[ARRAYIDX27]], align 4
+; CHECK-NEXT: [[ARRAYIDX28:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[TMP0]]
+; CHECK-NEXT: [[ARRAYIDX30:%.*]] = getelementptr [4 x i8], ptr [[ARRAYIDX28]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store float [[TMP1]], ptr [[ARRAYIDX30]], align 4
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV]], [[TMP0]]
+; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_END_LOOPEXIT]], label %[[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
+; CHECK: [[FOR_END_LOOPEXIT]]:
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ %vla = alloca float, i64 %len, align 16
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx16 = getelementptr [8 x i8], ptr %a, i64 %indvars.iv
+ %2 = load ptr, ptr %arrayidx16, align 8
+ %3 = load i64, ptr %2, align 8
+ %arrayidx18 = getelementptr [4 x i8], ptr %a, i64 %3
+ %4 = load float, ptr %arrayidx18, align 4
+ %arrayidx21 = getelementptr [4 x i8], ptr %vla, i64 %indvars.iv
+ store float %4, ptr %arrayidx21, align 4
+ %5 = load i64, ptr %b, align 8
+ %arrayidx27 = getelementptr [4 x i8], ptr %a, i64 %5
+ %6 = load float, ptr %arrayidx27, align 4
+ %arrayidx28 = getelementptr [4 x i8], ptr %vla, i64 %0
+ %arrayidx30 = getelementptr [4 x i8], ptr %arrayidx28, i64 %indvars.iv
+ store float %1, ptr %arrayidx30, align 4
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv, %0
+ br i1 %exitcond.not, label %for.end.loopexit, label %for.body
+
+for.end.loopexit: ; preds = %for.body
+ ret i32 0
+}
+
+attributes #0 = { "target-features"="+avx2" }
+;.
+; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
+; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
+; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
+; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]]}
+;.
>From ecafe93ef283c4fe44679b6c457ea0356742c068 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Mon, 1 Jun 2026 16:36:40 +0100
Subject: [PATCH 2/6] address IR renaming comments
---
.../X86}/nondetermisitic-widening-cost.ll | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
rename llvm/{lib/Transforms/Vectorize => test/Transforms/LoopVectorize/X86}/nondetermisitic-widening-cost.ll (92%)
diff --git a/llvm/lib/Transforms/Vectorize/nondetermisitic-widening-cost.ll b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
similarity index 92%
rename from llvm/lib/Transforms/Vectorize/nondetermisitic-widening-cost.ll
rename to llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
index 938f177c37854..0f47a580bce69 100644
--- a/llvm/lib/Transforms/Vectorize/nondetermisitic-widening-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
@@ -94,28 +94,28 @@ define i32 @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
;
entry:
%vla = alloca float, i64 %len, align 16
- br label %for.body
+ br label %loop
-for.body: ; preds = %for.body, %entry
- %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
- %arrayidx16 = getelementptr [8 x i8], ptr %a, i64 %indvars.iv
+loop: ; preds = %loop, %entry
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %arrayidx16 = getelementptr [8 x i8], ptr %a, i64 %iv
%2 = load ptr, ptr %arrayidx16, align 8
%3 = load i64, ptr %2, align 8
%arrayidx18 = getelementptr [4 x i8], ptr %a, i64 %3
%4 = load float, ptr %arrayidx18, align 4
- %arrayidx21 = getelementptr [4 x i8], ptr %vla, i64 %indvars.iv
+ %arrayidx21 = getelementptr [4 x i8], ptr %vla, i64 %iv
store float %4, ptr %arrayidx21, align 4
%5 = load i64, ptr %b, align 8
%arrayidx27 = getelementptr [4 x i8], ptr %a, i64 %5
%6 = load float, ptr %arrayidx27, align 4
%arrayidx28 = getelementptr [4 x i8], ptr %vla, i64 %0
- %arrayidx30 = getelementptr [4 x i8], ptr %arrayidx28, i64 %indvars.iv
+ %arrayidx30 = getelementptr [4 x i8], ptr %arrayidx28, i64 %iv
store float %1, ptr %arrayidx30, align 4
- %indvars.iv.next = add i64 %indvars.iv, 1
- %exitcond.not = icmp eq i64 %indvars.iv, %0
- br i1 %exitcond.not, label %for.end.loopexit, label %for.body
+ %iv.next = add i64 %iv, 1
+ %exitcond.not = icmp eq i64 %iv, %0
+ br i1 %exitcond.not, label %for.end.loopexit, label %loop
-for.end.loopexit: ; preds = %for.body
+for.end.loopexit: ; preds = %loop
ret i32 0
}
>From 3a1c8ff419519551e0fb77eda7381b7b71f1fbd4 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Mon, 1 Jun 2026 16:37:09 +0100
Subject: [PATCH 3/6] use correct version of opt in update_test_checks...
---
.../X86/nondetermisitic-widening-cost.ll | 49 +++++++++++++++----
1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
index 0f47a580bce69..d59664fca62e6 100644
--- a/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
@@ -13,14 +13,14 @@ define i32 @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[VLA:%.*]] = alloca float, i64 [[LEN]], align 16
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP0]], 1
-; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 4
+; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 8
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_MEMCHECK:.*]]
; CHECK: [[VECTOR_MEMCHECK]]:
; CHECK-NEXT: [[TMP3:%.*]] = shl i64 [[TMP0]], 2
-; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP3]], 16
+; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP3]], 32
; CHECK-NEXT: br i1 [[DIFF_CHECK]], label %[[SCALAR_PH]], label %[[VECTOR_PH:.*]]
; CHECK: [[VECTOR_PH]]:
-; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 4
+; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 8
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[TMP0]]
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[TMP1]], i64 0
@@ -28,26 +28,45 @@ define i32 @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
; CHECK: [[VECTOR_BODY]]:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
-; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[INDEX]], 0
; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 1
; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[INDEX]], 2
; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDEX]], 3
-; CHECK-NEXT: [[TMP9:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP5]]
+; CHECK-NEXT: [[TMP44:%.*]] = add i64 [[INDEX]], 4
+; CHECK-NEXT: [[TMP45:%.*]] = add i64 [[INDEX]], 5
+; CHECK-NEXT: [[TMP46:%.*]] = add i64 [[INDEX]], 6
+; CHECK-NEXT: [[TMP47:%.*]] = add i64 [[INDEX]], 7
+; CHECK-NEXT: [[TMP9:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[INDEX]]
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP6]]
; CHECK-NEXT: [[TMP11:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP7]]
; CHECK-NEXT: [[TMP12:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP8]]
+; CHECK-NEXT: [[TMP48:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP44]]
+; CHECK-NEXT: [[TMP49:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP45]]
+; CHECK-NEXT: [[TMP50:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP46]]
+; CHECK-NEXT: [[TMP51:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP47]]
; CHECK-NEXT: [[TMP13:%.*]] = load ptr, ptr [[TMP9]], align 8
; CHECK-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP10]], align 8
; CHECK-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP11]], align 8
; CHECK-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP12]], align 8
+; CHECK-NEXT: [[TMP60:%.*]] = load ptr, ptr [[TMP48]], align 8
+; CHECK-NEXT: [[TMP62:%.*]] = load ptr, ptr [[TMP49]], align 8
+; CHECK-NEXT: [[TMP64:%.*]] = load ptr, ptr [[TMP50]], align 8
+; CHECK-NEXT: [[TMP65:%.*]] = load ptr, ptr [[TMP51]], align 8
; CHECK-NEXT: [[TMP17:%.*]] = load i64, ptr [[TMP13]], align 8
; CHECK-NEXT: [[TMP18:%.*]] = load i64, ptr [[TMP14]], align 8
; CHECK-NEXT: [[TMP19:%.*]] = load i64, ptr [[TMP15]], align 8
; CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr [[TMP16]], align 8
+; CHECK-NEXT: [[TMP66:%.*]] = load i64, ptr [[TMP60]], align 8
+; CHECK-NEXT: [[TMP33:%.*]] = load i64, ptr [[TMP62]], align 8
+; CHECK-NEXT: [[TMP67:%.*]] = load i64, ptr [[TMP64]], align 8
+; CHECK-NEXT: [[TMP35:%.*]] = load i64, ptr [[TMP65]], align 8
; CHECK-NEXT: [[TMP21:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP17]]
; CHECK-NEXT: [[TMP22:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP18]]
; CHECK-NEXT: [[TMP23:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP19]]
; CHECK-NEXT: [[TMP24:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP20]]
+; CHECK-NEXT: [[TMP68:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP66]]
+; CHECK-NEXT: [[TMP69:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP33]]
+; CHECK-NEXT: [[TMP70:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP67]]
+; CHECK-NEXT: [[TMP43:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP35]]
; CHECK-NEXT: [[TMP25:%.*]] = load float, ptr [[TMP21]], align 4
; CHECK-NEXT: [[TMP26:%.*]] = load float, ptr [[TMP22]], align 4
; CHECK-NEXT: [[TMP27:%.*]] = load float, ptr [[TMP23]], align 4
@@ -56,13 +75,23 @@ define i32 @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
; CHECK-NEXT: [[TMP30:%.*]] = insertelement <4 x float> [[TMP29]], float [[TMP26]], i32 1
; CHECK-NEXT: [[TMP31:%.*]] = insertelement <4 x float> [[TMP30]], float [[TMP27]], i32 2
; CHECK-NEXT: [[TMP32:%.*]] = insertelement <4 x float> [[TMP31]], float [[TMP28]], i32 3
-; CHECK-NEXT: [[TMP33:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[TMP5]]
-; CHECK-NEXT: [[TMP34:%.*]] = getelementptr float, ptr [[TMP33]], i32 0
+; CHECK-NEXT: [[TMP52:%.*]] = load float, ptr [[TMP68]], align 4
+; CHECK-NEXT: [[TMP53:%.*]] = load float, ptr [[TMP69]], align 4
+; CHECK-NEXT: [[TMP54:%.*]] = load float, ptr [[TMP70]], align 4
+; CHECK-NEXT: [[TMP55:%.*]] = load float, ptr [[TMP43]], align 4
+; CHECK-NEXT: [[TMP56:%.*]] = insertelement <4 x float> poison, float [[TMP52]], i32 0
+; CHECK-NEXT: [[TMP57:%.*]] = insertelement <4 x float> [[TMP56]], float [[TMP53]], i32 1
+; CHECK-NEXT: [[TMP58:%.*]] = insertelement <4 x float> [[TMP57]], float [[TMP54]], i32 2
+; CHECK-NEXT: [[TMP59:%.*]] = insertelement <4 x float> [[TMP58]], float [[TMP55]], i32 3
+; CHECK-NEXT: [[TMP34:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[INDEX]]
+; CHECK-NEXT: [[TMP61:%.*]] = getelementptr float, ptr [[TMP34]], i64 4
; CHECK-NEXT: store <4 x float> [[TMP32]], ptr [[TMP34]], align 4
-; CHECK-NEXT: [[TMP35:%.*]] = getelementptr [4 x i8], ptr [[TMP4]], i64 [[TMP5]]
-; CHECK-NEXT: [[TMP36:%.*]] = getelementptr float, ptr [[TMP35]], i32 0
+; CHECK-NEXT: store <4 x float> [[TMP59]], ptr [[TMP61]], align 4
+; CHECK-NEXT: [[TMP36:%.*]] = getelementptr [4 x i8], ptr [[TMP4]], i64 [[INDEX]]
+; CHECK-NEXT: [[TMP63:%.*]] = getelementptr float, ptr [[TMP36]], i64 4
; CHECK-NEXT: store <4 x float> [[BROADCAST_SPLAT]], ptr [[TMP36]], align 4
-; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; CHECK-NEXT: store <4 x float> [[BROADCAST_SPLAT]], ptr [[TMP63]], align 4
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
; CHECK-NEXT: [[TMP37:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
; CHECK-NEXT: br i1 [[TMP37]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: [[MIDDLE_BLOCK]]:
>From b2c6b8f087271af3079ca47183df3105815b0304 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Mon, 1 Jun 2026 16:48:55 +0100
Subject: [PATCH 4/6] ret void
---
.../LoopVectorize/X86/nondetermisitic-widening-cost.ll | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
index d59664fca62e6..a41bd69de4e5c 100644
--- a/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
@@ -7,8 +7,8 @@
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux"
-define i32 @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
-; CHECK-LABEL: define i32 @fun(
+define void @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
+; CHECK-LABEL: define void @fun(
; CHECK-SAME: i64 [[TMP0:%.*]], float [[TMP1:%.*]], ptr [[A:%.*]], ptr [[B:%.*]], i64 [[LEN:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[VLA:%.*]] = alloca float, i64 [[LEN]], align 16
@@ -119,7 +119,7 @@ define i32 @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV]], [[TMP0]]
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_END_LOOPEXIT]], label %[[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
; CHECK: [[FOR_END_LOOPEXIT]]:
-; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: ret void
;
entry:
%vla = alloca float, i64 %len, align 16
@@ -145,7 +145,7 @@ loop: ; preds = %loop, %entry
br i1 %exitcond.not, label %for.end.loopexit, label %loop
for.end.loopexit: ; preds = %loop
- ret i32 0
+ ret void
}
attributes #0 = { "target-features"="+avx2" }
>From db19e697cf9cef06f9b8f66a1e6530324bb86ac6 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 10 Jun 2026 10:16:50 +0100
Subject: [PATCH 5/6] further test cleanup
---
.../X86/nondetermisitic-widening-cost.ll | 116 ++++++++----------
1 file changed, 52 insertions(+), 64 deletions(-)
diff --git a/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
index a41bd69de4e5c..2e68fdb7f46cf 100644
--- a/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
@@ -1,27 +1,22 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
; RUN: opt --passes=loop-vectorize %s -S | FileCheck %s
; Check that we see expected deterministic (over multiple test runs) output.
; NOTE: Beware, if this test fails it may be due to non-determinism.
-target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux"
-define void @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
+define void @fun(i64 %0, float %1, ptr noalias %a, ptr noalias %b, i64 %len) #0 {
; CHECK-LABEL: define void @fun(
-; CHECK-SAME: i64 [[TMP0:%.*]], float [[TMP1:%.*]], ptr [[A:%.*]], ptr [[B:%.*]], i64 [[LEN:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-SAME: i64 [[TMP0:%.*]], float [[TMP1:%.*]], ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[LEN:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[VLA:%.*]] = alloca float, i64 [[LEN]], align 16
-; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP0]], 1
-; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 8
-; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_MEMCHECK:.*]]
+; CHECK-NEXT: br label %[[VECTOR_MEMCHECK:.*]]
; CHECK: [[VECTOR_MEMCHECK]]:
; CHECK-NEXT: [[TMP3:%.*]] = shl i64 [[TMP0]], 2
; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP3]], 32
-; CHECK-NEXT: br i1 [[DIFF_CHECK]], label %[[SCALAR_PH]], label %[[VECTOR_PH:.*]]
+; CHECK-NEXT: br i1 [[DIFF_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
; CHECK: [[VECTOR_PH]]:
-; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 8
-; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[TMP0]]
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x float> poison, float [[TMP1]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x float> [[BROADCAST_SPLATINSERT]], <4 x float> poison, <4 x i32> zeroinitializer
@@ -31,50 +26,42 @@ define void @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 1
; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[INDEX]], 2
; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDEX]], 3
-; CHECK-NEXT: [[TMP44:%.*]] = add i64 [[INDEX]], 4
-; CHECK-NEXT: [[TMP45:%.*]] = add i64 [[INDEX]], 5
-; CHECK-NEXT: [[TMP46:%.*]] = add i64 [[INDEX]], 6
-; CHECK-NEXT: [[TMP47:%.*]] = add i64 [[INDEX]], 7
-; CHECK-NEXT: [[TMP9:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[INDEX]]
-; CHECK-NEXT: [[TMP10:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP6]]
-; CHECK-NEXT: [[TMP11:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP7]]
-; CHECK-NEXT: [[TMP12:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP8]]
-; CHECK-NEXT: [[TMP48:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP44]]
-; CHECK-NEXT: [[TMP49:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP45]]
-; CHECK-NEXT: [[TMP50:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP46]]
-; CHECK-NEXT: [[TMP51:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP47]]
-; CHECK-NEXT: [[TMP13:%.*]] = load ptr, ptr [[TMP9]], align 8
-; CHECK-NEXT: [[TMP14:%.*]] = load ptr, ptr [[TMP10]], align 8
-; CHECK-NEXT: [[TMP15:%.*]] = load ptr, ptr [[TMP11]], align 8
-; CHECK-NEXT: [[TMP16:%.*]] = load ptr, ptr [[TMP12]], align 8
+; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 4
+; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[INDEX]], 5
+; CHECK-NEXT: [[TMP9:%.*]] = add i64 [[INDEX]], 6
+; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[INDEX]], 7
+; CHECK-NEXT: [[TMP48:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[INDEX]]
+; CHECK-NEXT: [[TMP49:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP6]]
+; CHECK-NEXT: [[TMP50:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP7]]
+; CHECK-NEXT: [[TMP51:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP8]]
+; CHECK-NEXT: [[TMP15:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP11]]
+; CHECK-NEXT: [[TMP16:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP12]]
+; CHECK-NEXT: [[TMP17:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP9]]
+; CHECK-NEXT: [[TMP18:%.*]] = getelementptr [8 x i8], ptr [[A]], i64 [[TMP10]]
; CHECK-NEXT: [[TMP60:%.*]] = load ptr, ptr [[TMP48]], align 8
; CHECK-NEXT: [[TMP62:%.*]] = load ptr, ptr [[TMP49]], align 8
; CHECK-NEXT: [[TMP64:%.*]] = load ptr, ptr [[TMP50]], align 8
; CHECK-NEXT: [[TMP65:%.*]] = load ptr, ptr [[TMP51]], align 8
-; CHECK-NEXT: [[TMP17:%.*]] = load i64, ptr [[TMP13]], align 8
-; CHECK-NEXT: [[TMP18:%.*]] = load i64, ptr [[TMP14]], align 8
-; CHECK-NEXT: [[TMP19:%.*]] = load i64, ptr [[TMP15]], align 8
-; CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr [[TMP16]], align 8
+; CHECK-NEXT: [[TMP23:%.*]] = load ptr, ptr [[TMP15]], align 8
+; CHECK-NEXT: [[TMP24:%.*]] = load ptr, ptr [[TMP16]], align 8
+; CHECK-NEXT: [[TMP25:%.*]] = load ptr, ptr [[TMP17]], align 8
+; CHECK-NEXT: [[TMP26:%.*]] = load ptr, ptr [[TMP18]], align 8
; CHECK-NEXT: [[TMP66:%.*]] = load i64, ptr [[TMP60]], align 8
; CHECK-NEXT: [[TMP33:%.*]] = load i64, ptr [[TMP62]], align 8
; CHECK-NEXT: [[TMP67:%.*]] = load i64, ptr [[TMP64]], align 8
; CHECK-NEXT: [[TMP35:%.*]] = load i64, ptr [[TMP65]], align 8
-; CHECK-NEXT: [[TMP21:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP17]]
-; CHECK-NEXT: [[TMP22:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP18]]
-; CHECK-NEXT: [[TMP23:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP19]]
-; CHECK-NEXT: [[TMP24:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP20]]
+; CHECK-NEXT: [[TMP31:%.*]] = load i64, ptr [[TMP23]], align 8
+; CHECK-NEXT: [[TMP32:%.*]] = load i64, ptr [[TMP24]], align 8
+; CHECK-NEXT: [[TMP36:%.*]] = load i64, ptr [[TMP25]], align 8
+; CHECK-NEXT: [[TMP34:%.*]] = load i64, ptr [[TMP26]], align 8
; CHECK-NEXT: [[TMP68:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP66]]
; CHECK-NEXT: [[TMP69:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP33]]
; CHECK-NEXT: [[TMP70:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP67]]
; CHECK-NEXT: [[TMP43:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP35]]
-; CHECK-NEXT: [[TMP25:%.*]] = load float, ptr [[TMP21]], align 4
-; CHECK-NEXT: [[TMP26:%.*]] = load float, ptr [[TMP22]], align 4
-; CHECK-NEXT: [[TMP27:%.*]] = load float, ptr [[TMP23]], align 4
-; CHECK-NEXT: [[TMP28:%.*]] = load float, ptr [[TMP24]], align 4
-; CHECK-NEXT: [[TMP29:%.*]] = insertelement <4 x float> poison, float [[TMP25]], i32 0
-; CHECK-NEXT: [[TMP30:%.*]] = insertelement <4 x float> [[TMP29]], float [[TMP26]], i32 1
-; CHECK-NEXT: [[TMP31:%.*]] = insertelement <4 x float> [[TMP30]], float [[TMP27]], i32 2
-; CHECK-NEXT: [[TMP32:%.*]] = insertelement <4 x float> [[TMP31]], float [[TMP28]], i32 3
+; CHECK-NEXT: [[TMP44:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP31]]
+; CHECK-NEXT: [[TMP45:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP32]]
+; CHECK-NEXT: [[TMP46:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP36]]
+; CHECK-NEXT: [[TMP47:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[TMP34]]
; CHECK-NEXT: [[TMP52:%.*]] = load float, ptr [[TMP68]], align 4
; CHECK-NEXT: [[TMP53:%.*]] = load float, ptr [[TMP69]], align 4
; CHECK-NEXT: [[TMP54:%.*]] = load float, ptr [[TMP70]], align 4
@@ -83,22 +70,29 @@ define void @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
; CHECK-NEXT: [[TMP57:%.*]] = insertelement <4 x float> [[TMP56]], float [[TMP53]], i32 1
; CHECK-NEXT: [[TMP58:%.*]] = insertelement <4 x float> [[TMP57]], float [[TMP54]], i32 2
; CHECK-NEXT: [[TMP59:%.*]] = insertelement <4 x float> [[TMP58]], float [[TMP55]], i32 3
-; CHECK-NEXT: [[TMP34:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[INDEX]]
-; CHECK-NEXT: [[TMP61:%.*]] = getelementptr float, ptr [[TMP34]], i64 4
-; CHECK-NEXT: store <4 x float> [[TMP32]], ptr [[TMP34]], align 4
+; CHECK-NEXT: [[TMP71:%.*]] = load float, ptr [[TMP44]], align 4
+; CHECK-NEXT: [[TMP72:%.*]] = load float, ptr [[TMP45]], align 4
+; CHECK-NEXT: [[TMP73:%.*]] = load float, ptr [[TMP46]], align 4
+; CHECK-NEXT: [[TMP74:%.*]] = load float, ptr [[TMP47]], align 4
+; CHECK-NEXT: [[TMP75:%.*]] = insertelement <4 x float> poison, float [[TMP71]], i32 0
+; CHECK-NEXT: [[TMP76:%.*]] = insertelement <4 x float> [[TMP75]], float [[TMP72]], i32 1
+; CHECK-NEXT: [[TMP77:%.*]] = insertelement <4 x float> [[TMP76]], float [[TMP73]], i32 2
+; CHECK-NEXT: [[TMP78:%.*]] = insertelement <4 x float> [[TMP77]], float [[TMP74]], i32 3
+; CHECK-NEXT: [[TMP61:%.*]] = getelementptr [4 x i8], ptr [[VLA]], i64 [[INDEX]]
+; CHECK-NEXT: [[TMP79:%.*]] = getelementptr float, ptr [[TMP61]], i64 4
; CHECK-NEXT: store <4 x float> [[TMP59]], ptr [[TMP61]], align 4
-; CHECK-NEXT: [[TMP36:%.*]] = getelementptr [4 x i8], ptr [[TMP4]], i64 [[INDEX]]
-; CHECK-NEXT: [[TMP63:%.*]] = getelementptr float, ptr [[TMP36]], i64 4
-; CHECK-NEXT: store <4 x float> [[BROADCAST_SPLAT]], ptr [[TMP36]], align 4
+; CHECK-NEXT: store <4 x float> [[TMP78]], ptr [[TMP79]], align 4
+; CHECK-NEXT: [[TMP63:%.*]] = getelementptr [4 x i8], ptr [[TMP4]], i64 [[INDEX]]
+; CHECK-NEXT: [[TMP80:%.*]] = getelementptr float, ptr [[TMP63]], i64 4
; CHECK-NEXT: store <4 x float> [[BROADCAST_SPLAT]], ptr [[TMP63]], align 4
+; CHECK-NEXT: store <4 x float> [[BROADCAST_SPLAT]], ptr [[TMP80]], align 4
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
-; CHECK-NEXT: [[TMP37:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: [[TMP37:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128
; CHECK-NEXT: br i1 [[TMP37]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: [[MIDDLE_BLOCK]]:
-; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
-; CHECK-NEXT: br i1 [[CMP_N]], label %[[FOR_END_LOOPEXIT:.*]], label %[[SCALAR_PH]]
+; CHECK-NEXT: br label %[[SCALAR_PH]]
; CHECK: [[SCALAR_PH]]:
-; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ], [ 0, %[[VECTOR_MEMCHECK]] ]
+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 128, %[[MIDDLE_BLOCK]] ], [ 0, %[[VECTOR_MEMCHECK]] ]
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
; CHECK: [[FOR_BODY]]:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[FOR_BODY]] ]
@@ -116,8 +110,8 @@ define void @fun(i64 %0, float %1, ptr %a, ptr %b, i64 %len) #0 {
; CHECK-NEXT: [[ARRAYIDX30:%.*]] = getelementptr [4 x i8], ptr [[ARRAYIDX28]], i64 [[INDVARS_IV]]
; CHECK-NEXT: store float [[TMP1]], ptr [[ARRAYIDX30]], align 4
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
-; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV]], [[TMP0]]
-; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_END_LOOPEXIT]], label %[[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
+; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV]], 128
+; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_END_LOOPEXIT:.*]], label %[[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
; CHECK: [[FOR_END_LOOPEXIT]]:
; CHECK-NEXT: ret void
;
@@ -125,7 +119,7 @@ entry:
%vla = alloca float, i64 %len, align 16
br label %loop
-loop: ; preds = %loop, %entry
+loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%arrayidx16 = getelementptr [8 x i8], ptr %a, i64 %iv
%2 = load ptr, ptr %arrayidx16, align 8
@@ -141,17 +135,11 @@ loop: ; preds = %loop, %entry
%arrayidx30 = getelementptr [4 x i8], ptr %arrayidx28, i64 %iv
store float %1, ptr %arrayidx30, align 4
%iv.next = add i64 %iv, 1
- %exitcond.not = icmp eq i64 %iv, %0
+ %exitcond.not = icmp eq i64 %iv, 128
br i1 %exitcond.not, label %for.end.loopexit, label %loop
-for.end.loopexit: ; preds = %loop
+for.end.loopexit:
ret void
}
attributes #0 = { "target-features"="+avx2" }
-;.
-; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
-; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
-; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
-; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]]}
-;.
>From 7fbaf9d7c27a3947438423318778635be001cfdc Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Fri, 12 Jun 2026 10:58:22 +0100
Subject: [PATCH 6/6] add %vla use
---
.../LoopVectorize/X86/nondetermisitic-widening-cost.ll | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
index 2e68fdb7f46cf..b99322c0ce924 100644
--- a/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/nondetermisitic-widening-cost.ll
@@ -6,8 +6,8 @@
target triple = "x86_64-unknown-linux"
-define void @fun(i64 %0, float %1, ptr noalias %a, ptr noalias %b, i64 %len) #0 {
-; CHECK-LABEL: define void @fun(
+define float @fun(i64 %0, float %1, ptr noalias %a, ptr noalias %b, i64 %len) #0 {
+; CHECK-LABEL: define float @fun(
; CHECK-SAME: i64 [[TMP0:%.*]], float [[TMP1:%.*]], ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], i64 [[LEN:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[VLA:%.*]] = alloca float, i64 [[LEN]], align 16
@@ -113,7 +113,8 @@ define void @fun(i64 %0, float %1, ptr noalias %a, ptr noalias %b, i64 %len) #0
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV]], 128
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_END_LOOPEXIT:.*]], label %[[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
; CHECK: [[FOR_END_LOOPEXIT]]:
-; CHECK-NEXT: ret void
+; CHECK-NEXT: [[R:%.*]] = load float, ptr [[VLA]], align 4
+; CHECK-NEXT: ret float [[R]]
;
entry:
%vla = alloca float, i64 %len, align 16
@@ -139,7 +140,8 @@ loop:
br i1 %exitcond.not, label %for.end.loopexit, label %loop
for.end.loopexit:
- ret void
+ %r = load float, ptr %vla
+ ret float %r
}
attributes #0 = { "target-features"="+avx2" }
More information about the llvm-commits
mailing list