Skip to content

Commit 15e59a7

Browse files
committed
Fix crash lowering fir::EmboxOp whithout shape
This only affects POINTERs (which should not be initialized) and NULL allocatables so the actual contents of the shape doesn't matter. This is just so the embox operation is converted to LLVMIR correctly.
1 parent 50c6e3a commit 15e59a7

6 files changed

+91
-7
lines changed

flang/lib/Lower/OpenMP/PrivateReductionUtils.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,25 @@ fir::ShapeShiftOp Fortran::lower::omp::getShapeShift(fir::FirOpBuilder &builder,
115115
return shapeShift;
116116
}
117117

118+
static mlir::Value generateZeroShapeForRank(fir::FirOpBuilder &builder,
119+
mlir::Location loc,
120+
mlir::Value moldArg) {
121+
mlir::Type moldVal = fir::unwrapRefType(moldArg.getType());
122+
mlir::Type eleType = fir::dyn_cast_ptrOrBoxEleTy(moldVal);
123+
fir::SequenceType seqTy =
124+
mlir::dyn_cast_if_present<fir::SequenceType>(eleType);
125+
if (!seqTy)
126+
return nullptr;
127+
128+
unsigned rank = seqTy.getShape().size();
129+
mlir::Value zero =
130+
builder.createIntegerConstant(loc, builder.getIndexType(), 0);
131+
mlir::SmallVector<mlir::Value> dims;
132+
dims.resize(rank, zero);
133+
mlir::Type shapeTy = fir::ShapeType::get(builder.getContext(), rank);
134+
return builder.create<fir::ShapeOp>(loc, shapeTy, dims);
135+
}
136+
118137
void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
119138
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type argType,
120139
mlir::Value scalarInitValue, mlir::Block *initBlock,
@@ -156,8 +175,12 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
156175
/*withElseRegion=*/true);
157176
builder.setInsertionPointToStart(&ifOp.getThenRegion().front());
158177
// just embox the null address and return
178+
// we have to give the embox a shape so that the LLVM box structure has the
179+
// right rank. This returns nullptr if the types don't match.
180+
mlir::Value shape = generateZeroShapeForRank(builder, loc, moldArg);
181+
159182
mlir::Value nullBox =
160-
builder.create<fir::EmboxOp>(loc, ty, addr, /*shape=*/mlir::Value{},
183+
builder.create<fir::EmboxOp>(loc, ty, addr, shape,
161184
/*slice=*/mlir::Value{}, lenParams);
162185
builder.create<fir::StoreOp>(loc, nullBox, boxAlloca);
163186
return ifOp;
@@ -174,9 +197,17 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
174197
// The initial state of a private pointer is undefined so we don't need to
175198
// match the mold argument (OpenMP 5.2 end of page 106).
176199
if (isPrivate && mlir::isa<fir::PointerType>(boxTy.getEleTy())) {
200+
// we need a shape with the right rank so that the embox op is lowered
201+
// to an llvm struct of the right type. This returns nullptr if the types
202+
// aren't right.
203+
mlir::Value shape = generateZeroShapeForRank(builder, loc, moldArg);
177204
// Just incase, do initialize the box with a null value
178205
mlir::Value null = builder.createNullConstant(loc, boxTy.getEleTy());
179-
mlir::Value nullBox = builder.create<fir::EmboxOp>(loc, boxTy, null);
206+
mlir::Value nullBox;
207+
if (shape)
208+
nullBox = builder.create<fir::EmboxOp>(loc, boxTy, null, shape);
209+
else
210+
nullBox = builder.create<fir::EmboxOp>(loc, boxTy, null);
180211
builder.create<fir::StoreOp>(loc, nullBox, boxAlloca);
181212
yield(boxAlloca);
182213
return;

flang/test/Lower/OpenMP/delayed-privatization-allocatable-array.f90

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ subroutine delayed_privatization_private(var1, l1)
2727
! CHECK-NEXT: %[[ALLOC_COND:.*]] = arith.cmpi eq, %[[PRIV_ARG_ADDR]], %[[C0]] : i64
2828

2929
! CHECK-NEXT: fir.if %[[ALLOC_COND]] {
30-
! CHECK-NEXT: %[[EMBOX_2:.*]] = fir.embox %[[PRIV_ARG_BOX]]
30+
! CHECK-NEXT: %[[C0_2:.*]] = arith.constant 0 : index
31+
! CHECK-NEXT: %[[SHAPE:.*]] = fir.shape %[[C0_2]]
32+
! CHECK-NEXT: %[[EMBOX_2:.*]] = fir.embox %[[PRIV_ARG_BOX]](%[[SHAPE]])
3133
! CHECK-NEXT: fir.store %[[EMBOX_2]] to %[[PRIV_ALLOC]]
3234
! CHECK-NEXT: } else {
3335
! CHECK-NEXT: %[[C0:.*]] = arith.constant 0 : index

flang/test/Lower/OpenMP/parallel-reduction-allocatable-array.f90

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ program reduce
3030
! CHECK: %[[C0_I64:.*]] = arith.constant 0 : i64
3131
! CHECK: %[[IS_NULL:.*]] = arith.cmpi eq, %[[ADDRI]], %[[C0_I64]] : i64
3232
! CHECK: fir.if %[[IS_NULL]] {
33-
! CHECK: %[[NULL_BOX:.*]] = fir.embox %[[ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
33+
! CHECK: %[[C0_INDEX:.*]] = arith.constant 0 : index
34+
! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0_INDEX]]
35+
! CHECK: %[[NULL_BOX:.*]] = fir.embox %[[ADDR]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
3436
! CHECK: fir.store %[[NULL_BOX]] to %[[ALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
3537
! CHECK: } else {
3638
! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index

flang/test/Lower/OpenMP/parallel-reduction-pointer-array.f90

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ program reduce
3131
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
3232
! CHECK: %[[VAL_7:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_6]] : i64
3333
! CHECK: fir.if %[[VAL_7]] {
34-
! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]] : (!fir.ptr<!fir.array<?xi32>>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
34+
! CHECK: %[[C0:.*]] = arith.constant 0 : index
35+
! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]]
36+
! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]](%[[SHAPE]]) : (!fir.ptr<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
3537
! CHECK: fir.store %[[VAL_8]] to %[[ALLOC]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
3638
! CHECK: } else {
3739
! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
! Regression test for crash compiling privatizer for a pointer to an array.
2+
! The crash was because the fir.embox was not given a shape but it needs one.
3+
4+
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
5+
6+
! ALLOCATABLE case (2nd subroutine)
7+
!CHECK-LABEL: omp.private {type = firstprivate}
8+
!CHECK-SAME: @{{.*}} : !fir.box<!fir.heap<!fir.array<?x!fir.type<{{.*}}>>>> init {
9+
!CHECK: if %{{.*}} {
10+
!CHECK: %[[SHAPE:.*]] = fir.shape
11+
!CHECK: %[[BOX:.*]] = fir.embox %{{.*}}(%[[SHAPE]])
12+
!CHECK: } else {
13+
14+
! POINTER case (1st subroutine)
15+
!CHECK-LABEL: omp.private {type = firstprivate}
16+
!CHECK-SAME: @{{.*}} : !fir.box<!fir.ptr<!fir.array<?x!fir.type<{{.*}}>>>> init {
17+
!CHECK: %[[SHAPE:.*]] = fir.shape
18+
!CHECK: %[[ADDR:.*]] = fir.zero_bits
19+
!CHECK: %[[BOX:.*]] = fir.embox %[[ADDR]](%[[SHAPE]])
20+
21+
subroutine pointer_to_array_derived
22+
type t
23+
integer :: i
24+
end type
25+
type(t), pointer :: a(:)
26+
allocate(a(1))
27+
a(1)%i = 2
28+
!$omp parallel firstprivate(a)
29+
if (a(1)%i/=2) stop 2
30+
!$omp end parallel
31+
end subroutine
32+
33+
subroutine allocatable_array_derived
34+
type t
35+
integer :: i
36+
end type
37+
type(t), allocatable :: a(:)
38+
allocate(a(1))
39+
a(1)%i = 2
40+
!$omp parallel firstprivate(a)
41+
if (a(1)%i/=2) stop 2
42+
!$omp end parallel
43+
end subroutine

flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ program reduce15
4444
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
4545
! CHECK: %[[VAL_7:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_6]] : i64
4646
! CHECK: fir.if %[[VAL_7]] {
47-
! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
47+
! CHECK: %[[C0:.*]] = arith.constant 0 : index
48+
! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]]
49+
! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
4850
! CHECK: fir.store %[[VAL_8]] to %[[ALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
4951
! CHECK: } else {
5052
! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
@@ -103,7 +105,9 @@ program reduce15
103105
! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
104106
! CHECK: %[[VAL_7:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_6]] : i64
105107
! CHECK: fir.if %[[VAL_7]] {
106-
! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
108+
! CHECK: %[[C0:.*]] = arith.constant 0 : index
109+
! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]]
110+
! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
107111
! CHECK: fir.store %[[VAL_8]] to %[[ALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
108112
! CHECK: } else {
109113
! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index

0 commit comments

Comments
 (0)