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:
parent
175a5cc692
commit
47d18eb749
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue