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
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 3545b24..2108f22 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -4559,6 +4559,24 @@
}
}
+ // 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 @@
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;
}