llvm.org GIT mirror llvm / c0319dd
Revert "merge consecutive stores of extracted vector elements" This reverts commit r224611. This change causes crashes in X86 DAG->DAG Instruction Selection. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225031 91177308-0d34-0410-b5e6-96231b3b80d8 Alexey Samsonov 5 years ago
2 changed file(s) with 4 addition(s) and 108 deletion(s). Raw diff Collapse all Expand all
94989498 return false;
94999499
95009500 // Perform an early exit check. Do not bother looking at stored values that
9501 // are not constants, loads, or extracted vector elements.
9501 // are not constants or loads.
95029502 SDValue StoredVal = St->getValue();
95039503 bool IsLoadSrc = isa(StoredVal);
9504 bool IsConstantSrc = isa(StoredVal) ||
9505 isa(StoredVal);
9506 bool IsExtractVecEltSrc = (StoredVal.getOpcode() == ISD::EXTRACT_VECTOR_ELT);
9507
9508 if (!IsConstantSrc && !IsLoadSrc && !IsExtractVecEltSrc)
9504 if (!isa(StoredVal) && !isa(StoredVal) &&
9505 !IsLoadSrc)
95099506 return false;
95109507
95119508 // Only look at ends of store sequences.
96479644 LSBaseSDNode *FirstInChain = StoreNodes[0].MemNode;
96489645
96499646 // Store the constants into memory as one consecutive store.
9650 if (IsConstantSrc) {
9647 if (!IsLoadSrc) {
96519648 unsigned LastLegalType = 0;
96529649 unsigned LastLegalVectorType = 0;
96539650 bool NonZero = false;
97699766 // When we change it's chain to be St's chain they become identical,
97709767 // get CSEed and the net result is that X is now a use of St.
97719768 // Since we know that St is redundant, just iterate.
9772 while (!St->use_empty())
9773 DAG.ReplaceAllUsesWith(SDValue(St, 0), St->getChain());
9774 deleteAndRecombine(St);
9775 }
9776
9777 return true;
9778 }
9779
9780 // When extracting multiple vector elements, try to store them
9781 // in one vector store rather than a sequence of scalar stores.
9782 if (IsExtractVecEltSrc) {
9783 unsigned NumElem = 0;
9784 for (unsigned i = 0; i < LastConsecutiveStore + 1; ++i) {
9785 // Find a legal type for the vector store.
9786 EVT Ty = EVT::getVectorVT(*DAG.getContext(), MemVT, i+1);
9787 if (TLI.isTypeLegal(Ty))
9788 NumElem = i + 1;
9789 }
9790
9791 // Make sure we have a legal type and something to merge.
9792 if (NumElem < 2)
9793 return false;
9794
9795 unsigned EarliestNodeUsed = 0;
9796 for (unsigned i=0; i < NumElem; ++i) {
9797 // Find a chain for the new wide-store operand. Notice that some
9798 // of the store nodes that we found may not be selected for inclusion
9799 // in the wide store. The chain we use needs to be the chain of the
9800 // earliest store node which is *used* and replaced by the wide store.
9801 if (StoreNodes[i].SequenceNum > StoreNodes[EarliestNodeUsed].SequenceNum)
9802 EarliestNodeUsed = i;
9803 }
9804
9805 // The earliest Node in the DAG.
9806 LSBaseSDNode *EarliestOp = StoreNodes[EarliestNodeUsed].MemNode;
9807 SDLoc DL(StoreNodes[0].MemNode);
9808
9809 SDValue StoredVal;
9810
9811 // Find a legal type for the vector store.
9812 EVT Ty = EVT::getVectorVT(*DAG.getContext(), MemVT, NumElem);
9813
9814 SmallVector Ops;
9815 for (unsigned i = 0; i < NumElem ; ++i) {
9816 StoreSDNode *St = cast(StoreNodes[i].MemNode);
9817 SDValue Val = St->getValue();
9818 // All of the operands of a BUILD_VECTOR must have the same type.
9819 if (Val.getValueType() != MemVT)
9820 return false;
9821 Ops.push_back(Val);
9822 }
9823
9824 // Build the extracted vector elements back into a vector.
9825 StoredVal = DAG.getNode(ISD::BUILD_VECTOR, DL, Ty, Ops);
9826
9827 SDValue NewStore = DAG.getStore(EarliestOp->getChain(), DL, StoredVal,
9828 FirstInChain->getBasePtr(),
9829 FirstInChain->getPointerInfo(),
9830 false, false,
9831 FirstInChain->getAlignment());
9832
9833 // Replace the first store with the new store
9834 CombineTo(EarliestOp, NewStore);
9835 // Erase all other stores.
9836 for (unsigned i = 0; i < NumElem ; ++i) {
9837 if (StoreNodes[i].MemNode == EarliestOp)
9838 continue;
9839 StoreSDNode *St = cast(StoreNodes[i].MemNode);
98409769 while (!St->use_empty())
98419770 DAG.ReplaceAllUsesWith(SDValue(St, 0), St->getChain());
98429771 deleteAndRecombine(St);
433433 ;
434434 ret void
435435 }
436
437 define void @merge_vec_element_store(<8 x float> %v, float* %ptr) {
438 %vecext0 = extractelement <8 x float> %v, i32 0
439 %vecext1 = extractelement <8 x float> %v, i32 1
440 %vecext2 = extractelement <8 x float> %v, i32 2
441 %vecext3 = extractelement <8 x float> %v, i32 3
442 %vecext4 = extractelement <8 x float> %v, i32 4
443 %vecext5 = extractelement <8 x float> %v, i32 5
444 %vecext6 = extractelement <8 x float> %v, i32 6
445 %vecext7 = extractelement <8 x float> %v, i32 7
446 %arrayidx1 = getelementptr inbounds float* %ptr, i64 1
447 %arrayidx2 = getelementptr inbounds float* %ptr, i64 2
448 %arrayidx3 = getelementptr inbounds float* %ptr, i64 3
449 %arrayidx4 = getelementptr inbounds float* %ptr, i64 4
450 %arrayidx5 = getelementptr inbounds float* %ptr, i64 5
451 %arrayidx6 = getelementptr inbounds float* %ptr, i64 6
452 %arrayidx7 = getelementptr inbounds float* %ptr, i64 7
453 store float %vecext0, float* %ptr, align 4
454 store float %vecext1, float* %arrayidx1, align 4
455 store float %vecext2, float* %arrayidx2, align 4
456 store float %vecext3, float* %arrayidx3, align 4
457 store float %vecext4, float* %arrayidx4, align 4
458 store float %vecext5, float* %arrayidx5, align 4
459 store float %vecext6, float* %arrayidx6, align 4
460 store float %vecext7, float* %arrayidx7, align 4
461 ret void
462
463 ; CHECK-LABEL: merge_vec_element_store
464 ; CHECK: vmovups
465 ; CHECK-NEXT: vzeroupper
466 ; CHECK-NEXT: retq
467 }
468