mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-30 00:16:48 +00:00
This DAG combine BRCOND transformation can look pass truncate of the operand:
// %a = ...
// %b = and i32 %a, 2
// %c = srl i32 %b, 1
// brcond i32 %c ...
//
// into
//
// %a = ...
// %b = and i32 %a, 2
// %c = setcc eq %b, 0
// brcond %c ...
Make sure it restores local variable N1, which corresponds to the condition operand if it fails to match.
This apparently breaks TCE but since that backend isn't in the tree I don't have a test for it.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115571 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -5102,14 +5102,17 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
|
|||||||
N1.getOperand(0), N1.getOperand(1), N2);
|
N1.getOperand(0), N1.getOperand(1), N2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((N1.hasOneUse() && N1.getOpcode() == ISD::SRL) ||
|
||||||
|
((N1.getOpcode() == ISD::TRUNCATE && N1.hasOneUse()) &&
|
||||||
|
(N1.getOperand(0).hasOneUse() &&
|
||||||
|
N1.getOperand(0).getOpcode() == ISD::SRL))) {
|
||||||
SDNode *Trunc = 0;
|
SDNode *Trunc = 0;
|
||||||
if (N1.getOpcode() == ISD::TRUNCATE && N1.hasOneUse()) {
|
if (N1.getOpcode() == ISD::TRUNCATE) {
|
||||||
// Look past truncate.
|
// Look pass the truncate.
|
||||||
Trunc = N1.getNode();
|
Trunc = N1.getNode();
|
||||||
N1 = N1.getOperand(0);
|
N1 = N1.getOperand(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (N1.hasOneUse() && N1.getOpcode() == ISD::SRL) {
|
|
||||||
// Match this pattern so that we can generate simpler code:
|
// Match this pattern so that we can generate simpler code:
|
||||||
//
|
//
|
||||||
// %a = ...
|
// %a = ...
|
||||||
@@ -5164,6 +5167,10 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Trunc)
|
||||||
|
// Restore N1 if the above transformation doesn't match.
|
||||||
|
N1 = N->getOperand(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform br(xor(x, y)) -> br(x != y)
|
// Transform br(xor(x, y)) -> br(x != y)
|
||||||
@@ -5199,9 +5206,7 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
|
|||||||
Equal = true;
|
Equal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue NodeToReplace = Trunc ? SDValue(Trunc, 0) : N1;
|
EVT SetCCVT = N1.getValueType();
|
||||||
|
|
||||||
EVT SetCCVT = NodeToReplace.getValueType();
|
|
||||||
if (LegalTypes)
|
if (LegalTypes)
|
||||||
SetCCVT = TLI.getSetCCResultType(SetCCVT);
|
SetCCVT = TLI.getSetCCResultType(SetCCVT);
|
||||||
SDValue SetCC = DAG.getSetCC(TheXor->getDebugLoc(),
|
SDValue SetCC = DAG.getSetCC(TheXor->getDebugLoc(),
|
||||||
@@ -5210,9 +5215,9 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
|
|||||||
Equal ? ISD::SETEQ : ISD::SETNE);
|
Equal ? ISD::SETEQ : ISD::SETNE);
|
||||||
// Replace the uses of XOR with SETCC
|
// Replace the uses of XOR with SETCC
|
||||||
WorkListRemover DeadNodes(*this);
|
WorkListRemover DeadNodes(*this);
|
||||||
DAG.ReplaceAllUsesOfValueWith(NodeToReplace, SetCC, &DeadNodes);
|
DAG.ReplaceAllUsesOfValueWith(N1, SetCC, &DeadNodes);
|
||||||
removeFromWorkList(NodeToReplace.getNode());
|
removeFromWorkList(N1.getNode());
|
||||||
DAG.DeleteNode(NodeToReplace.getNode());
|
DAG.DeleteNode(N1.getNode());
|
||||||
return DAG.getNode(ISD::BRCOND, N->getDebugLoc(),
|
return DAG.getNode(ISD::BRCOND, N->getDebugLoc(),
|
||||||
MVT::Other, Chain, SetCC, N2);
|
MVT::Other, Chain, SetCC, N2);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user