[llvm] [LLVM][CodeGen] Flooring BW to 1 in isSaturatingMinMax (PR #160637)

Yatao Wang via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 24 20:46:38 PDT 2025


https://github.com/ningxinr created https://github.com/llvm/llvm-project/pull/160637

Fix Issue #160611

>From 9b4a9c64277af5a8eb0daebdb2fc1bcae9bac567 Mon Sep 17 00:00:00 2001
From: ningxinr <ningxinr at live.cn>
Date: Wed, 24 Sep 2025 20:43:22 -0700
Subject: [PATCH] Fix Issue #160611

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  2 +-
 llvm/test/CodeGen/AArch64/fpclamptosat.ll     | 24 ++++++++++++
 llvm/test/CodeGen/RISCV/fpclamptosat.ll       | 39 +++++++++++++++++++
 llvm/test/CodeGen/X86/fpclamptosat.ll         | 16 ++++++++
 4 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index a6ba6e518899f..c8c7882895ca6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6047,7 +6047,7 @@ static SDValue isSaturatingMinMax(SDValue N0, SDValue N1, SDValue N2,
   }
 
   if (MaxC == 0 && MinCPlus1.isPowerOf2()) {
-    BW = MinCPlus1.exactLogBase2();
+    BW = std::max(MinCPlus1.exactLogBase2(), 1);
     Unsigned = true;
     return N02;
   }
diff --git a/llvm/test/CodeGen/AArch64/fpclamptosat.ll b/llvm/test/CodeGen/AArch64/fpclamptosat.ll
index 00de1530fb72c..8b1f4e92fd339 100644
--- a/llvm/test/CodeGen/AArch64/fpclamptosat.ll
+++ b/llvm/test/CodeGen/AArch64/fpclamptosat.ll
@@ -1026,6 +1026,30 @@ entry:
   ret i64 %conv6
 }
 
+define i32 @ustest_f16const_i32() {
+; CHECK-CVT-LABEL: ustest_f16const_i32:
+; CHECK-CVT:       // %bb.0:
+; CHECK-CVT-NEXT:    mov w8, #2143289344 // =0x7fc00000
+; CHECK-CVT-NEXT:    fmov s0, w8
+; CHECK-CVT-NEXT:    fcvtzs w8, s0
+; CHECK-CVT-NEXT:    and w8, w8, w8, asr #31
+; CHECK-CVT-NEXT:    bic w0, w8, w8, asr #31
+; CHECK-CVT-NEXT:    ret
+;
+; CHECK-FP16-LABEL: ustest_f16const_i32:
+; CHECK-FP16:       // %bb.0:
+; CHECK-FP16-NEXT:    mov w8, #32256 // =0x7e00
+; CHECK-FP16-NEXT:    fmov h0, w8
+; CHECK-FP16-NEXT:    fcvtzs w8, h0
+; CHECK-FP16-NEXT:    and w8, w8, w8, asr #31
+; CHECK-FP16-NEXT:    bic w0, w8, w8, asr #31
+; CHECK-FP16-NEXT:    ret
+  %1 = fptosi half 0xH7E00 to i32
+  %2 = call i32 @llvm.smin.i32(i32 0, i32 %1)
+  %3 = call i32 @llvm.smax.i32(i32 %2, i32 0)
+  ret i32 %3
+}
+
 declare i32 @llvm.smin.i32(i32, i32)
 declare i32 @llvm.smax.i32(i32, i32)
 declare i32 @llvm.umin.i32(i32, i32)
diff --git a/llvm/test/CodeGen/RISCV/fpclamptosat.ll b/llvm/test/CodeGen/RISCV/fpclamptosat.ll
index 18d071cc39bb6..7bc58c43beb78 100644
--- a/llvm/test/CodeGen/RISCV/fpclamptosat.ll
+++ b/llvm/test/CodeGen/RISCV/fpclamptosat.ll
@@ -3829,6 +3829,45 @@ entry:
   ret i64 %conv6
 }
 
+define i32 @ustest_f16const_i32() {
+; CHECK-LABEL: ustest_f16const_i32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cvttss2si {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ecx
+; CHECK-NEXT:    movl %ecx, %eax
+; CHECK-NEXT:    sarl $31, %eax
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    andl %ecx, %eax
+; CHECK-NEXT:    cmovlel %edx, %eax
+; CHECK-NEXT:    retq
+; RV32-LABEL: ustest_f16const_i32:
+; RV32:       # %bb.0:
+; RV32-NEXT:    lui a0, 523264
+; RV32-NEXT:    fmv.w.x fa5, a0
+; RV32-NEXT:    fcvt.w.s a0, fa5, rtz
+; RV32-NEXT:    srai a1, a0, 31
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sgtz a1, a0
+; RV32-NEXT:    neg a1, a1
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: ustest_f16const_i32:
+; RV64:       # %bb.0:
+; RV64-NEXT:    lui a0, 523264
+; RV64-NEXT:    fmv.w.x fa5, a0
+; RV64-NEXT:    fcvt.l.s a0, fa5, rtz
+; RV64-NEXT:    srai a1, a0, 63
+; RV64-NEXT:    and a0, a1, a0
+; RV64-NEXT:    sgtz a1, a0
+; RV64-NEXT:    neg a1, a1
+; RV64-NEXT:    and a0, a1, a0
+; RV64-NEXT:    ret
+  %1 = fptosi half 0xH7E00 to i32
+  %2 = call i32 @llvm.smin.i32(i32 0, i32 %1)
+  %3 = call i32 @llvm.smax.i32(i32 %2, i32 0)
+  ret i32 %3
+}
+
 declare i32 @llvm.smin.i32(i32, i32)
 declare i32 @llvm.smax.i32(i32, i32)
 declare i32 @llvm.umin.i32(i32, i32)
diff --git a/llvm/test/CodeGen/X86/fpclamptosat.ll b/llvm/test/CodeGen/X86/fpclamptosat.ll
index 3f5ec7b530fe0..65492e772cebf 100644
--- a/llvm/test/CodeGen/X86/fpclamptosat.ll
+++ b/llvm/test/CodeGen/X86/fpclamptosat.ll
@@ -1170,6 +1170,22 @@ entry:
   ret i64 %conv6
 }
 
+define i32 @ustest_f16const_i32() {
+; CHECK-LABEL: ustest_f16const_i32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cvttss2si {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ecx
+; CHECK-NEXT:    movl %ecx, %eax
+; CHECK-NEXT:    sarl $31, %eax
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    andl %ecx, %eax
+; CHECK-NEXT:    cmovlel %edx, %eax
+; CHECK-NEXT:    retq
+  %1 = fptosi half 0xH7E00 to i32
+  %2 = call i32 @llvm.smin.i32(i32 0, i32 %1)
+  %3 = call i32 @llvm.smax.i32(i32 %2, i32 0)
+  ret i32 %3
+}
+
 declare i32 @llvm.smin.i32(i32, i32)
 declare i32 @llvm.smax.i32(i32, i32)
 declare i32 @llvm.umin.i32(i32, i32)



More information about the llvm-commits mailing list