FR: Fold floating-point divisions under FASTMATH.
This looks more dangerous than #39785 (closed) as will likely make result go away from the mathematically correct one instead of going closer, hence the separate issue. Doing this also suggests you can change x / CONST
to x * (1 / CONST)
as x / CONST
is equivalent to safe-looking x * 1 / CONST
, which looks even more dubious...
In either way, replacing #39785 (closed)’s +
with *
and -
with /
shows that /
don’t fold.
{$mode objfpc} {$h+}
{$optimization level1} {$optimization level2} {$optimization level3} {$optimization level4} {$optimization regvar} {$optimization fastmath}
label A0, A1, B0, B1, C0, C1;
var
x, y: single;
dontDrop: string;
begin
x := random;
A0:
y := x * 1 * 2 * 3 * 4 * 5 * 6; // folds
A1:
writestr(dontDrop, y);
writeln('x * 1 * 2 * 3 * 4 * 5 * 6: ', CodePointer(@A1) - CodePointer(@A0), ' b');
B0:
y := x * 1 / 2 * 3 / 4 * 5 / 6; // doesn’t fold
B1:
writestr(dontDrop, y);
writeln('x * 1 / 2 * 3 / 4 * 5 / 6: ', CodePointer(@B1) - CodePointer(@B0), ' b');
C0:
y := x / 1 / 2 / 3 / 4 / 5 / 6; // doesn’t fold
C1:
writestr(dontDrop, y);
writeln('x / 1 / 2 / 3 / 4 / 5 / 6: ', CodePointer(@C1) - CodePointer(@C0), ' b');
end.
⇓
x * 1 * 2 * 3 * 4 * 5 * 6: 15 b
x * 1 / 2 * 3 / 4 * 5 / 6: 47 b
x / 1 / 2 / 3 / 4 / 5 / 6: 47 b
Edited by Rika