flang-compiler / f18-llvm-project

Fork of llvm/llvm-project for f18. In sync with f18-mlir and f18.
http://llvm.org
28 stars 16 forks source link

SIGN intrinsic uses older F90 semantics #1054

Open mleair opened 2 years ago

mleair commented 2 years ago

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

sscalpone commented 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.

schweitzpgi commented 2 years ago

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.

jeanPerier commented 2 years ago

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).

schweitzpgi commented 2 years ago

https://github.com/flang-compiler/f18-llvm-project/pull/1223