From c00f3182243d097382b71af199719c3027d96900 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Wed, 18 Sep 2019 20:48:27 +0000 Subject: [PATCH] [DAGCombine][ARM][X86] (sub Carry, X) -> (addcarry (sub 0, X), 0, Carry) fold Summary: `DAGCombiner::visitADDLikeCommutative()` already has a sibling fold: `(add X, Carry) -> (addcarry X, 0, Carry)` This fold, as suggested by @efriedma, helps recover from //some// of the regressions of D62266 Reviewers: efriedma, deadalnix Subscribers: javed.absar, kristof.beyls, llvm-commits, efriedma Tags: #llvm Differential Revision: https://reviews.llvm.org/D62392 llvm-svn: 372259 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 12 +++++++++ .../test/CodeGen/ARM/addsubcarry-promotion.ll | 26 ++++++++++--------- llvm/test/CodeGen/X86/subcarry.ll | 6 ++--- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index a7e506855481..edb5ecb4d3df 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3384,6 +3384,18 @@ SDValue DAGCombiner::visitSUB(SDNode *N) { } } + if (TLI.isOperationLegalOrCustom(ISD::ADDCARRY, VT)) { + // (sub Carry, X) -> (addcarry (sub 0, X), 0, Carry) + if (SDValue Carry = getAsCarry(TLI, N0)) { + SDValue X = N1; + SDValue Zero = DAG.getConstant(0, DL, VT); + SDValue NegX = DAG.getNode(ISD::SUB, DL, VT, Zero, X); + return DAG.getNode(ISD::ADDCARRY, DL, + DAG.getVTList(VT, Carry.getValueType()), NegX, Zero, + Carry); + } + } + return SDValue(); } diff --git a/llvm/test/CodeGen/ARM/addsubcarry-promotion.ll b/llvm/test/CodeGen/ARM/addsubcarry-promotion.ll index 2dfd21705735..aaf7189a6bbe 100644 --- a/llvm/test/CodeGen/ARM/addsubcarry-promotion.ll +++ b/llvm/test/CodeGen/ARM/addsubcarry-promotion.ll @@ -10,11 +10,11 @@ define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 { ; ARM-LABEL: fn1: ; ARM: @ %bb.0: @ %entry +; ARM-NEXT: rsb r2, r2, #0 ; ARM-NEXT: adds r0, r1, r0 -; ARM-NEXT: mov r3, #0 -; ARM-NEXT: adc r0, r3, #0 ; ARM-NEXT: movw r1, #65535 -; ARM-NEXT: sub r0, r0, r2 +; ARM-NEXT: sxth r2, r2 +; ARM-NEXT: adc r0, r2, #0 ; ARM-NEXT: uxth r0, r0 ; ARM-NEXT: cmp r0, r1 ; ARM-NEXT: bxeq lr @@ -24,11 +24,12 @@ define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 { ; ; THUMBV6M-LABEL: fn1: ; THUMBV6M: @ %bb.0: @ %entry +; THUMBV6M-NEXT: rsbs r2, r2, #0 +; THUMBV6M-NEXT: sxth r2, r2 ; THUMBV6M-NEXT: movs r3, #0 ; THUMBV6M-NEXT: adds r0, r1, r0 -; THUMBV6M-NEXT: adcs r3, r3 -; THUMBV6M-NEXT: subs r0, r3, r2 -; THUMBV6M-NEXT: uxth r0, r0 +; THUMBV6M-NEXT: adcs r3, r2 +; THUMBV6M-NEXT: uxth r0, r3 ; THUMBV6M-NEXT: ldr r1, .LCPI0_0 ; THUMBV6M-NEXT: cmp r0, r1 ; THUMBV6M-NEXT: beq .LBB0_2 @@ -44,11 +45,12 @@ define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 { ; ; THUMBV8M-BASE-LABEL: fn1: ; THUMBV8M-BASE: @ %bb.0: @ %entry +; THUMBV8M-BASE-NEXT: rsbs r2, r2, #0 +; THUMBV8M-BASE-NEXT: sxth r2, r2 ; THUMBV8M-BASE-NEXT: movs r3, #0 ; THUMBV8M-BASE-NEXT: adds r0, r1, r0 -; THUMBV8M-BASE-NEXT: adcs r3, r3 -; THUMBV8M-BASE-NEXT: subs r0, r3, r2 -; THUMBV8M-BASE-NEXT: uxth r0, r0 +; THUMBV8M-BASE-NEXT: adcs r3, r2 +; THUMBV8M-BASE-NEXT: uxth r0, r3 ; THUMBV8M-BASE-NEXT: movw r1, #65535 ; THUMBV8M-BASE-NEXT: cmp r0, r1 ; THUMBV8M-BASE-NEXT: beq .LBB0_2 @@ -60,11 +62,11 @@ define void @fn1(i32 %a, i32 %b, i32 %c) local_unnamed_addr #0 { ; ; THUMB-LABEL: fn1: ; THUMB: @ %bb.0: @ %entry +; THUMB-NEXT: rsbs r2, r2, #0 ; THUMB-NEXT: adds r0, r0, r1 -; THUMB-NEXT: mov.w r3, #0 -; THUMB-NEXT: adc r0, r3, #0 ; THUMB-NEXT: movw r1, #65535 -; THUMB-NEXT: subs r0, r0, r2 +; THUMB-NEXT: sxth r2, r2 +; THUMB-NEXT: adc r0, r2, #0 ; THUMB-NEXT: uxth r0, r0 ; THUMB-NEXT: cmp r0, r1 ; THUMB-NEXT: it eq diff --git a/llvm/test/CodeGen/X86/subcarry.ll b/llvm/test/CodeGen/X86/subcarry.ll index d5f1d556d76a..75ee6ef5921b 100644 --- a/llvm/test/CodeGen/X86/subcarry.ll +++ b/llvm/test/CodeGen/X86/subcarry.ll @@ -169,11 +169,11 @@ declare {i64, i1} @llvm.usub.with.overflow(i64, i64) define i64 @sub_from_carry(i64 %x, i64 %y, i64* %valout, i64 %z) { ; CHECK-LABEL: sub_from_carry: ; CHECK: # %bb.0: -; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: movq %rcx, %rax +; CHECK-NEXT: negq %rax ; CHECK-NEXT: addq %rsi, %rdi -; CHECK-NEXT: setb %al ; CHECK-NEXT: movq %rdi, (%rdx) -; CHECK-NEXT: subq %rcx, %rax +; CHECK-NEXT: adcq $0, %rax ; CHECK-NEXT: retq %agg = call {i64, i1} @llvm.uadd.with.overflow(i64 %x, i64 %y) %val = extractvalue {i64, i1} %agg, 0