diff options
author | Chris Lattner <sabre@nondot.org> | 2006-09-13 03:50:39 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-09-13 03:50:39 +0000 |
commit | 79980b07dab50da1a8f572f9504674bfa853d484 (patch) | |
tree | 634eee17798e46465fe388176cde49a8bc8ea80e | |
parent | f95705163f45648fa58b1c481847b2c10bcb470f (diff) |
Compile X << 1 (where X is a long-long) to:
addl %ecx, %ecx
adcl %eax, %eax
instead of:
movl %ecx, %edx
addl %edx, %edx
shrl $31, %ecx
addl %eax, %eax
orl %ecx, %eax
and to:
addc r5, r5, r5
adde r4, r4, r4
instead of:
slwi r2,r9,1
srwi r0,r11,31
slwi r3,r11,1
or r2,r0,r2
on PPC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30284 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 3545b24689..2108f22cc5 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -4559,6 +4559,24 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ } } + // If ADDC/ADDE are supported and if the shift amount is a constant 1, emit + // this X << 1 as X+X. + if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(ShiftAmt)) { + if (ShAmt->getValue() == 1 && TLI.isOperationLegal(ISD::ADDC, NVT) && + TLI.isOperationLegal(ISD::ADDE, NVT)) { + SDOperand LoOps[2], HiOps[3]; + ExpandOp(Node->getOperand(0), LoOps[0], HiOps[0]); + SDVTList VTList = DAG.getVTList(LoOps[0].getValueType(), MVT::Flag); + LoOps[1] = LoOps[0]; + Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + + HiOps[1] = HiOps[0]; + HiOps[2] = Lo.getValue(1); + Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + break; + } + } + // If we can emit an efficient shift operation, do so now. if (ExpandShift(ISD::SHL, Node->getOperand(0), ShiftAmt, Lo, Hi)) break; @@ -4657,21 +4675,20 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ SDOperand LHSL, LHSH, RHSL, RHSH; ExpandOp(Node->getOperand(0), LHSL, LHSH); ExpandOp(Node->getOperand(1), RHSL, RHSH); - const MVT::ValueType *VTs = - DAG.getNodeValueTypes(LHSL.getValueType(),MVT::Flag); - SDOperand LoOps[2], HiOps[2]; + SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); + SDOperand LoOps[2], HiOps[3]; LoOps[0] = LHSL; LoOps[1] = RHSL; HiOps[0] = LHSH; HiOps[1] = RHSH; if (Node->getOpcode() == ISD::ADD) { - Lo = DAG.getNode(ISD::ADDC, VTs, 2, LoOps, 2); + Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTs, 2, HiOps, 3); + Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); } else { - Lo = DAG.getNode(ISD::SUBC, VTs, 2, LoOps, 2); + Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTs, 2, HiOps, 3); + Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); } break; } |