Add a bunch of calls to RemoveDeadNode in LegalizeDAG, so legalization doesn't get confused by CSE later on. Fixes PR11318.

Re-commit of r144034, with an extra fix so that RemoveDeadNode doesn't blow up.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144055 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2011-11-08 01:25:24 +00:00
parent 9ae7563732
commit 2efa35f779
3 changed files with 39 additions and 3 deletions

View File

@ -285,6 +285,7 @@ static void ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
Result = DAG.getStore(Chain, dl, Result, Ptr, ST->getPointerInfo(), Result = DAG.getStore(Chain, dl, Result, Ptr, ST->getPointerInfo(),
ST->isVolatile(), ST->isNonTemporal(), Alignment); ST->isVolatile(), ST->isNonTemporal(), Alignment);
DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL); DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL);
DAG.RemoveDeadNode(ST, DUL);
return; return;
} }
// Do a (aligned) store to a stack slot, then copy from the stack slot // Do a (aligned) store to a stack slot, then copy from the stack slot
@ -349,6 +350,7 @@ static void ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0],
Stores.size()); Stores.size());
DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL); DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL);
DAG.RemoveDeadNode(ST, DUL);
return; return;
} }
assert(ST->getMemoryVT().isInteger() && assert(ST->getMemoryVT().isInteger() &&
@ -381,6 +383,7 @@ static void ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG,
SDValue Result = SDValue Result =
DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2); DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2);
DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL); DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL);
DAG.RemoveDeadNode(ST, DUL);
} }
/// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads. /// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads.
@ -1144,6 +1147,7 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
if (!ST->isTruncatingStore()) { if (!ST->isTruncatingStore()) {
if (SDNode *OptStore = OptimizeFloatStore(ST).getNode()) { if (SDNode *OptStore = OptimizeFloatStore(ST).getNode()) {
DAG.ReplaceAllUsesWith(ST, OptStore, this); DAG.ReplaceAllUsesWith(ST, OptStore, this);
DAG.RemoveDeadNode(ST, this);
break; break;
} }
@ -1169,8 +1173,10 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
break; break;
case TargetLowering::Custom: case TargetLowering::Custom:
Tmp1 = TLI.LowerOperation(SDValue(Node, 0), DAG); Tmp1 = TLI.LowerOperation(SDValue(Node, 0), DAG);
if (Tmp1.getNode()) if (Tmp1.getNode()) {
DAG.ReplaceAllUsesWith(SDValue(Node, 0), Tmp1, this); DAG.ReplaceAllUsesWith(SDValue(Node, 0), Tmp1, this);
DAG.RemoveDeadNode(Node, this);
}
break; break;
case TargetLowering::Promote: { case TargetLowering::Promote: {
assert(VT.isVector() && "Unknown legal promote case!"); assert(VT.isVector() && "Unknown legal promote case!");
@ -1181,6 +1187,7 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
ST->getPointerInfo(), isVolatile, ST->getPointerInfo(), isVolatile,
isNonTemporal, Alignment); isNonTemporal, Alignment);
DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
DAG.RemoveDeadNode(Node, this);
break; break;
} }
} }
@ -1203,6 +1210,7 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(),
NVT, isVolatile, isNonTemporal, Alignment); NVT, isVolatile, isNonTemporal, Alignment);
DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
DAG.RemoveDeadNode(Node, this);
} else if (StWidth & (StWidth - 1)) { } else if (StWidth & (StWidth - 1)) {
// If not storing a power-of-2 number of bits, expand as two stores. // If not storing a power-of-2 number of bits, expand as two stores.
assert(!StVT.isVector() && "Unsupported truncstore!"); assert(!StVT.isVector() && "Unsupported truncstore!");
@ -1258,6 +1266,7 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
// The order of the stores doesn't matter. // The order of the stores doesn't matter.
SDValue Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); SDValue Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
DAG.RemoveDeadNode(Node, this);
} else { } else {
if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() || if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() ||
Tmp2 != ST->getBasePtr()) Tmp2 != ST->getBasePtr())
@ -1280,6 +1289,7 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
DAG.ReplaceAllUsesWith(SDValue(Node, 0), DAG.ReplaceAllUsesWith(SDValue(Node, 0),
TLI.LowerOperation(SDValue(Node, 0), DAG), TLI.LowerOperation(SDValue(Node, 0), DAG),
this); this);
DAG.RemoveDeadNode(Node, this);
break; break;
case TargetLowering::Expand: case TargetLowering::Expand:
assert(!StVT.isVector() && assert(!StVT.isVector() &&
@ -1292,6 +1302,7 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(),
isVolatile, isNonTemporal, Alignment); isVolatile, isNonTemporal, Alignment);
DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
DAG.RemoveDeadNode(Node, this);
break; break;
} }
} }
@ -3361,6 +3372,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0), DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0),
&Scalars[0], Scalars.size()); &Scalars[0], Scalars.size());
DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
DAG.RemoveDeadNode(Node, this);
break; break;
} }
case ISD::GLOBAL_OFFSET_TABLE: case ISD::GLOBAL_OFFSET_TABLE:
@ -3377,8 +3389,10 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
} }
// Replace the original node with the legalized result. // Replace the original node with the legalized result.
if (!Results.empty()) if (!Results.empty()) {
DAG.ReplaceAllUsesWith(Node, Results.data(), this); DAG.ReplaceAllUsesWith(Node, Results.data(), this);
DAG.RemoveDeadNode(Node, this);
}
} }
void SelectionDAGLegalize::PromoteNode(SDNode *Node) { void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
@ -3512,8 +3526,10 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
} }
// Replace the original node with the legalized result. // Replace the original node with the legalized result.
if (!Results.empty()) if (!Results.empty()) {
DAG.ReplaceAllUsesWith(Node, Results.data(), this); DAG.ReplaceAllUsesWith(Node, Results.data(), this);
DAG.RemoveDeadNode(Node, this);
}
} }
// SelectionDAG::Legalize - This is the entry point for the file. // SelectionDAG::Legalize - This is the entry point for the file.

View File

@ -564,6 +564,12 @@ void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes,
void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){ void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){
SmallVector<SDNode*, 16> DeadNodes(1, N); SmallVector<SDNode*, 16> DeadNodes(1, N);
// Create a dummy node that adds a reference to the root node, preventing
// it from being deleted. (This matters if the root is an operand of the
// dead node.)
HandleSDNode Dummy(getRoot());
RemoveDeadNodes(DeadNodes, UpdateListener); RemoveDeadNodes(DeadNodes, UpdateListener);
} }

View File

@ -0,0 +1,14 @@
; RUN: llc < %s -march=x86 -mattr=+avx | FileCheck %s
; We don't really care what this outputs; just make sure it's somewhat sane.
; CHECK: legalize_test
; CHECK: vmovups
define void @legalize_test(i32 %x, <8 x i32>* %p) nounwind {
entry:
%t1 = insertelement <8 x i32> <i32 undef, i32 undef, i32 15, i32 15, i32 15, i32 15, i32 15, i32 15>, i32 %x, i32 0
%t2 = shufflevector <8 x i32> %t1, <8 x i32> zeroinitializer, <8 x i32> <i32 0, i32 9, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
%int2float = sitofp <8 x i32> %t2 to <8 x float>
%blendAsInt.i821 = bitcast <8 x float> %int2float to <8 x i32>
store <8 x i32> %blendAsInt.i821, <8 x i32>* %p, align 4
ret void
}