Index: flang/lib/Lower/OpenMP.cpp =================================================================== --- flang/lib/Lower/OpenMP.cpp +++ flang/lib/Lower/OpenMP.cpp @@ -131,7 +131,8 @@ firOpBuilder.setInsertionPointToStart(&block); // Insert the terminator. - if constexpr (std::is_same_v) { + if constexpr (std::is_same_v || + std::is_same_v) { mlir::ValueRange results; firOpBuilder.create(loc, results); } else { @@ -387,10 +388,13 @@ noWaitClauseOperand, orderedClauseOperand, orderClauseOperand; const auto &wsLoopOpClauseList = std::get( std::get(loopConstruct.t).t); - if (llvm::omp::OMPD_do != + const auto &LoopDirective = std::get( std::get(loopConstruct.t).t) - .v) { + .v; + + if (llvm::omp::OMPD_do != LoopDirective && + llvm::omp::OMPD_simd != LoopDirective) { TODO(converter.getCurrentLocation(), "Combined worksharing loop construct"); } @@ -421,6 +425,17 @@ } iv = bounds->name.thing.symbol; + // 2.9.3.1 SIMD construct + // TODO: Support all the clauses + if (llvm::omp::OMPD_simd == LoopDirective) { + TypeRange resultType; + auto SimdLoopOp = firOpBuilder.create( + currentLocation, resultType, lowerBound, upperBound, step); + createBodyOfOp(SimdLoopOp, converter, currentLocation, + &wsLoopOpClauseList, iv); + return; + } + // FIXME: Add support for following clauses: // 1. linear // 2. order Index: flang/test/Fir/convert-to-llvm-openmp-and-fir.fir =================================================================== --- flang/test/Fir/convert-to-llvm-openmp-and-fir.fir +++ flang/test/Fir/convert-to-llvm-openmp-and-fir.fir @@ -71,3 +71,47 @@ // CHECK: } // CHECK: llvm.return // CHECK: } + +func.func @_QPsimd1(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !fir.ref> {fir.bindc_name = "arr"}) { + %c1_i64 = arith.constant 1 : i64 + %c1_i32 = arith.constant 1 : i32 + %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"} + omp.parallel { + %1 = fir.alloca i32 {adapt.valuebyref, pinned} + %2 = fir.load %arg0 : !fir.ref + omp.simdloop (%arg2) : i32 = (%c1_i32) to (%2) step (%c1_i32) { + fir.store %arg2 to %1 : !fir.ref + %3 = fir.load %1 : !fir.ref + %4 = fir.convert %3 : (i32) -> i64 + %5 = arith.subi %4, %c1_i64 : i64 + %6 = fir.coordinate_of %arg1, %5 : (!fir.ref>, i64) -> !fir.ref + fir.store %3 to %6 : !fir.ref + omp.yield + } + omp.terminator + } + return +} + +// CHECK-LABEL: _QPsimd1 +// CHECK-SAME: %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}, %[[ARR_REF:.*]]: !llvm.ptr {fir.bindc_name = "arr"}) { +// CHECK: %[[ONE_1:.*]] = llvm.mlir.constant(1 : i64) : i64 +// CHECK: %[[ONE_2:.*]] = llvm.mlir.constant(1 : i32) : i32 +// CHECK: omp.parallel { +// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64 +// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {adapt.valuebyref, in_type = i32, operand_segment_sizes = dense<0> : vector<2xi32>, pinned} : (i64) -> !llvm.ptr +// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr +// CHECK: omp.simdloop +// CHECK-SAME: (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) step (%[[ONE_2]]) { +// CHECK: llvm.store %[[I]], %[[I_VAR]] : !llvm.ptr +// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr +// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64 +// CHECK: %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]] : i64 +// CHECK: %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr +// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : !llvm.ptr +// CHECK: omp.yield +// CHECK: } +// CHECK: omp.terminator +// CHECK: } +// CHECK: llvm.return +// CHECK: } \ No newline at end of file Index: flang/test/Lower/OpenMP/simd.f90 =================================================================== --- /dev/null +++ flang/test/Lower/OpenMP/simd.f90 @@ -0,0 +1,19 @@ +! Tests for 2.9.3.1 Simd + +! RUN: bbc -fopenmp -emit-fir %s -o - | FileCheck %s + +!CHECK-LABEL: func @_QPsimdloop() +subroutine simdloop +integer :: i + +!$OMP SIMD +! CHECK: %[[LB:.*]] = arith.constant 1 : i32 +! CHECK-NEXT: %[[UB:.*]] = arith.constant 9 : i32 +! CHECK-NEXT: %[[STEP:.*]] = arith.constant 1 : i32 +! CHECK-NEXT: omp.simdloop (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) step (%[[STEP]]) { +do i=1, 9 + ! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[I]]) : (!fir.ref, i32) -> i1 + print*, i +end do +!$OMP END SIMD +end subroutine