[llvm] [LV][NFC] Add more debug when setting the widening decision (PR #227617)

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 02:56:37 PDT 2026


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

>From 93a04885697ef7859b87fdf137be89433e0b046a Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Wed, 30 Sep 2026 09:12:55 +0000
Subject: [PATCH 1/2] [LV][NFC] Add more debug when setting the widening
 decision

---
 .../Transforms/Vectorize/LoopVectorize.cpp    |  45 +++-
 .../AArch64/memory-widening-debug.ll          | 227 ++++++++++++++++++
 2 files changed, 270 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/Transforms/LoopVectorize/AArch64/memory-widening-debug.ll

diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 45edf702d7092..d2e1eaa91cc3f 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -887,11 +887,25 @@ class LoopVectorizationCostModel {
     CM_InvalidatedDecision
   };
 
+#ifndef NDEBUG
+  void debugWideningDecision(Instruction *I, ElementCount VF, InstWidening W) {
+    const char *WideningStr[] = {
+        "Unknown",       "Widen",     "Widen_Reverse",      "Interleave",
+        "GatherScatter", "Scalarize", "InvalidatedDecision"};
+    LLVM_DEBUG(dbgs() << "LV: Setting widening decision to " << WideningStr[W]
+                      << " for VF " << VF << " and instruction: " << *I
+                      << '\n');
+  }
+#endif
+
   /// Save vectorization decision \p W and \p Cost taken by the cost model for
   /// instruction \p I and vector width \p VF.
   void setWideningDecision(Instruction *I, ElementCount VF, InstWidening W,
                            InstructionCost Cost) {
     assert(VF.isVector() && "Expected VF >=2");
+#ifndef NDEBUG
+    debugWideningDecision(I, VF, W);
+#endif
     WideningDecisions[{I, VF}] = {W, Cost};
   }
 
@@ -912,6 +926,9 @@ class LoopVectorizationCostModel {
       OtherMemberCost = InsertPosCost = Cost / Grp->getNumMembers();
     ;
     for (auto *I : Grp->members()) {
+#ifndef NDEBUG
+      debugWideningDecision(I, VF, W);
+#endif
       if (Grp->getInsertPos() == I)
         WideningDecisions[{I, VF}] = {W, InsertPosCost};
       else
@@ -4561,6 +4578,8 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
       if (!Ptr)
         continue;
 
+      LLVM_DEBUG(dbgs() << "LV: Memory widening: calculating best strategy for "
+                        << I << '\n');
       if (isUniformMemOp(I, VF)) {
         auto IsLegalToScalarize = [&]() {
           if (!VF.isScalable())
@@ -4600,6 +4619,10 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
         // Choose better solution for the current VF,  Note that Invalid
         // costs compare as maximumal large.  If both are invalid, we get
         // scalable invalid which signals a failure and a vectorization abort.
+        LLVM_DEBUG(dbgs() << "LV: Memory widening: uniform memory op has "
+                             "GatherScatterCost =  "
+                          << GatherScatterCost << ", ScalarizationCost = "
+                          << ScalarizationCost << '\n');
         if (GatherScatterCost < ScalarizationCost)
           setWideningDecision(&I, VF, CM_GatherScatter, GatherScatterCost);
         else
@@ -4610,8 +4633,11 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
       // We assume that widening is the best solution when possible.
       if (std::optional<InstWidening> Decision =
               memoryInstructionCanBeWidened(&I, VF)) {
-        setWideningDecision(&I, VF, *Decision,
-                            getConsecutiveMemOpCost(&I, VF, *Decision));
+        InstructionCost WidenCost = getConsecutiveMemOpCost(&I, VF, *Decision);
+        LLVM_DEBUG(
+            dbgs() << "LV: Memory widening: can be widened normally with cost "
+                   << WidenCost << '\n');
+        setWideningDecision(&I, VF, *Decision, WidenCost);
         continue;
       }
 
@@ -4654,6 +4680,11 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
         Decision = CM_Scalarize;
         Cost = ScalarizationCost;
       }
+      LLVM_DEBUG(
+          dbgs() << "LV: Memory widening: InterleaveCost = " << InterleaveCost
+                 << ", GatherScatterCost = " << GatherScatterCost
+                 << ", ScalarizationCost = " << ScalarizationCost << '\n');
+
       // If the instructions belongs to an interleave group, the whole group
       // receives the same decision. The whole group receives the cost, but
       // the cost will actually be assigned to one instruction.
@@ -4710,6 +4741,10 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
         continue;
       if (getWideningDecision(cast<Instruction>(U), VF) != CM_Scalarize)
         continue;
+      auto UI = cast<Instruction>(U);
+      LLVM_DEBUG(
+          dbgs() << "LV: Memory widening: updating decision for load user "
+                 << *UI << '\n');
       setWideningDecision(
           cast<Instruction>(U), VF, CM_Scalarize,
           getMemInstScalarizationCost(cast<Instruction>(U), VF));
@@ -4727,6 +4762,8 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
            (!isUniformMemOp(*I, VF) && Decision == CM_Scalarize))) {
         // Scalarize a widened load of address or update the cost of a scalar
         // load of an address.
+        LLVM_DEBUG(dbgs() << "LV: Memory widening: updating decision for load "
+                          << *I << '\n');
         setWideningDecision(
             I, VF, CM_Scalarize,
             (VF.getKnownMinValue() *
@@ -4742,6 +4779,10 @@ void LoopVectorizationCostModel::setCostBasedWideningDecision(ElementCount VF) {
                                         getMemoryInstructionCost(
                                             Member, ElementCount::getFixed(1)))
                                      : getMemInstScalarizationCost(Member, VF);
+          LLVM_DEBUG(
+              dbgs()
+              << "LV: Memory widening: updating decision for interleave member "
+              << *Member << '\n');
           setWideningDecision(Member, VF, CM_Scalarize, Cost);
           UpdateMemOpUserCost(cast<LoadInst>(Member));
         }
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/memory-widening-debug.ll b/llvm/test/Transforms/LoopVectorize/AArch64/memory-widening-debug.ll
new file mode 100644
index 0000000000000..cad07645990c2
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/memory-widening-debug.ll
@@ -0,0 +1,227 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "LV: Memory widening:" --filter "Setting widening decision" --version 6
+; REQUIRES: asserts
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 \
+; RUN:   -force-vector-interleave=1 -tail-folding-policy=dont-fold-tail \
+; RUN:   -debug-only=loop-vectorize -disable-output %s 2>&1 | FileCheck %s --check-prefix=FIXED
+; RUN: opt -passes=loop-vectorize -mattr=+sve -force-vector-width="vscale x 2" \
+; RUN:   -force-vector-interleave=1 -tail-folding-policy=dont-fold-tail \
+; RUN:   -debug-only=loop-vectorize -disable-output %s 2>&1 | FileCheck %s --check-prefix=SVE
+
+target triple = "aarch64"
+
+ at a = common global [2048 x i32] zeroinitializer, align 16
+ at b = common global [2048 x i32] zeroinitializer, align 16
+ at c = common global [2048 x i32] zeroinitializer, align 16
+ at d = common global [2048 x i32] zeroinitializer, align 16
+
+define void @uniform_load(ptr noalias %dst, ptr noalias readonly %src, i64 %n) {
+; FIXED-LABEL: 'uniform_load'
+; FIXED:  LV: Memory widening: calculating best strategy for %val = load i32, ptr %src, align 4
+; FIXED:  LV: Memory widening: uniform memory op has GatherScatterCost = Invalid, ScalarizationCost = 3
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: %val = load i32, ptr %src, align 4
+; FIXED:  LV: Memory widening: calculating best strategy for store i32 %val, ptr %arrayidx, align 4
+; FIXED:  LV: Memory widening: can be widened normally with cost 1
+; FIXED:  LV: Setting widening decision to Widen for VF 4 and instruction: store i32 %val, ptr %arrayidx, align 4
+;
+; SVE-LABEL: 'uniform_load'
+; SVE:  LV: Memory widening: calculating best strategy for %val = load i32, ptr %src, align 4
+; SVE:  LV: Memory widening: uniform memory op has GatherScatterCost = 21, ScalarizationCost = 3
+; SVE:  LV: Setting widening decision to Scalarize for VF vscale x 2 and instruction: %val = load i32, ptr %src, align 4
+; SVE:  LV: Memory widening: calculating best strategy for store i32 %val, ptr %arrayidx, align 4
+; SVE:  LV: Memory widening: can be widened normally with cost 1
+; SVE:  LV: Setting widening decision to Widen for VF vscale x 2 and instruction: store i32 %val, ptr %arrayidx, align 4
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+  %val = load i32, ptr %src, align 4
+  %arrayidx = getelementptr inbounds i32, ptr %dst, i64 %iv
+  store i32 %val, ptr %arrayidx, align 4
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %for.end, label %for.body
+
+for.end:
+  ret void
+}
+
+define void @interleaved_load(ptr noalias readonly %src, ptr noalias %dst, i64 %n) {
+; FIXED-LABEL: 'interleaved_load'
+; FIXED:  LV: Memory widening: calculating best strategy for %load.0 = load i16, ptr %gep.0, align 2
+; FIXED:  LV: Memory widening: InterleaveCost = 2, GatherScatterCost = Invalid, ScalarizationCost = 32
+; FIXED:  LV: Setting widening decision to Interleave for VF 4 and instruction: %load.0 = load i16, ptr %gep.0, align 2
+; FIXED:  LV: Setting widening decision to Interleave for VF 4 and instruction: %load.1 = load i16, ptr %gep.1, align 2
+; FIXED:  LV: Memory widening: calculating best strategy for %load.1 = load i16, ptr %gep.1, align 2
+; FIXED:  LV: Memory widening: calculating best strategy for store i16 %add, ptr %dst.gep, align 2
+; FIXED:  LV: Memory widening: can be widened normally with cost 1
+; FIXED:  LV: Setting widening decision to Widen for VF 4 and instruction: store i16 %add, ptr %dst.gep, align 2
+;
+; SVE-LABEL: 'interleaved_load'
+; SVE:  LV: Memory widening: calculating best strategy for %load.0 = load i16, ptr %gep.0, align 2
+; SVE:  LV: Memory widening: InterleaveCost = 5, GatherScatterCost = 42, ScalarizationCost = Invalid
+; SVE:  LV: Setting widening decision to Interleave for VF vscale x 2 and instruction: %load.0 = load i16, ptr %gep.0, align 2
+; SVE:  LV: Setting widening decision to Interleave for VF vscale x 2 and instruction: %load.1 = load i16, ptr %gep.1, align 2
+; SVE:  LV: Memory widening: calculating best strategy for %load.1 = load i16, ptr %gep.1, align 2
+; SVE:  LV: Memory widening: calculating best strategy for store i16 %add, ptr %dst.gep, align 2
+; SVE:  LV: Memory widening: can be widened normally with cost 1
+; SVE:  LV: Setting widening decision to Widen for VF vscale x 2 and instruction: store i16 %add, ptr %dst.gep, align 2
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+  %iv2 = shl nuw nsw i64 %iv, 1
+  %gep.0 = getelementptr inbounds i16, ptr %src, i64 %iv2
+  %load.0 = load i16, ptr %gep.0, align 2
+  %idx.1 = or disjoint i64 %iv2, 1
+  %gep.1 = getelementptr inbounds i16, ptr %src, i64 %idx.1
+  %load.1 = load i16, ptr %gep.1, align 2
+  %add = add i16 %load.0, %load.1
+  %dst.gep = getelementptr inbounds i16, ptr %dst, i64 %iv
+  store i16 %add, ptr %dst.gep, align 2
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %for.end, label %for.body
+
+for.end:
+  ret void
+}
+
+define void @interleave_member_update() {
+; FIXED-LABEL: 'interleave_member_update'
+; FIXED:  LV: Memory widening: calculating best strategy for %idx = load i32, ptr %arrayidx, align 8
+; FIXED:  LV: Memory widening: InterleaveCost = 2, GatherScatterCost = Invalid, ScalarizationCost = 16
+; FIXED:  LV: Setting widening decision to Interleave for VF 4 and instruction: %idx = load i32, ptr %arrayidx, align 8
+; FIXED:  LV: Memory widening: calculating best strategy for %val = load i32, ptr %gather.ptr, align 4
+; FIXED:  LV: Memory widening: InterleaveCost = Invalid, GatherScatterCost = Invalid, ScalarizationCost = 52
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: %val = load i32, ptr %gather.ptr, align 4
+; FIXED:  LV: Memory widening: calculating best strategy for %addr.idx = load i32, ptr %addr.idx.ptr, align 4
+; FIXED:  LV: Memory widening: can be widened normally with cost 1
+; FIXED:  LV: Setting widening decision to Widen for VF 4 and instruction: %addr.idx = load i32, ptr %addr.idx.ptr, align 4
+; FIXED:  LV: Memory widening: calculating best strategy for store i32 %val, ptr %scatter.ptr, align 4
+; FIXED:  LV: Memory widening: InterleaveCost = Invalid, GatherScatterCost = Invalid, ScalarizationCost = 52
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: store i32 %val, ptr %scatter.ptr, align 4
+; FIXED:  LV: Memory widening: updating decision for load %addr.idx = load i32, ptr %addr.idx.ptr, align 4
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: %addr.idx = load i32, ptr %addr.idx.ptr, align 4
+; FIXED:  LV: Memory widening: updating decision for interleave member %idx = load i32, ptr %arrayidx, align 8
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: %idx = load i32, ptr %arrayidx, align 8
+;
+; SVE-LABEL: 'interleave_member_update'
+; SVE:  LV: Memory widening: calculating best strategy for %idx = load i32, ptr %arrayidx, align 8
+; SVE:  LV: Memory widening: InterleaveCost = 5, GatherScatterCost = 21, ScalarizationCost = Invalid
+; SVE:  LV: Setting widening decision to Interleave for VF vscale x 2 and instruction: %idx = load i32, ptr %arrayidx, align 8
+; SVE:  LV: Memory widening: calculating best strategy for %val = load i32, ptr %gather.ptr, align 4
+; SVE:  LV: Memory widening: InterleaveCost = Invalid, GatherScatterCost = 21, ScalarizationCost = Invalid
+; SVE:  LV: Setting widening decision to GatherScatter for VF vscale x 2 and instruction: %val = load i32, ptr %gather.ptr, align 4
+; SVE:  LV: Memory widening: calculating best strategy for %addr.idx = load i32, ptr %addr.idx.ptr, align 4
+; SVE:  LV: Memory widening: can be widened normally with cost 1
+; SVE:  LV: Setting widening decision to Widen for VF vscale x 2 and instruction: %addr.idx = load i32, ptr %addr.idx.ptr, align 4
+; SVE:  LV: Memory widening: calculating best strategy for store i32 %val, ptr %scatter.ptr, align 4
+; SVE:  LV: Memory widening: InterleaveCost = Invalid, GatherScatterCost = 21, ScalarizationCost = Invalid
+; SVE:  LV: Setting widening decision to GatherScatter for VF vscale x 2 and instruction: store i32 %val, ptr %scatter.ptr, align 4
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+  %iv2 = shl nsw i64 %iv, 1
+  %arrayidx = getelementptr inbounds [2048 x i32], ptr @c, i64 0, i64 %iv2
+  %idx = load i32, ptr %arrayidx, align 8
+  %idxprom = sext i32 %idx to i64
+  %gather.ptr = getelementptr inbounds [2048 x i32], ptr @b, i64 0, i64 %idxprom
+  %val = load i32, ptr %gather.ptr, align 4
+  %addr.idx.ptr = getelementptr inbounds [2048 x i32], ptr @d, i64 0, i64 %iv
+  %addr.idx = load i32, ptr %addr.idx.ptr, align 4
+  %scatter.idx = sext i32 %addr.idx to i64
+  %scatter.ptr = getelementptr inbounds [2048 x i32], ptr @a, i64 0, i64 %scatter.idx
+  store i32 %val, ptr %scatter.ptr, align 4
+  %iv.next = add i64 %iv, 1
+  %lftr.wideiv = trunc i64 %iv.next to i32
+  %exitcond = icmp eq i32 %lftr.wideiv, 256
+  br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+  ret void
+}
+
+define void @reverse_load_scatter(ptr noalias %src, ptr noalias %dst, i64 %n) {
+; FIXED-LABEL: 'reverse_load_scatter'
+; FIXED:  LV: Memory widening: calculating best strategy for %val = load i64, ptr %src.ptr, align 8
+; FIXED:  LV: Memory widening: can be widened normally with cost 4
+; FIXED:  LV: Setting widening decision to Widen_Reverse for VF 4 and instruction: %val = load i64, ptr %src.ptr, align 8
+; FIXED:  LV: Memory widening: calculating best strategy for store i64 %val, ptr %dst.ptr, align 8
+; FIXED:  LV: Memory widening: InterleaveCost = Invalid, GatherScatterCost = Invalid, ScalarizationCost = 60
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: store i64 %val, ptr %dst.ptr, align 8
+; FIXED:  LV: Memory widening: updating decision for load %val = load i64, ptr %src.ptr, align 8
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: %val = load i64, ptr %src.ptr, align 8
+; FIXED:  LV: Memory widening: updating decision for load user store i64 %val, ptr %dst.ptr, align 8
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: store i64 %val, ptr %dst.ptr, align 8
+;
+; SVE-LABEL: 'reverse_load_scatter'
+; SVE:  LV: Memory widening: calculating best strategy for %val = load i64, ptr %src.ptr, align 8
+; SVE:  LV: Memory widening: can be widened normally with cost 2
+; SVE:  LV: Setting widening decision to Widen_Reverse for VF vscale x 2 and instruction: %val = load i64, ptr %src.ptr, align 8
+; SVE:  LV: Memory widening: calculating best strategy for store i64 %val, ptr %dst.ptr, align 8
+; SVE:  LV: Memory widening: InterleaveCost = Invalid, GatherScatterCost = 21, ScalarizationCost = Invalid
+; SVE:  LV: Setting widening decision to GatherScatter for VF vscale x 2 and instruction: store i64 %val, ptr %dst.ptr, align 8
+;
+entry:
+  br label %loop
+
+loop:
+  %iv.dec = phi i64 [ %n, %entry ], [ %iv.dec.next, %loop ]
+  %src.ptr = getelementptr inbounds i64, ptr %src, i64 %iv.dec
+  %val = load i64, ptr %src.ptr, align 8
+  %dst.ptr = getelementptr inbounds i64, ptr %dst, i64 %val
+  store i64 %val, ptr %dst.ptr, align 8
+  %iv.dec.next = add i64 %iv.dec, -1
+  %done = icmp eq i64 %iv.dec.next, 0
+  br i1 %done, label %exit, label %loop
+
+exit:
+  ret void
+}
+
+define double @gather_load(ptr noalias readonly %data, ptr noalias readonly %offset, i64 %n) {
+; FIXED-LABEL: 'gather_load'
+; FIXED:  LV: Memory widening: calculating best strategy for %idx = load i32, ptr %idx.ptr, align 4
+; FIXED:  LV: Memory widening: can be widened normally with cost 1
+; FIXED:  LV: Setting widening decision to Widen for VF 4 and instruction: %idx = load i32, ptr %idx.ptr, align 4
+; FIXED:  LV: Memory widening: calculating best strategy for %val = load double, ptr %gather.ptr, align 8
+; FIXED:  LV: Memory widening: InterleaveCost = Invalid, GatherScatterCost = Invalid, ScalarizationCost = 48
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: %val = load double, ptr %gather.ptr, align 8
+; FIXED:  LV: Memory widening: updating decision for load %idx = load i32, ptr %idx.ptr, align 4
+; FIXED:  LV: Setting widening decision to Scalarize for VF 4 and instruction: %idx = load i32, ptr %idx.ptr, align 4
+;
+; SVE-LABEL: 'gather_load'
+; SVE:  LV: Memory widening: calculating best strategy for %idx = load i32, ptr %idx.ptr, align 4
+; SVE:  LV: Memory widening: can be widened normally with cost 1
+; SVE:  LV: Setting widening decision to Widen for VF vscale x 2 and instruction: %idx = load i32, ptr %idx.ptr, align 4
+; SVE:  LV: Memory widening: calculating best strategy for %val = load double, ptr %gather.ptr, align 8
+; SVE:  LV: Memory widening: InterleaveCost = Invalid, GatherScatterCost = 21, ScalarizationCost = Invalid
+; SVE:  LV: Setting widening decision to GatherScatter for VF vscale x 2 and instruction: %val = load double, ptr %gather.ptr, align 8
+;
+entry:
+  br label %for.body
+
+for.body:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
+  %sum = phi double [ 0.000000e+00, %entry ], [ %add, %for.body ]
+  %idx.ptr = getelementptr inbounds i32, ptr %offset, i64 %iv
+  %idx = load i32, ptr %idx.ptr, align 4
+  %idxprom = sext i32 %idx to i64
+  %gather.ptr = getelementptr inbounds double, ptr %data, i64 %idxprom
+  %val = load double, ptr %gather.ptr, align 8
+  %add = fadd double %sum, %val
+  %iv.next = add nuw nsw i64 %iv, 1
+  %exitcond.not = icmp eq i64 %iv.next, %n
+  br i1 %exitcond.not, label %for.end, label %for.body
+
+for.end:
+  %res = phi double [ %add, %for.body ]
+  ret double %res
+}

>From 363a6c91f020fc38f7cd8738c62a03357de79131 Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Thu, 1 Oct 2026 09:55:38 +0000
Subject: [PATCH 2/2] Address review comments

---
 .../Transforms/Vectorize/LoopVectorize.cpp    | 20 +++++++++----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index d2e1eaa91cc3f..ac94af68fd827 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -888,13 +888,11 @@ class LoopVectorizationCostModel {
   };
 
 #ifndef NDEBUG
-  void debugWideningDecision(Instruction *I, ElementCount VF, InstWidening W) {
-    const char *WideningStr[] = {
+  static constexpr StringLiteral getInstWideningStr(InstWidening W) {
+    constexpr StringLiteral WideningStr[] = {
         "Unknown",       "Widen",     "Widen_Reverse",      "Interleave",
         "GatherScatter", "Scalarize", "InvalidatedDecision"};
-    LLVM_DEBUG(dbgs() << "LV: Setting widening decision to " << WideningStr[W]
-                      << " for VF " << VF << " and instruction: " << *I
-                      << '\n');
+    return WideningStr[W];
   }
 #endif
 
@@ -903,9 +901,9 @@ class LoopVectorizationCostModel {
   void setWideningDecision(Instruction *I, ElementCount VF, InstWidening W,
                            InstructionCost Cost) {
     assert(VF.isVector() && "Expected VF >=2");
-#ifndef NDEBUG
-    debugWideningDecision(I, VF, W);
-#endif
+    LLVM_DEBUG(dbgs() << "LV: Setting widening decision to "
+                      << getInstWideningStr(W) << " for VF " << VF
+                      << " and instruction: " << *I << '\n');
     WideningDecisions[{I, VF}] = {W, Cost};
   }
 
@@ -926,9 +924,9 @@ class LoopVectorizationCostModel {
       OtherMemberCost = InsertPosCost = Cost / Grp->getNumMembers();
     ;
     for (auto *I : Grp->members()) {
-#ifndef NDEBUG
-      debugWideningDecision(I, VF, W);
-#endif
+      LLVM_DEBUG(dbgs() << "LV: Setting widening decision to "
+                        << getInstWideningStr(W) << " for VF " << VF
+                        << " and instruction: " << *I << '\n');
       if (Grp->getInsertPos() == I)
         WideningDecisions[{I, VF}] = {W, InsertPosCost};
       else



More information about the llvm-commits mailing list