mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 13:16:46 +00:00
[DAG] Add basic mul-with-overflow constant folding support
As noticed on D97160
This commit is contained in:
parent
a4f9c0f562
commit
8082bfe7e5
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user