[llvm] [SLP] Use getRegUsageForType() rather than getNumberOfParts() when determining reduction width (PR #226277)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 15:54:06 PDT 2026


https://github.com/bababuck updated https://github.com/llvm/llvm-project/pull/226277

>From 45a44176758e604153eb9726729aa9d781e4bde5 Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Thu, 24 Sep 2026 12:00:07 -0700
Subject: [PATCH 1/3] [SLP] Add new test for usage of getRegUsageForType()

Creates a large vector reduction where the vector width is larger than the
entire vector register file.
---
 .../RISCV/wide-load-reduction.ll              | 400 ++++++++++++++++++
 1 file changed, 400 insertions(+)
 create mode 100644 llvm/test/Transforms/SLPVectorizer/RISCV/wide-load-reduction.ll

diff --git a/llvm/test/Transforms/SLPVectorizer/RISCV/wide-load-reduction.ll b/llvm/test/Transforms/SLPVectorizer/RISCV/wide-load-reduction.ll
new file mode 100644
index 0000000000000..6d808f98a39f9
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/RISCV/wide-load-reduction.ll
@@ -0,0 +1,400 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=slp-vectorizer -mtriple=riscv64 -mattr=+v,+zvl128b -S | FileCheck %s
+
+define i64 @wide_load_reduction(ptr %ptr) {
+; CHECK-LABEL: define i64 @wide_load_reduction(
+; CHECK-SAME: ptr [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load <128 x i64>, ptr [[PTR]], align 8
+; CHECK-NEXT:    [[RED:%.*]] = call i64 @llvm.vector.reduce.add.v128i64(<128 x i64> [[TMP0]])
+; CHECK-NEXT:    [[RESULT:%.*]] = add i64 [[RED]], 0
+; CHECK-NEXT:    ret i64 [[RESULT]]
+;
+
+entry:
+  %v0 = load i64, ptr %ptr, align 8
+  %sum0 = add nuw nsw i64 %v0, 0
+  %p1 = getelementptr inbounds i64, ptr %ptr, i64 1
+  %v1 = load i64, ptr %p1, align 8
+  %sum1 = add nuw nsw i64 %sum0, %v1
+  %p2 = getelementptr inbounds i64, ptr %ptr, i64 2
+  %v2 = load i64, ptr %p2, align 8
+  %sum2 = add nuw nsw i64 %sum1, %v2
+  %p3 = getelementptr inbounds i64, ptr %ptr, i64 3
+  %v3 = load i64, ptr %p3, align 8
+  %sum3 = add nuw nsw i64 %sum2, %v3
+  %p4 = getelementptr inbounds i64, ptr %ptr, i64 4
+  %v4 = load i64, ptr %p4, align 8
+  %sum4 = add nuw nsw i64 %sum3, %v4
+  %p5 = getelementptr inbounds i64, ptr %ptr, i64 5
+  %v5 = load i64, ptr %p5, align 8
+  %sum5 = add nuw nsw i64 %sum4, %v5
+  %p6 = getelementptr inbounds i64, ptr %ptr, i64 6
+  %v6 = load i64, ptr %p6, align 8
+  %sum6 = add nuw nsw i64 %sum5, %v6
+  %p7 = getelementptr inbounds i64, ptr %ptr, i64 7
+  %v7 = load i64, ptr %p7, align 8
+  %sum7 = add nuw nsw i64 %sum6, %v7
+  %p8 = getelementptr inbounds i64, ptr %ptr, i64 8
+  %v8 = load i64, ptr %p8, align 8
+  %sum8 = add nuw nsw i64 %sum7, %v8
+  %p9 = getelementptr inbounds i64, ptr %ptr, i64 9
+  %v9 = load i64, ptr %p9, align 8
+  %sum9 = add nuw nsw i64 %sum8, %v9
+  %p10 = getelementptr inbounds i64, ptr %ptr, i64 10
+  %v10 = load i64, ptr %p10, align 8
+  %sum10 = add nuw nsw i64 %sum9, %v10
+  %p11 = getelementptr inbounds i64, ptr %ptr, i64 11
+  %v11 = load i64, ptr %p11, align 8
+  %sum11 = add nuw nsw i64 %sum10, %v11
+  %p12 = getelementptr inbounds i64, ptr %ptr, i64 12
+  %v12 = load i64, ptr %p12, align 8
+  %sum12 = add nuw nsw i64 %sum11, %v12
+  %p13 = getelementptr inbounds i64, ptr %ptr, i64 13
+  %v13 = load i64, ptr %p13, align 8
+  %sum13 = add nuw nsw i64 %sum12, %v13
+  %p14 = getelementptr inbounds i64, ptr %ptr, i64 14
+  %v14 = load i64, ptr %p14, align 8
+  %sum14 = add nuw nsw i64 %sum13, %v14
+  %p15 = getelementptr inbounds i64, ptr %ptr, i64 15
+  %v15 = load i64, ptr %p15, align 8
+  %sum15 = add nuw nsw i64 %sum14, %v15
+  %p16 = getelementptr inbounds i64, ptr %ptr, i64 16
+  %v16 = load i64, ptr %p16, align 8
+  %sum16 = add nuw nsw i64 %sum15, %v16
+  %p17 = getelementptr inbounds i64, ptr %ptr, i64 17
+  %v17 = load i64, ptr %p17, align 8
+  %sum17 = add nuw nsw i64 %sum16, %v17
+  %p18 = getelementptr inbounds i64, ptr %ptr, i64 18
+  %v18 = load i64, ptr %p18, align 8
+  %sum18 = add nuw nsw i64 %sum17, %v18
+  %p19 = getelementptr inbounds i64, ptr %ptr, i64 19
+  %v19 = load i64, ptr %p19, align 8
+  %sum19 = add nuw nsw i64 %sum18, %v19
+  %p20 = getelementptr inbounds i64, ptr %ptr, i64 20
+  %v20 = load i64, ptr %p20, align 8
+  %sum20 = add nuw nsw i64 %sum19, %v20
+  %p21 = getelementptr inbounds i64, ptr %ptr, i64 21
+  %v21 = load i64, ptr %p21, align 8
+  %sum21 = add nuw nsw i64 %sum20, %v21
+  %p22 = getelementptr inbounds i64, ptr %ptr, i64 22
+  %v22 = load i64, ptr %p22, align 8
+  %sum22 = add nuw nsw i64 %sum21, %v22
+  %p23 = getelementptr inbounds i64, ptr %ptr, i64 23
+  %v23 = load i64, ptr %p23, align 8
+  %sum23 = add nuw nsw i64 %sum22, %v23
+  %p24 = getelementptr inbounds i64, ptr %ptr, i64 24
+  %v24 = load i64, ptr %p24, align 8
+  %sum24 = add nuw nsw i64 %sum23, %v24
+  %p25 = getelementptr inbounds i64, ptr %ptr, i64 25
+  %v25 = load i64, ptr %p25, align 8
+  %sum25 = add nuw nsw i64 %sum24, %v25
+  %p26 = getelementptr inbounds i64, ptr %ptr, i64 26
+  %v26 = load i64, ptr %p26, align 8
+  %sum26 = add nuw nsw i64 %sum25, %v26
+  %p27 = getelementptr inbounds i64, ptr %ptr, i64 27
+  %v27 = load i64, ptr %p27, align 8
+  %sum27 = add nuw nsw i64 %sum26, %v27
+  %p28 = getelementptr inbounds i64, ptr %ptr, i64 28
+  %v28 = load i64, ptr %p28, align 8
+  %sum28 = add nuw nsw i64 %sum27, %v28
+  %p29 = getelementptr inbounds i64, ptr %ptr, i64 29
+  %v29 = load i64, ptr %p29, align 8
+  %sum29 = add nuw nsw i64 %sum28, %v29
+  %p30 = getelementptr inbounds i64, ptr %ptr, i64 30
+  %v30 = load i64, ptr %p30, align 8
+  %sum30 = add nuw nsw i64 %sum29, %v30
+  %p31 = getelementptr inbounds i64, ptr %ptr, i64 31
+  %v31 = load i64, ptr %p31, align 8
+  %sum31 = add nuw nsw i64 %sum30, %v31
+  %p32 = getelementptr inbounds i64, ptr %ptr, i64 32
+  %v32 = load i64, ptr %p32, align 8
+  %sum32 = add nuw nsw i64 %sum31, %v32
+  %p33 = getelementptr inbounds i64, ptr %ptr, i64 33
+  %v33 = load i64, ptr %p33, align 8
+  %sum33 = add nuw nsw i64 %sum32, %v33
+  %p34 = getelementptr inbounds i64, ptr %ptr, i64 34
+  %v34 = load i64, ptr %p34, align 8
+  %sum34 = add nuw nsw i64 %sum33, %v34
+  %p35 = getelementptr inbounds i64, ptr %ptr, i64 35
+  %v35 = load i64, ptr %p35, align 8
+  %sum35 = add nuw nsw i64 %sum34, %v35
+  %p36 = getelementptr inbounds i64, ptr %ptr, i64 36
+  %v36 = load i64, ptr %p36, align 8
+  %sum36 = add nuw nsw i64 %sum35, %v36
+  %p37 = getelementptr inbounds i64, ptr %ptr, i64 37
+  %v37 = load i64, ptr %p37, align 8
+  %sum37 = add nuw nsw i64 %sum36, %v37
+  %p38 = getelementptr inbounds i64, ptr %ptr, i64 38
+  %v38 = load i64, ptr %p38, align 8
+  %sum38 = add nuw nsw i64 %sum37, %v38
+  %p39 = getelementptr inbounds i64, ptr %ptr, i64 39
+  %v39 = load i64, ptr %p39, align 8
+  %sum39 = add nuw nsw i64 %sum38, %v39
+  %p40 = getelementptr inbounds i64, ptr %ptr, i64 40
+  %v40 = load i64, ptr %p40, align 8
+  %sum40 = add nuw nsw i64 %sum39, %v40
+  %p41 = getelementptr inbounds i64, ptr %ptr, i64 41
+  %v41 = load i64, ptr %p41, align 8
+  %sum41 = add nuw nsw i64 %sum40, %v41
+  %p42 = getelementptr inbounds i64, ptr %ptr, i64 42
+  %v42 = load i64, ptr %p42, align 8
+  %sum42 = add nuw nsw i64 %sum41, %v42
+  %p43 = getelementptr inbounds i64, ptr %ptr, i64 43
+  %v43 = load i64, ptr %p43, align 8
+  %sum43 = add nuw nsw i64 %sum42, %v43
+  %p44 = getelementptr inbounds i64, ptr %ptr, i64 44
+  %v44 = load i64, ptr %p44, align 8
+  %sum44 = add nuw nsw i64 %sum43, %v44
+  %p45 = getelementptr inbounds i64, ptr %ptr, i64 45
+  %v45 = load i64, ptr %p45, align 8
+  %sum45 = add nuw nsw i64 %sum44, %v45
+  %p46 = getelementptr inbounds i64, ptr %ptr, i64 46
+  %v46 = load i64, ptr %p46, align 8
+  %sum46 = add nuw nsw i64 %sum45, %v46
+  %p47 = getelementptr inbounds i64, ptr %ptr, i64 47
+  %v47 = load i64, ptr %p47, align 8
+  %sum47 = add nuw nsw i64 %sum46, %v47
+  %p48 = getelementptr inbounds i64, ptr %ptr, i64 48
+  %v48 = load i64, ptr %p48, align 8
+  %sum48 = add nuw nsw i64 %sum47, %v48
+  %p49 = getelementptr inbounds i64, ptr %ptr, i64 49
+  %v49 = load i64, ptr %p49, align 8
+  %sum49 = add nuw nsw i64 %sum48, %v49
+  %p50 = getelementptr inbounds i64, ptr %ptr, i64 50
+  %v50 = load i64, ptr %p50, align 8
+  %sum50 = add nuw nsw i64 %sum49, %v50
+  %p51 = getelementptr inbounds i64, ptr %ptr, i64 51
+  %v51 = load i64, ptr %p51, align 8
+  %sum51 = add nuw nsw i64 %sum50, %v51
+  %p52 = getelementptr inbounds i64, ptr %ptr, i64 52
+  %v52 = load i64, ptr %p52, align 8
+  %sum52 = add nuw nsw i64 %sum51, %v52
+  %p53 = getelementptr inbounds i64, ptr %ptr, i64 53
+  %v53 = load i64, ptr %p53, align 8
+  %sum53 = add nuw nsw i64 %sum52, %v53
+  %p54 = getelementptr inbounds i64, ptr %ptr, i64 54
+  %v54 = load i64, ptr %p54, align 8
+  %sum54 = add nuw nsw i64 %sum53, %v54
+  %p55 = getelementptr inbounds i64, ptr %ptr, i64 55
+  %v55 = load i64, ptr %p55, align 8
+  %sum55 = add nuw nsw i64 %sum54, %v55
+  %p56 = getelementptr inbounds i64, ptr %ptr, i64 56
+  %v56 = load i64, ptr %p56, align 8
+  %sum56 = add nuw nsw i64 %sum55, %v56
+  %p57 = getelementptr inbounds i64, ptr %ptr, i64 57
+  %v57 = load i64, ptr %p57, align 8
+  %sum57 = add nuw nsw i64 %sum56, %v57
+  %p58 = getelementptr inbounds i64, ptr %ptr, i64 58
+  %v58 = load i64, ptr %p58, align 8
+  %sum58 = add nuw nsw i64 %sum57, %v58
+  %p59 = getelementptr inbounds i64, ptr %ptr, i64 59
+  %v59 = load i64, ptr %p59, align 8
+  %sum59 = add nuw nsw i64 %sum58, %v59
+  %p60 = getelementptr inbounds i64, ptr %ptr, i64 60
+  %v60 = load i64, ptr %p60, align 8
+  %sum60 = add nuw nsw i64 %sum59, %v60
+  %p61 = getelementptr inbounds i64, ptr %ptr, i64 61
+  %v61 = load i64, ptr %p61, align 8
+  %sum61 = add nuw nsw i64 %sum60, %v61
+  %p62 = getelementptr inbounds i64, ptr %ptr, i64 62
+  %v62 = load i64, ptr %p62, align 8
+  %sum62 = add nuw nsw i64 %sum61, %v62
+  %p63 = getelementptr inbounds i64, ptr %ptr, i64 63
+  %v63 = load i64, ptr %p63, align 8
+  %sum63 = add nuw nsw i64 %sum62, %v63
+  %p64 = getelementptr inbounds i64, ptr %ptr, i64 64
+  %v64 = load i64, ptr %p64, align 8
+  %sum64 = add nuw nsw i64 %sum63, %v64
+  %p65 = getelementptr inbounds i64, ptr %ptr, i64 65
+  %v65 = load i64, ptr %p65, align 8
+  %sum65 = add nuw nsw i64 %sum64, %v65
+  %p66 = getelementptr inbounds i64, ptr %ptr, i64 66
+  %v66 = load i64, ptr %p66, align 8
+  %sum66 = add nuw nsw i64 %sum65, %v66
+  %p67 = getelementptr inbounds i64, ptr %ptr, i64 67
+  %v67 = load i64, ptr %p67, align 8
+  %sum67 = add nuw nsw i64 %sum66, %v67
+  %p68 = getelementptr inbounds i64, ptr %ptr, i64 68
+  %v68 = load i64, ptr %p68, align 8
+  %sum68 = add nuw nsw i64 %sum67, %v68
+  %p69 = getelementptr inbounds i64, ptr %ptr, i64 69
+  %v69 = load i64, ptr %p69, align 8
+  %sum69 = add nuw nsw i64 %sum68, %v69
+  %p70 = getelementptr inbounds i64, ptr %ptr, i64 70
+  %v70 = load i64, ptr %p70, align 8
+  %sum70 = add nuw nsw i64 %sum69, %v70
+  %p71 = getelementptr inbounds i64, ptr %ptr, i64 71
+  %v71 = load i64, ptr %p71, align 8
+  %sum71 = add nuw nsw i64 %sum70, %v71
+  %p72 = getelementptr inbounds i64, ptr %ptr, i64 72
+  %v72 = load i64, ptr %p72, align 8
+  %sum72 = add nuw nsw i64 %sum71, %v72
+  %p73 = getelementptr inbounds i64, ptr %ptr, i64 73
+  %v73 = load i64, ptr %p73, align 8
+  %sum73 = add nuw nsw i64 %sum72, %v73
+  %p74 = getelementptr inbounds i64, ptr %ptr, i64 74
+  %v74 = load i64, ptr %p74, align 8
+  %sum74 = add nuw nsw i64 %sum73, %v74
+  %p75 = getelementptr inbounds i64, ptr %ptr, i64 75
+  %v75 = load i64, ptr %p75, align 8
+  %sum75 = add nuw nsw i64 %sum74, %v75
+  %p76 = getelementptr inbounds i64, ptr %ptr, i64 76
+  %v76 = load i64, ptr %p76, align 8
+  %sum76 = add nuw nsw i64 %sum75, %v76
+  %p77 = getelementptr inbounds i64, ptr %ptr, i64 77
+  %v77 = load i64, ptr %p77, align 8
+  %sum77 = add nuw nsw i64 %sum76, %v77
+  %p78 = getelementptr inbounds i64, ptr %ptr, i64 78
+  %v78 = load i64, ptr %p78, align 8
+  %sum78 = add nuw nsw i64 %sum77, %v78
+  %p79 = getelementptr inbounds i64, ptr %ptr, i64 79
+  %v79 = load i64, ptr %p79, align 8
+  %sum79 = add nuw nsw i64 %sum78, %v79
+  %p80 = getelementptr inbounds i64, ptr %ptr, i64 80
+  %v80 = load i64, ptr %p80, align 8
+  %sum80 = add nuw nsw i64 %sum79, %v80
+  %p81 = getelementptr inbounds i64, ptr %ptr, i64 81
+  %v81 = load i64, ptr %p81, align 8
+  %sum81 = add nuw nsw i64 %sum80, %v81
+  %p82 = getelementptr inbounds i64, ptr %ptr, i64 82
+  %v82 = load i64, ptr %p82, align 8
+  %sum82 = add nuw nsw i64 %sum81, %v82
+  %p83 = getelementptr inbounds i64, ptr %ptr, i64 83
+  %v83 = load i64, ptr %p83, align 8
+  %sum83 = add nuw nsw i64 %sum82, %v83
+  %p84 = getelementptr inbounds i64, ptr %ptr, i64 84
+  %v84 = load i64, ptr %p84, align 8
+  %sum84 = add nuw nsw i64 %sum83, %v84
+  %p85 = getelementptr inbounds i64, ptr %ptr, i64 85
+  %v85 = load i64, ptr %p85, align 8
+  %sum85 = add nuw nsw i64 %sum84, %v85
+  %p86 = getelementptr inbounds i64, ptr %ptr, i64 86
+  %v86 = load i64, ptr %p86, align 8
+  %sum86 = add nuw nsw i64 %sum85, %v86
+  %p87 = getelementptr inbounds i64, ptr %ptr, i64 87
+  %v87 = load i64, ptr %p87, align 8
+  %sum87 = add nuw nsw i64 %sum86, %v87
+  %p88 = getelementptr inbounds i64, ptr %ptr, i64 88
+  %v88 = load i64, ptr %p88, align 8
+  %sum88 = add nuw nsw i64 %sum87, %v88
+  %p89 = getelementptr inbounds i64, ptr %ptr, i64 89
+  %v89 = load i64, ptr %p89, align 8
+  %sum89 = add nuw nsw i64 %sum88, %v89
+  %p90 = getelementptr inbounds i64, ptr %ptr, i64 90
+  %v90 = load i64, ptr %p90, align 8
+  %sum90 = add nuw nsw i64 %sum89, %v90
+  %p91 = getelementptr inbounds i64, ptr %ptr, i64 91
+  %v91 = load i64, ptr %p91, align 8
+  %sum91 = add nuw nsw i64 %sum90, %v91
+  %p92 = getelementptr inbounds i64, ptr %ptr, i64 92
+  %v92 = load i64, ptr %p92, align 8
+  %sum92 = add nuw nsw i64 %sum91, %v92
+  %p93 = getelementptr inbounds i64, ptr %ptr, i64 93
+  %v93 = load i64, ptr %p93, align 8
+  %sum93 = add nuw nsw i64 %sum92, %v93
+  %p94 = getelementptr inbounds i64, ptr %ptr, i64 94
+  %v94 = load i64, ptr %p94, align 8
+  %sum94 = add nuw nsw i64 %sum93, %v94
+  %p95 = getelementptr inbounds i64, ptr %ptr, i64 95
+  %v95 = load i64, ptr %p95, align 8
+  %sum95 = add nuw nsw i64 %sum94, %v95
+  %p96 = getelementptr inbounds i64, ptr %ptr, i64 96
+  %v96 = load i64, ptr %p96, align 8
+  %sum96 = add nuw nsw i64 %sum95, %v96
+  %p97 = getelementptr inbounds i64, ptr %ptr, i64 97
+  %v97 = load i64, ptr %p97, align 8
+  %sum97 = add nuw nsw i64 %sum96, %v97
+  %p98 = getelementptr inbounds i64, ptr %ptr, i64 98
+  %v98 = load i64, ptr %p98, align 8
+  %sum98 = add nuw nsw i64 %sum97, %v98
+  %p99 = getelementptr inbounds i64, ptr %ptr, i64 99
+  %v99 = load i64, ptr %p99, align 8
+  %sum99 = add nuw nsw i64 %sum98, %v99
+  %p100 = getelementptr inbounds i64, ptr %ptr, i64 100
+  %v100 = load i64, ptr %p100, align 8
+  %sum100 = add nuw nsw i64 %sum99, %v100
+  %p101 = getelementptr inbounds i64, ptr %ptr, i64 101
+  %v101 = load i64, ptr %p101, align 8
+  %sum101 = add nuw nsw i64 %sum100, %v101
+  %p102 = getelementptr inbounds i64, ptr %ptr, i64 102
+  %v102 = load i64, ptr %p102, align 8
+  %sum102 = add nuw nsw i64 %sum101, %v102
+  %p103 = getelementptr inbounds i64, ptr %ptr, i64 103
+  %v103 = load i64, ptr %p103, align 8
+  %sum103 = add nuw nsw i64 %sum102, %v103
+  %p104 = getelementptr inbounds i64, ptr %ptr, i64 104
+  %v104 = load i64, ptr %p104, align 8
+  %sum104 = add nuw nsw i64 %sum103, %v104
+  %p105 = getelementptr inbounds i64, ptr %ptr, i64 105
+  %v105 = load i64, ptr %p105, align 8
+  %sum105 = add nuw nsw i64 %sum104, %v105
+  %p106 = getelementptr inbounds i64, ptr %ptr, i64 106
+  %v106 = load i64, ptr %p106, align 8
+  %sum106 = add nuw nsw i64 %sum105, %v106
+  %p107 = getelementptr inbounds i64, ptr %ptr, i64 107
+  %v107 = load i64, ptr %p107, align 8
+  %sum107 = add nuw nsw i64 %sum106, %v107
+  %p108 = getelementptr inbounds i64, ptr %ptr, i64 108
+  %v108 = load i64, ptr %p108, align 8
+  %sum108 = add nuw nsw i64 %sum107, %v108
+  %p109 = getelementptr inbounds i64, ptr %ptr, i64 109
+  %v109 = load i64, ptr %p109, align 8
+  %sum109 = add nuw nsw i64 %sum108, %v109
+  %p110 = getelementptr inbounds i64, ptr %ptr, i64 110
+  %v110 = load i64, ptr %p110, align 8
+  %sum110 = add nuw nsw i64 %sum109, %v110
+  %p111 = getelementptr inbounds i64, ptr %ptr, i64 111
+  %v111 = load i64, ptr %p111, align 8
+  %sum111 = add nuw nsw i64 %sum110, %v111
+  %p112 = getelementptr inbounds i64, ptr %ptr, i64 112
+  %v112 = load i64, ptr %p112, align 8
+  %sum112 = add nuw nsw i64 %sum111, %v112
+  %p113 = getelementptr inbounds i64, ptr %ptr, i64 113
+  %v113 = load i64, ptr %p113, align 8
+  %sum113 = add nuw nsw i64 %sum112, %v113
+  %p114 = getelementptr inbounds i64, ptr %ptr, i64 114
+  %v114 = load i64, ptr %p114, align 8
+  %sum114 = add nuw nsw i64 %sum113, %v114
+  %p115 = getelementptr inbounds i64, ptr %ptr, i64 115
+  %v115 = load i64, ptr %p115, align 8
+  %sum115 = add nuw nsw i64 %sum114, %v115
+  %p116 = getelementptr inbounds i64, ptr %ptr, i64 116
+  %v116 = load i64, ptr %p116, align 8
+  %sum116 = add nuw nsw i64 %sum115, %v116
+  %p117 = getelementptr inbounds i64, ptr %ptr, i64 117
+  %v117 = load i64, ptr %p117, align 8
+  %sum117 = add nuw nsw i64 %sum116, %v117
+  %p118 = getelementptr inbounds i64, ptr %ptr, i64 118
+  %v118 = load i64, ptr %p118, align 8
+  %sum118 = add nuw nsw i64 %sum117, %v118
+  %p119 = getelementptr inbounds i64, ptr %ptr, i64 119
+  %v119 = load i64, ptr %p119, align 8
+  %sum119 = add nuw nsw i64 %sum118, %v119
+  %p120 = getelementptr inbounds i64, ptr %ptr, i64 120
+  %v120 = load i64, ptr %p120, align 8
+  %sum120 = add nuw nsw i64 %sum119, %v120
+  %p121 = getelementptr inbounds i64, ptr %ptr, i64 121
+  %v121 = load i64, ptr %p121, align 8
+  %sum121 = add nuw nsw i64 %sum120, %v121
+  %p122 = getelementptr inbounds i64, ptr %ptr, i64 122
+  %v122 = load i64, ptr %p122, align 8
+  %sum122 = add nuw nsw i64 %sum121, %v122
+  %p123 = getelementptr inbounds i64, ptr %ptr, i64 123
+  %v123 = load i64, ptr %p123, align 8
+  %sum123 = add nuw nsw i64 %sum122, %v123
+  %p124 = getelementptr inbounds i64, ptr %ptr, i64 124
+  %v124 = load i64, ptr %p124, align 8
+  %sum124 = add nuw nsw i64 %sum123, %v124
+  %p125 = getelementptr inbounds i64, ptr %ptr, i64 125
+  %v125 = load i64, ptr %p125, align 8
+  %sum125 = add nuw nsw i64 %sum124, %v125
+  %p126 = getelementptr inbounds i64, ptr %ptr, i64 126
+  %v126 = load i64, ptr %p126, align 8
+  %sum126 = add nuw nsw i64 %sum125, %v126
+  %p127 = getelementptr inbounds i64, ptr %ptr, i64 127
+  %v127 = load i64, ptr %p127, align 8
+  %sum127 = add nuw nsw i64 %sum126, %v127
+  ret i64 %sum127
+
+}

>From 8ff300afc63cfd1d78a73961a60387d5efc8cd77 Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Fri, 18 Sep 2026 15:36:58 -0700
Subject: [PATCH 2/3] [SLP] Use getRegUsageForType() rather than
 getNumberOfParts() where appropriate

---
 .../Transforms/Vectorize/SLPVectorizer.cpp    | 36 ++++++++++++++-----
 .../Vectorize/SLPVectorizer/SLPTypeUtils.cpp  |  8 +++--
 .../Vectorize/SLPVectorizer/SLPTypeUtils.h    |  6 ++--
 .../RISCV/wide-load-reduction.ll              |  7 ++--
 4 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 6287cb856c2ed..73689e9d1e7d5 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -849,8 +849,22 @@ class slpvectorizer::BoUpSLP {
     auto [It, Inserted] =
         NumberOfPartsCache.try_emplace(std::make_tuple(VecTy, ScalarTy, Limit));
     if (Inserted)
-      It->second = slpvectorizer::getNumberOfParts(*TTI, VecTy, ScalarTy,
-                                                   SLPReVec, Limit);
+      It->second = slpvectorizer::getNumberOfPartsOrRegs(
+          /*QueryNumParts*/ true, *TTI, VecTy, ScalarTy, SLPReVec, Limit);
+    return It->second;
+  }
+
+  /// \returns the number of parts, the type \p VecTy is split at the codegen
+  /// phase. The type legalization queries are repeated for the very same types
+  /// during the analysis, so the results are cached for the function.
+  unsigned getRegUsageForType(
+      Type *VecTy, Type *ScalarTy,
+      unsigned Limit = std::numeric_limits<unsigned>::max()) const {
+    auto [It, Inserted] =
+        NumberOfRegsCache.try_emplace(std::make_tuple(VecTy, ScalarTy, Limit));
+    if (Inserted)
+      It->second = slpvectorizer::getNumberOfPartsOrRegs(
+          /*QueryNumParts*/ false, *TTI, VecTy, ScalarTy, SLPReVec, Limit);
     return It->second;
   }
 
@@ -3778,6 +3792,10 @@ class slpvectorizer::BoUpSLP {
   mutable SmallDenseMap<std::tuple<Type *, Type *, unsigned>, unsigned>
       NumberOfPartsCache;
 
+  /// Cache of the number of regs for the types and the parts limit.
+  mutable SmallDenseMap<std::tuple<Type *, Type *, unsigned>, unsigned>
+      NumberOfRegsCache;
+
   /// Values already analyzed for minimal bitwidth and found to be
   /// non-profitable, mapped to the size of the tree used for the analysis.
   SmallDenseMap<Value *, unsigned> AnalyzedMinBWVals;
@@ -32359,24 +32377,24 @@ class HorizontalReduction {
 
       unsigned ReduxWidth = NumReducedVals;
       auto GetVectorFactor = [&, &TTI = *TTI](unsigned ReduxWidth) {
-        unsigned NumParts, NumRegs;
+        unsigned NumRegs, NumAvailRegs;
         Type *ScalarTy = Candidates.front()->getType();
         ReduxWidth = getFloorFullVectorNumberOfElements(TTI, ScalarTy,
                                                         ReduxWidth, SLPReVec);
         VectorType *Tp = cast<VectorType>(getWidenedType(ScalarTy, ReduxWidth));
-        NumParts = V.getNumberOfParts(Tp, ScalarTy);
-        NumRegs =
+        NumRegs = V.getRegUsageForType(Tp, ScalarTy);
+        NumAvailRegs =
             TTI.getNumberOfRegisters(TTI.getRegisterClassForType(true, Tp));
-        while (NumParts > NumRegs) {
+        while (NumRegs > NumAvailRegs) {
           assert(ReduxWidth > 0 && "ReduxWidth is unexpectedly 0.");
           ReduxWidth = bit_floor(ReduxWidth - 1);
           VectorType *Tp =
               cast<VectorType>(getWidenedType(ScalarTy, ReduxWidth));
-          NumParts = V.getNumberOfParts(Tp, ScalarTy);
-          NumRegs =
+          NumRegs = V.getRegUsageForType(Tp, ScalarTy);
+          NumAvailRegs =
               TTI.getNumberOfRegisters(TTI.getRegisterClassForType(true, Tp));
         }
-        if (NumParts > NumRegs / 2)
+        if (NumRegs > NumAvailRegs / 2)
           ReduxWidth = bit_floor(ReduxWidth);
         return ReduxWidth;
       };
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.cpp
index 2738857a5bb41..34f46f24be212 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.cpp
@@ -129,11 +129,13 @@ bool isAllowedNonPowerOf2VF(unsigned NumElts, bool AllowNonPowerOf2) {
   return AllowNonPowerOf2 && has_single_bit(NumElts + 1);
 }
 
-unsigned getNumberOfParts(const TargetTransformInfo &TTI, Type *VecTy,
-                          Type *ScalarTy, bool ReVec, unsigned Limit) {
+unsigned getNumberOfPartsOrRegs(bool QueryNumParts,
+                                const TargetTransformInfo &TTI, Type *VecTy,
+                                Type *ScalarTy, bool ReVec, unsigned Limit) {
   if (isa<StructType>(VecTy))
     return 1;
-  unsigned NumParts = TTI.getNumberOfParts(VecTy);
+  unsigned NumParts = QueryNumParts ? TTI.getNumberOfParts(VecTy)
+                                    : TTI.getRegUsageForType(VecTy);
   if (NumParts == 0 || NumParts >= Limit)
     return 1;
   unsigned Sz = getNumElements(VecTy);
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h
index 96ca89659265e..35d0e90ec0126 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPTypeUtils.h
@@ -81,9 +81,9 @@ bool isAllowedNonPowerOf2VF(unsigned NumElts, bool AllowNonPowerOf2);
 /// phase. If the type is going to be scalarized or does not use whole
 /// registers, returns 1.
 unsigned
-getNumberOfParts(const TargetTransformInfo &TTI, Type *VecTy, Type *ScalarTy,
-                 bool ReVec,
-                 unsigned Limit = std::numeric_limits<unsigned>::max());
+getNumberOfPartsOrRegs(bool QueryNumParts, const TargetTransformInfo &TTI,
+                       Type *VecTy, Type *ScalarTy, bool ReVec,
+                       unsigned Limit = std::numeric_limits<unsigned>::max());
 
 } // namespace llvm::slpvectorizer
 
diff --git a/llvm/test/Transforms/SLPVectorizer/RISCV/wide-load-reduction.ll b/llvm/test/Transforms/SLPVectorizer/RISCV/wide-load-reduction.ll
index 6d808f98a39f9..6f6713850b206 100644
--- a/llvm/test/Transforms/SLPVectorizer/RISCV/wide-load-reduction.ll
+++ b/llvm/test/Transforms/SLPVectorizer/RISCV/wide-load-reduction.ll
@@ -5,8 +5,11 @@ define i64 @wide_load_reduction(ptr %ptr) {
 ; CHECK-LABEL: define i64 @wide_load_reduction(
 ; CHECK-SAME: ptr [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
 ; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[TMP0:%.*]] = load <128 x i64>, ptr [[PTR]], align 8
-; CHECK-NEXT:    [[RED:%.*]] = call i64 @llvm.vector.reduce.add.v128i64(<128 x i64> [[TMP0]])
+; CHECK-NEXT:    [[TMP0:%.*]] = load <64 x i64>, ptr [[PTR]], align 8
+; CHECK-NEXT:    [[P64:%.*]] = getelementptr inbounds i64, ptr [[PTR]], i64 64
+; CHECK-NEXT:    [[TMP1:%.*]] = load <64 x i64>, ptr [[P64]], align 8
+; CHECK-NEXT:    [[RDX_OP:%.*]] = add <64 x i64> [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[RED:%.*]] = call i64 @llvm.vector.reduce.add.v64i64(<64 x i64> [[RDX_OP]])
 ; CHECK-NEXT:    [[RESULT:%.*]] = add i64 [[RED]], 0
 ; CHECK-NEXT:    ret i64 [[RESULT]]
 ;

>From 5c84dbe8bd030d3c7d8af69fb1d0a37d8a6258eb Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Thu, 24 Sep 2026 14:14:43 -0700
Subject: [PATCH 3/3] [SLP] Code formatting to address comments

---
 llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 3e91ff1dc6952..b76cf0677c2f6 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -850,7 +850,7 @@ class slpvectorizer::BoUpSLP {
         NumberOfPartsCache.try_emplace(std::make_tuple(VecTy, ScalarTy, Limit));
     if (Inserted)
       It->second = slpvectorizer::getNumberOfPartsOrRegs(
-          /*QueryNumParts*/ true, *TTI, VecTy, ScalarTy, SLPReVec, Limit);
+          /*QueryNumParts=*/true, *TTI, VecTy, ScalarTy, SLPReVec, Limit);
     return It->second;
   }
 
@@ -864,7 +864,7 @@ class slpvectorizer::BoUpSLP {
         NumberOfRegsCache.try_emplace(std::make_tuple(VecTy, ScalarTy, Limit));
     if (Inserted)
       It->second = slpvectorizer::getNumberOfPartsOrRegs(
-          /*QueryNumParts*/ false, *TTI, VecTy, ScalarTy, SLPReVec, Limit);
+          /*QueryNumParts=*/false, *TTI, VecTy, ScalarTy, SLPReVec, Limit);
     return It->second;
   }
 



More information about the llvm-commits mailing list