From f5dc6be964d75a23a2e81489e20cd0d4b1df483a Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Sun, 26 Jul 2026 12:12:20 +0800 Subject: [PATCH] int: implement signed comparison for unsigned integers Implement signed comparison for unsigned integers, which is very similar to unsigned integers but uses `to_signed()` rather than `to_unsigned()`. This fixes a case where niche optimization causes the discriminant to sometimes compare signed and unsigned values. Signed-off-by: Sean Cross --- src/int.rs | 26 ++++++++++++++++++++------ tests/run/int.rs | 25 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/int.rs b/src/int.rs index 13a867ab323..0c9a7556945 100644 --- a/src/int.rs +++ b/src/int.rs @@ -462,9 +462,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { lhs_high = self.context.new_cast(self.location, lhs_high, unsigned_type); rhs_high = self.context.new_cast(self.location, rhs_high, unsigned_type); } - // FIXME(antoyo): we probably need to handle signed comparison for unsigned - // integers. - _ => (), + IntPredicate::IntSGT + | IntPredicate::IntSGE + | IntPredicate::IntSLT + | IntPredicate::IntSLE => { + let signed_type = native_int_type.to_signed(self.cx); + lhs_high = self.context.new_cast(self.location, lhs_high, signed_type); + rhs_high = self.context.new_cast(self.location, rhs_high, signed_type); + } + IntPredicate::IntEQ | IntPredicate::IntNE => (), } let condition = self.context.new_comparison( @@ -602,9 +608,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { rhs = self.context.new_cast(self.location, rhs, unsigned_type); } } - // FIXME(antoyo): we probably need to handle signed comparison for unsigned - // integers. - _ => (), + IntPredicate::IntSGT + | IntPredicate::IntSGE + | IntPredicate::IntSLT + | IntPredicate::IntSLE => { + if !a_type.is_vector() { + let signed_type = a_type.to_signed(self.cx); + lhs = self.context.new_cast(self.location, lhs, signed_type); + rhs = self.context.new_cast(self.location, rhs, signed_type); + } + } + IntPredicate::IntEQ | IntPredicate::IntNE => (), } self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs) } diff --git a/tests/run/int.rs b/tests/run/int.rs index 78675acb544..ef825b4d801 100644 --- a/tests/run/int.rs +++ b/tests/run/int.rs @@ -319,4 +319,29 @@ fn main() { const VAL5: T = 73236519889708027473620326106273939584_i128; check_ops128!(); } + + { + #[allow(dead_code)] + #[repr(u8)] + enum Inner { + L0 = 0, + H255 = 255, + } + #[allow(dead_code)] + enum O { + A(Inner), + B, + C, + } + + #[inline(never)] + fn which(o: &O) -> &'static str { + match o { + O::A(_) => "a", + O::B => "b", + O::C => "c", + } + } + assert_eq!(which(black_box(&O::A(Inner::H255))), "a"); + } }