summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2019-09-08 19:24:39 +0000
committerCraig Topper <craig.topper@intel.com>2019-09-08 19:24:39 +0000
commitdac34f52d3f94b4b8716ee8f2cc0c086161d326d (patch)
tree50fa40bd8bca0c100a73537ef2f3a582dc5f8b6b
parent30837abd9623bf2c8582627d2179828ecf361965 (diff)
downloadbcm5719-llvm-dac34f52d3f94b4b8716ee8f2cc0c086161d326d.tar.gz
bcm5719-llvm-dac34f52d3f94b4b8716ee8f2cc0c086161d326d.zip
[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. llvm-svn: 371344
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp22
-rw-r--r--llvm/test/CodeGen/ARM/select.ll4
-rw-r--r--llvm/test/CodeGen/X86/xmulo.ll12
3 files changed, 25 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 248525e52e4..e1c04114cc3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/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/llvm/test/CodeGen/ARM/select.ll b/llvm/test/CodeGen/ARM/select.ll
index 45c32665e99..dbec6dd5709 100644
--- a/llvm/test/CodeGen/ARM/select.ll
+++ b/llvm/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/llvm/test/CodeGen/X86/xmulo.ll b/llvm/test/CodeGen/X86/xmulo.ll
index 86b15cce036..6f2c229ac1f 100644
--- a/llvm/test/CodeGen/X86/xmulo.ll
+++ b/llvm/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
OpenPOWER on IntegriCloud