test(codegen): lock in Int64(<large-literal>) value-cast lowering

The QBE backend once mis-lowered a value-cast of a >32-bit literal
(cMax = Int64(922337203685477580)), emitting a 'w'-typed operand that QBE
rejected with "invalid type for first operand ... in arg".  The width-by-
magnitude literal lowering now emits these as 'l', so the cast is correct on
both backends.

Adds an IR unit test asserting the 'l' (not 'w') lowering and an e2e test
(AssertRunsOnAll, both backends) exercising the const through folding,
arithmetic, and argument positions.
This commit is contained in:
Graeme Geldenhuys 2026-06-24 17:21:48 +01:00
parent 175a5cc692
commit 47d18eb749

View file

@ -46,6 +46,7 @@ type
procedure TestCodegen_UInt64_Mod_UsesUrem;
procedure TestCodegen_WriteLn_UInt64_CallsSysWriteUInt64;
procedure TestCodegen_IntToStr_UInt64_CallsUInt64ToStr;
procedure TestCodegen_Int64LargeLiteralCast_UsesLType;
end;
[Threaded]
@ -59,6 +60,12 @@ type
procedure TestRun_UInt64_Arithmetic;
procedure TestRun_UInt64_UnsignedCompare;
procedure TestRun_Int64_MinValue;
{ Regression: a const declared with the value-cast form
cMax = Int64(922337203685477580) must lower the large literal with the
'l' (64-bit) type — through const folding, arithmetic, and argument
positions. The QBE backend once emitted a 'w'-typed operand here and
QBE rejected the IR ("invalid type for first operand ... in arg"). }
procedure TestRun_Int64_LargeLiteralCast;
end;
implementation
@ -334,6 +341,26 @@ begin
AssertTrue('UInt64 mod uses urem', Pos('urem', IR) > 0);
end;
procedure TUInt64Tests.TestCodegen_Int64LargeLiteralCast_UsesLType;
var
IR: string;
begin
IR := GenIR(
'''
program P;
var N: Int64;
begin
N := Int64(922337203685477580)
end.
''');
{ The large literal must carry the 'l' (64-bit) type. A 'w copy' of a
>32-bit literal is the bug QBE rejected with "invalid type ... in arg". }
AssertTrue('large Int64 literal lowered as l',
Pos('=l copy 922337203685477580', IR) > 0);
AssertFalse('large Int64 literal not lowered as w',
Pos('=w copy 922337203685477580', IR) <> -1);
end;
procedure TUInt64Tests.TestCodegen_WriteLn_UInt64_CallsSysWriteUInt64;
var
IR: string;
@ -447,6 +474,22 @@ const
end.
''';
SrcInt64LargeLiteralCast =
'''
program P;
const
cMax = Int64(922337203685477580);
procedure Show(V: Int64);
begin WriteLn(V) end;
var N: Int64;
begin
Show(cMax);
N := cMax div 10;
Show(N);
WriteLn(Int64(922337203685477580))
end.
''';
procedure TUInt64E2ETests.TestRun_UInt64_RoundTrip;
var Output: string; RCode: Integer;
begin
@ -505,6 +548,15 @@ begin
'-9223372036854775808' + LE, Output);
end;
procedure TUInt64E2ETests.TestRun_Int64_LargeLiteralCast;
begin
if not ToolchainAvailable() then begin Ignore('toolchain unavailable'); Exit; end;
AssertRunsOnAll(SrcInt64LargeLiteralCast,
'922337203685477580' + LE +
'92233720368547758' + LE +
'922337203685477580' + LE, 0);
end;
initialization
RegisterTest(TUInt64Tests);
RegisterTest(TUInt64E2ETests);