[flang-commits] [flang] [flang][OpenMP] Lower DO, SIMD, and DO SIMD metadirective variants (PR #218555)
via flang-commits
flang-commits at lists.llvm.org
Thu Aug 27 22:02:14 PDT 2026
================
@@ -0,0 +1,883 @@
+! Test lowering of metadirectives with ordinary loop-associated variants.
+
+! RUN: %flang_fc1 -fopenmp -emit-hlfir -fopenmp-version=52 %s -o - | FileCheck %s
+
+! CHECK: #[[UNROLL:loop_unroll[0-9]*]] =
+! CHECK-SAME: #llvm.loop_unroll<disable = false, count = 4 : i64>
+! CHECK: #[[VECTORIZE:loop_vectorize[0-9]*]] =
+! CHECK-SAME: #llvm.loop_vectorize<disable = false>
+! CHECK: #[[UNROLL_ANNOTATION:loop_annotation[0-9]*]] =
+! CHECK-SAME: #llvm.loop_annotation<unroll = #[[UNROLL]]>
+! CHECK: #[[VECTOR_ANNOTATION:loop_annotation[0-9]*]] =
+! CHECK-SAME: #llvm.loop_annotation<vectorize = #[[VECTORIZE]]>
+
+! CHECK-LABEL: func.func @_QPtest_do(
+! CHECK-NOT: omp.parallel
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK: omp.wsloop private(@_QFtest_doEi_private_i32 {{.*}} ->
+! CHECK-SAME: %[[DO_PRIVATE:.*]] : !fir.ref<i32>)
+! CHECK: omp.loop_nest (%[[DO_IV:.*]]) :
+! CHECK: %[[DO_PRIVATE_DECL:.*]]:2 =
+! CHECK-SAME: hlfir.declare %[[DO_PRIVATE]]
+! CHECK: hlfir.assign %[[DO_IV]] to %[[DO_PRIVATE_DECL]]#0
+! CHECK: %[[DO_VALUE:.*]] =
+! CHECK-SAME: fir.load %[[DO_PRIVATE_DECL]]#0
+! CHECK: %[[DO_INDEX:.*]] =
+! CHECK-SAME: fir.load %[[DO_PRIVATE_DECL]]#0
+! CHECK: %[[DO_INDEX_I64:.*]] = fir.convert %[[DO_INDEX]]
+! CHECK-NOT: {{^ *}}}
+! CHECK: %[[DO_ELEMENT:.*]] = hlfir.designate
+! CHECK-SAME: (%[[DO_INDEX_I64]])
+! CHECK: hlfir.assign %[[DO_VALUE]] to %[[DO_ELEMENT]]
+! CHECK: omp.yield
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK: return
+subroutine test_do(n, a)
+ integer :: n, a(n), i
+ !$omp metadirective &
+ !$omp & when(implementation={vendor(llvm)}: do) &
+ !$omp & otherwise(nothing)
+ do i = 1, n
+ a(i) = i
+ end do
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_simd(
+! CHECK-NOT: omp.wsloop
+! CHECK: omp.simd linear(
+! CHECK: omp.loop_nest
+! CHECK: hlfir.assign
+! CHECK: omp.yield
+! CHECK-NOT: fir.do_loop
+! CHECK: fir.load
+! CHECK: hlfir.assign
+! CHECK: return
+subroutine test_simd(n, a, after)
+ integer :: n, a(n), after, i
+ !$omp metadirective &
+ !$omp & when(implementation={vendor(llvm)}: simd) &
+ !$omp & otherwise(nothing)
+ do i = 1, n
+ a(i) = i
+ end do
+ after = i
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_do_simd(
+! CHECK-NOT: omp.parallel
+! CHECK: omp.wsloop
+! CHECK: omp.simd linear(
+! CHECK: omp.loop_nest
+! CHECK: hlfir.assign
+! CHECK: omp.yield
+! CHECK: return
+subroutine test_do_simd(n, a)
+ integer :: n, a(n), i
+ !$omp metadirective &
+ !$omp & when(implementation={vendor(llvm)}: do simd) &
+ !$omp & otherwise(nothing)
+ do i = 1, n
+ a(i) = i
+ end do
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_begin_do(
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK: fir.if {{.*}} {
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK: omp.wsloop private(@_QFtest_begin_doEi_private_i32 {{.*}} ->
+! CHECK-SAME: %[[BEGIN_DO_PRIVATE:.*]] : !fir.ref<i32>)
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK: omp.loop_nest (%[[BEGIN_DO_IV:.*]]) :
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK: %[[BEGIN_DO_PRIVATE_DECL:.*]]:2 =
+! CHECK-SAME: hlfir.declare %[[BEGIN_DO_PRIVATE]]
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK: hlfir.assign %[[BEGIN_DO_IV]] to
+! CHECK-SAME: %[[BEGIN_DO_PRIVATE_DECL]]#0
+! CHECK: %[[BEGIN_DO_VALUE:.*]] =
+! CHECK-SAME: fir.load %[[BEGIN_DO_PRIVATE_DECL]]#0
+! CHECK: %[[BEGIN_DO_INDEX:.*]] =
+! CHECK-SAME: fir.load %[[BEGIN_DO_PRIVATE_DECL]]#0
+! CHECK: %[[BEGIN_DO_INDEX_I64:.*]] =
+! CHECK-SAME: fir.convert %[[BEGIN_DO_INDEX]]
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK-NOT: {{^ *}}}
+! CHECK: %[[BEGIN_DO_ELEMENT:.*]] = hlfir.designate
+! CHECK-SAME: (%[[BEGIN_DO_INDEX_I64]])
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK-NOT: {{^ *}}}
+! CHECK: hlfir.assign %[[BEGIN_DO_VALUE]] to
+! CHECK-SAME: %[[BEGIN_DO_ELEMENT]]
+! CHECK-NOT: omp.wsloop
+! CHECK-NOT: omp.loop_nest
+! CHECK-NOT: fir.do_loop
+! CHECK: } else {
+! CHECK-NOT: omp.
+! CHECK-NOT: fir.do_loop
+! CHECK: fir.do_loop %[[BEGIN_DO_FALLBACK_IV:.*]] =
+! CHECK: fir.store %[[BEGIN_DO_FALLBACK_IV]] to
+! CHECK-SAME: %[[BEGIN_DO_FALLBACK_IV_ADDR:.*]]
+! CHECK: %[[BEGIN_DO_FALLBACK_VALUE:.*]] =
----------------
MattPD wrote:
The new positive checks shorten the existing closing-brace negative's interval, so it no longer proves that the fallback body stays inside `fir.do_loop`. The current checker accepts verifier-valid HLFIR with the loads and assignment after the loop closes. The prior checker rejects the same IR.
Could each of the three rewritten fallback blocks add a closing-brace `CHECK-NOT` after each of these operations: the loop header, IV store, value load, and index load? The twelve guards accept the current output and reject the verifier-valid body-outside IR.
https://github.com/llvm/llvm-project/pull/218555
More information about the flang-commits
mailing list