]> granicus.if.org Git - llvm/commitdiff
[DAGCombiner][X86][ARM] Teach visitMULO to fold multiplies with 0 to 0 and no carry.
authorCraig Topper <craig.topper@intel.com>
Sun, 8 Sep 2019 19:24:39 +0000 (19:24 +0000)
committerCraig Topper <craig.topper@intel.com>
Sun, 8 Sep 2019 19:24:39 +0000 (19:24 +0000)
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

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/ARM/select.ll
test/CodeGen/X86/xmulo.ll

index 248525e52e4eac2e9e4788cd7755893410a4a5ae..e1c04114cc359c0ba3cb15cf05661d38b2f58770 100644 (file)
@@ -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();
 }
index 45c32665e991ccf011721d1a307f24d05827cef3..dbec6dd57090c6dbd9087e57ae270c71530dc08b 100644 (file)
@@ -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
 }
index 86b15cce036f6efb01be4cf337091c74f1f043ba..6f2c229ac1ffd9aef7624458c204f6f728408f74 100644 (file)
@@ -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