[SelectionDAGBuilder] Add SPF_NABS support to visitSelect
authorCraig Topper <craig.topper@sifive.com>
Wed, 25 Nov 2020 22:54:26 +0000 (14:54 -0800)
committerCraig Topper <craig.topper@sifive.com>
Wed, 25 Nov 2020 22:54:26 +0000 (14:54 -0800)
We currently don't match this which limits the effectiveness of D91120 until
InstCombine starts canonicalizing to llvm.abs. This should be easy to remove
if/when we remove the SPF_ABS handling.

Differential Revision: https://reviews.llvm.org/D92118

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/test/CodeGen/PowerPC/select.ll
llvm/test/CodeGen/RISCV/neg-abs.ll

index 959bb52..ca4c2ca 100644 (file)
@@ -3131,6 +3131,7 @@ void SelectionDAGBuilder::visitSelect(const User &I) {
       Cond.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT;
 
   bool IsUnaryAbs = false;
+  bool Negate = false;
 
   SDNodeFlags Flags;
   if (auto *FPOp = dyn_cast<FPMathOperator>(&I))
@@ -3195,12 +3196,13 @@ void SelectionDAGBuilder::visitSelect(const User &I) {
         break;
       }
       break;
+    case SPF_NABS:
+      Negate = true;
+      LLVM_FALLTHROUGH;
     case SPF_ABS:
       IsUnaryAbs = true;
       Opc = ISD::ABS;
       break;
-    case SPF_NABS:
-      // TODO: we need to produce sub(0, abs(X)).
     default: break;
     }
 
@@ -3227,10 +3229,13 @@ void SelectionDAGBuilder::visitSelect(const User &I) {
 
   if (IsUnaryAbs) {
     for (unsigned i = 0; i != NumValues; ++i) {
+      SDLoc dl = getCurSDLoc();
+      EVT VT = LHSVal.getNode()->getValueType(LHSVal.getResNo() + i);
       Values[i] =
-          DAG.getNode(OpCode, getCurSDLoc(),
-                      LHSVal.getNode()->getValueType(LHSVal.getResNo() + i),
-                      SDValue(LHSVal.getNode(), LHSVal.getResNo() + i));
+          DAG.getNode(OpCode, dl, VT, LHSVal.getValue(LHSVal.getResNo() + i));
+      if (Negate)
+        Values[i] = DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(0, dl, VT),
+                                Values[i]);
     }
   } else {
     for (unsigned i = 0; i != NumValues; ++i) {
index 1b53724..bbbffe4 100644 (file)
@@ -111,26 +111,18 @@ define i64 @f3(i64 %x, i64 %y) {
 define i64 @f4(i64 %x) {
 ; CHECK-LE-LABEL: f4:
 ; CHECK-LE:       # %bb.0:
-; CHECK-LE-NEXT:    neg r4, r3
-; CHECK-LE-NEXT:    cmpdi r3, 0
-; CHECK-LE-NEXT:    iselgt r3, r4, r3
+; CHECK-LE-NEXT:    sradi r4, r3, 63
+; CHECK-LE-NEXT:    xor r3, r3, r4
+; CHECK-LE-NEXT:    sub r3, r4, r3
 ; CHECK-LE-NEXT:    blr
 ;
 ; CHECK-32-LABEL: f4:
 ; CHECK-32:       # %bb.0:
-; CHECK-32-NEXT:    cmplwi r3, 0
-; CHECK-32-NEXT:    cmpwi cr1, r3, 0
-; CHECK-32-NEXT:    crandc 4*cr5+lt, 4*cr1+gt, eq
-; CHECK-32-NEXT:    cmpwi cr1, r4, 0
-; CHECK-32-NEXT:    subfic r5, r4, 0
-; CHECK-32-NEXT:    crandc 4*cr5+gt, eq, 4*cr1+eq
-; CHECK-32-NEXT:    cror 4*cr5+lt, 4*cr5+gt, 4*cr5+lt
-; CHECK-32-NEXT:    subfze r6, r3
-; CHECK-32-NEXT:    bc 12, 4*cr5+lt, .LBB4_1
-; CHECK-32-NEXT:    blr
-; CHECK-32-NEXT:  .LBB4_1:
-; CHECK-32-NEXT:    addi r3, r6, 0
-; CHECK-32-NEXT:    addi r4, r5, 0
+; CHECK-32-NEXT:    srawi r5, r3, 31
+; CHECK-32-NEXT:    xor r4, r4, r5
+; CHECK-32-NEXT:    xor r3, r3, r5
+; CHECK-32-NEXT:    subc r4, r5, r4
+; CHECK-32-NEXT:    subfe r3, r3, r5
 ; CHECK-32-NEXT:    blr
   %c = icmp sgt i64 %x, 0
   %x.neg = sub i64 0, %x
@@ -166,20 +158,18 @@ define i64 @f4_sge_0(i64 %x) {
 define i64 @f4_slt_0(i64 %x) {
 ; CHECK-LE-LABEL: f4_slt_0:
 ; CHECK-LE:       # %bb.0:
-; CHECK-LE-NEXT:    neg r4, r3
-; CHECK-LE-NEXT:    cmpdi r3, 0
-; CHECK-LE-NEXT:    isellt r3, r3, r4
+; CHECK-LE-NEXT:    sradi r4, r3, 63
+; CHECK-LE-NEXT:    xor r3, r3, r4
+; CHECK-LE-NEXT:    sub r3, r4, r3
 ; CHECK-LE-NEXT:    blr
 ;
 ; CHECK-32-LABEL: f4_slt_0:
 ; CHECK-32:       # %bb.0:
-; CHECK-32-NEXT:    subfic r5, r4, 0
-; CHECK-32-NEXT:    subfze r6, r3
-; CHECK-32-NEXT:    cmpwi r3, 0
-; CHECK-32-NEXT:    bclr 12, lt, 0
-; CHECK-32-NEXT:  # %bb.1:
-; CHECK-32-NEXT:    ori r3, r6, 0
-; CHECK-32-NEXT:    ori r4, r5, 0
+; CHECK-32-NEXT:    srawi r5, r3, 31
+; CHECK-32-NEXT:    xor r4, r4, r5
+; CHECK-32-NEXT:    xor r3, r3, r5
+; CHECK-32-NEXT:    subc r4, r5, r4
+; CHECK-32-NEXT:    subfe r3, r3, r5
 ; CHECK-32-NEXT:    blr
   %c = icmp slt i64 %x, 0
   %x.neg = sub i64 0, %x
@@ -219,21 +209,18 @@ define i64 @f4_sle_0(i64 %x) {
 define i64 @f4_sgt_m1(i64 %x) {
 ; CHECK-LE-LABEL: f4_sgt_m1:
 ; CHECK-LE:       # %bb.0:
-; CHECK-LE-NEXT:    neg r4, r3
-; CHECK-LE-NEXT:    cmpdi r3, -1
-; CHECK-LE-NEXT:    iselgt r3, r4, r3
+; CHECK-LE-NEXT:    sradi r4, r3, 63
+; CHECK-LE-NEXT:    xor r3, r3, r4
+; CHECK-LE-NEXT:    sub r3, r4, r3
 ; CHECK-LE-NEXT:    blr
 ;
 ; CHECK-32-LABEL: f4_sgt_m1:
 ; CHECK-32:       # %bb.0:
-; CHECK-32-NEXT:    subfic r5, r4, 0
-; CHECK-32-NEXT:    subfze r6, r3
-; CHECK-32-NEXT:    cmpwi r3, -1
-; CHECK-32-NEXT:    bc 12, gt, .LBB8_1
-; CHECK-32-NEXT:    blr
-; CHECK-32-NEXT:  .LBB8_1:
-; CHECK-32-NEXT:    addi r3, r6, 0
-; CHECK-32-NEXT:    addi r4, r5, 0
+; CHECK-32-NEXT:    srawi r5, r3, 31
+; CHECK-32-NEXT:    xor r4, r4, r5
+; CHECK-32-NEXT:    xor r3, r3, r5
+; CHECK-32-NEXT:    subc r4, r5, r4
+; CHECK-32-NEXT:    subfe r3, r3, r5
 ; CHECK-32-NEXT:    blr
   %c = icmp sgt i64 %x, -1
   %x.neg = sub i64 0, %x
index 10290a0..b5e5d2a 100644 (file)
@@ -27,19 +27,16 @@ define i32 @neg_abs32(i32 %x) {
 define i32 @select_neg_abs32(i32 %x) {
 ; RV32-LABEL: select_neg_abs32:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    bltz a0, .LBB1_2
-; RV32-NEXT:  # %bb.1:
-; RV32-NEXT:    neg a0, a0
-; RV32-NEXT:  .LBB1_2:
+; RV32-NEXT:    srai a1, a0, 31
+; RV32-NEXT:    xor a0, a0, a1
+; RV32-NEXT:    sub a0, a1, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: select_neg_abs32:
 ; RV64:       # %bb.0:
-; RV64-NEXT:    sext.w a1, a0
-; RV64-NEXT:    bltz a1, .LBB1_2
-; RV64-NEXT:  # %bb.1:
-; RV64-NEXT:    negw a0, a0
-; RV64-NEXT:  .LBB1_2:
+; RV64-NEXT:    sraiw a1, a0, 31
+; RV64-NEXT:    xor a0, a0, a1
+; RV64-NEXT:    subw a0, a1, a0
 ; RV64-NEXT:    ret
   %1 = icmp slt i32 %x, 0
   %2 = sub nsw i32 0, %x
@@ -73,21 +70,20 @@ define i64 @neg_abs64(i64 %x) {
 define i64 @select_neg_abs64(i64 %x) {
 ; RV32-LABEL: select_neg_abs64:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    bltz a1, .LBB3_2
-; RV32-NEXT:  # %bb.1:
-; RV32-NEXT:    snez a2, a0
-; RV32-NEXT:    add a1, a1, a2
-; RV32-NEXT:    neg a1, a1
-; RV32-NEXT:    neg a0, a0
-; RV32-NEXT:  .LBB3_2:
+; RV32-NEXT:    srai a2, a1, 31
+; RV32-NEXT:    xor a0, a0, a2
+; RV32-NEXT:    sltu a3, a2, a0
+; RV32-NEXT:    xor a1, a1, a2
+; RV32-NEXT:    sub a1, a2, a1
+; RV32-NEXT:    sub a1, a1, a3
+; RV32-NEXT:    sub a0, a2, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: select_neg_abs64:
 ; RV64:       # %bb.0:
-; RV64-NEXT:    bltz a0, .LBB3_2
-; RV64-NEXT:  # %bb.1:
-; RV64-NEXT:    neg a0, a0
-; RV64-NEXT:  .LBB3_2:
+; RV64-NEXT:    srai a1, a0, 63
+; RV64-NEXT:    xor a0, a0, a1
+; RV64-NEXT:    sub a0, a1, a0
 ; RV64-NEXT:    ret
   %1 = icmp slt i64 %x, 0
   %2 = sub nsw i64 0, %x