mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 04:59:25 +02:00
* convert n-n mod const into n div const*const, resolves #39615
This commit is contained in:
parent
7da8c774be
commit
0ba4cee279
@ -958,6 +958,16 @@ implementation
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ convert n - n mod const into n div const*const }
|
||||
if (nodetype=subn) and (right.nodetype=modn) and is_constintnode(taddnode(right).right) and
|
||||
(left.isequal(taddnode(right).left)) and not(might_have_sideeffects(left)) then
|
||||
begin
|
||||
result:=caddnode.create_internal(muln,cmoddivnode.create(divn,left,taddnode(right).right.getcopy),taddnode(right).right);
|
||||
left:=nil;
|
||||
taddnode(right).right:=nil;
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ both real constants ? }
|
||||
if (lt=realconstn) and (rt=realconstn) then
|
||||
begin
|
||||
|
30
tests/webtbs/tw39615a.pp
Normal file
30
tests/webtbs/tw39615a.pp
Normal file
@ -0,0 +1,30 @@
|
||||
{ $define unsigned}
|
||||
const
|
||||
Divisor = 17;
|
||||
TestRange = 3 * Divisor;
|
||||
var
|
||||
i, x, r1, r2: {$ifdef unsigned} uint32 {$else} int32 {$endif};
|
||||
ok: boolean;
|
||||
begin
|
||||
ok := true;
|
||||
for i := {$ifdef unsigned} 0 {$else} -2 * TestRange {$endif} to 2 * TestRange do
|
||||
begin
|
||||
{$ifndef unsigned}
|
||||
if i < -TestRange then
|
||||
x := Low(x) + (i - (-2 * TestRange)) // test [Low(x); Low(x) + TestRange)
|
||||
else
|
||||
{$endif}
|
||||
if i <= TestRange then x := i // test [-TestRange; TestRange] or [0; TestRange]
|
||||
else x := High(x) - (i - TestRange - 1); // test (High(x) - TestRange; High(x)]
|
||||
|
||||
r1 := x - x mod Divisor;
|
||||
r2 := x div Divisor * Divisor;
|
||||
|
||||
if r1 <> r2 then
|
||||
begin
|
||||
writeln('FAIL: x=', x, ', x - x mod ', Divisor, ' = ', r1, ', x div ', Divisor, ' * ', Divisor, ' = ', r2);
|
||||
ok := false;
|
||||
end;
|
||||
end;
|
||||
if ok then writeln('ok');
|
||||
end.
|
30
tests/webtbs/tw39615b.pp
Normal file
30
tests/webtbs/tw39615b.pp
Normal file
@ -0,0 +1,30 @@
|
||||
{$define unsigned}
|
||||
const
|
||||
Divisor = 17;
|
||||
TestRange = 3 * Divisor;
|
||||
var
|
||||
i, x, r1, r2: {$ifdef unsigned} uint32 {$else} int32 {$endif};
|
||||
ok: boolean;
|
||||
begin
|
||||
ok := true;
|
||||
for i := {$ifdef unsigned} 0 {$else} -2 * TestRange {$endif} to 2 * TestRange do
|
||||
begin
|
||||
{$ifndef unsigned}
|
||||
if i < -TestRange then
|
||||
x := Low(x) + (i - (-2 * TestRange)) // test [Low(x); Low(x) + TestRange)
|
||||
else
|
||||
{$endif}
|
||||
if i <= TestRange then x := i // test [-TestRange; TestRange] or [0; TestRange]
|
||||
else x := High(x) - (i - TestRange - 1); // test (High(x) - TestRange; High(x)]
|
||||
|
||||
r1 := x - x mod Divisor;
|
||||
r2 := x div Divisor * Divisor;
|
||||
|
||||
if r1 <> r2 then
|
||||
begin
|
||||
writeln('FAIL: x=', x, ', x - x mod ', Divisor, ' = ', r1, ', x div ', Divisor, ' * ', Divisor, ' = ', r2);
|
||||
ok := false;
|
||||
end;
|
||||
end;
|
||||
if ok then writeln('ok');
|
||||
end.
|
Loading…
Reference in New Issue
Block a user