Skip to content

Commit 985395c

Browse files
Krish GuptaKrish Gupta
authored andcommitted
[flang][OpenMP] Fix firstprivate in DO SIMD with lastprivate
Use wsloopItemDSP instead of simdItemDSP in genCompositeDoSimd to ensure firstprivate clauses are properly handled for the composite DO SIMD construct. Fixes #168306
1 parent af0fcf8 commit 985395c

File tree

3 files changed

+134
-1
lines changed

3 files changed

+134
-1
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3324,7 +3324,7 @@ static mlir::omp::WsloopOp genCompositeDoSimd(
33243324
genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, simdItem,
33253325
loopNestClauseOps, iv,
33263326
{{wsloopOp, wsloopArgs}, {simdOp, simdArgs}},
3327-
llvm::omp::Directive::OMPD_do_simd, simdItemDSP);
3327+
llvm::omp::Directive::OMPD_do_simd, wsloopItemDSP);
33283328
return wsloopOp;
33293329
}
33303330

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
! Test runtime behavior of DO SIMD with firstprivate and lastprivate on same variable
2+
! This is the reproducer from issue #168306
3+
4+
! RUN: %flang_fc1 -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefix=LLVM
5+
! RUN: %flang -fopenmp %s -o %t && %t | FileCheck %s
6+
7+
! LLVM-LABEL: define {{.*}} @_QQmain
8+
program main
9+
integer :: a
10+
integer :: i
11+
12+
a = 10
13+
!$omp do simd lastprivate(a) firstprivate(a)
14+
do i = 1, 1
15+
! Inside loop: a should be 10 (from firstprivate initialization)
16+
! CHECK: main1 : a = 10
17+
print *, "main1 : a = ", a
18+
a = 20
19+
end do
20+
!$omp end do simd
21+
! After loop: a should be 20 (from lastprivate copy-out)
22+
! CHECK: main2 : a = 20
23+
print *, "main2 : a = ", a
24+
25+
call sub
26+
! CHECK: pass
27+
print *, 'pass'
28+
end program main
29+
30+
subroutine sub
31+
integer :: a
32+
integer :: i
33+
34+
a = 10
35+
!$omp do simd lastprivate(a) firstprivate(a)
36+
do i = 1, 1
37+
! Inside loop: a should be 10 (from firstprivate initialization)
38+
! CHECK: sub1 : a = 10
39+
print *, "sub1 : a = ", a
40+
a = 20
41+
end do
42+
!$omp end do simd
43+
! After loop: a should be 20 (from lastprivate copy-out)
44+
! CHECK: sub2 : a = 20
45+
print *, "sub2 : a = ", a
46+
end subroutine sub
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
! Test for DO SIMD with the same variable in both firstprivate and lastprivate clauses
2+
! This tests the fix for issue #168306
3+
4+
! RUN: %flang_fc1 -fopenmp -mmlir --openmp-enable-delayed-privatization-staging=true -emit-hlfir %s -o - | FileCheck %s
5+
6+
! Test case 1: Basic test with firstprivate + lastprivate on same variable
7+
! CHECK-LABEL: func.func @_QPdo_simd_first_last_same_var
8+
subroutine do_simd_first_last_same_var()
9+
integer :: a
10+
integer :: i
11+
a = 10
12+
13+
! CHECK: omp.wsloop
14+
! CHECK-SAME: private(@{{.*}}firstprivate{{.*}} %{{.*}} -> %[[FIRSTPRIV_A:.*]] : !fir.ref<i32>)
15+
! CHECK-NEXT: omp.simd
16+
! CHECK-SAME: private(@{{.*}} %{{.*}} -> %[[PRIV_A:.*]], @{{.*}} %{{.*}} -> %[[PRIV_I:.*]] : !fir.ref<i32>, !fir.ref<i32>)
17+
! CHECK-NEXT: omp.loop_nest (%[[IV:.*]]) : i32
18+
!$omp do simd firstprivate(a) lastprivate(a)
19+
do i = 1, 1
20+
! CHECK: %[[FIRSTPRIV_A_DECL:.*]]:2 = hlfir.declare %[[FIRSTPRIV_A]]
21+
! CHECK: %[[PRIV_A_DECL:.*]]:2 = hlfir.declare %[[PRIV_A]]
22+
! CHECK: %[[PRIV_I_DECL:.*]]:2 = hlfir.declare %[[PRIV_I]]
23+
! The private copy should be initialized from firstprivate (value 10)
24+
! and then modified to 20
25+
a = 20
26+
end do
27+
!$omp end do simd
28+
! After the loop, 'a' should be 20 due to lastprivate
29+
end subroutine do_simd_first_last_same_var
30+
31+
! Test case 2: Test with lastprivate and firstprivate in reverse order
32+
! CHECK-LABEL: func.func @_QPdo_simd_last_first_reverse
33+
subroutine do_simd_last_first_reverse()
34+
integer :: a
35+
integer :: i
36+
a = 10
37+
38+
! CHECK: omp.wsloop
39+
! CHECK-SAME: private(@{{.*}}firstprivate{{.*}} %{{.*}} -> %[[FIRSTPRIV_A:.*]] : !fir.ref<i32>)
40+
! CHECK-NEXT: omp.simd
41+
!$omp do simd lastprivate(a) firstprivate(a)
42+
do i = 1, 1
43+
a = 20
44+
end do
45+
!$omp end do simd
46+
end subroutine do_simd_last_first_reverse
47+
48+
! Test case 3: Multiple variables with mixed privatization
49+
! CHECK-LABEL: func.func @_QPdo_simd_multiple_vars
50+
subroutine do_simd_multiple_vars()
51+
integer :: a, b, c
52+
integer :: i
53+
a = 10
54+
b = 20
55+
c = 30
56+
57+
! CHECK: omp.wsloop
58+
! CHECK-SAME: private(@{{.*}}firstprivate{{.*}} %{{.*}} -> %{{.*}}, @{{.*}}firstprivate{{.*}} %{{.*}} -> %{{.*}} : !fir.ref<i32>, !fir.ref<i32>)
59+
! CHECK-NEXT: omp.simd
60+
!$omp do simd firstprivate(a, b) lastprivate(a) private(c)
61+
do i = 1, 5
62+
a = a + 1
63+
b = b + 1
64+
c = i
65+
end do
66+
!$omp end do simd
67+
end subroutine do_simd_multiple_vars
68+
69+
! Test case 4: Reproducer from issue #168306
70+
! CHECK-LABEL: func.func @_QPissue_168306_reproducer
71+
subroutine issue_168306_reproducer()
72+
integer :: a
73+
integer :: i
74+
a = 10
75+
76+
! CHECK: omp.wsloop
77+
! CHECK-SAME: private(@{{.*}}firstprivate{{.*}} %{{.*}} -> %[[FIRSTPRIV_A:.*]] : !fir.ref<i32>)
78+
! CHECK-NEXT: omp.simd
79+
!$omp do simd lastprivate(a) firstprivate(a)
80+
do i = 1, 1
81+
! Inside the loop, 'a' should start at 10 (from firstprivate)
82+
! This is the key behavior that was broken
83+
a = 20
84+
end do
85+
!$omp end do simd
86+
! After the loop, 'a' should be 20 (from lastprivate)
87+
end subroutine issue_168306_reproducer

0 commit comments

Comments
 (0)