From 3d54972ba88d7cd2635d432a554bd86175a1befb Mon Sep 17 00:00:00 2001 From: Clement Courbet Date: Mon, 18 Feb 2019 08:24:29 +0000 Subject: [PATCH] Revert r354244 "[DAGCombiner] Eliminate dead stores to stack." Breaks some bots. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354245 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 6 - include/llvm/CodeGen/SelectionDAGAddressAnalysis.h | 20 +--- include/llvm/CodeGen/SelectionDAGNodes.h | 31 ----- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 125 ++++++--------------- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 30 ----- .../SelectionDAG/SelectionDAGAddressAnalysis.cpp | 75 ------------- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 21 ++-- lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp | 3 - test/CodeGen/BPF/remove_truncate_5.ll | 12 +- test/CodeGen/X86/swap.ll | 33 ++++++ test/DebugInfo/COFF/inlining.ll | 11 +- test/DebugInfo/COFF/lexicalblock.ll | 32 ++++++ 12 files changed, 124 insertions(+), 275 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 93c8ba4fdc9..c4755995526 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -1016,12 +1016,6 @@ public: ArrayRef Ops, EVT MemVT, MachineMemOperand *MMO); - /// Creates a LifetimeSDNode that starts (`IsStart==true`) or ends - /// (`IsStart==false`) the lifetime of the portion of `FrameIndex` between - /// offsets `Offset` and `Offset + Size`. - SDValue getLifetimeNode(bool IsStart, const SDLoc &dl, SDValue Chain, - int FrameIndex, int64_t Size, int64_t Offset = -1); - /// Create a MERGE_VALUES node from the given operands. SDValue getMergeValues(ArrayRef Ops, const SDLoc &dl); diff --git a/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h b/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h index 4173cbe635b..f168b846fda 100644 --- a/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h +++ b/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h @@ -48,30 +48,14 @@ public: SDValue getIndex() { return Index; } SDValue getIndex() const { return Index; } - // Returns true if `Other` and `*this` are both some offset from the same base - // pointer. In that case, `Off` is set to the offset between `*this` and - // `Other` (negative if `Other` is before `*this`). - bool equalBaseIndex(const BaseIndexOffset &Other, const SelectionDAG &DAG, - int64_t &Off) const; - bool equalBaseIndex(const BaseIndexOffset &Other, const SelectionDAG &DAG) const { int64_t Off; return equalBaseIndex(Other, DAG, Off); } - // Returns true if `Other` (with size `OtherSize`) can be proven to be fully - // contained in `*this` (with size `Size`). - bool contains(int64_t Size, const BaseIndexOffset &Other, int64_t OtherSize, - const SelectionDAG &DAG) const; - - // Returns true `BasePtr0` and `BasePtr1` can be proven to alias/not alias, in - // which case `IsAlias` is set to true/false. - static bool computeAliasing(const BaseIndexOffset &BasePtr0, - const int64_t NumBytes0, - const BaseIndexOffset &BasePtr1, - const int64_t NumBytes1, const SelectionDAG &DAG, - bool &IsAlias); + bool equalBaseIndex(const BaseIndexOffset &Other, const SelectionDAG &DAG, + int64_t &Off) const; /// Parses tree in Ptr for base, index, offset addresses. static BaseIndexOffset match(const LSBaseSDNode *N, const SelectionDAG &DAG); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index a5d494ff4e0..c0dd9d1e12f 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1692,37 +1692,6 @@ public: } }; -/// This SDNode is used for LIFETIME_START/LIFETIME_END values, which indicate -/// the offet and size that are started/ended in the underlying FrameIndex. -class LifetimeSDNode : public SDNode { - int64_t Size; - int64_t Offset; // -1 if offset is unknown. -public: - LifetimeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl, - SDVTList VTs, int64_t Size, int64_t Offset) - : SDNode(Opcode, Order, dl, VTs), Size(Size), Offset(Offset) {} - - int64_t getFrameIndex() const { - return cast(getOperand(1))->getIndex(); - } - - bool hasOffset() const { return Offset >= 0; } - int64_t getOffset() const { - assert(hasOffset() && "offset is unknown"); - return Offset; - } - int64_t getSize() const { - assert(hasOffset() && "offset is unknown"); - return Size; - } - - // Methods to support isa and dyn_cast - static bool classof(const SDNode *N) { - return N->getOpcode() == ISD::LIFETIME_START || - N->getOpcode() == ISD::LIFETIME_END; - } -}; - class JumpTableSDNode : public SDNode { friend class SelectionDAG; diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 78a6ea6d4fd..c2404f963ce 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -385,7 +385,6 @@ namespace { SDValue replaceStoreOfFPConstant(StoreSDNode *ST); SDValue visitSTORE(SDNode *N); - SDValue visitLIFETIME_END(SDNode *N); SDValue visitINSERT_VECTOR_ELT(SDNode *N); SDValue visitEXTRACT_VECTOR_ELT(SDNode *N); SDValue visitBUILD_VECTOR(SDNode *N); @@ -1590,7 +1589,6 @@ SDValue DAGCombiner::visit(SDNode *N) { case ISD::MLOAD: return visitMLOAD(N); case ISD::MSCATTER: return visitMSCATTER(N); case ISD::MSTORE: return visitMSTORE(N); - case ISD::LIFETIME_END: return visitLIFETIME_END(N); case ISD::FP_TO_FP16: return visitFP_TO_FP16(N); case ISD::FP16_TO_FP: return visitFP16_TO_FP(N); } @@ -15486,66 +15484,6 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { return ReduceLoadOpStoreWidth(N); } -SDValue DAGCombiner::visitLIFETIME_END(SDNode *N) { - const auto *LifetimeEnd = cast(N); - if (!LifetimeEnd->hasOffset()) - return SDValue(); - - const BaseIndexOffset LifetimeEndBase(N->getOperand(1), SDValue(), - LifetimeEnd->getOffset(), false); - - // We walk up the chains to find stores. - SmallVector Chains = {N->getOperand(0)}; - while (!Chains.empty()) { - SDValue Chain = Chains.back(); - Chains.pop_back(); - switch (Chain.getOpcode()) { - case ISD::TokenFactor: - for (unsigned Nops = Chain.getNumOperands(); Nops;) - Chains.push_back(Chain.getOperand(--Nops)); - break; - case ISD::LIFETIME_START: - case ISD::LIFETIME_END: { - // We can forward past any lifetime start/end that can be proven not to - // alias the node. - const auto *LifetimeStart = cast(Chain); - if (!LifetimeStart->hasOffset()) - break; // Be conservative if we don't know the extents of the object. - - const BaseIndexOffset LifetimeStartBase( - LifetimeStart->getOperand(1), SDValue(), LifetimeStart->getOffset(), - false); - bool IsAlias; - if (BaseIndexOffset::computeAliasing( - LifetimeEndBase, LifetimeEnd->getSize(), LifetimeStartBase, - LifetimeStart->getSize(), DAG, IsAlias) && - !IsAlias) { - Chains.push_back(Chain.getOperand(0)); - } - break; - } - - case ISD::STORE: { - StoreSDNode *ST = dyn_cast(Chain); - if (ST->isVolatile() || !ST->hasOneUse() || ST->isIndexed()) - continue; - const BaseIndexOffset StoreBase = BaseIndexOffset::match(ST, DAG); - // If we store purely within object bounds just before its lifetime ends, - // we can remove the store. - if (LifetimeEndBase.contains(LifetimeEnd->getSize(), StoreBase, - ST->getMemoryVT().getStoreSize(), DAG)) { - LLVM_DEBUG(dbgs() << "\nRemoving store:"; StoreBase.dump(); - dbgs() << "\nwithin LIFETIME_END of : "; - LifetimeEndBase.dump(); dbgs() << "\n"); - CombineTo(ST, ST->getChain()); - return SDValue(N, 0); - } - } - } - } - return SDValue(); -} - /// For the instruction sequence of store below, F and I values /// are bundled together as an i64 value before being stored into memory. /// Sometimes it is more efficent to generate separate stores for F and I, @@ -19297,11 +19235,41 @@ bool DAGCombiner::isAlias(LSBaseSDNode *Op0, LSBaseSDNode *Op1) const { unsigned NumBytes1 = Op1->getMemoryVT().getStoreSize(); // Check for BaseIndexOffset matching. - bool IsAlias; - if (BaseIndexOffset::computeAliasing( - BaseIndexOffset::match(Op0, DAG), NumBytes0, - BaseIndexOffset::match(Op1, DAG), NumBytes1, DAG, IsAlias)) - return IsAlias; + BaseIndexOffset BasePtr0 = BaseIndexOffset::match(Op0, DAG); + BaseIndexOffset BasePtr1 = BaseIndexOffset::match(Op1, DAG); + int64_t PtrDiff; + if (BasePtr0.getBase().getNode() && BasePtr1.getBase().getNode()) { + if (BasePtr0.equalBaseIndex(BasePtr1, DAG, PtrDiff)) + return !((NumBytes0 <= PtrDiff) || (PtrDiff + NumBytes1 <= 0)); + + // If both BasePtr0 and BasePtr1 are FrameIndexes, we will not be + // able to calculate their relative offset if at least one arises + // from an alloca. However, these allocas cannot overlap and we + // can infer there is no alias. + if (auto *A = dyn_cast(BasePtr0.getBase())) + if (auto *B = dyn_cast(BasePtr1.getBase())) { + MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); + // If the base are the same frame index but the we couldn't find a + // constant offset, (indices are different) be conservative. + if (A != B && (!MFI.isFixedObjectIndex(A->getIndex()) || + !MFI.isFixedObjectIndex(B->getIndex()))) + return false; + } + + bool IsFI0 = isa(BasePtr0.getBase()); + bool IsFI1 = isa(BasePtr1.getBase()); + bool IsGV0 = isa(BasePtr0.getBase()); + bool IsGV1 = isa(BasePtr1.getBase()); + bool IsCV0 = isa(BasePtr0.getBase()); + bool IsCV1 = isa(BasePtr1.getBase()); + + // If of mismatched base types or checkable indices we can check + // they do not alias. + if ((BasePtr0.getIndex() == BasePtr1.getIndex() || (IsFI0 != IsFI1) || + (IsGV0 != IsGV1) || (IsCV0 != IsCV1)) && + (IsFI0 || IsGV0 || IsCV0) && (IsFI1 || IsGV1 || IsCV1)) + return false; + } // If we know required SrcValue1 and SrcValue2 have relatively large // alignment compared to the size and offset of the access, we may be able @@ -19360,8 +19328,6 @@ void DAGCombiner::GatherAllAliases(LSBaseSDNode *N, SDValue OriginalChain, // Get alias information for node. bool IsLoad = isa(N) && !N->isVolatile(); - const BaseIndexOffset LSBasePtr = BaseIndexOffset::match(N, DAG); - const unsigned LSNumBytes = N->getMemoryVT().getStoreSize(); // Starting off. Chains.push_back(OriginalChain); @@ -19432,27 +19398,6 @@ void DAGCombiner::GatherAllAliases(LSBaseSDNode *N, SDValue OriginalChain, ++Depth; break; - case ISD::LIFETIME_START: - case ISD::LIFETIME_END: { - // We can forward past any lifetime start/end that can be proven not to - // alias the memory access. - const auto *Lifetime = cast(Chain); - if (!Lifetime->hasOffset()) - break; // Be conservative if we don't know the extents of the object. - - const BaseIndexOffset LifetimePtr(Lifetime->getOperand(1), SDValue(), - Lifetime->getOffset(), false); - bool IsAlias; - if (BaseIndexOffset::computeAliasing(LifetimePtr, Lifetime->getSize(), - LSBasePtr, LSNumBytes, DAG, - IsAlias) && - !IsAlias) { - Chains.push_back(Chain.getOperand(0)); - ++Depth; - } - break; - } - default: // For all other instructions we will just have to take what we can get. Aliases.push_back(Chain); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 05f733b5676..d7d7b8b7191 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -6502,36 +6502,6 @@ SDValue SelectionDAG::getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, return SDValue(N, 0); } -SDValue SelectionDAG::getLifetimeNode(bool IsStart, const SDLoc &dl, - SDValue Chain, int FrameIndex, - int64_t Size, int64_t Offset) { - const unsigned Opcode = IsStart ? ISD::LIFETIME_START : ISD::LIFETIME_END; - const auto VTs = getVTList(MVT::Other); - SDValue Ops[2] = { - Chain, - getFrameIndex(FrameIndex, - getTargetLoweringInfo().getFrameIndexTy(getDataLayout()), - true)}; - - FoldingSetNodeID ID; - AddNodeIDNode(ID, Opcode, VTs, Ops); - ID.AddInteger(FrameIndex); - ID.AddInteger(Size); - ID.AddInteger(Offset); - void *IP = nullptr; - if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) - return SDValue(E, 0); - - LifetimeSDNode *N = newSDNode( - Opcode, dl.getIROrder(), dl.getDebugLoc(), VTs, Size, Offset); - createOperands(N, Ops); - CSEMap.InsertNode(N, IP); - InsertNode(N); - SDValue V(N, 0); - NewSDValueDbgMsg(V, "Creating new node: ", this); - return V; -} - /// InferPointerInfo - If the specified ptr/offset is a frame index, infer a /// MachinePointerInfo record from it. This is particularly useful because the /// code generator has many cases where it doesn't bother passing in a diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp index c21ecfca13a..5666c1293e9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp @@ -79,81 +79,6 @@ bool BaseIndexOffset::equalBaseIndex(const BaseIndexOffset &Other, return false; } -bool BaseIndexOffset::computeAliasing(const BaseIndexOffset &BasePtr0, - const int64_t NumBytes0, - const BaseIndexOffset &BasePtr1, - const int64_t NumBytes1, - const SelectionDAG &DAG, bool &IsAlias) { - if (!(BasePtr0.getBase().getNode() && BasePtr1.getBase().getNode())) - return false; - int64_t PtrDiff; - if (BasePtr0.equalBaseIndex(BasePtr1, DAG, PtrDiff)) { - // BasePtr1 is PtrDiff away from BasePtr0. They alias if none of the - // following situations arise: - IsAlias = !( - // [----BasePtr0----] - // [---BasePtr1--] - // ========PtrDiff========> - (NumBytes0 <= PtrDiff) || - // [----BasePtr0----] - // [---BasePtr1--] - // =====(-PtrDiff)====> - (PtrDiff + NumBytes1 <= 0)); // i.e. NumBytes1 < -PtrDiff. - return true; - } - // If both BasePtr0 and BasePtr1 are FrameIndexes, we will not be - // able to calculate their relative offset if at least one arises - // from an alloca. However, these allocas cannot overlap and we - // can infer there is no alias. - if (auto *A = dyn_cast(BasePtr0.getBase())) - if (auto *B = dyn_cast(BasePtr1.getBase())) { - MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); - // If the base are the same frame index but the we couldn't find a - // constant offset, (indices are different) be conservative. - if (A != B && (!MFI.isFixedObjectIndex(A->getIndex()) || - !MFI.isFixedObjectIndex(B->getIndex()))) { - IsAlias = false; - return true; - } - } - - bool IsFI0 = isa(BasePtr0.getBase()); - bool IsFI1 = isa(BasePtr1.getBase()); - bool IsGV0 = isa(BasePtr0.getBase()); - bool IsGV1 = isa(BasePtr1.getBase()); - bool IsCV0 = isa(BasePtr0.getBase()); - bool IsCV1 = isa(BasePtr1.getBase()); - - // If of mismatched base types or checkable indices we can check - // they do not alias. - if ((BasePtr0.getIndex() == BasePtr1.getIndex() || (IsFI0 != IsFI1) || - (IsGV0 != IsGV1) || (IsCV0 != IsCV1)) && - (IsFI0 || IsGV0 || IsCV0) && (IsFI1 || IsGV1 || IsCV1)) { - IsAlias = false; - return true; - } - return false; // Cannot determine whether the pointers alias. -} - -bool BaseIndexOffset::contains(int64_t Size, const BaseIndexOffset &Other, - int64_t OtherSize, - const SelectionDAG &DAG) const { - int64_t Offset; - if (!equalBaseIndex(Other, DAG, Offset)) - return false; - if (Offset >= 0) { - // Other is after *this: - // [-------*this---------] - // [---Other--] - // ==Offset==> - return Offset + OtherSize <= Size; - } - // Other starts strictly before *this, it cannot be fully contained. - // [-------*this---------] - // [--Other--] - return false; -} - /// Parses tree in Ptr for base, index, offset addresses. BaseIndexOffset BaseIndexOffset::match(const LSBaseSDNode *N, const SelectionDAG &DAG) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 1b75dc7d2e5..75f7cc08aa9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6373,11 +6373,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { if (TM.getOptLevel() == CodeGenOpt::None) return nullptr; - const int64_t ObjectSize = - cast(I.getArgOperand(0))->getSExtValue(); - Value *const ObjectPtr = I.getArgOperand(1); SmallVector Allocas; - GetUnderlyingObjects(ObjectPtr, Allocas, *DL); + GetUnderlyingObjects(I.getArgOperand(1), Allocas, *DL); for (SmallVectorImpl::iterator Object = Allocas.begin(), E = Allocas.end(); Object != E; ++Object) { @@ -6393,13 +6390,15 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { if (SI == FuncInfo.StaticAllocaMap.end()) return nullptr; - const int FrameIndex = SI->second; - int64_t Offset; - if (GetPointerBaseWithConstantOffset( - ObjectPtr, Offset, DAG.getDataLayout()) != LifetimeObject) - Offset = -1; // Cannot determine offset from alloca to lifetime object. - Res = DAG.getLifetimeNode(IsStart, sdl, getRoot(), FrameIndex, ObjectSize, - Offset); + int FI = SI->second; + + SDValue Ops[2]; + Ops[0] = getRoot(); + Ops[1] = + DAG.getFrameIndex(FI, TLI.getFrameIndexTy(DAG.getDataLayout()), true); + unsigned Opcode = (IsStart ? ISD::LIFETIME_START : ISD::LIFETIME_END); + + Res = DAG.getNode(Opcode, sdl, MVT::Other, Ops); DAG.setRoot(Res); } return nullptr; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp index 365286309ea..490b2f9957e 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -709,9 +709,6 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const { << " -> " << ASC->getDestAddressSpace() << ']'; - } else if (const LifetimeSDNode *LN = dyn_cast(this)) { - if (LN->hasOffset()) - OS << "<" << LN->getOffset() << " to " << LN->getOffset() + LN->getSize() << ">"; } if (VerboseDAGDumping) { diff --git a/test/CodeGen/BPF/remove_truncate_5.ll b/test/CodeGen/BPF/remove_truncate_5.ll index c35a9c152f0..294f93dab9d 100644 --- a/test/CodeGen/BPF/remove_truncate_5.ll +++ b/test/CodeGen/BPF/remove_truncate_5.ll @@ -25,12 +25,12 @@ define dso_local void @test() local_unnamed_addr #0 { call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %2) #3 call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 4 %2, i8* align 4 bitcast (%struct.test_t* @test.t to i8*), i64 16, i1 false) ; CHECK: r1 = 0 -; CHECK-NEXT: r1 <<= 32 -; CHECK-NEXT: r2 = r1 -; CHECK: [[SECOND:r[12]]] |= 5 -; CHECK-NEXT: *(u64 *)(r10 - 16) = [[SECOND]] -; CHECK: [[FIRST:r[12]]] |= 0 -; CHECK-NEXT: *(u64 *)(r10 - 8) = [[FIRST]] +; CHECK: r1 <<= 32 +; CHECK: r2 = r1 +; CHECK: r2 |= 0 +; CHECK: *(u64 *)(r10 - 8) = r2 +; CHECK: r1 |= 5 +; CHECK: *(u64 *)(r10 - 16) = r1 call void @foo(i8* nonnull %2) #3 ; CHECK: call foo call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %2) #3 diff --git a/test/CodeGen/X86/swap.ll b/test/CodeGen/X86/swap.ll index 57fd7a178d1..e74ed248c60 100644 --- a/test/CodeGen/X86/swap.ll +++ b/test/CodeGen/X86/swap.ll @@ -22,6 +22,7 @@ define dso_local void @_Z4SwapP1SS0_(%struct.S* nocapture %a, %struct.S* nocaptu ; AA-LABEL: _Z4SwapP1SS0_: ; AA: # %bb.0: # %entry ; AA-NEXT: vmovups (%rdi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) ; AA-NEXT: vmovups (%rsi), %xmm1 ; AA-NEXT: vmovups %xmm1, (%rdi) ; AA-NEXT: vmovups %xmm0, (%rsi) @@ -42,10 +43,18 @@ entry: define dso_local void @onealloc_noreadback(i8* nocapture %a, i8* nocapture %b) local_unnamed_addr { ; NOAA-LABEL: onealloc_noreadback: ; NOAA: # %bb.0: # %entry +; NOAA-NEXT: vmovups (%rdi), %xmm0 +; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; NOAA-NEXT: vmovups (%rsi), %xmm0 +; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) ; NOAA-NEXT: retq ; ; AA-LABEL: onealloc_noreadback: ; AA: # %bb.0: # %entry +; AA-NEXT: vmovups (%rdi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; AA-NEXT: vmovups (%rsi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) ; AA-NEXT: retq entry: %alloc = alloca [16 x i8], i8 2, align 1 @@ -64,10 +73,18 @@ entry: define dso_local void @twoallocs_trivial(i8* nocapture %a, i8* nocapture %b) local_unnamed_addr { ; NOAA-LABEL: twoallocs_trivial: ; NOAA: # %bb.0: # %entry +; NOAA-NEXT: vmovups (%rdi), %xmm0 +; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; NOAA-NEXT: vmovups (%rsi), %xmm0 +; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) ; NOAA-NEXT: retq ; ; AA-LABEL: twoallocs_trivial: ; AA: # %bb.0: # %entry +; AA-NEXT: vmovups (%rdi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; AA-NEXT: vmovups (%rsi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) ; AA-NEXT: retq entry: %alloc1 = alloca [16 x i8], align 1 @@ -87,12 +104,16 @@ define dso_local void @twoallocs(i8* nocapture %a, i8* nocapture %b) local_unnam ; NOAA-LABEL: twoallocs: ; NOAA: # %bb.0: # %entry ; NOAA-NEXT: vmovups (%rdi), %xmm0 +; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; NOAA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0 ; NOAA-NEXT: vmovups %xmm0, (%rsi) ; NOAA-NEXT: retq ; ; AA-LABEL: twoallocs: ; AA: # %bb.0: # %entry ; AA-NEXT: vmovups (%rdi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; AA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0 ; AA-NEXT: vmovups %xmm0, (%rsi) ; AA-NEXT: retq entry: @@ -116,12 +137,18 @@ define dso_local void @onealloc_readback_1(i8* nocapture %a, i8* nocapture %b) l ; NOAA-NEXT: vmovups (%rdi), %xmm0 ; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) ; NOAA-NEXT: vmovups (%rsi), %xmm0 +; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; NOAA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0 ; NOAA-NEXT: vmovups %xmm0, (%rdi) ; NOAA-NEXT: retq ; ; AA-LABEL: onealloc_readback_1: ; AA: # %bb.0: # %entry +; AA-NEXT: vmovups (%rdi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) ; AA-NEXT: vmovups (%rsi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; AA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0 ; AA-NEXT: vmovups %xmm0, (%rdi) ; AA-NEXT: retq entry: @@ -144,12 +171,18 @@ define dso_local void @onealloc_readback_2(i8* nocapture %a, i8* nocapture %b) l ; NOAA-NEXT: vmovups (%rdi), %xmm0 ; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) ; NOAA-NEXT: vmovups (%rsi), %xmm0 +; NOAA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; NOAA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0 ; NOAA-NEXT: vmovups %xmm0, (%rdi) ; NOAA-NEXT: retq ; ; AA-LABEL: onealloc_readback_2: ; AA: # %bb.0: # %entry +; AA-NEXT: vmovups (%rdi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) ; AA-NEXT: vmovups (%rsi), %xmm0 +; AA-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) +; AA-NEXT: vmovaps -{{[0-9]+}}(%rsp), %xmm0 ; AA-NEXT: vmovups %xmm0, (%rdi) ; AA-NEXT: retq entry: diff --git a/test/DebugInfo/COFF/inlining.ll b/test/DebugInfo/COFF/inlining.ll index bb07cacb1cf..c399aca1325 100644 --- a/test/DebugInfo/COFF/inlining.ll +++ b/test/DebugInfo/COFF/inlining.ll @@ -29,6 +29,7 @@ ; ASM: .cv_loc 1 1 9 5 # t.cpp:9:5 ; ASM: addl $4, "?x@@3HC" ; ASM: .cv_inline_site_id 2 within 1 inlined_at 1 10 3 +; ASM: .cv_loc 2 1 3 7 # t.cpp:3:7 ; ASM: .cv_loc 2 1 4 5 # t.cpp:4:5 ; ASM: addl {{.*}}, "?x@@3HC" ; ASM: .cv_loc 2 1 5 5 # t.cpp:5:5 @@ -171,7 +172,7 @@ ; OBJ: PtrParent: 0x0 ; OBJ: PtrEnd: 0x0 ; OBJ: PtrNext: 0x0 -; OBJ: CodeSize: 0x35 +; OBJ: CodeSize: 0x3C ; OBJ: DbgStart: 0x0 ; OBJ: DbgEnd: 0x0 ; OBJ: FunctionType: baz (0x1004) @@ -188,9 +189,9 @@ ; OBJ: Inlinee: bar (0x1002) ; OBJ: BinaryAnnotations [ ; OBJ-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x8, LineOffset: 1} -; OBJ-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x9, LineOffset: 1} +; OBJ-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x7, LineOffset: 1} ; OBJ-NEXT: ChangeLineOffset: 1 -; OBJ-NEXT: ChangeCodeOffset: 0x14 +; OBJ-NEXT: ChangeCodeOffset: 0x1D ; OBJ-NEXT: ChangeCodeLength: 0x7 ; OBJ: ] ; OBJ: } @@ -199,8 +200,8 @@ ; OBJ: PtrEnd: 0x0 ; OBJ: Inlinee: foo (0x1003) ; OBJ: BinaryAnnotations [ -; OBJ-NEXT: ChangeLineOffset: 2 -; OBJ-NEXT: ChangeCodeOffset: 0x11 +; OBJ-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0xF, LineOffset: 1} +; OBJ-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x9, LineOffset: 1} ; OBJ-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x6, LineOffset: 1} ; OBJ-NEXT: ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x7, LineOffset: 1} ; OBJ-NEXT: ChangeCodeLength: 0x7 diff --git a/test/DebugInfo/COFF/lexicalblock.ll b/test/DebugInfo/COFF/lexicalblock.ll index 970aae27d69..39fcd991f39 100644 --- a/test/DebugInfo/COFF/lexicalblock.ll +++ b/test/DebugInfo/COFF/lexicalblock.ll @@ -70,6 +70,9 @@ ; CHECK: Kind: S_BLOCK32 {{.*}} ; CHECK: BlockName: ; CHECK: } +; CHECK: LocalSym { +; CHECK: VarName: localC +; CHECK: } ; CHECK: ScopeEndSym { ; CHECK: Kind: S_END {{.*}} ; CHECK: } @@ -77,6 +80,9 @@ ; CHECK: Kind: S_BLOCK32 {{.*}} ; CHECK: BlockName: ; CHECK: } +; CHECK: LocalSym { +; CHECK: VarName: localD +; CHECK: } ; CHECK: ScopeEndSym { ; CHECK: Kind: S_END {{.*}} ; CHECK: } @@ -84,12 +90,38 @@ ; CHECK: Kind: S_BLOCK32 {{.*}} ; CHECK: BlockName: ; CHECK: } +; CHECK: LocalSym { +; CHECK: VarName: localE +; CHECK: } +; CHECK: ScopeEndSym { +; CHECK: } +; CHECK: BlockSym { +; CHECK: Kind: S_BLOCK32 {{.*}} +; CHECK: BlockName: +; CHECK: } +; CHECK: LocalSym { +; CHECK: VarName: localF +; CHECK: } +; CHECK: BlockSym { +; CHECK: Kind: S_BLOCK32 {{.*}} +; CHECK: BlockName: +; CHECK: } +; CHECK: LocalSym { +; CHECK: VarName: localG +; CHECK: } ; CHECK: ScopeEndSym { +; CHECK: Kind: S_END {{.*}} +; CHECK: } +; CHECK: ScopeEndSym { +; CHECK: Kind: S_END {{.*}} ; CHECK: } ; CHECK: BlockSym { ; CHECK: Kind: S_BLOCK32 {{.*}} ; CHECK: BlockName: ; CHECK: } +; CHECK: LocalSym { +; CHECK: VarName: localH +; CHECK: } ; CHECK: ScopeEndSym { ; CHECK: Kind: S_END {{.*}} ; CHECK: } -- 2.11.4.GIT