Skip to content

int: implement signed comparison for unsigned integers#931

Merged
antoyo merged 1 commit into
rust-lang:masterfrom
xobs:support-signed-comparison
Jul 26, 2026
Merged

int: implement signed comparison for unsigned integers#931
antoyo merged 1 commit into
rust-lang:masterfrom
xobs:support-signed-comparison

Conversation

@xobs

@xobs xobs commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

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.

This was caught when running a test suite for an embedded device compiled under the gcc backend. A reproducer when compiling under -O for x86-64 is:

use std::hint::black_box;

#[repr(u8)]
enum Inner { L0 = 0, H255 = 255 }
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" }
}

fn main() {
    assert_eq!(which(black_box(&O::A(Inner::H255))), "a"); // 0xFF
    println!("all ok");
}

The problem only shows up with -O, not by default.

thread 'main' (1223) panicked at /home/seancross/work/testcase/testcase-3.rs:13:5:
assertion `left == right` failed
  left: "c"
 right: "a"

@xobs

xobs commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Let me know if you'd like me to open an issue in the rust repo, or if there's a place I can add a testcase here. I'm manually driving rustc due to #930.

I have a few other minor fixes, and I can send PRs with them once I know how you'd prefer them formatted.

Comment thread src/int.rs
@antoyo

antoyo commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Let me know if you'd like me to open an issue in the rust repo, or if there's a place I can add a testcase here. I'm manually driving rustc due to #930.

No need to open an issue: you can open a PR right away.
You can add a test in this directory.

I have a few other minor fixes, and I can send PRs with them once I know how you'd prefer them formatted.

Anything else you need to know about my preferences here?

Thanks for your contribution!

@xobs
xobs force-pushed the support-signed-comparison branch from bc6d978 to 5c533bc Compare July 26, 2026 12:28
Comment thread tests/run/int.rs
@xobs

xobs commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

That should be it. Now I know how to add and run tests, I can use that to make sure the changes I push actually fix things.

There are a few bigger changes I've accumulated (LTO improvements, link section fixes, clobber support), and a couple of them require patches to gcc (and consequently gccjit support), but I'll start with these small patches first.

@xobs
xobs force-pushed the support-signed-comparison branch 2 times, most recently from 0f0cfa0 to feab042 Compare July 26, 2026 12:38
@xobs

xobs commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Hmm... The test doesn't seem to work without int128. Or on m68k. Think that is a real bug, or should I gate the test on x86 only?

@antoyo

antoyo commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Hmm... The test doesn't seem to work without int128. Or on m68k. Think that is a real bug, or should I gate the test on x86 only?

It seems like a real bug to me.
Without int128, the error is:

gcc_jit_context_new_cast: cannot cast param0[(int)1] from type: __int64_t  __attribute__((aligned(8))) to type: __int64_t  __attribute__((aligned(8)))[2]

which means it seems you try to cast a low/high value to the complete 128-bit representation (which is an array of i64).
I guess the code needs to be adjusted to call to_signed on the inner element type instead of the array type.

@xobs
xobs force-pushed the support-signed-comparison branch from feab042 to 2a023ce Compare July 26, 2026 13:19
@xobs

xobs commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

Yep, sorry, I just needed to figure out how to use gcc-15-without-int128.deb. Now I see I just need to extract it somewhere and point config.toml:gcc-path at it.

Hopefully works now. So happy CI and test coverage exists.

@antoyo antoyo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last thing, then we can merge this:

View changes since this review

Comment thread src/int.rs Outdated
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 <sean@xobs.io>
@xobs
xobs force-pushed the support-signed-comparison branch from 2a023ce to f5dc6be Compare July 26, 2026 22:56
@antoyo
antoyo merged commit 2fb1b6d into rust-lang:master Jul 26, 2026
40 checks passed
@antoyo

antoyo commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants