[llvm] 8082bfe - [DAG] Add basic mul-with-overflow constant folding support

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 24 03:09:56 PST 2021


Author: Simon Pilgrim
Date: 2021-02-24T11:09:02Z
New Revision: 8082bfe7e58d89f6f065fab101db3481516afdbe

URL: https://github.com/llvm/llvm-project/commit/8082bfe7e58d89f6f065fab101db3481516afdbe
DIFF: https://github.com/llvm/llvm-project/commit/8082bfe7e58d89f6f065fab101db3481516afdbe.diff

LOG: [DAG] Add basic mul-with-overflow constant folding support

As noticed on D97160

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/test/CodeGen/X86/xmulo.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 2b4ce5ff7ec77..62759b97b571a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -4638,6 +4638,21 @@ SDValue DAGCombiner::visitMULO(SDNode *N) {
   EVT CarryVT = N->getValueType(1);
   SDLoc DL(N);
 
+  ConstantSDNode *N0C = isConstOrConstSplat(N0);
+  ConstantSDNode *N1C = isConstOrConstSplat(N1);
+
+  // fold operation with constant operands.
+  // TODO: Move this to FoldConstantArithmetic when it supports nodes with
+  // multiple results.
+  if (N0C && N1C) {
+    bool Overflow;
+    APInt Result =
+        IsSigned ? N0C->getAPIntValue().smul_ov(N1C->getAPIntValue(), Overflow)
+                 : N0C->getAPIntValue().umul_ov(N1C->getAPIntValue(), Overflow);
+    return CombineTo(N, DAG.getConstant(Result, DL, VT),
+                     DAG.getBoolConstant(Overflow, DL, CarryVT, CarryVT));
+  }
+
   // canonicalize constant to RHS.
   if (DAG.isConstantIntBuildVectorOrConstantInt(N0) &&
       !DAG.isConstantIntBuildVectorOrConstantInt(N1))
@@ -4649,10 +4664,9 @@ SDValue DAGCombiner::visitMULO(SDNode *N) {
                      DAG.getConstant(0, DL, CarryVT));
 
   // (mulo x, 2) -> (addo x, x)
-  if (ConstantSDNode *C2 = isConstOrConstSplat(N1))
-    if (C2->getAPIntValue() == 2)
-      return DAG.getNode(IsSigned ? ISD::SADDO : ISD::UADDO, DL,
-                         N->getVTList(), N0, N0);
+  if (N1C && N1C->getAPIntValue() == 2)
+    return DAG.getNode(IsSigned ? ISD::SADDO : ISD::UADDO, DL,
+                       N->getVTList(), N0, N0);
 
   return SDValue();
 }

diff  --git a/llvm/test/CodeGen/X86/xmulo.ll b/llvm/test/CodeGen/X86/xmulo.ll
index 3ac2ce0772191..f6c36f5afd99a 100644
--- a/llvm/test/CodeGen/X86/xmulo.ll
+++ b/llvm/test/CodeGen/X86/xmulo.ll
@@ -6,10 +6,8 @@
 define {i64, i1} @t1() nounwind {
 ; CHECK-LABEL: t1:
 ; CHECK:       ## %bb.0:
-; CHECK-NEXT:    movl $8, %ecx
-; CHECK-NEXT:    movl $9, %eax
-; CHECK-NEXT:    mulq %rcx
-; CHECK-NEXT:    seto %dl
+; CHECK-NEXT:    movl $72, %eax
+; CHECK-NEXT:    xorl %edx, %edx
 ; CHECK-NEXT:    retq
   %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 8)
   ret {i64, i1} %1
@@ -28,10 +26,8 @@ define {i64, i1} @t2() nounwind {
 define {i64, i1} @t3() nounwind {
 ; CHECK-LABEL: t3:
 ; CHECK:       ## %bb.0:
-; CHECK-NEXT:    movq $-1, %rcx
-; CHECK-NEXT:    movl $9, %eax
-; CHECK-NEXT:    mulq %rcx
-; CHECK-NEXT:    seto %dl
+; CHECK-NEXT:    movq $-9, %rax
+; CHECK-NEXT:    movb $1, %dl
 ; CHECK-NEXT:    retq
   %1 = call {i64, i1} @llvm.umul.with.overflow.i64(i64 9, i64 -1)
   ret {i64, i1} %1


        


More information about the llvm-commits mailing list