[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