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.

llvm-svn: 115571
This commit is contained in:
Evan Cheng 2010-10-04 22:41:01 +00:00
parent 405fe67f14
commit c8d6cfd730
1 changed files with 18 additions and 13 deletions

View File

@ -5102,14 +5102,17 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
N1.getOperand(0), N1.getOperand(1), N2);
}
SDNode *Trunc = 0;
if (N1.getOpcode() == ISD::TRUNCATE && N1.hasOneUse()) {
// Look past truncate.
Trunc = N1.getNode();
N1 = N1.getOperand(0);
}
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;
if (N1.getOpcode() == ISD::TRUNCATE) {
// Look pass the truncate.
Trunc = N1.getNode();
N1 = N1.getOperand(0);
}
if (N1.hasOneUse() && N1.getOpcode() == ISD::SRL) {
// Match this pattern so that we can generate simpler code:
//
// %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)
@ -5199,9 +5206,7 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
Equal = true;
}
SDValue NodeToReplace = Trunc ? SDValue(Trunc, 0) : N1;
EVT SetCCVT = NodeToReplace.getValueType();
EVT SetCCVT = N1.getValueType();
if (LegalTypes)
SetCCVT = TLI.getSetCCResultType(SetCCVT);
SDValue SetCC = DAG.getSetCC(TheXor->getDebugLoc(),
@ -5210,9 +5215,9 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) {
Equal ? ISD::SETEQ : ISD::SETNE);
// Replace the uses of XOR with SETCC
WorkListRemover DeadNodes(*this);
DAG.ReplaceAllUsesOfValueWith(NodeToReplace, SetCC, &DeadNodes);
removeFromWorkList(NodeToReplace.getNode());
DAG.DeleteNode(NodeToReplace.getNode());
DAG.ReplaceAllUsesOfValueWith(N1, SetCC, &DeadNodes);
removeFromWorkList(N1.getNode());
DAG.DeleteNode(N1.getNode());
return DAG.getNode(ISD::BRCOND, N->getDebugLoc(),
MVT::Other, Chain, SetCC, N2);
}