[llvm] [SelectionDAG] Calculate Knownbits for SMIN (PR #85584)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 17 16:52:40 PDT 2024
https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/85584
>From e40104469f9de05f1c69641ee67c360e9d714db6 Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Sun, 17 Mar 2024 17:56:01 -0400
Subject: [PATCH] [SelectionDAG] Calculate KnownBits for SMIN
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 ++-
llvm/test/CodeGen/RISCV/min-max.ll | 82 +++++++++++++++----
2 files changed, 78 insertions(+), 16 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 0115b48b7124c9..cc691a7374d985 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, -10
+; 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, -10
+; 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, -10
+; 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, -10
+; 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 -10)
+ 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
;
More information about the llvm-commits
mailing list