Fix a testcase provided by Bill in which the node

id could end up being wrong mostly because of
forgetting to remap new nodes that morphed into
processed nodes through CSE.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58323 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands 2008-10-28 09:38:36 +00:00
parent 6e1c6231ba
commit 1acb29c8ea
3 changed files with 47 additions and 29 deletions

View File

@ -222,10 +222,12 @@ NodeDone:
/// new nodes. Correct any processed operands (this may change the node) and
/// calculate the NodeId.
/// Returns the potentially changed node.
SDNode *DAGTypeLegalizer::AnalyzeNewNode(SDNode *N) {
void DAGTypeLegalizer::AnalyzeNewNode(SDValue &Val) {
SDNode *N = Val.getNode();
// If this was an existing node that is already done, we're done.
if (N->getNodeId() != NewNode)
return N;
return;
// Remove any stale map entries.
ExpungeNode(N);
@ -249,10 +251,10 @@ SDNode *DAGTypeLegalizer::AnalyzeNewNode(SDNode *N) {
if (Op.getNode()->getNodeId() == Processed)
RemapNode(Op);
if (Op.getNode()->getNodeId() == NewNode)
else if (Op.getNode()->getNodeId() == NewNode)
AnalyzeNewNode(Op);
else if (Op.getNode()->getNodeId() == Processed)
if (Op.getNode()->getNodeId() == Processed)
++NumProcessed;
if (!NewOps.empty()) {
@ -267,29 +269,30 @@ SDNode *DAGTypeLegalizer::AnalyzeNewNode(SDNode *N) {
}
// Some operands changed - update the node.
if (!NewOps.empty())
N = DAG.UpdateNodeOperands(SDValue(N, 0),
&NewOps[0],
NewOps.size()).getNode();
if (!NewOps.empty()) {
Val = DAG.UpdateNodeOperands(Val, &NewOps[0], NewOps.size());
if (Val.getNode() != N) {
// The node morphed, work with the new node.
N = Val.getNode();
// Calculate the NodeId if we haven't morphed into an existing node for
// which it is already known.
if (N->getNodeId() == NewNode) {
N->setNodeId(N->getNumOperands()-NumProcessed);
if (N->getNodeId() == ReadyToProcess)
Worklist.push_back(N);
// Maybe it morphed into a previously analyzed node?
if (N->getNodeId() != NewNode) {
if (N->getNodeId() == Processed)
// An already processed node may need to be remapped.
RemapNode(Val);
return;
}
// It morphed into a different new node. Do the equivalent of passing
// it to AnalyzeNewNode: expunge it and calculate the NodeId.
ExpungeNode(N);
}
}
return N;
}
/// AnalyzeNewNode - call AnalyzeNewNode(SDNode *N)
/// and update the node in SDValue if necessary.
void DAGTypeLegalizer::AnalyzeNewNode(SDValue &Val) {
SDNode *N(Val.getNode());
SDNode *M(AnalyzeNewNode(N));
if (N != M)
Val.setNode(M);
// Calculate the NodeId.
N->setNodeId(N->getNumOperands()-NumProcessed);
if (N->getNodeId() == ReadyToProcess)
Worklist.push_back(N);
}
@ -353,7 +356,9 @@ void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) {
// If expansion produced new nodes, make sure they are properly marked.
ExpungeNode(From);
To = AnalyzeNewNode(To); // Expunges To.
SDValue Val(To, 0);
AnalyzeNewNode(Val); // Expunges To. FIXME: All results mapped the same?
To = Val.getNode();
assert(From->getNumValues() == To->getNumValues() &&
"Node results don't match");
@ -382,6 +387,7 @@ void DAGTypeLegalizer::RemapNode(SDValue &N) {
RemapNode(I->second);
N = I->second;
}
assert(N.getNode()->getNodeId() != NewNode && "Mapped to unanalyzed node!");
}
/// ExpungeNode - If N has a bogus mapping in ReplacedNodes, eliminate it.

View File

@ -155,9 +155,11 @@ public:
/// ReanalyzeNode - Recompute the NodeID and correct processed operands
/// for the specified node, adding it to the worklist if ready.
SDNode *ReanalyzeNode(SDNode *N) {
void ReanalyzeNode(SDNode *N) {
N->setNodeId(NewNode);
return AnalyzeNewNode(N);
SDValue Val(N, 0);
AnalyzeNewNode(Val);
// The node may have changed but we don't care.
}
void NoteDeletion(SDNode *Old, SDNode *New) {
@ -169,7 +171,6 @@ public:
private:
void AnalyzeNewNode(SDValue &Val);
SDNode *AnalyzeNewNode(SDNode *N);
void ReplaceValueWith(SDValue From, SDValue To);
void ReplaceNodeWith(SDNode *From, SDNode *To);

View File

@ -0,0 +1,11 @@
; RUN: llvm-as < %s | llc -march=ppc64
define void @__divtc3({ ppc_fp128, ppc_fp128 }* noalias sret %agg.result, ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d) nounwind {
entry:
%imag59 = load ppc_fp128* null, align 8 ; <ppc_fp128> [#uses=1]
%0 = mul ppc_fp128 0xM00000000000000000000000000000000, %imag59 ; <ppc_fp128> [#uses=1]
%1 = mul ppc_fp128 0xM00000000000000000000000000000000, 0xM00000000000000000000000000000000 ; <ppc_fp128> [#uses=1]
%2 = add ppc_fp128 %0, %1 ; <ppc_fp128> [#uses=1]
store ppc_fp128 %2, ppc_fp128* null, align 16
unreachable
}