[llvm] 455ca0e - [SLP] Allow reordering of vectorization trees with reused instructions.

Alexey.Bataev via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 19 08:44:27 PDT 2020


Hi Bogdan, yes, this is what I thought! Thanks, I'll investigate it.

-------------
Best regards,
Alexey Bataev

19.09.2020 11:38 AM, Bogdan Graur пишет:
> Hi folks,
>
> I've attached with gdb to the running clang process (after ~1h 40m it
> started compiling) and got this trace:
>
> (gdb) bt
> #0  0x0000557ce35c98af in
> llvm::slpvectorizer::BoUpSLP::findRootOrder(llvm::SmallVector<unsigned
> int, 4u>&) ()
> #1  0x0000557ce4212a56 in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #2  0x0000557ce4212c2d in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #3  0x0000557ce42120fd in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #4  0x0000557ce4211cc6 in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #5  0x0000557ce4212c50 in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #6  0x0000557ce4211cc6 in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #7  0x0000557ce421341b in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #8  0x0000557ce4212c50 in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #9  0x0000557ce42147ef in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #10 0x0000557ce4212996 in
> llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>,
> unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) ()
> #11 0x0000557ce420f3ba in
> llvm::slpvectorizer::BoUpSLP::buildTree(llvm::ArrayRef<llvm::Value*>,
> llvm::MapVector<llvm::Value*, llvm::SmallVector<llvm::Instruction*,
> 2u>, llvm::DenseMap<llvm::Value*, unsigned int,
> llvm::DenseMapInfo<llvm::Value*>,
> llvm::detail::DenseMapPair<llvm::Value*, unsigned int> >,
> std::__u::vector<std::__u::pair<llvm::Value*,
> llvm::SmallVector<llvm::Instruction*, 2u> >,
> std::__u::allocator<std::__u::pair<llvm::Value*,
> llvm::SmallVector<llvm::Instruction*, 2u> > > > >&,
> llvm::ArrayRef<llvm::Value*>) ()                                      
>                                                                      
>                                                                      
>                                
> #12 0x0000557ce420afca in
> llvm::SLPVectorizerPass::vectorizeRootInstruction(llvm::PHINode*,
> llvm::Value*, llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&,
> llvm::TargetTransformInfo*) ()
> #13 0x0000557ce420269d in
> llvm::SLPVectorizerPass::runImpl(llvm::Function&,
> llvm::ScalarEvolution*, llvm::TargetTransformInfo*,
> llvm::TargetLibraryInfo*, llvm::AAResults*, llvm::LoopInfo*,
> llvm::DominatorTree*, llvm::AssumptionCache*, llvm::DemandedBits*,
> llvm::OptimizationRemarkEmitter*) ()
> #14 0x0000557ce2e7c7af in
> llvm::SLPVectorizerPass::run(llvm::Function&,
> llvm::AnalysisManager<llvm::Function>&) ()
> #15 0x0000557ce2e7c5b2 in llvm::detail::PassModel<llvm::Function,
> llvm::SLPVectorizerPass, llvm::PreservedAnalyses,
> llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&,
> llvm::AnalysisManager<llvm::Function>&) ()
> #16 0x0000557ce39153c7 in llvm::PassManager<llvm::Function,
> llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&,
> llvm::AnalysisManager<llvm::Function>&) ()
> #17 0x0000557ce44d8c69 in llvm::detail::PassModel<llvm::Module,
> llvm::ModuleToFunctionPassAdaptor<llvm::PassManager<llvm::Function,
> llvm::AnalysisManager<llvm::Function>> >, llvm::PreservedAnalyses,
> llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&,
> llvm::AnalysisManager<llvm::Module>&) ()
> #18 0x0000557ce2fda20b in llvm::PassManager<llvm::Module,
> llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&,
> llvm::AnalysisManager<llvm::Module>&) ()
> #19 0x0000557ce2fda0b2 in llvm::detail::PassModel<llvm::Module,
> llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>,
> llvm::PreservedAnalyses,
> llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&,
> llvm::AnalysisManager<llvm::Module>&) ()
> #20 0x0000557ce2fda20b in llvm::PassManager<llvm::Module,
> llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&,
> llvm::AnalysisManager<llvm::Module>&) ()
> #21 0x0000557ce44b7c08 in (anonymous
> namespace)::EmitAssemblyHelper::EmitAssemblyWithNewPassManager(clang::BackendAction,
> std::__u::unique_ptr<llvm::raw_pwrite_stream,
> std::__u::default_delete<llvm::raw_pwrite_stream> >) ()
> #22 0x0000557ce31bb048 in
> clang::EmitBackendOutput(clang::DiagnosticsEngine&,
> clang::HeaderSearchOptions const&, clang::CodeGenOptions const&,
> clang::TargetOptions const&, clang::LangOptions const&,
> llvm::DataLayout const&, llvm::Module*, clang::BackendAction,
> std::__u::unique_ptr<llvm::raw_pwrite_stream,
> std::__u::default_delete<llvm::raw_pwrite_stream> >) ()
> #23 0x0000557ce31ba7f6 in
> clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) ()
> #24 0x0000557ce3005d80 in clang::ParseAST(clang::Sema&, bool, bool) ()
> #25 0x0000557ce3138515 in clang::FrontendAction::Execute() ()
> #26 0x0000557ce3137b54 in
> clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) ()
> #27 0x0000557ce3136bb0 in
> clang::ExecuteCompilerInvocation(clang::CompilerInstance*) ()
> #28 0x0000557ce312a4ae in cc1_main(llvm::ArrayRef<char const*>, char
> const*, void*) ()
> #29 0x0000557ce312997d in ExecuteCC1Tool(llvm::SmallVectorImpl<char
> const*>&) ()
> #30 0x0000557ce42ab049 in main ()
>
> It looks to me the control flow is stuck in
> llvm::slpvectorizer::BoUpSLP::findRootOrder(llvm::SmallVector<unsigned
> int, 4u>&) () as I issued a GDB 'finish' command which didn't finish
> after ~5m.
>
> Please let me know if you need more info!
>
> Best,
>
> On Fri, Sep 18, 2020 at 10:47 PM Eric Christopher <echristo at gmail.com
> <mailto:echristo at gmail.com>> wrote:
>
>     Following up here:
>
>     After discussing with Alexey on IRC I've temporarily reverted
>     this. Bogdan was seeing infinite loops in compilation and is going
>     to follow up with a backtrace and a test case later if the
>     backtrace isn't enough.
>
>     Reverted thusly:
>     echristo at athyra ~/s/llvm-project (master)> git push
>     To github.com:llvm/llvm-project.git
>        b168bbfae42..ecfd8161bf4  master -> master
>
>     Thanks a ton Alexey, we'll get back to you asap.
>
>     -eric
>
>
>     On Fri, Sep 18, 2020 at 9:38 AM Alexey Bataev via llvm-commits
>     <llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>>
>     wrote:
>
>
>         Author: Alexey Bataev
>         Date: 2020-09-18T09:34:59-04:00
>         New Revision: 455ca0ebb69210046928fedffe292420a30f89ad
>
>         URL:
>         https://github.com/llvm/llvm-project/commit/455ca0ebb69210046928fedffe292420a30f89ad
>         <https://github.com/llvm/llvm-project/commit/455ca0ebb69210046928fedffe292420a30f89ad>
>         DIFF:
>         https://github.com/llvm/llvm-project/commit/455ca0ebb69210046928fedffe292420a30f89ad.diff
>         <https://github.com/llvm/llvm-project/commit/455ca0ebb69210046928fedffe292420a30f89ad.diff>
>
>         LOG: [SLP] Allow reordering of vectorization trees with reused
>         instructions.
>
>         If some leaves have the same instructions to be vectorized, we may
>         incorrectly evaluate the best order for the root node (it is
>         built for the
>         vector of instructions without repeated instructions and,
>         thus, has less
>         elements than the root node). In this case we just can not try
>         to reorder
>         the tree + we may calculate the wrong number of nodes that
>         requre the
>         same reordering.
>         For example, if the root node is \<a+b, a+c, a+d, f+e\>, then
>         the leaves
>         are \<a, a, a, f\> and \<b, c, d, e\>. When we try to
>         vectorize the first
>         leaf, it will be shrink to \<a, b\>. If instructions in this
>         leaf should
>         be reordered, the best order will be \<1, 0\>. We need to
>         extend this
>         order for the root node. For the root node this order should
>         look like
>         \<3, 0, 1, 2\>. This patch allows extension of the orders of
>         the nodes
>         with the reused instructions.
>
>         Reviewed By: RKSimon
>
>         Differential Revision: https://reviews.llvm.org/D45263
>         <https://reviews.llvm.org/D45263>
>
>         Added:
>
>
>         Modified:
>             llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
>             llvm/test/Transforms/SLPVectorizer/X86/jumbled_store_crash.ll
>             llvm/test/Transforms/SLPVectorizer/X86/reorder_repeated_ops.ll
>            
>         llvm/test/Transforms/SLPVectorizer/X86/vectorize-reorder-reuse.ll
>
>         Removed:
>
>
>
>         ################################################################################
>         diff  --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
>         b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
>         index c487301177c1..e4cad01e958a 100644
>         --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
>         +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
>         @@ -523,6 +523,15 @@ static bool isSimple(Instruction *I) {
>
>          namespace llvm {
>
>         +static void inversePermutation(ArrayRef<unsigned> Indices,
>         +                               SmallVectorImpl<int> &Mask) {
>         +  Mask.clear();
>         +  const unsigned E = Indices.size();
>         +  Mask.resize(E, E + 1);
>         +  for (unsigned I = 0; I < E; ++I)
>         +    Mask[Indices[I]] = I;
>         +}
>         +
>          namespace slpvectorizer {
>
>          /// Bottom Up SLP Vectorizer.
>         @@ -537,6 +546,7 @@ class BoUpSLP {
>            using StoreList = SmallVector<StoreInst *, 8>;
>            using ExtraValueToDebugLocsMap =
>                MapVector<Value *, SmallVector<Instruction *, 2>>;
>         +  using OrdersType = SmallVector<unsigned, 4>;
>
>            BoUpSLP(Function *Func, ScalarEvolution *Se,
>         TargetTransformInfo *Tti,
>                    TargetLibraryInfo *TLi, AAResults *Aa, LoopInfo *Li,
>         @@ -614,6 +624,14 @@ class BoUpSLP {
>
>            /// \returns The best order of instructions for vectorization.
>            Optional<ArrayRef<unsigned>> bestOrder() const {
>         +    assert(llvm::all_of(
>         +               NumOpsWantToKeepOrder,
>         +               [this](const
>         decltype(NumOpsWantToKeepOrder)::value_type &D) {
>         +                 return D.getFirst().size() ==
>         +                        VectorizableTree[0]->Scalars.size();
>         +               }) &&
>         +           "All orders must have the same size as number of
>         instructions in "
>         +           "tree node.");
>              auto I = std::max_element(
>                  NumOpsWantToKeepOrder.begin(),
>         NumOpsWantToKeepOrder.end(),
>                  [](const decltype(NumOpsWantToKeepOrder)::value_type &D1,
>         @@ -627,6 +645,79 @@ class BoUpSLP {
>              return makeArrayRef(I->getFirst());
>            }
>
>         +  /// Builds the correct order for root instructions.
>         +  /// If some leaves have the same instructions to be
>         vectorized, we may
>         +  /// incorrectly evaluate the best order for the root node
>         (it is built for the
>         +  /// vector of instructions without repeated instructions
>         and, thus, has less
>         +  /// elements than the root node). This function builds the
>         correct order for
>         +  /// the root node.
>         +  /// For example, if the root node is \<a+b, a+c, a+d,
>         f+e\>, then the leaves
>         +  /// are \<a, a, a, f\> and \<b, c, d, e\>. When we try to
>         vectorize the first
>         +  /// leaf, it will be shrink to \<a, b\>. If instructions in
>         this leaf should
>         +  /// be reordered, the best order will be \<1, 0\>. We need
>         to extend this
>         +  /// order for the root node. For the root node this order
>         should look like
>         +  /// \<3, 0, 1, 2\>. This function extends the order for the
>         reused
>         +  /// instructions.
>         +  void findRootOrder(OrdersType &Order) {
>         +    // If the leaf has the same number of instructions to
>         vectorize as the root
>         +    // - order must be set already.
>         +    unsigned RootSize = VectorizableTree[0]->Scalars.size();
>         +    if (Order.size() == RootSize)
>         +      return;
>         +    SmallVector<unsigned, 4> RealOrder(Order.size());
>         +    std::swap(Order, RealOrder);
>         +    SmallVector<int, 4> Mask;
>         +    inversePermutation(RealOrder, Mask);
>         +    for (int I = 0, E = Mask.size(); I < E; ++I)
>         +      Order[I] = Mask[I];
>         +    // The leaf has less number of instructions - need to
>         find the true order of
>         +    // the root.
>         +    // Scan the nodes starting from the leaf back to the root.
>         +    const TreeEntry *PNode = VectorizableTree.back().get();
>         +    while (PNode) {
>         +      const TreeEntry &Node = *PNode;
>         +      PNode = Node.UserTreeIndices.back().UserTE;
>         +      if (Node.ReuseShuffleIndices.empty())
>         +        continue;
>         +      // Build the order for the parent node.
>         +      OrdersType NewOrder(Node.ReuseShuffleIndices.size(),
>         RootSize);
>         +      SmallVector<unsigned, 4> OrderCounter(Order.size(), 0);
>         +      // The algorithm of the order extension is:
>         +      // 1. Calculate the number of the same instructions for
>         the order.
>         +      // 2. Calculate the index of the new order: total
>         number of instructions
>         +      // with order less than the order of the current
>         instruction + reuse
>         +      // number of the current instruction.
>         +      // 3. The new order is just the index of the
>         instruction in the original
>         +      // vector of the instructions.
>         +      for (unsigned I : Node.ReuseShuffleIndices)
>         +        ++OrderCounter[Order[I]];
>         +      SmallVector<unsigned, 4> CurrentCounter(Order.size(), 0);
>         +      for (unsigned I = 0, E =
>         Node.ReuseShuffleIndices.size(); I < E; ++I) {
>         +        unsigned ReusedIdx = Node.ReuseShuffleIndices[I];
>         +        unsigned OrderIdx = Order[ReusedIdx];
>         +        unsigned NewIdx = 0;
>         +        for (unsigned J = 0; J < OrderIdx; ++J)
>         +          NewIdx += OrderCounter[J];
>         +        NewIdx += CurrentCounter[OrderIdx];
>         +        ++CurrentCounter[OrderIdx];
>         +        assert(NewOrder[NewIdx] == RootSize &&
>         +               "The order index should not be written already.");
>         +        NewOrder[NewIdx] = I;
>         +      }
>         +      std::swap(Order, NewOrder);
>         +      // If the size of the order is the same as number of
>         instructions in the
>         +      // root node, no need to extend it more.
>         +      if (Order.size() == RootSize)
>         +        break;
>         +    }
>         +    assert((!PNode || Order.size() == RootSize) &&
>         +           "Root node is expected or the size of the order
>         must be the same as "
>         +           "the number of elements in the root node.");
>         +    assert(llvm::all_of(Order,
>         +                        [RootSize](unsigned Val) { return Val
>         != RootSize; }) &&
>         +           "All indices must be initialized");
>         +  }
>         +
>            /// \return The vector element size in bits to use when
>         vectorizing the
>            /// expression tree ending at \p V. If V is a store, the
>         size is the width of
>            /// the stored value. Otherwise, the size is the width of
>         the largest loaded
>         @@ -1467,7 +1558,7 @@ class BoUpSLP {
>              SmallVector<int, 4> ReuseShuffleIndices;
>
>              /// Does this entry require reordering?
>         -    ArrayRef<unsigned> ReorderIndices;
>         +    SmallVector<unsigned, 4> ReorderIndices;
>
>              /// Points back to the VectorizableTree.
>              ///
>         @@ -1660,7 +1751,7 @@ class BoUpSLP {
>              Last->State = Vectorized ? TreeEntry::Vectorize :
>         TreeEntry::NeedToGather;
>              Last->ReuseShuffleIndices.append(ReuseShuffleIndices.begin(),
>                                               ReuseShuffleIndices.end());
>         -    Last->ReorderIndices = ReorderIndices;
>         +    Last->ReorderIndices.append(ReorderIndices.begin(),
>         ReorderIndices.end());
>              Last->setOperations(S);
>              if (Vectorized) {
>                for (int i = 0, e = VL.size(); i != e; ++i) {
>         @@ -2197,7 +2288,6 @@ class BoUpSLP {
>            /// List of users to ignore during scheduling and that
>         don't need extracting.
>            ArrayRef<Value *> UserIgnoreList;
>
>         -  using OrdersType = SmallVector<unsigned, 4>;
>            /// A DenseMapInfo implementation for holding DenseMaps and
>         DenseSets of
>            /// sorted SmallVectors of unsigned.
>            struct OrdersTypeDenseMapInfo {
>         @@ -2659,12 +2749,10 @@ void
>         BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
>                  });
>                  // Insert new order with initial value 0, if it does
>         not exist,
>                  // otherwise return the iterator to the existing one.
>         -        auto StoredCurrentOrderAndNum =
>         -           
>         NumOpsWantToKeepOrder.try_emplace(CurrentOrder).first;
>         -        ++StoredCurrentOrderAndNum->getSecond();
>                  newTreeEntry(VL, Bundle /*vectorized*/, S, UserTreeIdx,
>         -                     ReuseShuffleIndicies,
>         -                     StoredCurrentOrderAndNum->getFirst());
>         +                     ReuseShuffleIndicies, CurrentOrder);
>         +        findRootOrder(CurrentOrder);
>         +        ++NumOpsWantToKeepOrder[CurrentOrder];
>                  // This is a special case, as it does not gather, but
>         at the same time
>                  // we are not extending buildTree_rec() towards the
>         operands.
>                  ValueList Op0;
>         @@ -2741,13 +2829,13 @@ void
>         BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
>                      LLVM_DEBUG(dbgs() << "SLP: added a vector of
>         loads.\n");
>                    } else {
>                      // Need to reorder.
>         -            auto I =
>         NumOpsWantToKeepOrder.try_emplace(CurrentOrder).first;
>         -            ++I->getSecond();
>                      TreeEntry *TE =
>                          newTreeEntry(VL, Bundle /*vectorized*/, S,
>         UserTreeIdx,
>         -                             ReuseShuffleIndicies,
>         I->getFirst());
>         +                             ReuseShuffleIndicies, CurrentOrder);
>                      TE->setOperandsInOrder();
>                      LLVM_DEBUG(dbgs() << "SLP: added a vector of
>         jumbled loads.\n");
>         +            findRootOrder(CurrentOrder);
>         +            ++NumOpsWantToKeepOrder[CurrentOrder];
>                    }
>                    return;
>                  }
>         @@ -3003,15 +3091,14 @@ void
>         BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth,
>                      buildTree_rec(Operands, Depth + 1, {TE, 0});
>                      LLVM_DEBUG(dbgs() << "SLP: added a vector of
>         stores.\n");
>                    } else {
>         -            // Need to reorder.
>         -            auto I =
>         NumOpsWantToKeepOrder.try_emplace(CurrentOrder).first;
>         -            ++(I->getSecond());
>                      TreeEntry *TE =
>                          newTreeEntry(VL, Bundle /*vectorized*/, S,
>         UserTreeIdx,
>         -                             ReuseShuffleIndicies,
>         I->getFirst());
>         +                             ReuseShuffleIndicies, CurrentOrder);
>                      TE->setOperandsInOrder();
>                      buildTree_rec(Operands, Depth + 1, {TE, 0});
>                      LLVM_DEBUG(dbgs() << "SLP: added a vector of
>         jumbled stores.\n");
>         +            findRootOrder(CurrentOrder);
>         +            ++NumOpsWantToKeepOrder[CurrentOrder];
>                    }
>                    return;
>                  }
>         @@ -4141,15 +4228,6 @@ Value
>         *BoUpSLP::vectorizeTree(ArrayRef<Value *> VL) {
>            return V;
>          }
>
>         -static void inversePermutation(ArrayRef<unsigned> Indices,
>         -                               SmallVectorImpl<int> &Mask) {
>         -  Mask.clear();
>         -  const unsigned E = Indices.size();
>         -  Mask.resize(E);
>         -  for (unsigned I = 0; I < E; ++I)
>         -    Mask[Indices[I]] = I;
>         -}
>         -
>          Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
>            IRBuilder<>::InsertPointGuard Guard(Builder);
>
>         @@ -6873,8 +6951,10 @@ class HorizontalReduction {
>                ArrayRef<Value *> VL = makeArrayRef(&ReducedVals[i],
>         ReduxWidth);
>                V.buildTree(VL, ExternallyUsedValues, IgnoreList);
>                Optional<ArrayRef<unsigned>> Order = V.bestOrder();
>         -      // TODO: Handle orders of size less than number of
>         elements in the vector.
>         -      if (Order && Order->size() == VL.size()) {
>         +      if (Order) {
>         +        assert(Order->size() == VL.size() &&
>         +               "Order size must be the same as number of
>         vectorized "
>         +               "instructions.");
>                  // TODO: reorder tree nodes without tree rebuilding.
>                  SmallVector<Value *, 4> ReorderedOps(VL.size());
>                  llvm::transform(*Order, ReorderedOps.begin(),
>
>         diff  --git
>         a/llvm/test/Transforms/SLPVectorizer/X86/jumbled_store_crash.ll
>         b/llvm/test/Transforms/SLPVectorizer/X86/jumbled_store_crash.ll
>         index 8b12b9272c7e..a84b1f7e4fcd 100644
>         ---
>         a/llvm/test/Transforms/SLPVectorizer/X86/jumbled_store_crash.ll
>         +++
>         b/llvm/test/Transforms/SLPVectorizer/X86/jumbled_store_crash.ll
>         @@ -11,7 +11,7 @@
>          @h = common dso_local global float 0.000000e+00, align 4
>
>          define dso_local void @j() local_unnamed_addr {
>         -; CHECK-LABEL: define {{[^@]+}}@j(
>         +; CHECK-LABEL: @j(
>          ; CHECK-NEXT:  entry:
>          ; CHECK-NEXT:    [[TMP0:%.*]] = load i32*, i32** @b, align 8
>          ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds
>         i32, i32* [[TMP0]], i64 4
>         @@ -19,42 +19,39 @@ define dso_local void @j()
>         local_unnamed_addr {
>          ; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds
>         i32, i32* [[TMP0]], i64 5
>          ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[ARRAYIDX]] to
>         <2 x i32>*
>          ; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i32>, <2 x i32>*
>         [[TMP1]], align 4
>         -; CHECK-NEXT:    [[REORDER_SHUFFLE1:%.*]] = shufflevector <2
>         x i32> [[TMP2]], <2 x i32> undef, <2 x i32> <i32 1, i32 0>
>          ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds
>         i32, i32* [[TMP0]], i64 13
>          ; CHECK-NEXT:    [[TMP3:%.*]] = bitcast i32* [[ARRAYIDX1]] to
>         <2 x i32>*
>          ; CHECK-NEXT:    [[TMP4:%.*]] = load <2 x i32>, <2 x i32>*
>         [[TMP3]], align 4
>         -; CHECK-NEXT:    [[REORDER_SHUFFLE:%.*]] = shufflevector <2 x
>         i32> [[TMP4]], <2 x i32> undef, <2 x i32> <i32 1, i32 0>
>         -; CHECK-NEXT:    [[TMP5:%.*]] = add nsw <2 x i32>
>         [[REORDER_SHUFFLE]], [[REORDER_SHUFFLE1]]
>         +; CHECK-NEXT:    [[TMP5:%.*]] = add nsw <2 x i32> [[TMP4]],
>         [[TMP2]]
>          ; CHECK-NEXT:    [[TMP6:%.*]] = sitofp <2 x i32> [[TMP5]] to
>         <2 x float>
>          ; CHECK-NEXT:    [[TMP7:%.*]] = fmul <2 x float> [[TMP6]],
>         <float 1.000000e+01, float 1.000000e+01>
>         -; CHECK-NEXT:    [[TMP8:%.*]] = fsub <2 x float> <float
>         0.000000e+00, float 1.000000e+00>, [[TMP7]]
>         -; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float>
>         [[TMP8]], <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 0,
>         i32 1>
>         -; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <4 x float>
>         [[SHUFFLE]], i32 1
>         +; CHECK-NEXT:    [[TMP8:%.*]] = fsub <2 x float> <float
>         1.000000e+00, float 0.000000e+00>, [[TMP7]]
>         +; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x float>
>         [[TMP8]], <2 x float> undef, <4 x i32> <i32 0, i32 0, i32 1,
>         i32 1>
>         +; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <4 x float>
>         [[SHUFFLE]], i32 0
>          ; CHECK-NEXT:    store float [[TMP9]], float* @g, align 4
>         -; CHECK-NEXT:    [[TMP10:%.*]] = fadd <4 x float>
>         [[SHUFFLE]], <float -1.000000e+00, float -1.000000e+00, float
>         1.000000e+00, float 1.000000e+00>
>         -; CHECK-NEXT:    [[TMP11:%.*]] = extractelement <4 x float>
>         [[TMP10]], i32 2
>         +; CHECK-NEXT:    [[TMP10:%.*]] = fadd <4 x float>
>         [[SHUFFLE]], <float -1.000000e+00, float 1.000000e+00, float
>         -1.000000e+00, float 1.000000e+00>
>         +; CHECK-NEXT:    [[TMP11:%.*]] = extractelement <4 x float>
>         [[TMP10]], i32 3
>          ; CHECK-NEXT:    store float [[TMP11]], float* @c, align 4
>         -; CHECK-NEXT:    [[TMP12:%.*]] = extractelement <4 x float>
>         [[TMP10]], i32 0
>         +; CHECK-NEXT:    [[TMP12:%.*]] = extractelement <4 x float>
>         [[TMP10]], i32 2
>          ; CHECK-NEXT:    store float [[TMP12]], float* @d, align 4
>         -; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <4 x float>
>         [[TMP10]], i32 3
>         +; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <4 x float>
>         [[TMP10]], i32 1
>          ; CHECK-NEXT:    store float [[TMP13]], float* @e, align 4
>         -; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x float>
>         [[TMP10]], i32 1
>         +; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <4 x float>
>         [[TMP10]], i32 0
>          ; CHECK-NEXT:    store float [[TMP14]], float* @f, align 4
>          ; CHECK-NEXT:    [[ARRAYIDX15:%.*]] = getelementptr inbounds
>         i32, i32* [[TMP0]], i64 14
>          ; CHECK-NEXT:    [[ARRAYIDX18:%.*]] = getelementptr inbounds
>         i32, i32* [[TMP0]], i64 15
>          ; CHECK-NEXT:    [[TMP15:%.*]] = load i32, i32* @a, align 4
>          ; CHECK-NEXT:    [[CONV19:%.*]] = sitofp i32 [[TMP15]] to float
>         -; CHECK-NEXT:    [[TMP16:%.*]] = insertelement <4 x float>
>         undef, float [[CONV19]], i32 0
>         -; CHECK-NEXT:    [[TMP17:%.*]] = insertelement <4 x float>
>         [[TMP16]], float -1.000000e+00, i32 1
>         -; CHECK-NEXT:    [[TMP18:%.*]] = extractelement <4 x float>
>         [[SHUFFLE]], i32 0
>         -; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x float>
>         [[TMP17]], float [[TMP18]], i32 2
>         -; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x float>
>         [[TMP19]], float -1.000000e+00, i32 3
>         -; CHECK-NEXT:    [[TMP21:%.*]] = fsub <4 x float> [[TMP10]],
>         [[TMP20]]
>         -; CHECK-NEXT:    [[TMP22:%.*]] = fadd <4 x float> [[TMP10]],
>         [[TMP20]]
>         -; CHECK-NEXT:    [[TMP23:%.*]] = shufflevector <4 x float>
>         [[TMP21]], <4 x float> [[TMP22]], <4 x i32> <i32 0, i32 5, i32
>         2, i32 7>
>         -; CHECK-NEXT:    [[TMP24:%.*]] = fptosi <4 x float> [[TMP23]]
>         to <4 x i32>
>         -; CHECK-NEXT:    [[TMP25:%.*]] = bitcast i32* [[ARRAYIDX1]]
>         to <4 x i32>*
>         -; CHECK-NEXT:    store <4 x i32> [[TMP24]], <4 x i32>*
>         [[TMP25]], align 4
>         +; CHECK-NEXT:    [[TMP16:%.*]] = insertelement <4 x float>
>         <float -1.000000e+00, float -1.000000e+00, float undef, float
>         undef>, float [[CONV19]], i32 2
>         +; CHECK-NEXT:    [[TMP17:%.*]] = extractelement <4 x float>
>         [[SHUFFLE]], i32 2
>         +; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <4 x float>
>         [[TMP16]], float [[TMP17]], i32 3
>         +; CHECK-NEXT:    [[TMP19:%.*]] = fadd <4 x float> [[TMP10]],
>         [[TMP18]]
>         +; CHECK-NEXT:    [[TMP20:%.*]] = fsub <4 x float> [[TMP10]],
>         [[TMP18]]
>         +; CHECK-NEXT:    [[TMP21:%.*]] = shufflevector <4 x float>
>         [[TMP19]], <4 x float> [[TMP20]], <4 x i32> <i32 0, i32 1, i32
>         6, i32 7>
>         +; CHECK-NEXT:    [[TMP22:%.*]] = fptosi <4 x float> [[TMP21]]
>         to <4 x i32>
>         +; CHECK-NEXT:    [[REORDER_SHUFFLE:%.*]] = shufflevector <4 x
>         i32> [[TMP22]], <4 x i32> undef, <4 x i32> <i32 2, i32 0, i32
>         3, i32 1>
>         +; CHECK-NEXT:    [[TMP23:%.*]] = bitcast i32* [[ARRAYIDX1]]
>         to <4 x i32>*
>         +; CHECK-NEXT:    store <4 x i32> [[REORDER_SHUFFLE]], <4 x
>         i32>* [[TMP23]], align 4
>          ; CHECK-NEXT:    ret void
>          ;
>          entry:
>
>         diff  --git
>         a/llvm/test/Transforms/SLPVectorizer/X86/reorder_repeated_ops.ll
>         b/llvm/test/Transforms/SLPVectorizer/X86/reorder_repeated_ops.ll
>         index 384e540efb79..9ed21a1c3f8c 100644
>         ---
>         a/llvm/test/Transforms/SLPVectorizer/X86/reorder_repeated_ops.ll
>         +++
>         b/llvm/test/Transforms/SLPVectorizer/X86/reorder_repeated_ops.ll
>         @@ -14,11 +14,10 @@ define void @hoge() {
>          ; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i16>
>         undef, i16 [[T]], i32 0
>          ; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i16>
>         [[TMP0]], i16 undef, i32 1
>          ; CHECK-NEXT:    [[TMP2:%.*]] = sext <2 x i16> [[TMP1]] to <2
>         x i32>
>         -; CHECK-NEXT:    [[REORDER_SHUFFLE:%.*]] = shufflevector <2 x
>         i32> [[TMP2]], <2 x i32> undef, <2 x i32> <i32 1, i32 0>
>         -; CHECK-NEXT:    [[TMP3:%.*]] = sub nsw <2 x i32> <i32 63,
>         i32 undef>, [[REORDER_SHUFFLE]]
>         +; CHECK-NEXT:    [[TMP3:%.*]] = sub nsw <2 x i32> <i32 undef,
>         i32 63>, [[TMP2]]
>          ; CHECK-NEXT:    [[TMP4:%.*]] = sub <2 x i32> [[TMP3]], undef
>         -; CHECK-NEXT:    [[SHUFFLE5:%.*]] = shufflevector <2 x i32>
>         [[TMP4]], <2 x i32> undef, <4 x i32> <i32 0, i32 1, i32 1, i32 1>
>         -; CHECK-NEXT:    [[TMP5:%.*]] = add <4 x i32> [[SHUFFLE5]],
>         <i32 undef, i32 15, i32 31, i32 47>
>         +; CHECK-NEXT:    [[SHUFFLE5:%.*]] = shufflevector <2 x i32>
>         [[TMP4]], <2 x i32> undef, <4 x i32> <i32 0, i32 0, i32 0, i32 1>
>         +; CHECK-NEXT:    [[TMP5:%.*]] = add <4 x i32> [[SHUFFLE5]],
>         <i32 15, i32 31, i32 47, i32 undef>
>          ; CHECK-NEXT:    [[TMP6:%.*]] = call i32
>         @llvm.experimental.vector.reduce.smax.v4i32(<4 x i32> [[TMP5]])
>          ; CHECK-NEXT:    [[T19:%.*]] = select i1 undef, i32 [[TMP6]],
>         i32 undef
>          ; CHECK-NEXT:    [[T20:%.*]] = icmp sgt i32 [[T19]], 63
>
>         diff  --git
>         a/llvm/test/Transforms/SLPVectorizer/X86/vectorize-reorder-reuse.ll
>         b/llvm/test/Transforms/SLPVectorizer/X86/vectorize-reorder-reuse.ll
>         index b7cff2dac5d4..02e7c5b37f3e 100644
>         ---
>         a/llvm/test/Transforms/SLPVectorizer/X86/vectorize-reorder-reuse.ll
>         +++
>         b/llvm/test/Transforms/SLPVectorizer/X86/vectorize-reorder-reuse.ll
>         @@ -7,16 +7,15 @@ define i32 @foo(i32* nocapture readonly
>         %arr, i32 %a1, i32 %a2, i32 %a3, i32 %a4
>          ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds
>         i32, i32* [[ARR:%.*]], i64 1
>          ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ARR]] to <2 x
>         i32>*
>          ; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i32>, <2 x i32>*
>         [[TMP0]], align 4
>         -; CHECK-NEXT:    [[REORDER_SHUFFLE:%.*]] = shufflevector <2 x
>         i32> [[TMP1]], <2 x i32> undef, <2 x i32> <i32 1, i32 0>
>         -; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x i32>
>         [[REORDER_SHUFFLE]], <2 x i32> undef, <8 x i32> <i32 0, i32 0,
>         i32 0, i32 0, i32 0, i32 0, i32 1, i32 1>
>         -; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <8 x i32>
>         undef, i32 [[A1:%.*]], i32 0
>         -; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <8 x i32>
>         [[TMP2]], i32 [[A2:%.*]], i32 1
>         -; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <8 x i32>
>         [[TMP3]], i32 [[A3:%.*]], i32 2
>         -; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <8 x i32>
>         [[TMP4]], i32 [[A4:%.*]], i32 3
>         -; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <8 x i32>
>         [[TMP5]], i32 [[A5:%.*]], i32 4
>         -; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <8 x i32>
>         [[TMP6]], i32 [[A6:%.*]], i32 5
>         -; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <8 x i32>
>         [[TMP7]], i32 [[A7:%.*]], i32 6
>         -; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <8 x i32>
>         [[TMP8]], i32 [[A8:%.*]], i32 7
>         +; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x i32>
>         [[TMP1]], <2 x i32> undef, <8 x i32> <i32 0, i32 0, i32 1, i32
>         1, i32 1, i32 1, i32 1, i32 1>
>         +; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <8 x i32>
>         undef, i32 [[A7:%.*]], i32 0
>         +; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <8 x i32>
>         [[TMP2]], i32 [[A8:%.*]], i32 1
>         +; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <8 x i32>
>         [[TMP3]], i32 [[A1:%.*]], i32 2
>         +; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <8 x i32>
>         [[TMP4]], i32 [[A2:%.*]], i32 3
>         +; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <8 x i32>
>         [[TMP5]], i32 [[A3:%.*]], i32 4
>         +; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <8 x i32>
>         [[TMP6]], i32 [[A4:%.*]], i32 5
>         +; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <8 x i32>
>         [[TMP7]], i32 [[A5:%.*]], i32 6
>         +; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <8 x i32>
>         [[TMP8]], i32 [[A6:%.*]], i32 7
>          ; CHECK-NEXT:    [[TMP10:%.*]] = add <8 x i32> [[SHUFFLE]],
>         [[TMP9]]
>          ; CHECK-NEXT:    [[TMP11:%.*]] = call i32
>         @llvm.experimental.vector.reduce.umin.v8i32(<8 x i32> [[TMP10]])
>          ; CHECK-NEXT:    ret i32 [[TMP11]]
>         @@ -58,16 +57,15 @@ define i32 @foo1(i32* nocapture readonly
>         %arr, i32 %a1, i32 %a2, i32 %a3, i32 %a
>          ; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds
>         i32, i32* [[ARR]], i64 3
>          ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ARR]] to <4 x
>         i32>*
>          ; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>*
>         [[TMP0]], align 4
>         -; CHECK-NEXT:    [[REORDER_SHUFFLE:%.*]] = shufflevector <4 x
>         i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32
>         3, i32 0>
>         -; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i32>
>         [[REORDER_SHUFFLE]], <4 x i32> undef, <8 x i32> <i32 0, i32 1,
>         i32 2, i32 0, i32 0, i32 3, i32 1, i32 0>
>         -; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <8 x i32>
>         undef, i32 [[A1:%.*]], i32 0
>         -; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <8 x i32>
>         [[TMP2]], i32 [[A2:%.*]], i32 1
>         -; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <8 x i32>
>         [[TMP3]], i32 [[A3:%.*]], i32 2
>         -; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <8 x i32>
>         [[TMP4]], i32 [[A4:%.*]], i32 3
>         -; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <8 x i32>
>         [[TMP5]], i32 [[A5:%.*]], i32 4
>         -; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <8 x i32>
>         [[TMP6]], i32 [[A6:%.*]], i32 5
>         +; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i32>
>         [[TMP1]], <4 x i32> undef, <8 x i32> <i32 0, i32 1, i32 1, i32
>         1, i32 1, i32 2, i32 2, i32 3>
>         +; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <8 x i32>
>         undef, i32 [[A6:%.*]], i32 0
>         +; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <8 x i32>
>         [[TMP2]], i32 [[A1:%.*]], i32 1
>         +; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <8 x i32>
>         [[TMP3]], i32 [[A4:%.*]], i32 2
>         +; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <8 x i32>
>         [[TMP4]], i32 [[A5:%.*]], i32 3
>         +; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <8 x i32>
>         [[TMP5]], i32 [[A8:%.*]], i32 4
>         +; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <8 x i32>
>         [[TMP6]], i32 [[A2:%.*]], i32 5
>          ; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <8 x i32>
>         [[TMP7]], i32 [[A7:%.*]], i32 6
>         -; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <8 x i32>
>         [[TMP8]], i32 [[A8:%.*]], i32 7
>         +; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <8 x i32>
>         [[TMP8]], i32 [[A3:%.*]], i32 7
>          ; CHECK-NEXT:    [[TMP10:%.*]] = add <8 x i32> [[SHUFFLE]],
>         [[TMP9]]
>          ; CHECK-NEXT:    [[TMP11:%.*]] = call i32
>         @llvm.experimental.vector.reduce.umin.v8i32(<8 x i32> [[TMP10]])
>          ; CHECK-NEXT:    ret i32 [[TMP11]]
>         @@ -113,16 +111,15 @@ define i32 @foo2(i32* nocapture readonly
>         %arr, i32 %a1, i32 %a2, i32 %a3, i32 %a
>          ; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr inbounds
>         i32, i32* [[ARR]], i64 1
>          ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[ARR]] to <4 x
>         i32>*
>          ; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i32>, <4 x i32>*
>         [[TMP0]], align 4
>         -; CHECK-NEXT:    [[REORDER_SHUFFLE:%.*]] = shufflevector <4 x
>         i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32
>         0, i32 1>
>         -; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i32>
>         [[REORDER_SHUFFLE]], <4 x i32> undef, <8 x i32> <i32 0, i32 1,
>         i32 0, i32 2, i32 3, i32 2, i32 1, i32 3>
>         -; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <8 x i32>
>         undef, i32 [[A1:%.*]], i32 0
>         -; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <8 x i32>
>         [[TMP2]], i32 [[A2:%.*]], i32 1
>         -; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <8 x i32>
>         [[TMP3]], i32 [[A3:%.*]], i32 2
>         -; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <8 x i32>
>         [[TMP4]], i32 [[A4:%.*]], i32 3
>         -; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <8 x i32>
>         [[TMP5]], i32 [[A5:%.*]], i32 4
>         -; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <8 x i32>
>         [[TMP6]], i32 [[A6:%.*]], i32 5
>         -; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <8 x i32>
>         [[TMP7]], i32 [[A7:%.*]], i32 6
>         -; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <8 x i32>
>         [[TMP8]], i32 [[A8:%.*]], i32 7
>         +; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <4 x i32>
>         [[TMP1]], <4 x i32> undef, <8 x i32> <i32 0, i32 0, i32 1, i32
>         1, i32 2, i32 2, i32 3, i32 3>
>         +; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <8 x i32>
>         undef, i32 [[A4:%.*]], i32 0
>         +; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <8 x i32>
>         [[TMP2]], i32 [[A6:%.*]], i32 1
>         +; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <8 x i32>
>         [[TMP3]], i32 [[A5:%.*]], i32 2
>         +; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <8 x i32>
>         [[TMP4]], i32 [[A8:%.*]], i32 3
>         +; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <8 x i32>
>         [[TMP5]], i32 [[A2:%.*]], i32 4
>         +; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <8 x i32>
>         [[TMP6]], i32 [[A7:%.*]], i32 5
>         +; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <8 x i32>
>         [[TMP7]], i32 [[A1:%.*]], i32 6
>         +; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <8 x i32>
>         [[TMP8]], i32 [[A3:%.*]], i32 7
>          ; CHECK-NEXT:    [[TMP10:%.*]] = add <8 x i32> [[SHUFFLE]],
>         [[TMP9]]
>          ; CHECK-NEXT:    [[TMP11:%.*]] = call i32
>         @llvm.experimental.vector.reduce.umin.v8i32(<8 x i32> [[TMP10]])
>          ; CHECK-NEXT:    ret i32 [[TMP11]]
>
>
>
>         _______________________________________________
>         llvm-commits mailing list
>         llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
>         https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>         <https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits>
>
>
>
> -- 
>
>
> Bogdan Graur | 	 Software Engineer | 	 bgraur at google.com
> <mailto:bgraur at google.com> | 	 
>
>
> Google Germany GmbH
>
> Erika-Mann-Str. 33
> D-80636 Munich
>
> Geschäftsführer:Paul Manicle, Halimah DeLaine Prado
>
> Registergericht und -nummer: Hamburg, HRB 86891
>
> Sitz der Gesellschaft: Hamburg
>
>
> Diese E-Mail ist vertraulich. Wenn Sie nicht der richtige Adressat
> sind, leiten Sie diese bitte nicht weiter, informieren Sie den
> Absender und löschen Sie die E-Mail und alle Anhänge. Vielen Dank.
>
>       
>
> This e-mail is confidential. If you are not the right addressee please
> do not forward it, please inform the sender, and please erase this
> e-mail including any attachments. Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200919/82186e75/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0xFEE42AA7A747E6CE.asc
Type: application/pgp-keys
Size: 3844 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200919/82186e75/attachment-0001.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200919/82186e75/attachment-0001.sig>


More information about the llvm-commits mailing list