Index: lib/Transforms/Vectorize/SLPVectorizer.cpp =================================================================== --- lib/Transforms/Vectorize/SLPVectorizer.cpp +++ lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -3940,8 +3940,17 @@ /// /// \returns A candidate reduction value if possible, or \code nullptr \endcode /// if not possible. -static Value *getReductionValue(PHINode *P, BasicBlock *ParentBB, - LoopInfo *LI) { +static Value *getReductionValue(const DominatorTree *DT, PHINode *P, + BasicBlock *ParentBB, LoopInfo *LI) { + // There are situations where the reduction value is not dominated by the + // reduction phi. Vectorizing such cases has been reported to cause + // miscompiles. See PR25787. + auto DominatedReduxValue = [&](Value *R) { + return ( + dyn_cast(R) && + DT->dominates(P->getParent(), dyn_cast(R)->getParent())); + }; + Value *Rdx = nullptr; // Return the incoming value if it comes from the same BB as the phi node. @@ -3951,16 +3960,16 @@ Rdx = P->getIncomingValue(1); } - if (Rdx) + if (Rdx && DominatedReduxValue(Rdx)) return Rdx; // Otherwise, check whether we have a loop latch to look at. Loop *BBL = LI->getLoopFor(ParentBB); if (!BBL) - return Rdx; + return nullptr; BasicBlock *BBLatch = BBL->getLoopLatch(); if (!BBLatch) - return Rdx; + return nullptr; // There is a loop latch, return the incoming value if it comes from // that. This reduction pattern occassionaly turns up. @@ -3970,7 +3979,10 @@ Rdx = P->getIncomingValue(1); } - return Rdx; + if (Rdx && DominatedReduxValue(Rdx)) + return Rdx; + + return nullptr; } /// \brief Attempt to reduce a horizontal reduction. @@ -4065,7 +4077,7 @@ if (P->getNumIncomingValues() != 2) return Changed; - Value *Rdx = getReductionValue(P, BB, LI); + Value *Rdx = getReductionValue(DT, P, BB, LI); // Check if this is a Binary Operator. BinaryOperator *BI = dyn_cast_or_null(Rdx); Index: test/Transforms/SLPVectorizer/AArch64/pr25787.ll =================================================================== --- /dev/null +++ test/Transforms/SLPVectorizer/AArch64/pr25787.ll @@ -0,0 +1,35 @@ +; RUN: opt -slp-vectorizer -slp-threshold=-100 < %s + +; This testcase ensures a that the reduction values feeding a phi +; are dominated by said phi. Failing to handle this case can cause +; codegen errors. +; This test case will crash if such an attempt is made to vectorize +; such a reduction. + +target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" +target triple = "aarch64--linux" + +define void @pr25787() { +bb4: + %_tmp473 = load volatile i16, i16* undef, align 1 + %_tmp503 = load volatile i16, i16* undef, align 1 + %_tmp505 = load volatile i16, i16* undef, align 1 + %_tmp519 = load volatile i16, i16* undef, align 1 + %_tmp521 = load volatile i16, i16* undef, align 1 + %_tmp527 = load volatile i16, i16* undef, align 1 + %_tmp529 = load volatile i16, i16* undef, align 1 + %_tmp535 = load volatile i16, i16* undef, align 1 + %_tmp976 = sub i16 %_tmp527, %_tmp521 + %_tmp983 = sub i16 %_tmp535, %_tmp529 + %_tmp1088 = sub i16 %_tmp503, %_tmp473 + %_tmp1091 = add i16 %_tmp983, %_tmp976 + %_tmp1094 = sub i16 %_tmp519, %_tmp505 + %_tmp1095 = add i16 %_tmp1091, %_tmp1094 + %_tmp1119 = add i16 %_tmp1095, %_tmp1088 + br label %bb15 + +bb15: ; preds = %bb4, %bb15 + %f7.355.0 = phi i16 [ 0, %bb4 ], [ %_tmp1119, %bb15 ] + br label %bb15 +} +