Open AntonRydahl opened 1 year ago
@llvm/issue-subscribers-flang-ir
@llvm/issue-subscribers-openmp
FWIW, while the frontend might want to do the folding, enabling the Attributor will get us the desired folding as well.
Thanks for looking into this. I think you are seeing a few issues, with the relevant code being the following.
%9 = load i32, ptr %loadgep_, align 4, !tbaa !4
%10 = sitofp i32 %9 to float
%11 = fdiv contract float 1.000000e+00, %10
MemRefDataFlowOpt
that forwards Stores to Loads. This might help remove the constant load. If you are using the fir-opt
tool then this can be enabled using the option -fir-memref-dataflow-opt
. %28 = fir.convert %c1048576_i32 : (i32) -> f32
%29 = arith.divf %cst, %28 fastmath<contract> : f32
sitofp
feeding a div
.
%105 = llvm.sitofp %14 : i32 to f32
%106 = llvm.fdiv %10, %105 {fastmathFlags = #llvm.fastmath<contract>} : f32
But on translation to LLVM IR this conversion seems to be gone. I am able to obtain the following IR in the loop region.
store double 0x3EB0000000000000, ptr %20, align 8
CommandLine
./bin/flang-new -fc1 -emit-fir -fopenmp -O3 canon.f90 -o - | ./bin/fir-opt --canonicalize --cse --fir-memref-dataflow-opt --canonicalize --cse --cfg-conversion --cg-rewrite --fir-to-llvm-ir | ./bin/mlir-translate --mlir-to-llvmir -allow-unregistered-dialect
It will be good to investigate whether the pass MemRefDataFlowOpt
can be enabled by default when the Optimization flags (O1,O2,O3,Ofast) are ON.
It will be good to investigate the vectorization issue as well. One reason could be that we are not generating the atomic
version for reductions.
@llvm/issue-subscribers-bug
I noticed that Flang-new does not perform constant propagation as I would have expected. I made two simple test programs in C and Fortran using reductions in OpenMP. The programs are the following:
I compiled the two programs with:
In the LLVM IR generated with Clang,
1.0/length
has been replaced with0x3EB0000000000000
which is exactly1.0/(1024.0*1024,0)
as one would expect:In the LLVM IR generated with Flang-new, the expression
1.0/length
is evaluated every iteration. That happens in line%11 = fdiv contract float 1.000000e+00, %10
since%10
is a floating point cast of%9
, which is an extension of%loadgep_
, which ultimately refers to the statically allocated variablelength
.Finally, the Flang IR has not been vectorized like the Clang IR. Should I file that as a separate bug report? The full LLVM IR and source files can be found here:
https://github.com/AntonRydahl/flangtests/blob/main/ir/CC/loop_reduction.ll https://github.com/AntonRydahl/flangtests/blob/main/ir/FC/loop_reduction.ll https://github.com/AntonRydahl/flangtests/blob/main/src/loop_reduction.c https://github.com/AntonRydahl/flangtests/blob/main/src/loop_reduction.f90