[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