Skip to content

Commit 5228c2c

Browse files
authored
[flang][FIR] add fir.is_assumed_size operation (#93853)
Assumed-rank fir.box/class may describe assumed-size array. This case needs special handling in SELECT RANK. It is not possible to generate FIR code to detect that a fir.box is an assumed-size (the way to detect that is to check that upper dimension extent is -1 in the descriptor). Instead of emitting a runtime call directly in lowering, add an operation that can later be lowered to a runtime call or inline code when the descriptor layout is known.
1 parent f49d26b commit 5228c2c

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

flang/include/flang/Optimizer/Dialect/FIROps.td

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,23 @@ def fir_BoxIsArrayOp : fir_SimpleOp<"box_isarray", [NoMemoryEffect]> {
11711171
let results = (outs BoolLike);
11721172
}
11731173

1174+
def fir_IsAssumedSizeOp : fir_SimpleOp<"is_assumed_size", [NoMemoryEffect]> {
1175+
let summary = "detect if a boxed value is an assumed-size array";
1176+
1177+
let description = [{
1178+
Fir box SSA values may describe assumed-size arrays. This operation
1179+
allows detecting this, even for assumed-rank box.
1180+
1181+
```
1182+
%a = fir.is_assumed_size %b : (!fir.box<!fir.array<*:f64>>) -> i1
1183+
```
1184+
}];
1185+
1186+
let arguments = (ins BoxOrClassType:$val);
1187+
1188+
let results = (outs BoolLike);
1189+
}
1190+
11741191
def fir_BoxIsPtrOp : fir_SimpleOp<"box_isptr", [NoMemoryEffect]> {
11751192
let summary = "is the boxed value a POINTER?";
11761193

flang/test/Fir/fir-ops.fir

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,3 +912,14 @@ func.func @test_rebox_assumed_rank(%arg0: !fir.box<!fir.array<*:f32>> ) {
912912
// CHECK: fir.rebox_assumed_rank %[[A]] lbs ones : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.array<*:f32>>
913913
// CHECK: fir.rebox_assumed_rank %[[A]] lbs zeroes : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.array<*:f32>>
914914
// CHECK: fir.rebox_assumed_rank %[[A]] lbs preserve : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.array<*:f32>>
915+
916+
func.func @test_is_assumed_size(%arg0: !fir.class<!fir.array<*:none>>, %arg1 : !fir.box<!fir.array<?xf32>>) {
917+
%1 = fir.is_assumed_size %arg0 : (!fir.class<!fir.array<*:none>>) -> i1
918+
%2 = fir.is_assumed_size %arg1 : (!fir.box<!fir.array<?xf32>>) -> i1
919+
return
920+
}
921+
// CHECK-LABEL: func.func @test_is_assumed_size(
922+
// CHECK-SAME: %[[A:.*]]: !fir.class<!fir.array<*:none>>,
923+
// CHECK-SAME: %[[B:.*]]: !fir.box<!fir.array<?xf32>>)
924+
// CHECK: fir.is_assumed_size %[[A]] : (!fir.class<!fir.array<*:none>>) -> i1
925+
// CHECK: fir.is_assumed_size %[[B]] : (!fir.box<!fir.array<?xf32>>) -> i1

flang/test/Fir/invalid.fir

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,3 +1002,11 @@ func.func @bad_rebox_assumed_rank_3(%arg0: !fir.box<!fir.array<*:f32>> ) {
10021002
%1 = fir.rebox_assumed_rank %arg0 lbs ones : (!fir.box<!fir.array<*:f32>>) -> !fir.box<!fir.array<*:i32>>
10031003
return
10041004
}
1005+
1006+
// -----
1007+
1008+
func.func @bad_is_assumed_size(%arg0: !fir.ref<!fir.array<*:none>>) {
1009+
// expected-error@+1{{op operand #0 must be box or class, but got '!fir.ref<!fir.array<*:none>>'}}
1010+
%1 = fir.is_assumed_size %arg0 : (!fir.ref<!fir.array<*:none>>) -> i1
1011+
return
1012+
}

0 commit comments

Comments
 (0)