From: Craig Topper Date: Tue, 9 Apr 2019 18:33:56 +0000 (+0000) Subject: [DAGCombiner][X86][SystemZ] Canonicalize SSUBO with immediate RHS to SADDO by negatin... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b77427871e5a348e8351efd35c53b414e8137d76;p=llvm [DAGCombiner][X86][SystemZ] Canonicalize SSUBO with immediate RHS to SADDO by negating the immediate. This lines up with what we do for regular subtract and it matches up better with X86 assumptions in isel patterns that add with immediate is more canonical than sub with immediate. Differential Revision: https://reviews.llvm.org/D60020 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358027 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 5d7890ee08f..c61b24f8d21 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3037,6 +3037,14 @@ SDValue DAGCombiner::visitSUBO(SDNode *N) { return CombineTo(N, DAG.getConstant(0, DL, VT), DAG.getConstant(0, DL, CarryVT)); + ConstantSDNode *N1C = getAsNonOpaqueConstant(N1); + + // fold (subox, c) -> (addo x, -c) + if (IsSigned && N1C && !N1C->getAPIntValue().isMinSignedValue()) { + return DAG.getNode(ISD::SADDO, DL, N->getVTList(), N0, + DAG.getConstant(-N1C->getAPIntValue(), DL, VT)); + } + // fold (subo x, 0) -> x + no borrow if (isNullOrNullSplat(N1)) return CombineTo(N, N0, DAG.getConstant(0, DL, CarryVT)); diff --git a/test/CodeGen/SystemZ/int-ssub-07.ll b/test/CodeGen/SystemZ/int-ssub-07.ll index dd3b00a4bb0..970c14e0391 100644 --- a/test/CodeGen/SystemZ/int-ssub-07.ll +++ b/test/CodeGen/SystemZ/int-ssub-07.ll @@ -154,9 +154,9 @@ define zeroext i1 @f9(i64 %dummy, i64 %a, i64 *%res) { ; Check the next value down, which must use register subtraction instead. define zeroext i1 @f10(i64 %dummy, i64 %a, i64 *%res) { ; CHECK-LABEL: f10: -; CHECK: lgfi [[REG1:%r[0-9]+]], -2147483648 -; CHECK: sgr %r3, [[REG1]] -; CHECK-DAG: stg %r3, 0(%r4) +; CHECK: llilh [[REG1:%r[0-9]+]], 32768 +; CHECK: agr [[REG1]], %r3 +; CHECK-DAG: stg [[REG1]], 0(%r4) ; CHECK-DAG: ipm [[REG:%r[0-5]]] ; CHECK-DAG: afi [[REG]], 1342177280 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33 diff --git a/test/CodeGen/X86/sub-with-overflow.ll b/test/CodeGen/X86/sub-with-overflow.ll index 0bcf2d8a565..6de0beeabdf 100644 --- a/test/CodeGen/X86/sub-with-overflow.ll +++ b/test/CodeGen/X86/sub-with-overflow.ll @@ -83,7 +83,8 @@ declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) define i1 @func3(i32 %x) nounwind { ; CHECK-LABEL: func3: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: cmpl $1, {{[0-9]+}}(%esp) +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: decl %eax ; CHECK-NEXT: seto %al ; CHECK-NEXT: retl entry: diff --git a/test/CodeGen/X86/xaluo.ll b/test/CodeGen/X86/xaluo.ll index 70d36fd7fa1..0de8bdeddd6 100644 --- a/test/CodeGen/X86/xaluo.ll +++ b/test/CodeGen/X86/xaluo.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=SDAG +; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=SDAG --check-prefix=GENERIC ; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort=1 < %s | FileCheck %s --check-prefix=FAST -; RUN: llc -mtriple=x86_64-darwin-unknown -mcpu=knl < %s | FileCheck %s --check-prefix=SDAG +; RUN: llc -mtriple=x86_64-darwin-unknown -mcpu=knl < %s | FileCheck %s --check-prefix=SDAG --check-prefix=KNL ; ; Get the actual value of the overflow bit. @@ -1104,14 +1104,14 @@ define i32 @incovfselectstore(i32 %v1, i32 %v2, i32* %x) { ; Make sure we select a DEC for both the data use and the flag use. define i32 @decovfselectstore(i32 %v1, i32 %v2, i32* %x) { -; SDAG-LABEL: decovfselectstore: -; SDAG: ## %bb.0: -; SDAG-NEXT: movl %esi, %eax -; SDAG-NEXT: movl %edi, %ecx -; SDAG-NEXT: decl %ecx -; SDAG-NEXT: cmovol %edi, %eax -; SDAG-NEXT: movl %ecx, (%rdx) -; SDAG-NEXT: retq +; GENERIC-LABEL: decovfselectstore: +; GENERIC: ## %bb.0: +; GENERIC-NEXT: movl %esi, %eax +; GENERIC-NEXT: movl %edi, %ecx +; GENERIC-NEXT: decl %ecx +; GENERIC-NEXT: cmovol %edi, %eax +; GENERIC-NEXT: movl %ecx, (%rdx) +; GENERIC-NEXT: retq ; ; FAST-LABEL: decovfselectstore: ; FAST: ## %bb.0: @@ -1121,6 +1121,15 @@ define i32 @decovfselectstore(i32 %v1, i32 %v2, i32* %x) { ; FAST-NEXT: cmovol %edi, %eax ; FAST-NEXT: movl %ecx, (%rdx) ; FAST-NEXT: retq +; +; KNL-LABEL: decovfselectstore: +; KNL: ## %bb.0: +; KNL-NEXT: movl %esi, %eax +; KNL-NEXT: movl %edi, %ecx +; KNL-NEXT: addl $-1, %ecx +; KNL-NEXT: cmovol %edi, %eax +; KNL-NEXT: movl %ecx, (%rdx) +; KNL-NEXT: retq %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 1) %obit = extractvalue {i32, i1} %t, 1 %ret = select i1 %obit, i32 %v1, i32 %v2