[llvm] r356050 - Re-land r354244 "[DAGCombiner] Eliminate dead stores to stack."
Clement Courbet via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 13 06:56:23 PDT 2019
Author: courbet
Date: Wed Mar 13 06:56:23 2019
New Revision: 356050
URL: http://llvm.org/viewvc/llvm-project?rev=356050&view=rev
Log:
Re-land r354244 "[DAGCombiner] Eliminate dead stores to stack."
Always check candidates for hasOtherUses(), not only stores.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/trunk/test/CodeGen/X86/swap.ll
llvm/trunk/test/DebugInfo/COFF/lexicalblock.ll
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=356050&r1=356049&r2=356050&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Mar 13 06:56:23 2019
@@ -384,6 +384,7 @@ 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);
@@ -1591,6 +1592,7 @@ 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);
case ISD::VECREDUCE_FADD:
@@ -15561,6 +15563,66 @@ SDValue DAGCombiner::visitSTORE(SDNode *
return ReduceLoadOpStoreWidth(N);
}
+SDValue DAGCombiner::visitLIFETIME_END(SDNode *N) {
+ const auto *LifetimeEnd = cast<LifetimeSDNode>(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<SDValue, 8> Chains = {N->getOperand(0)};
+ while (!Chains.empty()) {
+ SDValue Chain = Chains.back();
+ Chains.pop_back();
+ if (!Chain.hasOneUse())
+ continue;
+ 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 *Lifetime = cast<LifetimeSDNode>(Chain);
+ if (!Lifetime->hasOffset())
+ break; // Be conservative if we don't know the extents of the object.
+
+ const BaseIndexOffset LifetimeBase(Lifetime->getOperand(1), SDValue(),
+ Lifetime->getOffset(), false);
+ bool IsAlias;
+ if (BaseIndexOffset::computeAliasing(LifetimeEndBase,
+ LifetimeEnd->getSize(), LifetimeBase,
+ Lifetime->getSize(), DAG, IsAlias) &&
+ !IsAlias) {
+ Chains.push_back(Chain.getOperand(0));
+ }
+ break;
+ }
+ case ISD::STORE: {
+ StoreSDNode *ST = dyn_cast<StoreSDNode>(Chain);
+ if (ST->isVolatile() || 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(DAG, LifetimeEnd->getSize() * 8, StoreBase,
+ ST->getMemoryVT().getStoreSizeInBits())) {
+ 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,
@@ -19394,6 +19456,8 @@ void DAGCombiner::GatherAllAliases(LSBas
// Get alias information for node.
bool IsLoad = isa<LoadSDNode>(N) && !N->isVolatile();
+ const BaseIndexOffset LSBasePtr = BaseIndexOffset::match(N, DAG);
+ const unsigned LSNumBytes = N->getMemoryVT().getStoreSize();
// Starting off.
Chains.push_back(OriginalChain);
@@ -19464,6 +19528,31 @@ void DAGCombiner::GatherAllAliases(LSBas
++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<LifetimeSDNode>(Chain);
+ if (!Lifetime->hasOffset()) {
+ Aliases.push_back(Chain);
+ 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;
+ } else {
+ Aliases.push_back(Chain);
+ }
+ break;
+ }
+
default:
// For all other instructions we will just have to take what we can get.
Aliases.push_back(Chain);
Modified: llvm/trunk/test/CodeGen/X86/swap.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/swap.ll?rev=356050&r1=356049&r2=356050&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/swap.ll (original)
+++ llvm/trunk/test/CodeGen/X86/swap.ll Wed Mar 13 06:56:23 2019
@@ -22,7 +22,6 @@ define dso_local void @_Z4SwapP1SS0_(%st
; 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)
@@ -43,18 +42,10 @@ 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
@@ -73,18 +64,10 @@ 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
@@ -105,7 +88,6 @@ define dso_local void @twoallocs(i8* noc
; 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
;
@@ -113,7 +95,6 @@ define dso_local void @twoallocs(i8* noc
; 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:
@@ -148,7 +129,6 @@ define dso_local void @onealloc_readback
; 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:
@@ -182,7 +162,6 @@ define dso_local void @onealloc_readback
; 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:
Modified: llvm/trunk/test/DebugInfo/COFF/lexicalblock.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/lexicalblock.ll?rev=356050&r1=356049&r2=356050&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/lexicalblock.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/lexicalblock.ll Wed Mar 13 06:56:23 2019
@@ -70,9 +70,6 @@
; CHECK: Kind: S_BLOCK32 {{.*}}
; CHECK: BlockName:
; CHECK: }
-; CHECK: LocalSym {
-; CHECK: VarName: localC
-; CHECK: }
; CHECK: ScopeEndSym {
; CHECK: Kind: S_END {{.*}}
; CHECK: }
@@ -80,9 +77,6 @@
; CHECK: Kind: S_BLOCK32 {{.*}}
; CHECK: BlockName:
; CHECK: }
-; CHECK: LocalSym {
-; CHECK: VarName: localD
-; CHECK: }
; CHECK: ScopeEndSym {
; CHECK: Kind: S_END {{.*}}
; CHECK: }
@@ -90,38 +84,12 @@
; 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: }
More information about the llvm-commits
mailing list