diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -758,6 +758,7 @@ Optional:$shape, Optional:$slice, Variadic:$typeparams, + Optional:$tdesc, OptionalAttr:$accessMap ); @@ -767,14 +768,16 @@ OpBuilder<(ins "llvm::ArrayRef":$resultTypes, "mlir::Value":$memref, CArg<"mlir::Value", "{}">:$shape, CArg<"mlir::Value", "{}">:$slice, - CArg<"mlir::ValueRange", "{}">:$typeparams), + CArg<"mlir::ValueRange", "{}">:$typeparams, + CArg<"mlir::Value", "{}">:$tdesc), [{ return build($_builder, $_state, resultTypes, memref, shape, slice, - typeparams, mlir::AffineMapAttr{}); }]> + typeparams, tdesc, mlir::AffineMapAttr{}); }]> ]; let assemblyFormat = [{ $memref (`(` $shape^ `)`)? (`[` $slice^ `]`)? (`typeparams` $typeparams^)? - (`map` $accessMap^)? attr-dict `:` functional-type(operands, results) + (`tdesc` $tdesc^)? (`map` $accessMap^)? attr-dict `:` + functional-type(operands, results) }]; let hasVerifier = 1; @@ -1160,7 +1163,7 @@ ``` }]; - let arguments = (ins fir_BoxType:$val); + let arguments = (ins BoxOrClassType:$val); let results = (outs fir_TypeDescType); } diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -1145,6 +1145,8 @@ return emitOpError("shape must not be provided for a scalar"); if (getSlice() && !isArray) return emitOpError("slice must not be provided for a scalar"); + if (getTdesc() && !getResult().getType().isa()) + return emitOpError("tdesc must be used with fir.class result type"); return mlir::success(); } diff --git a/flang/test/Fir/fir-ops.fir b/flang/test/Fir/fir-ops.fir --- a/flang/test/Fir/fir-ops.fir +++ b/flang/test/Fir/fir-ops.fir @@ -819,3 +819,34 @@ // CHECK: fir.dispatch "proc3"(%[[CLASS]] : !fir.class>) (%[[INTARG]], %[[CLASS]] : i32, !fir.class>) {pass_arg_pos = 1 : i32} return } + + +// CHECK-LABEL: func.func @embox_tdesc +func.func @embox_tdesc(%arg0: !fir.class>>) { + %0 = fir.alloca i32 + %c1_i32 = arith.constant 1 : i32 + %1 = fir.convert %c1_i32 : (i32) -> index + %c10_i32 = arith.constant 10 : i32 + %2 = fir.convert %c10_i32 : (i32) -> index + %c1 = arith.constant 1 : index + %3 = fir.convert %1 : (index) -> i32 + %4:2 = fir.do_loop %arg2 = %1 to %2 step %c1 iter_args(%arg3 = %3) -> (index, i32) { + fir.store %arg3 to %0 : !fir.ref + %9 = fir.load %0 : !fir.ref + %10 = fir.convert %9 : (i32) -> i64 + %c1_i64 = arith.constant 1 : i64 + %11 = arith.subi %10, %c1_i64 : i64 + %12 = fir.coordinate_of %arg0, %11 : (!fir.class>>, i64) -> !fir.ref> + %tdesc = fir.box_tdesc %arg0 : (!fir.class>>) -> (!fir.tdesc>) + // CHECK: %[[TDESC:.*]] = fir.box_tdesc %{{.*}} : (!fir.class>>) -> !fir.tdesc> + %13 = fir.embox %12 tdesc %tdesc : (!fir.ref>, !fir.tdesc>) -> !fir.class> + // CHECK: %{{.*}} = fir.embox %{{.*}} tdesc %[[TDESC]] : (!fir.ref>, !fir.tdesc>) -> !fir.class> + %14 = arith.addi %arg2, %c1 : index + %15 = fir.convert %c1 : (index) -> i32 + %16 = fir.load %0 : !fir.ref + %17 = arith.addi %16, %15 : i32 + fir.result %14, %17 : index, i32 + } + fir.store %4#1 to %0 : !fir.ref + return +} diff --git a/flang/test/Fir/invalid.fir b/flang/test/Fir/invalid.fir --- a/flang/test/Fir/invalid.fir +++ b/flang/test/Fir/invalid.fir @@ -345,6 +345,36 @@ // ----- +func.func @embox_tdesc(%arg0: !fir.class>>) { + %0 = fir.alloca i32 + %c1_i32 = arith.constant 1 : i32 + %1 = fir.convert %c1_i32 : (i32) -> index + %c10_i32 = arith.constant 10 : i32 + %2 = fir.convert %c10_i32 : (i32) -> index + %c1 = arith.constant 1 : index + %3 = fir.convert %1 : (index) -> i32 + %4:2 = fir.do_loop %arg2 = %1 to %2 step %c1 iter_args(%arg3 = %3) -> (index, i32) { + fir.store %arg3 to %0 : !fir.ref + %9 = fir.load %0 : !fir.ref + %10 = fir.convert %9 : (i32) -> i64 + %c1_i64 = arith.constant 1 : i64 + %11 = arith.subi %10, %c1_i64 : i64 + %12 = fir.coordinate_of %arg0, %11 : (!fir.class>>, i64) -> !fir.ref> + %tdesc = fir.box_tdesc %arg0 : (!fir.class>>) -> (!fir.tdesc>) + // expected-error@+1 {{'fir.embox' op tdesc must be used with fir.class result type}} + %13 = fir.embox %12 tdesc %tdesc : (!fir.ref>, !fir.tdesc>) -> !fir.box> + %14 = arith.addi %arg2, %c1 : index + %15 = fir.convert %c1 : (index) -> i32 + %16 = fir.load %0 : !fir.ref + %17 = arith.addi %16, %15 : i32 + fir.result %14, %17 : index, i32 + } + fir.store %4#1 to %0 : !fir.ref + return +} + +// ----- + %lo = arith.constant 1 : index %c1 = arith.constant 1 : index %up = arith.constant 10 : index