[llvm] [LV][NFC] Add cost model tests for VPInstructionWithType (PR #200135)

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 1 00:42:29 PDT 2026


https://github.com/david-arm updated https://github.com/llvm/llvm-project/pull/200135

>From 0c0bb48dc244e640a8d1c7aff8a069b71b34a029 Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Thu, 28 May 2026 08:39:31 +0000
Subject: [PATCH 1/5] [LV][NFC] Add cost model tests for VPInstructionWithType

---
 .../LoopVectorize/ext_or_trunc_iv_costs.ll    | 66 +++++++++++++++++++
 .../Transforms/LoopVectorize/vscale-cost.ll   | 45 +++++++++++++
 2 files changed, 111 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
 create mode 100644 llvm/test/Transforms/LoopVectorize/vscale-cost.ll

diff --git a/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll b/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
new file mode 100644
index 0000000000000..0b1fe649acdf1
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
@@ -0,0 +1,66 @@
+; REQUIRES: asserts
+; RUN: opt -p loop-vectorize -S -disable-output -debug-only=loop-vectorize %s 2>&1 | FileCheck %s
+
+define void @trunc_store(ptr %dst) {
+; CHECK-LABEL: Checking a loop in 'trunc_store'
+; CHECK: Cost of 0 for VF 2: EMIT-SCALAR vp{{.*}} = trunc {{.*}} to i8
+; CHECK: Cost of 0 for VF 4: EMIT-SCALAR vp{{.*}} = trunc {{.*}} to i8
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %iv.trunc = trunc i64 %iv to i8
+  %gep = getelementptr i8, ptr %dst, i64 %iv
+  store i8 %iv.trunc, ptr %gep, align 1
+  %iv.next = add i64 %iv, 1
+  %ec = icmp eq i64 %iv.next, 7
+  br i1 %ec, label %exit, label %loop
+
+exit:
+  ret void
+}
+
+define i32 @sext_reduc(i32 %x, i32 %y) {
+; CHECK-LABEL: Checking a loop in 'sext_reduc'
+; CHECK: Cost of 0 for VF 2: EMIT-SCALAR vp{{.*}}  = sext vp{{.*}}  to i32
+; CHECK: Cost of 0 for VF 4: EMIT-SCALAR vp{{.*}}  = sext vp{{.*}}  to i32
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i32 [ %x, %entry ], [ %iv.next, %for.body ]
+  %red = phi i32 [ %y, %entry ], [ %red.next, %for.body ]
+  %t0 = and i32 %red, 1
+  %red.next = add i32 %t0, -1
+  %iv.next = add nsw i32 %iv, 1
+  %cond = icmp sgt i32 %iv, 77
+  br i1 %cond, label %for.end, label %for.body
+
+for.end:
+  ret i32 %red.next
+}
+
+define i8 @reduc_add_trunc(ptr %A) {
+; CHECK-LABEL: Checking a loop in 'reduc_add_trunc'
+; CHECK: Cost of 0 for VF 2: EMIT-SCALAR vp{{.*}} = zext vp{{.*}} to i32
+; CHECK: Cost of 0 for VF 4: EMIT-SCALAR vp{{.*}} = zext vp{{.*}} to i32
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
+  %red = phi i32 [ %red.next, %loop ], [ 255, %entry ]
+  %red.trunc = and i32 %red, 255
+  %gep = getelementptr inbounds i8, ptr %A, i32 %iv
+  %load = load i8, ptr %gep, align 4
+  %zext = zext i8 %load to i32
+  %red.next = add i32 %red.trunc, %zext
+  %iv.next = add i32 %iv, 1
+  %exitcond = icmp eq i32 %iv.next, 256
+  br i1 %exitcond, label %exit, label %loop
+
+exit:
+  %ret = trunc i32 %red.next to i8
+  ret i8 %ret
+}
diff --git a/llvm/test/Transforms/LoopVectorize/vscale-cost.ll b/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
new file mode 100644
index 0000000000000..e005f36412228
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
@@ -0,0 +1,45 @@
+; REQUIRES: asserts
+; RUN: opt %s -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -enable-interleaved-mem-accesses \
+; RUN:   -force-target-supports-scalable-vectors=true -scalable-vectorization=preferred -disable-output \
+; RUN:   -debug-only=loop-vectorize -S 2>&1 | FileCheck %s
+
+define void @scalablevf(ptr %dst.start, i8 %a, i8 %b) {
+; CHECK-LABEL: Checking a loop in 'scalablevf'
+; CHECK: Cost of 0 for VF vscale x 4: EMIT-SCALAR vp{{.*}} = vscale i64
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %dst = phi ptr [ %dst.start, %entry ], [ %dst.next, %loop ]
+  %dst.next = getelementptr inbounds nuw i8, ptr %dst, i64 4
+  %load.dst = load i8, ptr %dst, align 1
+  %mul.dst.0 = mul nuw i8 %load.dst, %b
+  %udiv.0 = udiv i8 %mul.dst.0, 255
+  %val.0 = add i8 %a, %udiv.0
+  store i8 %val.0, ptr %dst, align 1
+  %gep.dst.1 = getelementptr inbounds nuw i8, ptr %dst, i64 1
+  %load.dst.1 = load i8, ptr %gep.dst.1, align 1
+  %mul.dst.1 = mul nuw i8 %load.dst.1, %b
+  %udiv.1 = udiv i8 %mul.dst.1, 255
+  %val.1 = add i8 %a, %udiv.1
+  store i8 %val.1, ptr %gep.dst.1, align 1
+  %gep.dst.2 = getelementptr inbounds nuw i8, ptr %dst, i64 2
+  %load.dst.2 = load i8, ptr %gep.dst.2, align 1
+  %mul.dst.2 = mul nuw i8 %load.dst.2, %b
+  %udiv.2 = udiv i8 %mul.dst.2, 255
+  %val.2 = add i8 %a, %udiv.2
+  store i8 %val.2, ptr %gep.dst.2, align 1
+  %gep.dst.3 = getelementptr inbounds nuw i8, ptr %dst, i64 3
+  %load.dst.3 = load i8, ptr %gep.dst.3, align 1
+  %mul.dst.3 = mul nuw i8 %load.dst.3, %b
+  %udiv.3 = udiv i8 %mul.dst.3, 255
+  %val.3 = add i8 %a, %udiv.3
+  store i8 %val.3, ptr %gep.dst.3, align 1
+  %iv.next = add i64 %iv, 4
+  %exit.cond = icmp eq i64 %iv.next, 256
+  br i1 %exit.cond, label %exit, label %loop
+
+exit:
+  ret void
+}

>From 473389c62599c78d14d9f9746bcd86f8680cac4e Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Thu, 28 May 2026 11:24:50 +0000
Subject: [PATCH 2/5] Address review comment

---
 .../LoopVectorize/ext_or_trunc_iv_costs.ll    | 32 +++++++++++++------
 .../Transforms/LoopVectorize/vscale-cost.ll   | 11 +++++--
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll b/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
index 0b1fe649acdf1..6c570225802b5 100644
--- a/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
+++ b/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
@@ -1,10 +1,12 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost.*EMIT-SCALAR" --version 6
 ; REQUIRES: asserts
 ; RUN: opt -p loop-vectorize -S -disable-output -debug-only=loop-vectorize %s 2>&1 | FileCheck %s
 
 define void @trunc_store(ptr %dst) {
-; CHECK-LABEL: Checking a loop in 'trunc_store'
-; CHECK: Cost of 0 for VF 2: EMIT-SCALAR vp{{.*}} = trunc {{.*}} to i8
-; CHECK: Cost of 0 for VF 4: EMIT-SCALAR vp{{.*}} = trunc {{.*}} to i8
+; CHECK-LABEL: 'trunc_store'
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP5:%[0-9]+]]> = trunc vp<[[VP4:%[0-9]+]]> to i8
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP5]]> = trunc vp<[[VP4]]> to i8
+;
 entry:
   br label %loop
 
@@ -22,9 +24,15 @@ exit:
 }
 
 define i32 @sext_reduc(i32 %x, i32 %y) {
-; CHECK-LABEL: Checking a loop in 'sext_reduc'
-; CHECK: Cost of 0 for VF 2: EMIT-SCALAR vp{{.*}}  = sext vp{{.*}}  to i32
-; CHECK: Cost of 0 for VF 4: EMIT-SCALAR vp{{.*}}  = sext vp{{.*}}  to i32
+; CHECK-LABEL: 'sext_reduc'
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP3:%[0-9]+]]>, middle.block ], [ ir<%x>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP10:%[0-9]+]]>, middle.block ], [ ir<%y>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP10]]> = sext vp<[[VP9:%[0-9]+]]> to i32
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP3]]>, middle.block ], [ ir<%x>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP10]]>, middle.block ], [ ir<%y>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP10]]> = sext vp<[[VP9]]> to i32
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP10]]> = sext vp<[[VP9]]> to i32
+;
 entry:
   br label %for.body
 
@@ -42,9 +50,15 @@ for.end:
 }
 
 define i8 @reduc_add_trunc(ptr %A) {
-; CHECK-LABEL: Checking a loop in 'reduc_add_trunc'
-; CHECK: Cost of 0 for VF 2: EMIT-SCALAR vp{{.*}} = zext vp{{.*}} to i32
-; CHECK: Cost of 0 for VF 4: EMIT-SCALAR vp{{.*}} = zext vp{{.*}} to i32
+; CHECK-LABEL: 'reduc_add_trunc'
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2:%[0-9]+]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP11:%[0-9]+]]>, middle.block ], [ ir<255>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP11]]> = zext vp<[[VP10:%[0-9]+]]> to i32
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP11]]>, middle.block ], [ ir<255>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP11]]> = zext vp<[[VP10]]> to i32
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP11]]> = zext vp<[[VP10]]> to i32
+;
 entry:
   br label %loop
 
diff --git a/llvm/test/Transforms/LoopVectorize/vscale-cost.ll b/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
index e005f36412228..e9e06b4dd1f11 100644
--- a/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
@@ -1,11 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost.*EMIT-SCALAR" --version 6
 ; REQUIRES: asserts
 ; RUN: opt %s -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -enable-interleaved-mem-accesses \
 ; RUN:   -force-target-supports-scalable-vectors=true -scalable-vectorization=preferred -disable-output \
 ; RUN:   -debug-only=loop-vectorize -S 2>&1 | FileCheck %s
 
 define void @scalablevf(ptr %dst.start, i8 %a, i8 %b) {
-; CHECK-LABEL: Checking a loop in 'scalablevf'
-; CHECK: Cost of 0 for VF vscale x 4: EMIT-SCALAR vp{{.*}} = vscale i64
+; CHECK-LABEL: 'scalablevf'
+; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP4:%[0-9]+]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<%bc.resume.val>.1 = phi [ vp<[[VP5:%[0-9]+]]>, middle.block ], [ ir<%dst.start>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<[[VP2:%[0-9]+]]> = vscale i64
+; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP4]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<%bc.resume.val>.1 = phi [ vp<[[VP5]]>, middle.block ], [ ir<%dst.start>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<[[VP2]]> = vscale i64
+;
 entry:
   br label %loop
 

>From 132fa8d49196c764e3070cb6c33e9a5e182f0528 Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Fri, 29 May 2026 08:14:35 +0000
Subject: [PATCH 3/5] Tighten the CHECK lines

---
 .../LoopVectorize/ext_or_trunc_iv_costs.ll         | 14 +++-----------
 llvm/test/Transforms/LoopVectorize/vscale-cost.ll  |  6 +-----
 2 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll b/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
index 6c570225802b5..e7ad5b4a74567 100644
--- a/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
+++ b/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost.*EMIT-SCALAR" --version 6
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost.*EMIT-SCALAR.*(trunc|sext|zext)" --version 6
 ; REQUIRES: asserts
 ; RUN: opt -p loop-vectorize -S -disable-output -debug-only=loop-vectorize %s 2>&1 | FileCheck %s
 
@@ -25,11 +25,7 @@ exit:
 
 define i32 @sext_reduc(i32 %x, i32 %y) {
 ; CHECK-LABEL: 'sext_reduc'
-; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP3:%[0-9]+]]>, middle.block ], [ ir<%x>, ir-bb<entry> ]
-; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP10:%[0-9]+]]>, middle.block ], [ ir<%y>, ir-bb<entry> ]
-; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP10]]> = sext vp<[[VP9:%[0-9]+]]> to i32
-; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP3]]>, middle.block ], [ ir<%x>, ir-bb<entry> ]
-; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP10]]>, middle.block ], [ ir<%y>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP10:%[0-9]+]]> = sext vp<[[VP9:%[0-9]+]]> to i32
 ; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP10]]> = sext vp<[[VP9]]> to i32
 ; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP10]]> = sext vp<[[VP9]]> to i32
 ;
@@ -51,11 +47,7 @@ for.end:
 
 define i8 @reduc_add_trunc(ptr %A) {
 ; CHECK-LABEL: 'reduc_add_trunc'
-; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2:%[0-9]+]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
-; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP11:%[0-9]+]]>, middle.block ], [ ir<255>, ir-bb<entry> ]
-; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP11]]> = zext vp<[[VP10:%[0-9]+]]> to i32
-; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP2]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
-; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<[[VP11]]>, middle.block ], [ ir<255>, ir-bb<entry> ]
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP11:%[0-9]+]]> = zext vp<[[VP10:%[0-9]+]]> to i32
 ; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP11]]> = zext vp<[[VP10]]> to i32
 ; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP11]]> = zext vp<[[VP10]]> to i32
 ;
diff --git a/llvm/test/Transforms/LoopVectorize/vscale-cost.ll b/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
index e9e06b4dd1f11..b9ce8affaba15 100644
--- a/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost.*EMIT-SCALAR" --version 6
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost.*EMIT-SCALAR.*vscale" --version 6
 ; REQUIRES: asserts
 ; RUN: opt %s -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -enable-interleaved-mem-accesses \
 ; RUN:   -force-target-supports-scalable-vectors=true -scalable-vectorization=preferred -disable-output \
@@ -6,11 +6,7 @@
 
 define void @scalablevf(ptr %dst.start, i8 %a, i8 %b) {
 ; CHECK-LABEL: 'scalablevf'
-; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP4:%[0-9]+]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
-; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<%bc.resume.val>.1 = phi [ vp<[[VP5:%[0-9]+]]>, middle.block ], [ ir<%dst.start>, ir-bb<entry> ]
 ; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<[[VP2:%[0-9]+]]> = vscale i64
-; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP4]]>, middle.block ], [ ir<0>, ir-bb<entry> ]
-; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<%bc.resume.val>.1 = phi [ vp<[[VP5]]>, middle.block ], [ ir<%dst.start>, ir-bb<entry> ]
 ; CHECK:  Cost of 0 for VF vscale x 4: EMIT-SCALAR vp<[[VP2]]> = vscale i64
 ;
 entry:

>From d3a917724efa6787b38a3c3b0d7d595ce46b951d Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Fri, 29 May 2026 12:40:31 +0000
Subject: [PATCH 4/5] Address review comments

---
 .../LoopVectorize/ext_or_trunc_iv_costs.ll    | 72 -------------------
 .../Transforms/LoopVectorize/vscale-cost.ll   | 22 ++----
 2 files changed, 5 insertions(+), 89 deletions(-)
 delete mode 100644 llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll

diff --git a/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll b/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
deleted file mode 100644
index e7ad5b4a74567..0000000000000
--- a/llvm/test/Transforms/LoopVectorize/ext_or_trunc_iv_costs.ll
+++ /dev/null
@@ -1,72 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost.*EMIT-SCALAR.*(trunc|sext|zext)" --version 6
-; REQUIRES: asserts
-; RUN: opt -p loop-vectorize -S -disable-output -debug-only=loop-vectorize %s 2>&1 | FileCheck %s
-
-define void @trunc_store(ptr %dst) {
-; CHECK-LABEL: 'trunc_store'
-; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP5:%[0-9]+]]> = trunc vp<[[VP4:%[0-9]+]]> to i8
-; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP5]]> = trunc vp<[[VP4]]> to i8
-;
-entry:
-  br label %loop
-
-loop:
-  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
-  %iv.trunc = trunc i64 %iv to i8
-  %gep = getelementptr i8, ptr %dst, i64 %iv
-  store i8 %iv.trunc, ptr %gep, align 1
-  %iv.next = add i64 %iv, 1
-  %ec = icmp eq i64 %iv.next, 7
-  br i1 %ec, label %exit, label %loop
-
-exit:
-  ret void
-}
-
-define i32 @sext_reduc(i32 %x, i32 %y) {
-; CHECK-LABEL: 'sext_reduc'
-; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP10:%[0-9]+]]> = sext vp<[[VP9:%[0-9]+]]> to i32
-; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP10]]> = sext vp<[[VP9]]> to i32
-; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP10]]> = sext vp<[[VP9]]> to i32
-;
-entry:
-  br label %for.body
-
-for.body:
-  %iv = phi i32 [ %x, %entry ], [ %iv.next, %for.body ]
-  %red = phi i32 [ %y, %entry ], [ %red.next, %for.body ]
-  %t0 = and i32 %red, 1
-  %red.next = add i32 %t0, -1
-  %iv.next = add nsw i32 %iv, 1
-  %cond = icmp sgt i32 %iv, 77
-  br i1 %cond, label %for.end, label %for.body
-
-for.end:
-  ret i32 %red.next
-}
-
-define i8 @reduc_add_trunc(ptr %A) {
-; CHECK-LABEL: 'reduc_add_trunc'
-; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP11:%[0-9]+]]> = zext vp<[[VP10:%[0-9]+]]> to i32
-; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP11]]> = zext vp<[[VP10]]> to i32
-; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP11]]> = zext vp<[[VP10]]> to i32
-;
-entry:
-  br label %loop
-
-loop:
-  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
-  %red = phi i32 [ %red.next, %loop ], [ 255, %entry ]
-  %red.trunc = and i32 %red, 255
-  %gep = getelementptr inbounds i8, ptr %A, i32 %iv
-  %load = load i8, ptr %gep, align 4
-  %zext = zext i8 %load to i32
-  %red.next = add i32 %red.trunc, %zext
-  %iv.next = add i32 %iv, 1
-  %exitcond = icmp eq i32 %iv.next, 256
-  br i1 %exitcond, label %exit, label %loop
-
-exit:
-  %ret = trunc i32 %red.next to i8
-  ret i8 %ret
-}
diff --git a/llvm/test/Transforms/LoopVectorize/vscale-cost.ll b/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
index b9ce8affaba15..8291237cd3d63 100644
--- a/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
+++ b/llvm/test/Transforms/LoopVectorize/vscale-cost.ll
@@ -16,29 +16,17 @@ loop:
   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
   %dst = phi ptr [ %dst.start, %entry ], [ %dst.next, %loop ]
   %dst.next = getelementptr inbounds nuw i8, ptr %dst, i64 4
-  %load.dst = load i8, ptr %dst, align 1
-  %mul.dst.0 = mul nuw i8 %load.dst, %b
-  %udiv.0 = udiv i8 %mul.dst.0, 255
-  %val.0 = add i8 %a, %udiv.0
-  store i8 %val.0, ptr %dst, align 1
+  %load.dst.0 = load i8, ptr %dst, align 1
+  store i8 %load.dst.0, ptr %dst, align 1
   %gep.dst.1 = getelementptr inbounds nuw i8, ptr %dst, i64 1
   %load.dst.1 = load i8, ptr %gep.dst.1, align 1
-  %mul.dst.1 = mul nuw i8 %load.dst.1, %b
-  %udiv.1 = udiv i8 %mul.dst.1, 255
-  %val.1 = add i8 %a, %udiv.1
-  store i8 %val.1, ptr %gep.dst.1, align 1
+  store i8 %load.dst.1, ptr %gep.dst.1, align 1
   %gep.dst.2 = getelementptr inbounds nuw i8, ptr %dst, i64 2
   %load.dst.2 = load i8, ptr %gep.dst.2, align 1
-  %mul.dst.2 = mul nuw i8 %load.dst.2, %b
-  %udiv.2 = udiv i8 %mul.dst.2, 255
-  %val.2 = add i8 %a, %udiv.2
-  store i8 %val.2, ptr %gep.dst.2, align 1
+  store i8 %load.dst.2, ptr %gep.dst.2, align 1
   %gep.dst.3 = getelementptr inbounds nuw i8, ptr %dst, i64 3
   %load.dst.3 = load i8, ptr %gep.dst.3, align 1
-  %mul.dst.3 = mul nuw i8 %load.dst.3, %b
-  %udiv.3 = udiv i8 %mul.dst.3, 255
-  %val.3 = add i8 %a, %udiv.3
-  store i8 %val.3, ptr %gep.dst.3, align 1
+  store i8 %load.dst.3, ptr %gep.dst.3, align 1
   %iv.next = add i64 %iv, 4
   %exit.cond = icmp eq i64 %iv.next, 256
   br i1 %exit.cond, label %exit, label %loop

>From e7a69adadc8b600716bcf48c622decf8a00eafa1 Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Fri, 29 May 2026 12:42:36 +0000
Subject: [PATCH 5/5] Add test file back in

---
 .../Transforms/LoopVectorize/cast-costs.ll    | 80 +++++++++++++++++++
 1 file changed, 80 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopVectorize/cast-costs.ll

diff --git a/llvm/test/Transforms/LoopVectorize/cast-costs.ll b/llvm/test/Transforms/LoopVectorize/cast-costs.ll
new file mode 100644
index 0000000000000..14b3e71b39166
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/cast-costs.ll
@@ -0,0 +1,80 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "Cost.*EMIT-SCALAR.*(trunc|sext|zext)" --filter "Cost.*WIDEN-CAST" --filter-out-after "LV: Selecting VF" --version 6
+; REQUIRES: asserts
+; RUN: opt -p loop-vectorize -S -disable-output -debug-only=loop-vectorize %s 2>&1 | FileCheck %s
+
+define void @trunc_store(ptr %dst) {
+; CHECK-LABEL: 'trunc_store'
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP5:%[0-9]+]]> = trunc vp<[[VP4:%[0-9]+]]> to i8
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP5]]> = trunc vp<[[VP4]]> to i8
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %iv.trunc = trunc i64 %iv to i8
+  %gep = getelementptr i8, ptr %dst, i64 %iv
+  store i8 %iv.trunc, ptr %gep, align 1
+  %iv.next = add i64 %iv, 1
+  %ec = icmp eq i64 %iv.next, 7
+  br i1 %ec, label %exit, label %loop
+
+exit:
+  ret void
+}
+
+define i32 @sext_reduc(i32 %x, i32 %y) {
+; CHECK-LABEL: 'sext_reduc'
+; CHECK:  Cost of 1 for VF 2: WIDEN-CAST vp<[[VP6:%[0-9]+]]> = trunc ir<%red.next> to i1
+; CHECK:  Cost of 1 for VF 2: WIDEN-CAST vp<[[VP7:%[0-9]+]]> = sext vp<[[VP6]]> to i32
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP10:%[0-9]+]]> = sext vp<[[VP9:%[0-9]+]]> to i32
+; CHECK:  Cost of 1 for VF 4: WIDEN-CAST vp<[[VP6]]> = trunc ir<%red.next> to i1
+; CHECK:  Cost of 1 for VF 4: WIDEN-CAST vp<[[VP7]]> = sext vp<[[VP6]]> to i32
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP10]]> = sext vp<[[VP9]]> to i32
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i32 [ %x, %entry ], [ %iv.next, %for.body ]
+  %red = phi i32 [ %y, %entry ], [ %red.next, %for.body ]
+  %t0 = and i32 %red, 1
+  %red.next = add i32 %t0, -1
+  %iv.next = add nsw i32 %iv, 1
+  %cond = icmp sgt i32 %iv, 77
+  br i1 %cond, label %for.end, label %for.body
+
+for.end:
+  ret i32 %red.next
+}
+
+define i8 @reduc_add_trunc(ptr %A) {
+; CHECK-LABEL: 'reduc_add_trunc'
+; CHECK:  Cost of 0 for VF 2: WIDEN-CAST ir<%zext> = zext ir<%load> to i32
+; CHECK:  Cost of 1 for VF 2: WIDEN-CAST vp<[[VP7:%[0-9]+]]> = trunc ir<%red.next> to i8
+; CHECK:  Cost of 1 for VF 2: WIDEN-CAST vp<[[VP8:%[0-9]+]]> = zext vp<[[VP7]]> to i32
+; CHECK:  Cost of 0 for VF 2: EMIT-SCALAR vp<[[VP11:%[0-9]+]]> = zext vp<[[VP10:%[0-9]+]]> to i32
+; CHECK:  Cost of 0 for VF 4: WIDEN-CAST ir<%zext> = zext ir<%load> to i32
+; CHECK:  Cost of 1 for VF 4: WIDEN-CAST vp<[[VP7]]> = trunc ir<%red.next> to i8
+; CHECK:  Cost of 1 for VF 4: WIDEN-CAST vp<[[VP8]]> = zext vp<[[VP7]]> to i32
+; CHECK:  Cost of 0 for VF 4: EMIT-SCALAR vp<[[VP11]]> = zext vp<[[VP10]]> to i32
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
+  %red = phi i32 [ %red.next, %loop ], [ 255, %entry ]
+  %red.trunc = and i32 %red, 255
+  %gep = getelementptr inbounds i8, ptr %A, i32 %iv
+  %load = load i8, ptr %gep, align 4
+  %zext = zext i8 %load to i32
+  %red.next = add i32 %red.trunc, %zext
+  %iv.next = add i32 %iv, 1
+  %exitcond = icmp eq i32 %iv.next, 256
+  br i1 %exitcond, label %exit, label %loop
+
+exit:
+  %ret = trunc i32 %red.next to i8
+  ret i8 %ret
+}



More information about the llvm-commits mailing list