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
- Repository
- rG LLVM Github Monorepo
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 | ||
---|---|---|
907–909 | ||
1049–1050 | 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. |