@@ -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
@@ -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
+ {$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
+ writeln('FAIL: x=', x, ', x - x mod ', Divisor, ' = ', r1, ', x div ', Divisor, ' * ', Divisor, ' = ', r2);
+ ok := false;
+ if ok then writeln('ok');
+end.
+{$define unsigned}