From 871ddc392df3e10be1a4b9dba9d0eaeaa37d1928 Mon Sep 17 00:00:00 2001 From: nella Date: Fri, 6 Nov 2026 16:07:00 +0100 Subject: [PATCH] Fix x87 int conversion. --- src/backend/pass/emit/x86/x86_lower_ops.cpp | 9 +++++++-- .../correctness/custom/x87_from_narrow_int_noopt.c | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/compiler/test/correctness/custom/x87_from_narrow_int_noopt.c diff --git a/src/backend/pass/emit/x86/x86_lower_ops.cpp b/src/backend/pass/emit/x86/x86_lower_ops.cpp index c48f4b7..d8f56ba 100644 --- a/src/backend/pass/emit/x86/x86_lower_ops.cpp +++ b/src/backend/pass/emit/x86/x86_lower_ops.cpp @@ -1038,9 +1038,14 @@ namespace rat { case Opcode::FPTrunc: fstpSse(vregFor(n), opWidth(n->getType()), x); return; - case Opcode::SIToFP: - fild(x87SlotOf(n), s); + case Opcode::SIToFP: { + // fild reads all 64 bits, a narrower source loaded from memory is zero extended + VReg wide = fresh(detail::kGp); + mov(wide, s); + signExtBits(wide, intBits(st)); + fild(x87SlotOf(n), wide); return; + } case Opcode::UIToFP: emitUIntToX87(n, s, intBits(st)); return; diff --git a/src/compiler/test/correctness/custom/x87_from_narrow_int_noopt.c b/src/compiler/test/correctness/custom/x87_from_narrow_int_noopt.c new file mode 100644 index 0000000..c4a08c1 --- /dev/null +++ b/src/compiler/test/correctness/custom/x87_from_narrow_int_noopt.c @@ -0,0 +1,10 @@ +// expect: 1 +// passes: + +// a negative int read back from memory, converted to long double +long double widen(int s) { + int* p = &s; + return *p; +} + +int main(void) { return widen(-1) == -1.0L; }