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
endsubroutine 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
endRun 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. | |