fix: promote mismatched comparison operands before emitting cmp (issue 0146)
A comparison with int-vs-float (or two float widths) operands emitted cmp on the raw operands with no promotion, unlike the arithmetic arms -- producing a mixed-type compare the LLVM verifier rejects / mis-evaluates. lowerBinaryOp now coerces each operand to the promoted common type (from arithResultType) via coerceToType (SIToFP / FPExt) for the ordering/equality arms when the promoted type is a float, so LLVM gets a well-typed fcmp. Regression: examples/0189-types-int-float-compare-promote.sx
This commit is contained in:
32
examples/0189-types-int-float-compare-promote.sx
Normal file
32
examples/0189-types-int-float-compare-promote.sx
Normal file
@@ -0,0 +1,32 @@
|
||||
// A comparison with mismatched scalar operands (int vs float, or two float
|
||||
// widths) must promote both operands to the common type before emitting the
|
||||
// compare — `lowerBinaryOp` now coerces each operand to the promoted float
|
||||
// type for the ordering/equality arms (as the arithmetic arms already do),
|
||||
// so the cast materializes and LLVM gets a well-typed fcmp instead of a
|
||||
// mixed-type compare that the verifier rejects / silently mis-evaluates.
|
||||
//
|
||||
// Regression (issue 0146).
|
||||
#import "modules/std.sx";
|
||||
|
||||
// i32 < f32: the `xx i` cast must materialize as an i32->f32 SIToFP.
|
||||
ceil_half :: (v: f32) -> i32 {
|
||||
t := v - 0.5;
|
||||
i : i32 = xx t;
|
||||
if xx i < t { // 1.0 < 1.8 -> true
|
||||
i += 1;
|
||||
}
|
||||
i
|
||||
}
|
||||
|
||||
// f64 vs f32 sibling: `xx y + 0.5` infers f64; comparing to an f32 must FPExt.
|
||||
ge :: (y: i32, lo: f32) -> i32 {
|
||||
sy := xx y + 0.5; // 3.5 (f64)
|
||||
if sy >= lo { return 1; }
|
||||
0
|
||||
}
|
||||
|
||||
main :: () -> i32 {
|
||||
print("{}\n", ceil_half(2.3)); // 2
|
||||
print("{}\n", ge(3, 2.0)); // 1
|
||||
0
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
2
|
||||
1
|
||||
Reference in New Issue
Block a user