This supports lowering from parse-tree to MLIR and translation from
MLIR to LLVM IR using OMPIRBuilder for OpenMP simdlen clause in SIMD
construct.
Details
Diff Detail
Event Timeline
Thanks for working on this patch. Can we add a verifier for
simdlen to error when the given value is negative? From the OpenMP standards "The parameter of the simdlen clause must be a constant positive integer expression."
Good point. I think it would be simpler to change simdlen argument type from I32 to Confined<OptionalAttr<I64Attr>, [IntMinValue<0>]> in the MLIR op definition. We use the aforementioned type currently for clauses such as ordered, which are also required to be "constant positive integer expression".
- Can we have a test case in invalid.mlir
- Can we have a testcase where the simdlen is specified through a function argument or a local variable?
- Add invalid.mlir testcase
- Add Flang test case with simdlen from a local parameter instead of a literal
flang/lib/Lower/OpenMP.cpp | ||
---|---|---|
786–787 | ||
882–883 | We can have simdlenClauseOperand as an IntegerAttr instead of an Attribute (suggested edit in the code above). That will avoid type-casting to and from Attribute for this. | |
flang/test/Lower/OpenMP/simd.f90 | ||
61 | Can we also have a test here that has an expression. Like SIMDLEN(simdlen * 2 + n) or something. | |
mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp | ||
975 | nit: expand auto. | |
978 | There are no tests for MLIR->LLVM IR translation. Changes to OpenMPToLLVMIRTranslation.cpp and the tests for that (in mlir/test/Target/LLVMIR/openmp-llvm.mlir) should be a part of the same patch. You can send them as a separate patch if you'd like. |
- Expand auto
- Add expression Flang test case
- Use IntegerAttr directly to avoid the need for a dyn_cast
- Add mlir/test/Target/LLVMIR/openmp-llvm.mlir testcase
flang/test/Lower/OpenMP/simd.f90 | ||
---|---|---|
61 | I instead used SIMDLEN(simdlen*2 + 2), because in this example n is not constant, so you can't use it in an expression for simdlen. |
LGTM.
flang/test/Lower/OpenMP/simd.f90 | ||
---|---|---|
61 | Hmm, gfortran seems to accept simdlen*2+n in this example. The standard mentions that the argument must be a "constant positive integer expression". It is probably incorrect behavior in gfortran. Please wait for a day or two if anyone has a preference for being accurate to standard vs being compatible with gfortran. If no one objects, we can go ahead and merge this. For me, this is fine. |
flang/test/Lower/OpenMP/simd.f90 | ||
---|---|---|
61 | I wanted to point out that it is the parser that complains with Must be a constant value. If we are going to try and be compatible with gfortran, I think it would make more sense to do this in a separate patch where we change the parser and the other affected parts accordingly. Also, if you write a similar C program as shown below and compile it with Clang, Clang also complains similarly, so I believe Flang's existing parsing behaviour is correct. #define N 1000000000 void func (int n) { int a[N] = {0}; #pragma omp simd safelen(n) for (int i=0; i<N; i++) { a[i] = a[i] + i; } } ./ex.c:10:27: error: expression is not an integer constant expression #pragma omp simd safelen(n) |
Nit: In summary:
This supports lowering from parse-tree to MLIR and translation from MLIR to LLVM IR using OMPIRBuilder for OpenMP simdlen clause in SIMD construct.
flang/test/Lower/OpenMP/simd.f90 | ||
---|---|---|
61 | @shraiysh @psoni2628 Don't worry about this. It's safe to emit one semantic error for this. Check the following cases: subroutine sub(N, x, y, z) integer :: N integer :: l = 1 integer :: x(N), y(N), z(N) !$omp simd simdlen(l) do i = 1, N x(i) = x(i) + y(i)*z(i) enddo !$omp end simd end subroutine sub(N, x, y, z) integer :: N integer, parameter :: l = 1 integer :: x(N), y(N), z(N) !$omp simd simdlen(l) do i = 1, N x(i) = x(i) + y(i)*z(i) enddo !$omp end simd end Run gfortran -fopenmp test.f90 -O3 -S -o test-omp.s and you will see simdlen with variable won't work. The variable is unknown in compile-time. I don't think you can add one variable in the loop vectorization metadata. |