[llvm] [LoopVectorize] Fix crash in VPWidenRecipe (PR #177357)

Manasij Mukherjee via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 22 05:29:58 PST 2026


https://github.com/manasij7479 created https://github.com/llvm/llvm-project/pull/177357

VPWidenRecipe crashed when the ExtractValue operand was a struct constant. 
Use the extracted value instead.

Fixes #176663

>From f9de623de2dcb31b644d0853cd594455eeab84fd Mon Sep 17 00:00:00 2001
From: Manasij Mukherjee <manasijm at nvidia.com>
Date: Thu, 22 Jan 2026 05:24:23 -0800
Subject: [PATCH] [LoopVectorize] Fix crash in VPWidenRecipe

VPWidenRecipe crashed when the ExtractValue operand was a struct constant.
Use the extracted value instead.

Fixes #176663
---
 .../lib/Transforms/Vectorize/VPlanRecipes.cpp |  4 ++-
 .../multiple-result-intrinsics.ll             | 27 +++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 584b430c8e78e..59209c80d1be1 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -2273,9 +2273,11 @@ void VPWidenRecipe::execute(VPTransformState &State) {
   }
   case Instruction::ExtractValue: {
     assert(getNumOperands() == 2 && "expected single level extractvalue");
-    Value *Op = State.get(getOperand(0));
+    Value *Op = State.get(getOperand(0), /*NeedsScalar=*/true);
     Value *Extract = Builder.CreateExtractValue(
         Op, cast<VPConstantInt>(getOperand(1))->getZExtValue());
+    if (!Extract->getType()->isVectorTy())
+      Extract = Builder.CreateVectorSplat(State.VF, Extract);
     State.set(this, Extract);
     break;
   }
diff --git a/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll b/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll
index f64d43adecfb8..a1650416760cc 100644
--- a/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll
+++ b/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll
@@ -816,3 +816,30 @@ for.body:
 exit:
   ret void
 }
+
+define i32 @smul_with_overflow_constant_args() {
+;
+; CHECK-LABEL: define i32 @smul_with_overflow_constant_args() {
+; CHECK:  [[ENTRY:.*:]]
+; CHECK:  [[VECTOR_PH:.*:]]
+; CHECK:  [[VECTOR_BODY:.*:]]
+; CHECK:  [[MIDDLE_BLOCK:.*:]]
+; CHECK:  [[EXIT:.*:]]
+;
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+  %acc = phi i32 [ 0, %entry ], [ %or, %loop ]
+  %call = tail call { i32, i1 } @llvm.smul.with.overflow.i32(i32 0, i32 0)
+  %overflow = extractvalue { i32, i1 } %call, 1
+  %ext = zext i1 %overflow to i32
+  %or = or i32 %acc, %ext
+  %iv.next = add i64 %iv, 1
+  %done = icmp eq i64 %iv, 1
+  br i1 %done, label %exit, label %loop
+
+exit:
+  ret i32 %or
+}



More information about the llvm-commits mailing list