[llvm] Fix potential crash in SLPVectorizer caused by missing check (PR #95937)
Gabriel Baraldi via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 26 07:37:14 PDT 2024
https://github.com/gbaraldi updated https://github.com/llvm/llvm-project/pull/95937
>From ede86891d995c0d7b4f14756aea8bf9a198553ff Mon Sep 17 00:00:00 2001
From: Gabriel Baraldi <baraldigabriel at gmail.com>
Date: Tue, 18 Jun 2024 14:38:54 +0000
Subject: [PATCH 1/2] Fix potential crash in SLPVectorizer caused by missing
null check
---
.../Transforms/Vectorize/SLPVectorizer.cpp | 2 +-
.../SLPVectorizer/AArch64/uselistorder.ll | 43 +++++++++++++++++++
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Transforms/SLPVectorizer/AArch64/uselistorder.ll
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index ae0819c964bef..edc9af258644c 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -835,7 +835,7 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
auto *CallBase = cast<CallInst>(IBase);
if (Call->getCalledFunction() != CallBase->getCalledFunction())
return InstructionsState(VL[BaseIndex], nullptr, nullptr);
- if (Call->hasOperandBundles() &&
+ if (Call->hasOperandBundles() && CallBase->hasOperandBundles() &&
!std::equal(Call->op_begin() + Call->getBundleOperandsStartIndex(),
Call->op_begin() + Call->getBundleOperandsEndIndex(),
CallBase->op_begin() +
diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/uselistorder.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/uselistorder.ll
new file mode 100644
index 0000000000000..3a68a37c9f82c
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/AArch64/uselistorder.ll
@@ -0,0 +1,43 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=slp-vectorizer -S -pass-remarks-missed=slp-vectorizer 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-gnu"
+
+; This test has UB but the crash in #95016 only happens with it
+define void @uselistorder_test() {
+; CHECK-LABEL: @uselistorder_test(
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x double> poison, double 0.000000e+00, i32 0
+; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x double> [[TMP1]], double 0.000000e+00, i32 1
+; CHECK-NEXT: [[TMP3:%.*]] = fadd <2 x double> [[TMP2]], zeroinitializer
+; CHECK-NEXT: [[TMP4:%.*]] = fmul <2 x double> zeroinitializer, [[TMP3]]
+; CHECK-NEXT: [[TMP5:%.*]] = fmul <2 x double> [[TMP4]], zeroinitializer
+; CHECK-NEXT: [[TMP6:%.*]] = select <2 x i1> zeroinitializer, <2 x double> zeroinitializer, <2 x double> [[TMP5]]
+; CHECK-NEXT: [[TMP7:%.*]] = fmul <2 x double> [[TMP6]], zeroinitializer
+; CHECK-NEXT: [[TMP8:%.*]] = fadd <2 x double> [[TMP7]], zeroinitializer
+; CHECK-NEXT: store <2 x double> [[TMP8]], ptr null, align 8
+; CHECK-NEXT: ret void
+;
+ %max1 = call double @llvm.maximum.f64(double 0.000000e+00, double 0.000000e+00) [ "a_list"(ptr null) ]
+ %add1 = fadd double %max1, 0.000000e+00
+ %mul1 = fmul double 0.000000e+00, %add1
+ %mul2 = fmul double %mul1, 0.000000e+00
+ %sel1 = select i1 false, double 0.000000e+00, double %mul2
+ %max2 = call double @llvm.maximum.f64(double 0.000000e+00, double 0.000000e+00)
+ %add2 = fadd double %max2, 0.000000e+00
+ %mul3 = fmul double 0.000000e+00, %add2
+ %mul4 = fmul double %mul3, 0.000000e+00
+ %sel2 = select i1 false, double 0.000000e+00, double %mul4
+ %mul5 = fmul double %sel2, 0.000000e+00
+ %add3 = fadd double 0.000000e+00, %mul5
+ %gep1 = getelementptr { double, [1 x [2 x double]] }, ptr null, i64 0, i32 1
+ store double %add3, ptr %gep1, align 8
+ %mul6 = fmul double %sel1, 0.000000e+00
+ %add4 = fadd double %mul6, 0.000000e+00
+ store double %add4, ptr null, align 8
+ ret void
+}
+
+declare double @llvm.maximum.f64(double, double) #0
+
+attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
>From 86deae0c7f818c29ca76fa9bdd607e7946327360 Mon Sep 17 00:00:00 2001
From: Gabriel Baraldi <baraldigabriel at gmail.com>
Date: Wed, 26 Jun 2024 14:36:58 +0000
Subject: [PATCH 2/2] Apply suggestions from code review
---
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 4948b5f191b1a..e098e0d2f5f5a 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -835,11 +835,11 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
auto *CallBase = cast<CallInst>(IBase);
if (Call->getCalledFunction() != CallBase->getCalledFunction())
return InstructionsState(VL[BaseIndex], nullptr, nullptr);
- if (Call->hasOperandBundles() && CallBase->hasOperandBundles() &&
+ if (Call->hasOperandBundles() && (!CallBase->hasOperandBundles() ||
!std::equal(Call->op_begin() + Call->getBundleOperandsStartIndex(),
Call->op_begin() + Call->getBundleOperandsEndIndex(),
CallBase->op_begin() +
- CallBase->getBundleOperandsStartIndex()))
+ CallBase->getBundleOperandsStartIndex())))
return InstructionsState(VL[BaseIndex], nullptr, nullptr);
Intrinsic::ID ID = getVectorIntrinsicIDForCall(Call, &TLI);
if (ID != BaseID)
More information about the llvm-commits
mailing list