Commit 79845ed6 authored by David Green's avatar David Green
Browse files

[DAG] Fold setcc eq with ashr to compare to zero.

Pulled out of D109149, this folds set_cc seteq (ashr X, BW-1), -1 ->
set_cc setlt X, 0 to prevent some regressions later on when folding
select_cc setgt X, -1, C, ~C -> xor (ashr X, BW-1), C

Differential Revision: https://reviews.llvm.org/D109214
parent 9c476172
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -3910,6 +3910,17 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
        return DAG.getSetCC(dl, VT, N0.getOperand(0), N1, Cond);
    }

    // Fold set_cc seteq (ashr X, BW-1), -1 -> set_cc setlt X, 0
    //  and set_cc setne (ashr X, BW-1), -1 -> set_cc setge X, 0
    if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
        N0.getOpcode() == ISD::SRA && isa<ConstantSDNode>(N0.getOperand(1)) &&
        N0.getConstantOperandAPInt(1) == OpVT.getScalarSizeInBits() - 1 &&
        N1C && N1C->isAllOnesValue()) {
      return DAG.getSetCC(dl, VT, N0.getOperand(0),
                          DAG.getConstant(0, dl, OpVT),
                          Cond == ISD::SETEQ ? ISD::SETLT : ISD::SETGT);
    }

    if (SDValue V =
            optimizeSetCCOfSignedTruncationCheck(VT, N0, N1, Cond, DCI, dl))
      return V;
+4 −6
Original line number Diff line number Diff line
@@ -103,9 +103,8 @@ define i32 @selecti8i32(i8 %a) {
define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
; CHECK-LABEL: icmpasreq:
; CHECK:       // %bb.0:
; CHECK-NEXT:    mov w8, #-1
; CHECK-NEXT:    cmp w8, w0, asr #31
; CHECK-NEXT:    csel w0, w1, w2, eq
; CHECK-NEXT:    cmp w0, #0
; CHECK-NEXT:    csel w0, w1, w2, lt
; CHECK-NEXT:    ret
  %sh = ashr i32 %input, 31
  %c = icmp eq i32 %sh, -1
@@ -116,9 +115,8 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
; CHECK-LABEL: icmpasrne:
; CHECK:       // %bb.0:
; CHECK-NEXT:    mov w8, #-1
; CHECK-NEXT:    cmp w8, w0, asr #31
; CHECK-NEXT:    csel w0, w1, w2, ne
; CHECK-NEXT:    cmp w0, #0
; CHECK-NEXT:    csel w0, w1, w2, gt
; CHECK-NEXT:    ret
  %sh = ashr i32 %input, 31
  %c = icmp ne i32 %sh, -1
+2 −4
Original line number Diff line number Diff line
@@ -123,8 +123,7 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
; CHECK-NEXT:    v_ashrrev_i32_e32 v0, 31, v0
; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc_lo, -1, v0
; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc_lo, 0, v0
; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %sh = ashr i32 %input, 31
@@ -138,8 +137,7 @@ define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
; CHECK:       ; %bb.0:
; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
; CHECK-NEXT:    v_ashrrev_i32_e32 v0, 31, v0
; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc_lo, -1, v0
; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc_lo, 0, v0
; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
; CHECK-NEXT:    s_setpc_b64 s[30:31]
  %sh = ashr i32 %input, 31
+18 −26
Original line number Diff line number Diff line
@@ -353,17 +353,15 @@ define i32 @selecti8i32(i8 %a) {
define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
; CHECK7A-LABEL: icmpasreq:
; CHECK7A:       @ %bb.0:
; CHECK7A-NEXT:    mvn r3, #0
; CHECK7A-NEXT:    cmp r3, r0, asr #31
; CHECK7A-NEXT:    movne r1, r2
; CHECK7A-NEXT:    cmp r0, #0
; CHECK7A-NEXT:    movpl r1, r2
; CHECK7A-NEXT:    mov r0, r1
; CHECK7A-NEXT:    bx lr
;
; CHECK6M-LABEL: icmpasreq:
; CHECK6M:       @ %bb.0:
; CHECK6M-NEXT:    asrs r0, r0, #31
; CHECK6M-NEXT:    adds r0, r0, #1
; CHECK6M-NEXT:    beq .LBB8_2
; CHECK6M-NEXT:    cmp r0, #0
; CHECK6M-NEXT:    bmi .LBB8_2
; CHECK6M-NEXT:  @ %bb.1:
; CHECK6M-NEXT:    mov r1, r2
; CHECK6M-NEXT:  .LBB8_2:
@@ -372,18 +370,16 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
;
; CHECK7M-LABEL: icmpasreq:
; CHECK7M:       @ %bb.0:
; CHECK7M-NEXT:    asrs r0, r0, #31
; CHECK7M-NEXT:    adds r0, #1
; CHECK7M-NEXT:    it ne
; CHECK7M-NEXT:    movne r1, r2
; CHECK7M-NEXT:    cmp r0, #0
; CHECK7M-NEXT:    it pl
; CHECK7M-NEXT:    movpl r1, r2
; CHECK7M-NEXT:    mov r0, r1
; CHECK7M-NEXT:    bx lr
;
; CHECK81M-LABEL: icmpasreq:
; CHECK81M:       @ %bb.0:
; CHECK81M-NEXT:    asrs r0, r0, #31
; CHECK81M-NEXT:    adds r0, #1
; CHECK81M-NEXT:    csel r0, r1, r2, eq
; CHECK81M-NEXT:    cmp r0, #0
; CHECK81M-NEXT:    csel r0, r1, r2, mi
; CHECK81M-NEXT:    bx lr
  %sh = ashr i32 %input, 31
  %c = icmp eq i32 %sh, -1
@@ -394,17 +390,15 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
; CHECK7A-LABEL: icmpasrne:
; CHECK7A:       @ %bb.0:
; CHECK7A-NEXT:    mvn r3, #0
; CHECK7A-NEXT:    cmp r3, r0, asr #31
; CHECK7A-NEXT:    moveq r1, r2
; CHECK7A-NEXT:    cmp r0, #0
; CHECK7A-NEXT:    movle r1, r2
; CHECK7A-NEXT:    mov r0, r1
; CHECK7A-NEXT:    bx lr
;
; CHECK6M-LABEL: icmpasrne:
; CHECK6M:       @ %bb.0:
; CHECK6M-NEXT:    asrs r0, r0, #31
; CHECK6M-NEXT:    adds r0, r0, #1
; CHECK6M-NEXT:    bne .LBB9_2
; CHECK6M-NEXT:    cmp r0, #0
; CHECK6M-NEXT:    bgt .LBB9_2
; CHECK6M-NEXT:  @ %bb.1:
; CHECK6M-NEXT:    mov r1, r2
; CHECK6M-NEXT:  .LBB9_2:
@@ -413,18 +407,16 @@ define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
;
; CHECK7M-LABEL: icmpasrne:
; CHECK7M:       @ %bb.0:
; CHECK7M-NEXT:    asrs r0, r0, #31
; CHECK7M-NEXT:    adds r0, #1
; CHECK7M-NEXT:    it eq
; CHECK7M-NEXT:    moveq r1, r2
; CHECK7M-NEXT:    cmp r0, #0
; CHECK7M-NEXT:    it le
; CHECK7M-NEXT:    movle r1, r2
; CHECK7M-NEXT:    mov r0, r1
; CHECK7M-NEXT:    bx lr
;
; CHECK81M-LABEL: icmpasrne:
; CHECK81M:       @ %bb.0:
; CHECK81M-NEXT:    asrs r0, r0, #31
; CHECK81M-NEXT:    adds r0, #1
; CHECK81M-NEXT:    csel r0, r1, r2, ne
; CHECK81M-NEXT:    cmp r0, #0
; CHECK81M-NEXT:    csel r0, r1, r2, gt
; CHECK81M-NEXT:    bx lr
  %sh = ashr i32 %input, 31
  %c = icmp ne i32 %sh, -1
+4 −6
Original line number Diff line number Diff line
@@ -113,9 +113,8 @@ define i32 @selecti8i32(i8 %a) {
define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
; CHECK-LABEL: icmpasreq:
; CHECK:       # %bb.0:
; CHECK-NEXT:    srawi 3, 3, 31
; CHECK-NEXT:    cmpwi 3, -1
; CHECK-NEXT:    iseleq 3, 4, 5
; CHECK-NEXT:    cmpwi 3, 0
; CHECK-NEXT:    isellt 3, 4, 5
; CHECK-NEXT:    blr
  %sh = ashr i32 %input, 31
  %c = icmp eq i32 %sh, -1
@@ -126,9 +125,8 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
; CHECK-LABEL: icmpasrne:
; CHECK:       # %bb.0:
; CHECK-NEXT:    srawi 3, 3, 31
; CHECK-NEXT:    cmpwi 3, -1
; CHECK-NEXT:    iseleq 3, 5, 4
; CHECK-NEXT:    cmpwi 3, 0
; CHECK-NEXT:    iselgt 3, 4, 5
; CHECK-NEXT:    blr
  %sh = ashr i32 %input, 31
  %c = icmp ne i32 %sh, -1
Loading