[Flang][OpenMP] Add support for safelen clause
authorPrabhdeep Singh Soni <prabhdeep.singh.soni2@huawei.com>
Wed, 24 Aug 2022 17:18:31 +0000 (13:18 -0400)
committerPrabhdeep Singh Soni <prabhdeep.singh.soni2@huawei.com>
Wed, 24 Aug 2022 19:06:12 +0000 (15:06 -0400)
This supports lowering from parse-tree to MLIR for OpenMP safelen clause
in SIMD construct.

Reviewed By: kiranchandramohan

Differential Revision: https://reviews.llvm.org/D132574

flang/lib/Lower/OpenMP.cpp
flang/test/Lower/OpenMP/simd.f90

index 523edc0..0b5e97a 100644 (file)
@@ -1004,7 +1004,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
   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>(
@@ -1129,6 +1129,13 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
       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);
     }
   }
 
@@ -1150,7 +1157,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
     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);
index 1be8863..32fec46 100644 (file)
@@ -90,6 +90,58 @@ integer, parameter :: simdlen = 2;
   !$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