Open mleair opened 2 years ago
It's fine to have a flag. We should implement the modern semantics, and, if it is straightforward, so the old semantics; otherwise, assert that the flag is set to modern so future generations can know where to look. Comment appropriately.
Lowering is generating:
%10 = fir.call @_FortranAioInputReal32(%9, %1) : (!fir.ref<i8>, !fir.ref<f32>) -> i1
%11 = fir.call @_FortranAioEndIoStatement(%9) : (!fir.ref<i8>) -> i32
%12 = fir.load %1 : !fir.ref<f32>
%13 = fir.call @llvm.fabs.f32(%cst_0) : (f32) -> f32
%14 = negf %13 : f32
%15 = cmpf olt, %12, %cst : f32
%16 = select %15, %14, %13 : f32
_FortranAioInputReal32
is returning a -0.0 float in %1
. cmpf.olt
is returning false.
Codegen produces:
%5 = load float, float* %1, align 4, !dbg !12
%6 = call float @llvm.fabs.f32(float 1.000000e+00), !dbg !13
%7 = fneg float %6, !dbg !14
%8 = fcmp olt float %5, 0.000000e+00, !dbg !15
%9 = select i1 %8, float %7, float %6, !dbg !16
which is again using fcmp olt
.
Basically, this is missing the test: fcmp oeq float %5, -0.0
.
Doesn't fcmp oeq float %5, -0.0
returns true too if %5
is 0.0
?
The only way I could find so far to detect -0.0 is to bitcast -0.0 and %5 to integer type of the same size and to compare that (this does not assume much about the underlying representation, other than -0. and 0. are not represented the same).
The way SIGN treats -0.0 in the second argument changed between F90 and F95. Most compilers use the F95 semantics by default. ifort uses F90 semantics by default but can use F95 semantics with a compiler switch (-assume minus0). Nag can switch to F90 semantics with a -f90_sign swich. Should F18 also have a switch? Or should it just support F95 semantics for SIGN?
program sign_test character5 :: ch = "-0.0" real :: r read(ch,1) r 1 format(f4.1) if (sign(1.0,r)==1.0) stop "F95 SIGN not supported" print ,"ok" end