From: Craig Topper Date: Sun, 8 Sep 2019 19:24:39 +0000 (+0000) Subject: [DAGCombiner][X86][ARM] Teach visitMULO to fold multiplies with 0 to 0 and no carry. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=efb11053fc072a68e85af1d90325d6c268372d16;p=llvm [DAGCombiner][X86][ARM] Teach visitMULO to fold multiplies with 0 to 0 and no carry. I modified the ARM test to use two inputs instead of 0 so the test hopefully still tests what was intended. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@371344 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 248525e52e4..e1c04114cc3 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4404,13 +4404,29 @@ SDValue DAGCombiner::visitUMUL_LOHI(SDNode *N) { } SDValue DAGCombiner::visitMULO(SDNode *N) { + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + EVT VT = N0.getValueType(); bool IsSigned = (ISD::SMULO == N->getOpcode()); + EVT CarryVT = N->getValueType(1); + SDLoc DL(N); + + // canonicalize constant to RHS. + if (DAG.isConstantIntBuildVectorOrConstantInt(N0) && + !DAG.isConstantIntBuildVectorOrConstantInt(N1)) + return DAG.getNode(N->getOpcode(), DL, N->getVTList(), N1, N0); + + // fold (mulo x, 0) -> 0 + no carry out + if (isNullOrNullSplat(N1)) + return CombineTo(N, DAG.getConstant(0, DL, VT), + DAG.getConstant(0, DL, CarryVT)); + // (mulo x, 2) -> (addo x, x) - if (ConstantSDNode *C2 = isConstOrConstSplat(N->getOperand(1))) + if (ConstantSDNode *C2 = isConstOrConstSplat(N1)) if (C2->getAPIntValue() == 2) - return DAG.getNode(IsSigned ? ISD::SADDO : ISD::UADDO, SDLoc(N), - N->getVTList(), N->getOperand(0), N->getOperand(0)); + return DAG.getNode(IsSigned ? ISD::SADDO : ISD::UADDO, DL, + N->getVTList(), N0, N0); return SDValue(); } diff --git a/test/CodeGen/ARM/select.ll b/test/CodeGen/ARM/select.ll index 45c32665e99..dbec6dd5709 100644 --- a/test/CodeGen/ARM/select.ll +++ b/test/CodeGen/ARM/select.ll @@ -143,11 +143,11 @@ define float @f12(i32 %a, i32 %b) nounwind uwtable readnone ssp { } ; CHECK-LABEL: test_overflow_recombine: -define i1 @test_overflow_recombine(i32 %in) { +define i1 @test_overflow_recombine(i32 %in1, i32 %in2) { ; CHECK: smull [[LO:r[0-9]+]], [[HI:r[0-9]+]] ; CHECK: subs [[ZERO:r[0-9]+]], [[HI]], [[LO]], asr #31 ; CHECK: movne [[ZERO]], #1 - %prod = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 0, i32 %in) + %prod = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %in1, i32 %in2) %overflow = extractvalue { i32, i1 } %prod, 1 ret i1 %overflow } diff --git a/test/CodeGen/X86/xmulo.ll b/test/CodeGen/X86/xmulo.ll index 86b15cce036..6f2c229ac1f 100644 --- a/test/CodeGen/X86/xmulo.ll +++ b/test/CodeGen/X86/xmulo.ll @@ -26,18 +26,14 @@ define {i64, i1} @t1() nounwind { define {i64, i1} @t2() nounwind { ; SDAG-LABEL: t2: ; SDAG: ## %bb.0: -; SDAG-NEXT: xorl %ecx, %ecx -; SDAG-NEXT: movl $9, %eax -; SDAG-NEXT: mulq %rcx -; SDAG-NEXT: seto %dl +; SDAG-NEXT: xorl %eax, %eax +; SDAG-NEXT: xorl %edx, %edx ; SDAG-NEXT: retq ; ; FAST-LABEL: t2: ; FAST: ## %bb.0: -; FAST-NEXT: xorl %ecx, %ecx -; FAST-NEXT: movl $9, %eax -; FAST-NEXT: mulq %rcx -; FAST-NEXT: seto %dl +; FAST-NEXT: xorl %eax, %eax +; FAST-NEXT: xorl %edx, %edx ; FAST-NEXT: retq %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 0) ret {i64, i1} %1