mlir::Value scheduleChunkClauseOperand, ifClauseOperand;
mlir::Attribute scheduleClauseOperand, noWaitClauseOperand,
orderedClauseOperand, orderClauseOperand;
- mlir::IntegerAttr simdlenClauseOperand;
+ mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand;
SmallVector<Attribute> reductionDeclSymbols;
Fortran::lower::StatementContext stmtCtx;
const auto &loopOpClauseList = std::get<Fortran::parser::OmpClauseList>(
const std::optional<std::int64_t> simdlenVal =
Fortran::evaluate::ToInt64(*expr);
simdlenClauseOperand = firOpBuilder.getI64IntegerAttr(*simdlenVal);
+ } else if (const auto &safelenClause =
+ std::get_if<Fortran::parser::OmpClause::Safelen>(
+ &clause.u)) {
+ const auto *expr = Fortran::semantics::GetExpr(safelenClause->v);
+ const std::optional<std::int64_t> safelenVal =
+ Fortran::evaluate::ToInt64(*expr);
+ safelenClauseOperand = firOpBuilder.getI64IntegerAttr(*safelenVal);
}
}
TypeRange resultType;
auto SimdLoopOp = firOpBuilder.create<mlir::omp::SimdLoopOp>(
currentLocation, resultType, lowerBound, upperBound, step,
- ifClauseOperand, simdlenClauseOperand, nullptr,
+ ifClauseOperand, simdlenClauseOperand, safelenClauseOperand,
/*inclusive=*/firOpBuilder.getUnitAttr());
createBodyOfOp<omp::SimdLoopOp>(SimdLoopOp, converter, currentLocation,
eval, &loopOpClauseList, iv);
!$OMP END SIMD
end subroutine
+!CHECK-LABEL: func @_QPsimdloop_with_safelen_clause
+subroutine simdloop_with_safelen_clause(n, threshold)
+integer :: i, n, threshold
+ !$OMP SIMD SAFELEN(2)
+ ! CHECK: %[[LB:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[UB:.*]] = fir.load %arg0
+ ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
+ ! CHECK: omp.simdloop safelen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
+ do i = 1, n
+ ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
+ ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
+ ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) : (!fir.ref<i8>, i32) -> i1
+ print*, i
+ end do
+ !$OMP END SIMD
+end subroutine
+
+!CHECK-LABEL: func @_QPsimdloop_with_safelen_clause_from_expr_from_param
+subroutine simdloop_with_safelen_clause_from_expr_from_param(n, threshold)
+integer :: i, n, threshold
+integer, parameter :: safelen = 2;
+ !$OMP SIMD SAFELEN(safelen*2 + 2)
+ ! CHECK: %[[LB:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[UB:.*]] = fir.load %arg0
+ ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
+ ! CHECK: omp.simdloop safelen(6) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
+ do i = 1, n
+ ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
+ ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
+ ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) : (!fir.ref<i8>, i32) -> i1
+ print*, i
+ end do
+ !$OMP END SIMD
+end subroutine
+
+!CHECK-LABEL: func @_QPsimdloop_with_simdlen_safelen_clause
+subroutine simdloop_with_simdlen_safelen_clause(n, threshold)
+integer :: i, n, threshold
+ !$OMP SIMD SIMDLEN(1) SAFELEN(2)
+ ! CHECK: %[[LB:.*]] = arith.constant 1 : i32
+ ! CHECK: %[[UB:.*]] = fir.load %arg0
+ ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32
+ ! CHECK: omp.simdloop simdlen(1) safelen(2) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
+ do i = 1, n
+ ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref<i32>
+ ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref<i32>
+ ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LD]]) : (!fir.ref<i8>, i32) -> i1
+ print*, i
+ end do
+ !$OMP END SIMD
+end subroutine
+
!CHECK-LABEL: func @_QPsimdloop_with_collapse_clause
subroutine simdloop_with_collapse_clause(n)
integer :: i, j, n