llvm.org GIT mirror llvm / 538282c
Revert "[SDAG] Relax conditions under stores of loaded values can be merged" This reverts r302712. The change fails with ASAN enabled: ERROR: AddressSanitizer: use-after-poison on address ... at ... READ of size 2 at ... thread T0 #0 ... in llvm::SDNode::getNumValues() const <snip>/include/llvm/CodeGen/SelectionDAGNodes.h:855:42 #1 ... in llvm::SDNode::hasAnyUseOfValue(unsigned int) const <snip>/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:7270:3 #2 ... in llvm::SDValue::use_empty() const <snip> include/llvm/CodeGen/SelectionDAGNodes.h:1042:17 #3 ... in (anonymous namespace)::DAGCombiner::MergeConsecutiveStores(llvm::StoreSDNode*) <snip>/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:12944:7 Reviewers: niravd Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33081 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302746 91177308-0d34-0410-b5e6-96231b3b80d8 David L. Jones 3 years ago
3 changed file(s) with 28 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
4242
4343 /// EntryToken - This is the marker used to indicate the start of a region.
4444 EntryToken,
45
46 /// DummyNode - Temporary node for node replacement. These nodes
47 /// should not persist beyond their introduction.
48 DummyNode,
4945
5046 /// TokenFactor - This node takes multiple tokens as input and produces a
5147 /// single token result. This is used to represent the fact that the operand
1278212782 LoadSDNode *Ld = dyn_cast(St->getValue());
1278312783 if (!Ld) break;
1278412784
12785 // Loads must only have one use.
12786 if (!Ld->hasNUsesOfValue(1, 0))
12787 break;
12788
1278512789 // The memory operands must not be volatile.
1278612790 if (Ld->isVolatile() || Ld->isIndexed())
1278712791 break;
1278812792
1278912793 // We do not accept ext loads.
1279012794 if (Ld->getExtensionType() != ISD::NON_EXTLOAD)
12795 break;
12796
12797 // The stored memory type must be the same.
12798 if (Ld->getMemoryVT() != MemVT)
1279112799 break;
1279212800
1279312801 BaseIndexOffset LdPtr = BaseIndexOffset::match(Ld->getBasePtr(), DAG);
1292112929 // Transfer chain users from old loads to the new load.
1292212930 for (unsigned i = 0; i < NumElem; ++i) {
1292312931 LoadSDNode *Ld = cast(LoadNodes[i].MemNode);
12924 if (SDValue(Ld, 0).hasOneUse()) {
12925 // Only the original store used value so just replace chain.
12926 DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1),
12927 SDValue(NewLoad.getNode(), 1));
12928 } else {
12929 // Multiple uses exist. Keep the old load in line with the new
12930 // load, i.e. Replace chains using Ld's chain with a
12931 // TokenFactor. Create a temporary node to serve as a placer so
12932 // we do not replace the reference to original Load's chain in
12933 // the TokenFactor.
12934 SDValue TokenDummy = DAG.getNode(ISD::DummyNode, SDLoc(Ld), MVT::Other);
12935
12936 // Replace all references to Load's output chain to TokenDummy
12937 CombineTo(Ld, SDValue(Ld, 0), TokenDummy, false);
12938 SDValue Token =
12939 DAG.getNode(ISD::TokenFactor, SDLoc(Ld), MVT::Other, SDValue(Ld, 1),
12940 SDValue(NewLoad.getNode(), 1));
12941 // Replace all uses of TokenDummy from itself to Ld's output chain.
12942 CombineTo(TokenDummy.getNode(), Token);
12943 assert(TokenDummy.use_empty() && "TokenDummy should be unused");
12944 AddToWorklist(Ld);
12945 }
12932 DAG.ReplaceAllUsesOfValueWith(SDValue(Ld, 1),
12933 SDValue(NewLoad.getNode(), 1));
1294612934 }
1294712935
1294812936 // Replace the all stores with the new store.
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
11 ; RUN: llc %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -o - | FileCheck %s
22
3 ; PR32086
3
44 target triple = "x86_64-unknown-linux-gnu"
55
66 define void @merge_double(double* noalias nocapture %st, double* noalias nocapture readonly %ld) #0 {
77 ; CHECK-LABEL: merge_double:
88 ; CHECK: # BB#0:
9 ; CHECK-NEXT: movups (%rsi), %xmm0
10 ; CHECK-NEXT: movups %xmm0, (%rdi)
11 ; CHECK-NEXT: movups %xmm0, 16(%rdi)
9 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
10 ; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero
11 ; CHECK-NEXT: movsd %xmm0, (%rdi)
12 ; CHECK-NEXT: movsd %xmm1, 8(%rdi)
13 ; CHECK-NEXT: movsd %xmm0, 16(%rdi)
14 ; CHECK-NEXT: movsd %xmm1, 24(%rdi)
1215 ; CHECK-NEXT: retq
1316 %ld_idx1 = getelementptr inbounds double, double* %ld, i64 1
1417 %ld0 = load double, double* %ld, align 8, !tbaa !2
2831 define void @merge_loadstore_int(i64* noalias nocapture readonly %p, i64* noalias nocapture %q) local_unnamed_addr #0 {
2932 ; CHECK-LABEL: merge_loadstore_int:
3033 ; CHECK: # BB#0: # %entry
31 ; CHECK-NEXT: movups (%rdi), %xmm0
32 ; CHECK-NEXT: movups %xmm0, (%rsi)
33 ; CHECK-NEXT: movups %xmm0, 16(%rsi)
34 ; CHECK-NEXT: movq (%rdi), %rax
35 ; CHECK-NEXT: movq 8(%rdi), %rcx
36 ; CHECK-NEXT: movq %rax, (%rsi)
37 ; CHECK-NEXT: movq %rcx, 8(%rsi)
38 ; CHECK-NEXT: movq %rax, 16(%rsi)
39 ; CHECK-NEXT: movq %rcx, 24(%rsi)
3440 ; CHECK-NEXT: retq
3541 entry:
3642 %0 = load i64, i64* %p, align 8, !tbaa !1
5056 ; CHECK-LABEL: merge_loadstore_int_with_extra_use:
5157 ; CHECK: # BB#0: # %entry
5258 ; CHECK-NEXT: movq (%rdi), %rax
53 ; CHECK-NEXT: movups (%rdi), %xmm0
54 ; CHECK-NEXT: movups %xmm0, (%rsi)
55 ; CHECK-NEXT: movups %xmm0, 16(%rsi)
59 ; CHECK-NEXT: movq 8(%rdi), %rcx
60 ; CHECK-NEXT: movq %rax, (%rsi)
61 ; CHECK-NEXT: movq %rcx, 8(%rsi)
62 ; CHECK-NEXT: movq %rax, 16(%rsi)
63 ; CHECK-NEXT: movq %rcx, 24(%rsi)
5664 ; CHECK-NEXT: retq
5765 entry:
5866 %0 = load i64, i64* %p, align 8, !tbaa !1