Author: Alexis Engelke Date: 2024-08-11T05:55:56Z New Revision: 1739628f12950e3ddbd80418750b93cdc11b48e8
URL: https://github.com/llvm/llvm-project/commit/1739628f12950e3ddbd80418750b93cdc11b48e8 DIFF: https://github.com/llvm/llvm-project/commit/1739628f12950e3ddbd80418750b93cdc11b48e8.diff LOG: Fix SLPVectorize assumption that all users are in the same function Added: llvm/test/Transforms/SLPVectorizer/const-in-different-functions.ll Modified: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 186b382addd710..91e180f9eea13c 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -5998,7 +5998,9 @@ BoUpSLP::collectUserStores(const BoUpSLP::TreeEntry *TE) const { // Collect stores per pointer object. for (User *U : V->users()) { auto *SI = dyn_cast<StoreInst>(U); - if (SI == nullptr || !SI->isSimple() || + // Test whether we can handle the store. If V is a constant, its users + // might be in diff erent functions. + if (SI == nullptr || !SI->isSimple() || SI->getFunction() != F || !isValidElementType(SI->getValueOperand()->getType())) continue; // Skip entry if already diff --git a/llvm/test/Transforms/SLPVectorizer/const-in- diff erent-functions.ll b/llvm/test/Transforms/SLPVectorizer/const-in- diff erent-functions.ll new file mode 100644 index 00000000000000..29a8f15733c450 --- /dev/null +++ b/llvm/test/Transforms/SLPVectorizer/const-in- diff erent-functions.ll @@ -0,0 +1,46 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -S -mtriple=x86_64 -passes=slp-vectorizer < %s | FileCheck %s + +; Test that SLP vectorize doesn't crash if a stored constant is used in multiple +; functions. + +define void @_Z1hPfl() { +; CHECK-LABEL: define void @_Z1hPfl() { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr null, i64 28 +; CHECK-NEXT: store <2 x float> <float 0.000000e+00, float 1.000000e+00>, ptr [[TMP0]], align 4 +; CHECK-NEXT: ret void +; +entry: + %0 = getelementptr i8, ptr null, i64 28 + store float 0.000000e+00, ptr %0, align 4 + %1 = getelementptr i8, ptr null, i64 32 + store float 1.000000e+00, ptr %1, align 16 + ret void +} + +define void @_Z1mv(i64 %arrayidx4.i.2.idx) { +; CHECK-LABEL: define void @_Z1mv( +; CHECK-SAME: i64 [[ARRAYIDX4_I_2_IDX:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: ret void +; CHECK: [[FOR_COND1_PREHEADER_LR_PH_I:.*:]] +; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER_I:.*]] +; CHECK: [[FOR_COND1_PREHEADER_I]]: +; CHECK-NEXT: store float 1.000000e+00, ptr null, align 4 +; CHECK-NEXT: [[ARRAYIDX4_I_2:%.*]] = getelementptr i8, ptr null, i64 [[ARRAYIDX4_I_2_IDX]] +; CHECK-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX4_I_2]], align 4 +; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER_I]] +; +entry: + ret void + +for.cond1.preheader.lr.ph.i: ; No predecessors! + br label %for.cond1.preheader.i + +for.cond1.preheader.i: ; preds = %for.cond1.preheader.i, %for.cond1.preheader.lr.ph.i + store float 1.000000e+00, ptr null, align 4 + %arrayidx4.i.2 = getelementptr i8, ptr null, i64 %arrayidx4.i.2.idx + store float 0.000000e+00, ptr %arrayidx4.i.2, align 4 + br label %for.cond1.preheader.i +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits