[llvm] [SelectionDAG] Calculate Knownbits for SMIN (PR #85584)

via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 17 15:03:20 PDT 2024


https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/85584

>From a14926cb560345fc6406d9dbc5cad3af8c23326c Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sun, 17 Mar 2024 17:56:01 -0400
Subject: [PATCH 1/2] [SelectionDAG] Pre-commit tests (NFC)

---
 llvm/test/CodeGen/RISCV/min-max.ll | 82 +++++++++++++++++++++++++-----
 1 file changed, 68 insertions(+), 14 deletions(-)

diff --git a/llvm/test/CodeGen/RISCV/min-max.ll b/llvm/test/CodeGen/RISCV/min-max.ll
index 0115b48b7124c9..9de0a730bc2502 100644
--- a/llvm/test/CodeGen/RISCV/min-max.ll
+++ b/llvm/test/CodeGen/RISCV/min-max.ll
@@ -599,15 +599,69 @@ define signext i32 @smax_i32_pos_constant(i32 signext %a) {
   ret i32 %c
 }
 
+define signext i32 @smin_i32_neg_constant(i32 signext %a) {
+; RV32I-LABEL: smin_i32_neg_constant:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    .cfi_def_cfa_offset 16
+; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT:    .cfi_offset ra, -4
+; RV32I-NEXT:    li a1, -1
+; RV32I-NEXT:    call llvm.min.i32
+; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: smin_i32_neg_constant:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    addi sp, sp, -16
+; RV64I-NEXT:    .cfi_def_cfa_offset 16
+; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT:    .cfi_offset ra, -8
+; RV64I-NEXT:    li a1, -1
+; RV64I-NEXT:    call llvm.min.i32
+; RV64I-NEXT:    sext.w a0, a0
+; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT:    addi sp, sp, 16
+; RV64I-NEXT:    ret
+;
+; RV32ZBB-LABEL: smin_i32_neg_constant:
+; RV32ZBB:       # %bb.0:
+; RV32ZBB-NEXT:    addi sp, sp, -16
+; RV32ZBB-NEXT:    .cfi_def_cfa_offset 16
+; RV32ZBB-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32ZBB-NEXT:    .cfi_offset ra, -4
+; RV32ZBB-NEXT:    li a1, -1
+; RV32ZBB-NEXT:    call llvm.min.i32
+; RV32ZBB-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32ZBB-NEXT:    addi sp, sp, 16
+; RV32ZBB-NEXT:    ret
+;
+; RV64ZBB-LABEL: smin_i32_neg_constant:
+; RV64ZBB:       # %bb.0:
+; RV64ZBB-NEXT:    addi sp, sp, -16
+; RV64ZBB-NEXT:    .cfi_def_cfa_offset 16
+; RV64ZBB-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64ZBB-NEXT:    .cfi_offset ra, -8
+; RV64ZBB-NEXT:    li a1, -1
+; RV64ZBB-NEXT:    call llvm.min.i32
+; RV64ZBB-NEXT:    sext.w a0, a0
+; RV64ZBB-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64ZBB-NEXT:    addi sp, sp, 16
+; RV64ZBB-NEXT:    ret
+  %c = call i32 @llvm.min.i32(i32 %a, i32 -1)
+  ret i32 %c
+}
+
 define signext i32 @smax_i32_pos_constant_trailing_zeros(i32 signext %a) {
 ; NOZBB-LABEL: smax_i32_pos_constant_trailing_zeros:
 ; NOZBB:       # %bb.0:
 ; NOZBB-NEXT:    andi a0, a0, -8
 ; NOZBB-NEXT:    li a1, 16
-; NOZBB-NEXT:    blt a1, a0, .LBB25_2
+; NOZBB-NEXT:    blt a1, a0, .LBB26_2
 ; NOZBB-NEXT:  # %bb.1:
 ; NOZBB-NEXT:    li a0, 16
-; NOZBB-NEXT:  .LBB25_2:
+; NOZBB-NEXT:  .LBB26_2:
 ; NOZBB-NEXT:    ret
 ;
 ; ZBB-LABEL: smax_i32_pos_constant_trailing_zeros:
@@ -680,15 +734,15 @@ define i64 @umax_i64_one(i64 %a, i64 %b) {
 ; RV32I-LABEL: umax_i64_one:
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    mv a2, a0
-; RV32I-NEXT:    beqz a1, .LBB28_3
+; RV32I-NEXT:    beqz a1, .LBB29_3
 ; RV32I-NEXT:  # %bb.1:
-; RV32I-NEXT:    beqz a1, .LBB28_4
-; RV32I-NEXT:  .LBB28_2:
+; RV32I-NEXT:    beqz a1, .LBB29_4
+; RV32I-NEXT:  .LBB29_2:
 ; RV32I-NEXT:    ret
-; RV32I-NEXT:  .LBB28_3:
+; RV32I-NEXT:  .LBB29_3:
 ; RV32I-NEXT:    li a0, 1
-; RV32I-NEXT:    bnez a1, .LBB28_2
-; RV32I-NEXT:  .LBB28_4:
+; RV32I-NEXT:    bnez a1, .LBB29_2
+; RV32I-NEXT:  .LBB29_4:
 ; RV32I-NEXT:    seqz a0, a2
 ; RV32I-NEXT:    add a0, a2, a0
 ; RV32I-NEXT:    ret
@@ -703,15 +757,15 @@ define i64 @umax_i64_one(i64 %a, i64 %b) {
 ; RV32ZBB:       # %bb.0:
 ; RV32ZBB-NEXT:    mv a2, a0
 ; RV32ZBB-NEXT:    li a3, 1
-; RV32ZBB-NEXT:    beqz a1, .LBB28_3
+; RV32ZBB-NEXT:    beqz a1, .LBB29_3
 ; RV32ZBB-NEXT:  # %bb.1:
-; RV32ZBB-NEXT:    beqz a1, .LBB28_4
-; RV32ZBB-NEXT:  .LBB28_2:
+; RV32ZBB-NEXT:    beqz a1, .LBB29_4
+; RV32ZBB-NEXT:  .LBB29_2:
 ; RV32ZBB-NEXT:    ret
-; RV32ZBB-NEXT:  .LBB28_3:
+; RV32ZBB-NEXT:  .LBB29_3:
 ; RV32ZBB-NEXT:    li a0, 1
-; RV32ZBB-NEXT:    bnez a1, .LBB28_2
-; RV32ZBB-NEXT:  .LBB28_4:
+; RV32ZBB-NEXT:    bnez a1, .LBB29_2
+; RV32ZBB-NEXT:  .LBB29_4:
 ; RV32ZBB-NEXT:    maxu a0, a2, a3
 ; RV32ZBB-NEXT:    ret
 ;

>From 13cd22f67201bdb15e59aec9d4e2726d92b4c2a3 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sun, 17 Mar 2024 17:27:32 -0400
Subject: [PATCH 2/2] [SelectionDAG] Calculate Knownbits for SMIN

---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 ++-
 llvm/test/CodeGen/RISCV/min-max.ll            | 89 ++++++-------------
 2 files changed, 37 insertions(+), 64 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 2670f48aebcff5..f6ac5d98d1d402 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4007,8 +4007,6 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
 
     // For SMAX, if CstLow is non-negative we know the result will be
     // non-negative and thus all sign bits are 0.
-    // TODO: There's an equivalent of this for smin with negative constant for
-    // known ones.
     if (IsMax && CstLow) {
       const APInt &ValueLow = CstLow->getAPIntValue();
       if (ValueLow.isNonNegative()) {
@@ -4017,6 +4015,16 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
       }
     }
 
+    // For SMIN, if CstHigh is negative we know the result will be
+    // negative and thus all sign bits are 1.
+    if (!IsMax && CstHigh) {
+      const APInt &ValueHigh = CstHigh->getAPIntValue();
+      if (ValueHigh.isNegative()) {
+        unsigned SignBits = ComputeNumSignBits(Op.getOperand(0), Depth + 1);
+        Known.One.setHighBits(std::min(SignBits, ValueHigh.getNumSignBits()));
+      }
+    }
+
     break;
   }
   case ISD::UINT_TO_FP: {
diff --git a/llvm/test/CodeGen/RISCV/min-max.ll b/llvm/test/CodeGen/RISCV/min-max.ll
index 9de0a730bc2502..28c7f6feb50e1f 100644
--- a/llvm/test/CodeGen/RISCV/min-max.ll
+++ b/llvm/test/CodeGen/RISCV/min-max.ll
@@ -600,55 +600,20 @@ define signext i32 @smax_i32_pos_constant(i32 signext %a) {
 }
 
 define signext i32 @smin_i32_neg_constant(i32 signext %a) {
-; RV32I-LABEL: smin_i32_neg_constant:
-; RV32I:       # %bb.0:
-; RV32I-NEXT:    addi sp, sp, -16
-; RV32I-NEXT:    .cfi_def_cfa_offset 16
-; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
-; RV32I-NEXT:    .cfi_offset ra, -4
-; RV32I-NEXT:    li a1, -1
-; RV32I-NEXT:    call llvm.min.i32
-; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
-; RV32I-NEXT:    addi sp, sp, 16
-; RV32I-NEXT:    ret
-;
-; RV64I-LABEL: smin_i32_neg_constant:
-; RV64I:       # %bb.0:
-; RV64I-NEXT:    addi sp, sp, -16
-; RV64I-NEXT:    .cfi_def_cfa_offset 16
-; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT:    .cfi_offset ra, -8
-; RV64I-NEXT:    li a1, -1
-; RV64I-NEXT:    call llvm.min.i32
-; RV64I-NEXT:    sext.w a0, a0
-; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
-; RV64I-NEXT:    addi sp, sp, 16
-; RV64I-NEXT:    ret
-;
-; RV32ZBB-LABEL: smin_i32_neg_constant:
-; RV32ZBB:       # %bb.0:
-; RV32ZBB-NEXT:    addi sp, sp, -16
-; RV32ZBB-NEXT:    .cfi_def_cfa_offset 16
-; RV32ZBB-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
-; RV32ZBB-NEXT:    .cfi_offset ra, -4
-; RV32ZBB-NEXT:    li a1, -1
-; RV32ZBB-NEXT:    call llvm.min.i32
-; RV32ZBB-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
-; RV32ZBB-NEXT:    addi sp, sp, 16
-; RV32ZBB-NEXT:    ret
+; NOZBB-LABEL: smax_i32_pos_constant:
+; NOZBB:       # %bb.0:
+; NOZBB-NEXT:    li a1, 10
+; NOZBB-NEXT:    blt a1, a0, .LBB24_2
+; NOZBB-NEXT:  # %bb.1:
+; NOZBB-NEXT:    li a0, 10
+; NOZBB-NEXT:  .LBB24_2:
+; NOZBB-NEXT:    ret
 ;
-; RV64ZBB-LABEL: smin_i32_neg_constant:
-; RV64ZBB:       # %bb.0:
-; RV64ZBB-NEXT:    addi sp, sp, -16
-; RV64ZBB-NEXT:    .cfi_def_cfa_offset 16
-; RV64ZBB-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64ZBB-NEXT:    .cfi_offset ra, -8
-; RV64ZBB-NEXT:    li a1, -1
-; RV64ZBB-NEXT:    call llvm.min.i32
-; RV64ZBB-NEXT:    sext.w a0, a0
-; RV64ZBB-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
-; RV64ZBB-NEXT:    addi sp, sp, 16
-; RV64ZBB-NEXT:    ret
+; ZBB-LABEL: smax_i32_pos_constant:
+; ZBB:       # %bb.0:
+; ZBB-NEXT:    li a1, 10
+; ZBB-NEXT:    max a0, a0, a1
+; ZBB-NEXT:    ret
   %c = call i32 @llvm.min.i32(i32 %a, i32 -1)
   ret i32 %c
 }
@@ -658,10 +623,10 @@ define signext i32 @smax_i32_pos_constant_trailing_zeros(i32 signext %a) {
 ; NOZBB:       # %bb.0:
 ; NOZBB-NEXT:    andi a0, a0, -8
 ; NOZBB-NEXT:    li a1, 16
-; NOZBB-NEXT:    blt a1, a0, .LBB26_2
+; NOZBB-NEXT:    blt a1, a0, .LBB25_2
 ; NOZBB-NEXT:  # %bb.1:
 ; NOZBB-NEXT:    li a0, 16
-; NOZBB-NEXT:  .LBB26_2:
+; NOZBB-NEXT:  .LBB25_2:
 ; NOZBB-NEXT:    ret
 ;
 ; ZBB-LABEL: smax_i32_pos_constant_trailing_zeros:
@@ -734,15 +699,15 @@ define i64 @umax_i64_one(i64 %a, i64 %b) {
 ; RV32I-LABEL: umax_i64_one:
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    mv a2, a0
-; RV32I-NEXT:    beqz a1, .LBB29_3
+; RV32I-NEXT:    beqz a1, .LBB28_3
 ; RV32I-NEXT:  # %bb.1:
-; RV32I-NEXT:    beqz a1, .LBB29_4
-; RV32I-NEXT:  .LBB29_2:
+; RV32I-NEXT:    beqz a1, .LBB28_4
+; RV32I-NEXT:  .LBB28_2:
 ; RV32I-NEXT:    ret
-; RV32I-NEXT:  .LBB29_3:
+; RV32I-NEXT:  .LBB28_3:
 ; RV32I-NEXT:    li a0, 1
-; RV32I-NEXT:    bnez a1, .LBB29_2
-; RV32I-NEXT:  .LBB29_4:
+; RV32I-NEXT:    bnez a1, .LBB28_2
+; RV32I-NEXT:  .LBB28_4:
 ; RV32I-NEXT:    seqz a0, a2
 ; RV32I-NEXT:    add a0, a2, a0
 ; RV32I-NEXT:    ret
@@ -757,15 +722,15 @@ define i64 @umax_i64_one(i64 %a, i64 %b) {
 ; RV32ZBB:       # %bb.0:
 ; RV32ZBB-NEXT:    mv a2, a0
 ; RV32ZBB-NEXT:    li a3, 1
-; RV32ZBB-NEXT:    beqz a1, .LBB29_3
+; RV32ZBB-NEXT:    beqz a1, .LBB28_3
 ; RV32ZBB-NEXT:  # %bb.1:
-; RV32ZBB-NEXT:    beqz a1, .LBB29_4
-; RV32ZBB-NEXT:  .LBB29_2:
+; RV32ZBB-NEXT:    beqz a1, .LBB28_4
+; RV32ZBB-NEXT:  .LBB28_2:
 ; RV32ZBB-NEXT:    ret
-; RV32ZBB-NEXT:  .LBB29_3:
+; RV32ZBB-NEXT:  .LBB28_3:
 ; RV32ZBB-NEXT:    li a0, 1
-; RV32ZBB-NEXT:    bnez a1, .LBB29_2
-; RV32ZBB-NEXT:  .LBB29_4:
+; RV32ZBB-NEXT:    bnez a1, .LBB28_2
+; RV32ZBB-NEXT:  .LBB28_4:
 ; RV32ZBB-NEXT:    maxu a0, a2, a3
 ; RV32ZBB-NEXT:    ret
 ;



More information about the llvm-commits mailing list