[llvm] 8e9216f - [SLP] Do not make an attempt to match reduction on already erased instruction.

Valery N Dmitriev via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 9 17:18:17 PDT 2021


Author: Valery N Dmitriev
Date: 2021-07-09T17:13:15-07:00
New Revision: 8e9216fe877cf263c93a0f769235bef425d395b6

URL: https://github.com/llvm/llvm-project/commit/8e9216fe877cf263c93a0f769235bef425d395b6
DIFF: https://github.com/llvm/llvm-project/commit/8e9216fe877cf263c93a0f769235bef425d395b6.diff

LOG: [SLP] Do not make an attempt to match reduction on already erased instruction.

 Differential Revision: https://reviews.llvm.org/D105752

Added: 
    llvm/test/Transforms/SLPVectorizer/X86/revectorized_rdx_crash.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 04ee349396cd..c7f36b2de088 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -8174,6 +8174,11 @@ static bool tryToVectorizeHorReductionOrInstOperands(
     Instruction *Inst;
     unsigned Level;
     std::tie(Inst, Level) = Stack.pop_back_val();
+    // Do not try to analyze instruction that has already been vectorized.
+    // This may happen when we vectorize instruction operands on a previous
+    // iteration while stack was populated before that happened.
+    if (R.isDeleted(Inst))
+      continue;
     Value *B0, *B1;
     bool IsBinop = matchRdxBop(Inst, B0, B1);
     bool IsSelect = match(Inst, m_Select(m_Value(), m_Value(), m_Value()));

diff  --git a/llvm/test/Transforms/SLPVectorizer/X86/revectorized_rdx_crash.ll b/llvm/test/Transforms/SLPVectorizer/X86/revectorized_rdx_crash.ll
new file mode 100644
index 000000000000..3d21f47c05b5
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/revectorized_rdx_crash.ll
@@ -0,0 +1,94 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -mtriple=x86_64-unknown -slp-vectorizer -S | FileCheck %s
+
+; REQUIRES: asserts
+
+; SLP crashed when tried to delete instruction with uses.
+; It tried to match reduction subsequently on %i23, then %i22 etc
+; When it reached %i18 it was still failing to match reduction but
+; succeeded with its operands pair: %i17, %i11.
+; Then it popped instruction %i17 from stack to make next attempt on
+; matching reduction but the instruction was actually erased on prior
+; iteration (it was matched and vectorized, which added a use of a deleted
+; instruction)
+
+define void @test() {
+; CHECK-LABEL: @test(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 undef, label [[IF_END:%.*]], label [[FOR_COND_PREHEADER:%.*]]
+; CHECK:       for.cond.preheader:
+; CHECK-NEXT:    [[I:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 2
+; CHECK-NEXT:    [[I1:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 3
+; CHECK-NEXT:    [[I2:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 4
+; CHECK-NEXT:    [[I3:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 5
+; CHECK-NEXT:    [[I4:%.*]] = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 6
+; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[I]] to <2 x i32>*
+; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i32>, <2 x i32>* [[TMP0]], align 8
+; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i32* [[I1]] to <2 x i32>*
+; CHECK-NEXT:    [[TMP3:%.*]] = load <2 x i32>, <2 x i32>* [[TMP2]], align 4
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast i32* [[I2]] to <2 x i32>*
+; CHECK-NEXT:    [[TMP5:%.*]] = load <2 x i32>, <2 x i32>* [[TMP4]], align 16
+; CHECK-NEXT:    [[TMP6:%.*]] = bitcast i32* [[I3]] to <2 x i32>*
+; CHECK-NEXT:    [[TMP7:%.*]] = load <2 x i32>, <2 x i32>* [[TMP6]], align 4
+; CHECK-NEXT:    [[TMP8:%.*]] = add <2 x i32> undef, [[TMP7]]
+; CHECK-NEXT:    [[TMP9:%.*]] = add <2 x i32> [[TMP8]], [[TMP5]]
+; CHECK-NEXT:    [[TMP10:%.*]] = add <2 x i32> [[TMP9]], [[TMP3]]
+; CHECK-NEXT:    [[TMP11:%.*]] = add <2 x i32> [[TMP10]], [[TMP1]]
+; CHECK-NEXT:    [[TMP12:%.*]] = add <2 x i32> [[TMP11]], undef
+; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <2 x i32> [[TMP12]], i32 0
+; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <2 x i32> [[TMP11]], i32 0
+; CHECK-NEXT:    [[I11:%.*]] = add i32 [[TMP14]], [[TMP13]]
+; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x i32> [[TMP12]], i32 1
+; CHECK-NEXT:    [[I18:%.*]] = add i32 [[TMP15]], [[I11]]
+; CHECK-NEXT:    [[I19:%.*]] = add i32 [[TMP15]], [[I18]]
+; CHECK-NEXT:    [[I20:%.*]] = add i32 undef, [[I19]]
+; CHECK-NEXT:    [[I21:%.*]] = add i32 undef, [[I20]]
+; CHECK-NEXT:    [[I22:%.*]] = add i32 undef, [[I21]]
+; CHECK-NEXT:    [[I23:%.*]] = add i32 undef, [[I22]]
+; CHECK-NEXT:    br label [[IF_END]]
+; CHECK:       if.end:
+; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[I23]], [[FOR_COND_PREHEADER]] ], [ undef, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 undef, label %if.end, label %for.cond.preheader
+
+for.cond.preheader:                               ; preds = %entry
+  %i = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 2
+  %i1 = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 3
+  %i2 = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 4
+  %i3 = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 5
+  %i4 = getelementptr inbounds [100 x i32], [100 x i32]* undef, i64 0, i64 6
+  %ld0 = load i32, i32* %i, align 8
+  %ld1 = load i32, i32* %i1, align 4
+  %ld2 = load i32, i32* %i2, align 16
+  %ld3 = load i32, i32* %i3, align 4
+  %i5 = add i32 undef, undef
+  %i6 = add i32 %i5, %ld3
+  %i7 = add i32 %i6, %ld2
+  %i8 = add i32 %i7, %ld1
+  %i9 = add i32 %i8, %ld0
+  %i10 = add i32 %i9, undef
+  %i11 = add i32 %i9, %i10
+  %ld4 = load i32, i32* %i1, align 4
+  %ld5 = load i32, i32* %i2, align 16
+  %ld6 = load i32, i32* %i3, align 4
+  %ld7 = load i32, i32* %i4, align 8
+  %i12 = add i32 undef, undef
+  %i13 = add i32 %i12, %ld7
+  %i14 = add i32 %i13, %ld6
+  %i15 = add i32 %i14, %ld5
+  %i16 = add i32 %i15, %ld4
+  %i17 = add i32 %i16, undef
+  %i18 = add i32 %i17, %i11
+  %i19 = add i32 %i17, %i18
+  %i20 = add i32 undef, %i19
+  %i21 = add i32 undef, %i20
+  %i22 = add i32 undef, %i21
+  %i23 = add i32 undef, %i22
+  br label %if.end
+
+if.end:                                           ; preds = %for.cond.preheader, %entry
+  %r = phi i32 [ %i23, %for.cond.preheader ], [ undef, %entry ]
+  ret void
+}


        


More information about the llvm-commits mailing list