From 5630ec5d1e41a8a1529ae1ac540aa866ab3285d1 Mon Sep 17 00:00:00 2001 From: Dominik Adamski Date: Tue, 23 Jan 2024 15:10:01 -0600 Subject: [PATCH 1/2] [Flang][OpenMP] Use simdloop operation only for omp simd pragma OpenMP standard differentiates between omp simd (2.9.3.1) and omp do/for simd (2.9.3.2 for OpenMP 5.0 standard) pragmas. The first one describes the loop which needs to be vectorized. The second pragma describes the loop which needs to be workshared between existing threads. Each thread can use SIMD instructions to execute its chunk of the loop. That's why we need to model !$omp simd do-loop as omp.simdloop operation and add compiler hints for vectorization. The worksharing loop: !$omp do simd do-loop should be represented as worksharing loop. Currently Flang denotes both type of OpenMP pragmas by omp.simdloop operation. In consequence we cannot differentiate between: !$omp parallel simd do-loop and !$omp parallel do simd do-loop The second loop should be workshared between multiple threads. The first one describes the loop which needs to be redundantly executed by multiple threads. Current Flang implementation does not perform worksharing for `!$omp do simd` pragma and generates valid code only for first case. --- flang/lib/Lower/OpenMP.cpp | 50 +++++++++++++++++-- flang/test/Lower/OpenMP/FIR/if-clause.f90 | 34 +++++-------- flang/test/Lower/OpenMP/FIR/loop-combined.f90 | 6 +-- .../Lower/OpenMP/Todo/omp-do-simd-aligned.f90 | 16 ++++++ .../Lower/OpenMP/Todo/omp-do-simd-linear.f90 | 14 ++++++ .../Lower/OpenMP/Todo/omp-do-simd-safelen.f90 | 14 ++++++ .../Lower/OpenMP/Todo/omp-do-simd-simdlen.f90 | 14 ++++++ flang/test/Lower/OpenMP/if-clause.f90 | 34 +++++-------- flang/test/Lower/OpenMP/loop-combined.f90 | 6 +-- 9 files changed, 137 insertions(+), 51 deletions(-) create mode 100644 flang/test/Lower/OpenMP/Todo/omp-do-simd-aligned.f90 create mode 100644 flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90 create mode 100644 flang/test/Lower/OpenMP/Todo/omp-do-simd-safelen.f90 create mode 100644 flang/test/Lower/OpenMP/Todo/omp-do-simd-simdlen.f90 diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index d2215f4d1bf1c..0888b25f1c59d 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -3311,6 +3311,43 @@ static void createWsLoop(Fortran::lower::AbstractConverter &converter, /*outer=*/false, &dsp); } +static void createSimdWsLoop( + Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &eval, llvm::omp::Directive ompDirective, + const Fortran::parser::OmpClauseList &beginClauseList, + const Fortran::parser::OmpClauseList *endClauseList, mlir::Location loc) { + ClauseProcessor cp(converter, beginClauseList); + cp.processTODO< + Fortran::parser::OmpClause::Aligned, Fortran::parser::OmpClause::Allocate, + Fortran::parser::OmpClause::Linear, Fortran::parser::OmpClause::Safelen, + Fortran::parser::OmpClause::Simdlen, Fortran::parser::OmpClause::Order>( + loc, ompDirective); + // TODO: Add support for vectorization - add vectorization hints inside loop + // body. + // OpenMP standard does not specify the length of vector instructions. + // Currently we safely assume that for !$omp do simd pragma the SIMD length + // is equal to 1 (i.e. we generate standard workshare loop). + // When support for vectorization is enabled, then we need to add handling of + // if clause. Currently if clause can be skipped because we always assume + // SIMD length = 1. + createWsLoop(converter, eval, ompDirective, beginClauseList, endClauseList, + loc); +} + +static bool isWorkshareSimdConstruct(llvm::omp::Directive ompDirective) { + switch (ompDirective) { + default: + return false; + case llvm::omp::OMPD_distribute_parallel_do_simd: + case llvm::omp::OMPD_do_simd: + case llvm::omp::OMPD_parallel_do_simd: + case llvm::omp::OMPD_target_parallel_do_simd: + case llvm::omp::OMPD_target_teams_distribute_parallel_do_simd: + case llvm::omp::OMPD_teams_distribute_parallel_do_simd: + return true; + } +} + static void genOMP(Fortran::lower::AbstractConverter &converter, Fortran::lower::SymMap &symTable, Fortran::semantics::SemanticsContext &semanticsContext, @@ -3377,10 +3414,17 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, ")"); } - // 2.9.3.1 SIMD construct if (llvm::omp::allSimdSet.test(ompDirective)) { - createSimdLoop(converter, eval, ompDirective, loopOpClauseList, - currentLocation); + if (isWorkshareSimdConstruct(ompDirective)) { + // 2.9.3.2 Workshare SIMD construct + createSimdWsLoop(converter, eval, ompDirective, loopOpClauseList, + endClauseList, currentLocation); + + } else { + // 2.9.3.1 SIMD construct + createSimdLoop(converter, eval, ompDirective, loopOpClauseList, + currentLocation); + } } else { createWsLoop(converter, eval, ompDirective, loopOpClauseList, endClauseList, currentLocation); diff --git a/flang/test/Lower/OpenMP/FIR/if-clause.f90 b/flang/test/Lower/OpenMP/FIR/if-clause.f90 index ef98a00f10dbd..a1235be8e61ea 100644 --- a/flang/test/Lower/OpenMP/FIR/if-clause.f90 +++ b/flang/test/Lower/OpenMP/FIR/if-clause.f90 @@ -28,7 +28,7 @@ program main ! ---------------------------------------------------------------------------- ! DO SIMD ! ---------------------------------------------------------------------------- - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp do simd @@ -36,15 +36,13 @@ program main end do !$omp end do simd - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp do simd if(.true.) do i = 1, 10 end do !$omp end do simd - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp do simd if(simd: .true.) do i = 1, 10 end do @@ -103,7 +101,7 @@ program main ! CHECK: omp.parallel ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp parallel do simd @@ -113,8 +111,7 @@ program main ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp parallel do simd if(.true.) do i = 1, 10 end do @@ -122,8 +119,7 @@ program main ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp parallel do simd if(parallel: .true.) if(simd: .false.) do i = 1, 10 end do @@ -131,7 +127,7 @@ program main ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp parallel do simd if(parallel: .true.) @@ -142,8 +138,7 @@ program main ! CHECK: omp.parallel ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp parallel do simd if(simd: .true.) do i = 1, 10 end do @@ -306,7 +301,7 @@ program main ! CHECK: omp.parallel ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp target parallel do simd @@ -318,8 +313,7 @@ program main ! CHECK-SAME: if({{.*}}) ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp target parallel do simd if(.true.) do i = 1, 10 end do @@ -329,8 +323,7 @@ program main ! CHECK-SAME: if({{.*}}) ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp target parallel do simd if(target: .true.) if(parallel: .false.) & !$omp& if(simd: .true.) do i = 1, 10 @@ -342,7 +335,7 @@ program main ! CHECK: omp.parallel ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp target parallel do simd if(target: .true.) @@ -355,8 +348,7 @@ program main ! CHECK-SAME: { ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp target parallel do simd if(parallel: .true.) if(simd: .false.) do i = 1, 10 end do diff --git a/flang/test/Lower/OpenMP/FIR/loop-combined.f90 b/flang/test/Lower/OpenMP/FIR/loop-combined.f90 index 117f7d625270e..a6cec1beb49c8 100644 --- a/flang/test/Lower/OpenMP/FIR/loop-combined.f90 +++ b/flang/test/Lower/OpenMP/FIR/loop-combined.f90 @@ -23,7 +23,7 @@ program main ! ---------------------------------------------------------------------------- ! DO SIMD ! ---------------------------------------------------------------------------- - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop !$omp do simd do i = 1, 10 end do @@ -33,7 +33,7 @@ program main ! PARALLEL DO SIMD ! ---------------------------------------------------------------------------- ! CHECK: omp.parallel - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop !$omp parallel do simd do i = 1, 10 end do @@ -54,7 +54,7 @@ program main ! ---------------------------------------------------------------------------- ! CHECK: omp.target ! CHECK: omp.parallel - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop !$omp target parallel do simd do i = 1, 10 end do diff --git a/flang/test/Lower/OpenMP/Todo/omp-do-simd-aligned.f90 b/flang/test/Lower/OpenMP/Todo/omp-do-simd-aligned.f90 new file mode 100644 index 0000000000000..b62c54182442a --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/omp-do-simd-aligned.f90 @@ -0,0 +1,16 @@ +! This test checks lowering of OpenMP do simd aligned() pragma + +! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s +subroutine testDoSimdAligned(int_array) + use iso_c_binding + type(c_ptr) :: int_array +!CHECK: not yet implemented: Unhandled clause ALIGNED in DO SIMD construct +!$omp do simd aligned(int_array) + do index_ = 1, 10 + call c_test_call(int_array) + end do +!$omp end do simd + +end subroutine testDoSimdAligned + diff --git a/flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90 b/flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90 new file mode 100644 index 0000000000000..a9e0446ec8c34 --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90 @@ -0,0 +1,14 @@ +! This test checks lowering of OpenMP do simd linear() pragma + +! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s +subroutine testDoSimdLinear(int_array) + integer :: int_array(*) +!CHECK: not yet implemented: Unhandled clause LINEAR in DO SIMD construct +!$omp do simd linear(int_array) + do index_ = 1, 10 + end do +!$omp end do simd + +end subroutine testDoSimdLinear + diff --git a/flang/test/Lower/OpenMP/Todo/omp-do-simd-safelen.f90 b/flang/test/Lower/OpenMP/Todo/omp-do-simd-safelen.f90 new file mode 100644 index 0000000000000..054eb52ea170a --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/omp-do-simd-safelen.f90 @@ -0,0 +1,14 @@ +! This test checks lowering of OpenMP do simd safelen() pragma + +! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s +subroutine testDoSimdSafelen(int_array) + integer :: int_array(*) +!CHECK: not yet implemented: Unhandled clause SAFELEN in DO SIMD construct +!$omp do simd safelen(4) + do index_ = 1, 10 + end do +!$omp end do simd + +end subroutine testDoSimdSafelen + diff --git a/flang/test/Lower/OpenMP/Todo/omp-do-simd-simdlen.f90 b/flang/test/Lower/OpenMP/Todo/omp-do-simd-simdlen.f90 new file mode 100644 index 0000000000000..bd00b6f336c93 --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/omp-do-simd-simdlen.f90 @@ -0,0 +1,14 @@ +! This test checks lowering of OpenMP do simd simdlen() pragma + +! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s +! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s +subroutine testDoSimdSimdlen(int_array) + integer :: int_array(*) +!CHECK: not yet implemented: Unhandled clause SIMDLEN in DO SIMD construct +!$omp do simd simdlen(4) + do index_ = 1, 10 + end do +!$omp end do simd + +end subroutine testDoSimdSimdlen + diff --git a/flang/test/Lower/OpenMP/if-clause.f90 b/flang/test/Lower/OpenMP/if-clause.f90 index 032009add3153..f982bf67b0722 100644 --- a/flang/test/Lower/OpenMP/if-clause.f90 +++ b/flang/test/Lower/OpenMP/if-clause.f90 @@ -28,7 +28,7 @@ program main ! ---------------------------------------------------------------------------- ! DO SIMD ! ---------------------------------------------------------------------------- - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp do simd @@ -36,15 +36,13 @@ program main end do !$omp end do simd - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp do simd if(.true.) do i = 1, 10 end do !$omp end do simd - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp do simd if(simd: .true.) do i = 1, 10 end do @@ -103,7 +101,7 @@ program main ! CHECK: omp.parallel ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp parallel do simd @@ -113,8 +111,7 @@ program main ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp parallel do simd if(.true.) do i = 1, 10 end do @@ -122,8 +119,7 @@ program main ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp parallel do simd if(parallel: .true.) if(simd: .false.) do i = 1, 10 end do @@ -131,7 +127,7 @@ program main ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp parallel do simd if(parallel: .true.) @@ -142,8 +138,7 @@ program main ! CHECK: omp.parallel ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp parallel do simd if(simd: .true.) do i = 1, 10 end do @@ -306,7 +301,7 @@ program main ! CHECK: omp.parallel ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp target parallel do simd @@ -318,8 +313,7 @@ program main ! CHECK-SAME: if({{.*}}) ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp target parallel do simd if(.true.) do i = 1, 10 end do @@ -329,8 +323,7 @@ program main ! CHECK-SAME: if({{.*}}) ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp target parallel do simd if(target: .true.) if(parallel: .false.) & !$omp& if(simd: .true.) do i = 1, 10 @@ -342,7 +335,7 @@ program main ! CHECK: omp.parallel ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop ! CHECK-NOT: if({{.*}}) ! CHECK-SAME: { !$omp target parallel do simd if(target: .true.) @@ -355,8 +348,7 @@ program main ! CHECK-SAME: { ! CHECK: omp.parallel ! CHECK-SAME: if({{.*}}) - ! CHECK: omp.simdloop - ! CHECK-SAME: if({{.*}}) + ! CHECK: omp.wsloop !$omp target parallel do simd if(parallel: .true.) if(simd: .false.) do i = 1, 10 end do diff --git a/flang/test/Lower/OpenMP/loop-combined.f90 b/flang/test/Lower/OpenMP/loop-combined.f90 index 960e9518127d7..70488b6a769ce 100644 --- a/flang/test/Lower/OpenMP/loop-combined.f90 +++ b/flang/test/Lower/OpenMP/loop-combined.f90 @@ -23,7 +23,7 @@ program main ! ---------------------------------------------------------------------------- ! DO SIMD ! ---------------------------------------------------------------------------- - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop !$omp do simd do i = 1, 10 end do @@ -33,7 +33,7 @@ program main ! PARALLEL DO SIMD ! ---------------------------------------------------------------------------- ! CHECK: omp.parallel - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop !$omp parallel do simd do i = 1, 10 end do @@ -54,7 +54,7 @@ program main ! ---------------------------------------------------------------------------- ! CHECK: omp.target ! CHECK: omp.parallel - ! CHECK: omp.simdloop + ! CHECK: omp.wsloop !$omp target parallel do simd do i = 1, 10 end do From 7b2d7f74552364b79091b249ebd9ed009bb59d4d Mon Sep 17 00:00:00 2001 From: Dominik Adamski Date: Fri, 26 Jan 2024 07:37:23 -0600 Subject: [PATCH 2/2] Applied Sergio's remark --- flang/lib/Lower/OpenMP.cpp | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 0888b25f1c59d..94ab0ec43c300 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -3334,20 +3334,6 @@ static void createSimdWsLoop( loc); } -static bool isWorkshareSimdConstruct(llvm::omp::Directive ompDirective) { - switch (ompDirective) { - default: - return false; - case llvm::omp::OMPD_distribute_parallel_do_simd: - case llvm::omp::OMPD_do_simd: - case llvm::omp::OMPD_parallel_do_simd: - case llvm::omp::OMPD_target_parallel_do_simd: - case llvm::omp::OMPD_target_teams_distribute_parallel_do_simd: - case llvm::omp::OMPD_teams_distribute_parallel_do_simd: - return true; - } -} - static void genOMP(Fortran::lower::AbstractConverter &converter, Fortran::lower::SymMap &symTable, Fortran::semantics::SemanticsContext &semanticsContext, @@ -3414,17 +3400,15 @@ static void genOMP(Fortran::lower::AbstractConverter &converter, ")"); } - if (llvm::omp::allSimdSet.test(ompDirective)) { - if (isWorkshareSimdConstruct(ompDirective)) { - // 2.9.3.2 Workshare SIMD construct - createSimdWsLoop(converter, eval, ompDirective, loopOpClauseList, - endClauseList, currentLocation); + if (llvm::omp::allDoSimdSet.test(ompDirective)) { + // 2.9.3.2 Workshare SIMD construct + createSimdWsLoop(converter, eval, ompDirective, loopOpClauseList, + endClauseList, currentLocation); - } else { - // 2.9.3.1 SIMD construct - createSimdLoop(converter, eval, ompDirective, loopOpClauseList, - currentLocation); - } + } else if (llvm::omp::allSimdSet.test(ompDirective)) { + // 2.9.3.1 SIMD construct + createSimdLoop(converter, eval, ompDirective, loopOpClauseList, + currentLocation); } else { createWsLoop(converter, eval, ompDirective, loopOpClauseList, endClauseList, currentLocation);