Implement mulo x, 2 -> addo x, x in DAGCombiner.

llvm-svn: 131800
This commit is contained in:
Benjamin Kramer 2011-05-21 18:31:55 +00:00
parent e08fb1dce9
commit 2fd48f2730
2 changed files with 48 additions and 0 deletions

View File

@ -165,6 +165,8 @@ namespace {
SDValue visitMULHS(SDNode *N); SDValue visitMULHS(SDNode *N);
SDValue visitSMUL_LOHI(SDNode *N); SDValue visitSMUL_LOHI(SDNode *N);
SDValue visitUMUL_LOHI(SDNode *N); SDValue visitUMUL_LOHI(SDNode *N);
SDValue visitSMULO(SDNode *N);
SDValue visitUMULO(SDNode *N);
SDValue visitSDIVREM(SDNode *N); SDValue visitSDIVREM(SDNode *N);
SDValue visitUDIVREM(SDNode *N); SDValue visitUDIVREM(SDNode *N);
SDValue visitAND(SDNode *N); SDValue visitAND(SDNode *N);
@ -1047,6 +1049,8 @@ SDValue DAGCombiner::visit(SDNode *N) {
case ISD::MULHS: return visitMULHS(N); case ISD::MULHS: return visitMULHS(N);
case ISD::SMUL_LOHI: return visitSMUL_LOHI(N); case ISD::SMUL_LOHI: return visitSMUL_LOHI(N);
case ISD::UMUL_LOHI: return visitUMUL_LOHI(N); case ISD::UMUL_LOHI: return visitUMUL_LOHI(N);
case ISD::SMULO: return visitSMULO(N);
case ISD::UMULO: return visitUMULO(N);
case ISD::SDIVREM: return visitSDIVREM(N); case ISD::SDIVREM: return visitSDIVREM(N);
case ISD::UDIVREM: return visitUDIVREM(N); case ISD::UDIVREM: return visitUDIVREM(N);
case ISD::AND: return visitAND(N); case ISD::AND: return visitAND(N);
@ -2177,6 +2181,26 @@ SDValue DAGCombiner::visitUMUL_LOHI(SDNode *N) {
return SDValue(); return SDValue();
} }
SDValue DAGCombiner::visitSMULO(SDNode *N) {
// (smulo x, 2) -> (saddo x, x)
if (ConstantSDNode *C2 = dyn_cast<ConstantSDNode>(N->getOperand(1)))
if (C2->getAPIntValue() == 2)
return DAG.getNode(ISD::SADDO, N->getDebugLoc(), N->getVTList(),
N->getOperand(0), N->getOperand(0));
return SDValue();
}
SDValue DAGCombiner::visitUMULO(SDNode *N) {
// (umulo x, 2) -> (uaddo x, x)
if (ConstantSDNode *C2 = dyn_cast<ConstantSDNode>(N->getOperand(1)))
if (C2->getAPIntValue() == 2)
return DAG.getNode(ISD::UADDO, N->getDebugLoc(), N->getVTList(),
N->getOperand(0), N->getOperand(0));
return SDValue();
}
SDValue DAGCombiner::visitSDIVREM(SDNode *N) { SDValue DAGCombiner::visitSDIVREM(SDNode *N) {
SDValue Res = SimplifyNodeWithTwoResults(N, ISD::SDIV, ISD::SREM); SDValue Res = SimplifyNodeWithTwoResults(N, ISD::SDIV, ISD::SREM);
if (Res.getNode()) return Res; if (Res.getNode()) return Res;

View File

@ -12,3 +12,27 @@ define i1 @a(i32 %x) zeroext nounwind {
; CHECK: movzbl %al, %eax ; CHECK: movzbl %al, %eax
; CHECK: ret ; CHECK: ret
} }
define i32 @test2(i32 %a, i32 %b) nounwind readnone {
entry:
%tmp0 = add i32 %b, %a
%tmp1 = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %tmp0, i32 2)
%tmp2 = extractvalue { i32, i1 } %tmp1, 0
ret i32 %tmp2
; CHECK: test2:
; CHECK: addl
; CHECK-NEXT: addl
; CHECK-NEXT: ret
}
define i32 @test3(i32 %a, i32 %b) nounwind readnone {
entry:
%tmp0 = add i32 %b, %a
%tmp1 = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %tmp0, i32 4)
%tmp2 = extractvalue { i32, i1 } %tmp1, 0
ret i32 %tmp2
; CHECK: test3:
; CHECK: addl
; CHECK: mull
; CHECK-NEXT: ret
}