+/// SimplifyNodeWithTwoResults - Perform optimizations common to nodes that
+/// compute two values. LoOp and HiOp give the opcodes for the two computations
+/// that are being performed. Return true if a simplification was made.
+///
+SDOperand DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
+ unsigned HiOp) {
+ // If the high half is not needed, just compute the low half.
+ bool HiExists = N->hasAnyUseOfValue(1);
+ if (!HiExists &&
+ (!AfterLegalize ||
+ TLI.isOperationLegal(LoOp, N->getValueType(0)))) {
+ SDOperand Res = DAG.getNode(LoOp, N->getValueType(0), N->op_begin(),
+ N->getNumOperands());
+ return CombineTo(N, Res, Res);
+ }
+
+ // If the low half is not needed, just compute the high half.
+ bool LoExists = N->hasAnyUseOfValue(0);
+ if (!LoExists &&
+ (!AfterLegalize ||
+ TLI.isOperationLegal(HiOp, N->getValueType(1)))) {
+ SDOperand Res = DAG.getNode(HiOp, N->getValueType(1), N->op_begin(),
+ N->getNumOperands());
+ return CombineTo(N, Res, Res);
+ }
+
+ // If both halves are used, return as it is.
+ if (LoExists && HiExists)
+ return SDOperand();
+
+ // If the two computed results can be simplified separately, separate them.
+ if (LoExists) {
+ SDOperand Lo = DAG.getNode(LoOp, N->getValueType(0),
+ N->op_begin(), N->getNumOperands());
+ AddToWorkList(Lo.Val);
+ SDOperand LoOpt = combine(Lo.Val);
+ if (LoOpt.Val && LoOpt.Val != Lo.Val &&
+ TLI.isOperationLegal(LoOpt.getOpcode(), LoOpt.getValueType()))
+ return CombineTo(N, LoOpt, LoOpt);
+ }
+
+ if (HiExists) {
+ SDOperand Hi = DAG.getNode(HiOp, N->getValueType(1),
+ N->op_begin(), N->getNumOperands());
+ AddToWorkList(Hi.Val);
+ SDOperand HiOpt = combine(Hi.Val);
+ if (HiOpt.Val && HiOpt != Hi &&
+ TLI.isOperationLegal(HiOpt.getOpcode(), HiOpt.getValueType()))
+ return CombineTo(N, HiOpt, HiOpt);
+ }
+ return SDOperand();
+}
+
+SDOperand DAGCombiner::visitSMUL_LOHI(SDNode *N) {
+ SDOperand Res = SimplifyNodeWithTwoResults(N, ISD::MUL, ISD::MULHS);
+ if (Res.Val) return Res;
+
+ return SDOperand();
+}
+
+SDOperand DAGCombiner::visitUMUL_LOHI(SDNode *N) {
+ SDOperand Res = SimplifyNodeWithTwoResults(N, ISD::MUL, ISD::MULHU);
+ if (Res.Val) return Res;
+
+ return SDOperand();
+}
+
+SDOperand DAGCombiner::visitSDIVREM(SDNode *N) {
+ SDOperand Res = SimplifyNodeWithTwoResults(N, ISD::SDIV, ISD::SREM);
+ if (Res.Val) return Res;
+
+ return SDOperand();
+}
+
+SDOperand DAGCombiner::visitUDIVREM(SDNode *N) {
+ SDOperand Res = SimplifyNodeWithTwoResults(N, ISD::UDIV, ISD::UREM);
+ if (Res.Val) return Res;
+
+ return SDOperand();
+}
+