Skip to content

[VectorCombine] Fix crash in scalarizeVPIntrinsic #72039

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 12, 2023

Conversation

michaelmaitland
Copy link
Contributor

When getSplatOp returns nullptr, the intrinsic cannot be scalarized. This patch includes a test case that fixes a crash from trying to scalarize the VPIntrinsic when getSplatOp returns nullptr. This case can be scalarized in the future by improving getSplatOp, but the checks added in this patch should remain.

This fixes #72034.

When getSplatOp returns nullptr, the intrinsic cannot be scalarized.
This patch includes a test case that fixes a crash from trying to
scalarize the VPIntrinsic when getSplatOp returns nullptr. This case can
be scalarized in the future by improving getSplatOp, but the checks
added in this patch should remain.

This fixes llvm#72034.
@llvmbot
Copy link
Member

llvmbot commented Nov 11, 2023

@llvm/pr-subscribers-llvm-transforms

Author: Michael Maitland (michaelmaitland)

Changes

When getSplatOp returns nullptr, the intrinsic cannot be scalarized. This patch includes a test case that fixes a crash from trying to scalarize the VPIntrinsic when getSplatOp returns nullptr. This case can be scalarized in the future by improving getSplatOp, but the checks added in this patch should remain.

This fixes #72034.


Full diff: https://github.com/llvm/llvm-project/pull/72039.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/VectorCombine.cpp (+2)
  • (added) llvm/test/Transforms/VectorCombine/RISCV/vpintrin-scalarization-shufflevector-splat.ll (+16)
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 9a91ce207bb04c9..6d79c9b13add067 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -843,6 +843,8 @@ bool VectorCombine::scalarizeVPIntrinsic(Instruction &I) {
 
   Value *ScalarOp0 = getSplatValue(Op0);
   Value *ScalarOp1 = getSplatValue(Op1);
+  if (!ScalarOp0 || !ScalarOp1)
+    return false;
   Value *ScalarVal =
       ScalarIntrID
           ? Builder.CreateIntrinsic(VecTy->getScalarType(), *ScalarIntrID,
diff --git a/llvm/test/Transforms/VectorCombine/RISCV/vpintrin-scalarization-shufflevector-splat.ll b/llvm/test/Transforms/VectorCombine/RISCV/vpintrin-scalarization-shufflevector-splat.ll
new file mode 100644
index 000000000000000..d3c477d180aa54f
--- /dev/null
+++ b/llvm/test/Transforms/VectorCombine/RISCV/vpintrin-scalarization-shufflevector-splat.ll
@@ -0,0 +1,16 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt -S -mtriple=riscv64 -mattr=+v %s -passes=vector-combine | FileCheck %s --check-prefix
+
+declare <4 x i64> @llvm.vp.add.v4i64(<4 x i64>, <4 x i64>, <4 x i1>, i32)
+
+define <4 x i64> @add_v4i64_allonesmask(<4 x i64> %x) {
+; CHECK-LABEL: define <4 x i64> @add_v4i64_allonesmask(
+; CHECK-SAME: <4 x i64> [[X:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i64> [[X]], <4 x i64> zeroinitializer, <4 x i32> zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = call <4 x i64> @llvm.vp.add.v4i64(<4 x i64> [[TMP1]], <4 x i64> zeroinitializer, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, i32 0)
+; CHECK-NEXT:    ret <4 x i64> [[TMP2]]
+;
+  %1 = shufflevector <4 x i64> %x, <4 x i64> zeroinitializer, <4 x i32> zeroinitializer
+  %2 = call <4 x i64> @llvm.vp.add.v4i64(<4 x i64> %1, <4 x i64> zeroinitializer, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, i32 0)
+  ret <4 x i64> %2
+}

@@ -843,6 +843,8 @@ bool VectorCombine::scalarizeVPIntrinsic(Instruction &I) {

Value *ScalarOp0 = getSplatValue(Op0);
Value *ScalarOp1 = getSplatValue(Op1);
if (!ScalarOp0 || !ScalarOp1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use getSplatValue at the top where we used isSplatValue? That way we fail out before we do wasted work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Do you know why getSplatValue fails to get the splat even though isSplatValue returns true? That sounds like a bug to me?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getSplatValue can't create new instructions, it can only return an operand of existing instructions. isSplatValue can look at shuffles and see that it splat one of the elements of its input. To get that element as a scalar you would need to insert an extractelement instruction.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@michaelmaitland michaelmaitland merged commit acef83c into llvm:main Nov 12, 2023
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
When getSplatOp returns nullptr, the intrinsic cannot be scalarized.
This patch includes a test case that fixes a crash from trying to
scalarize the VPIntrinsic when getSplatOp returns nullptr.

This fixes llvm#72034.
Guzhu-AMD pushed a commit to GPUOpen-Drivers/llvm-project that referenced this pull request Nov 23, 2023
Local branch amd-gfx 46373f4 Merged main:994d882e151c into amd-gfx:77a9f8374d78
Remote branch main acef83c [VectorCombine] Fix crash in scalarizeVPIntrinsic (llvm#72039)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

vectorcombine crash
3 participants