From 59c469582f0a7897e7dc4cc7ef1ef1cd52454726 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Thu, 29 Oct 2026 14:56:50 +0100 Subject: [PATCH 1/6] [flang][MIF] Add lowering for EVENT_QUERY --- .../flang/Optimizer/Builder/IntrinsicCall.h | 1 + .../flang/Optimizer/Dialect/MIF/MIFOps.td | 19 + flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 20 + .../Optimizer/Transforms/MIFOpConversion.cpp | 64 +- flang/test/Fir/MIF/event_query01.mlir | 241 +++++++ flang/test/Fir/MIF/event_query02.mlir | 642 ++++++++++++++++++ flang/test/Lower/MIF/event_query01.f90 | 105 +++ flang/test/Lower/MIF/event_query02.f90 | 266 ++++++++ 8 files changed, 1347 insertions(+), 11 deletions(-) create mode 100644 flang/test/Fir/MIF/event_query01.mlir create mode 100644 flang/test/Fir/MIF/event_query02.mlir create mode 100644 flang/test/Lower/MIF/event_query01.f90 create mode 100644 flang/test/Lower/MIF/event_query02.f90 diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h index 53c975e4b3f663..a6edd12ba0c658 100644 --- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h +++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h @@ -211,6 +211,7 @@ struct IntrinsicLibrary { void genExecuteCommandLine(mlir::ArrayRef args); fir::ExtendedValue genEtime(std::optional, mlir::ArrayRef args); + void genEventQuery(llvm::ArrayRef); mlir::Value genTimef(mlir::Type resultType, llvm::ArrayRef args); mlir::Value genExponent(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genExtendsTypeOf(mlir::Type, diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td index aa9153b83244fd..5100a2d72978df 100644 --- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td @@ -644,4 +644,23 @@ def mif_EventWaitOp : mif_Op<"event_wait", [AttrSizedOperandSegments]> { }]; } +def mif_EventQueryOp : mif_Op<"event_query", []> { + let summary = "Query the count of an event on the calling image."; + let description = [{ + Argument: `event` shall be a coarray of type EVENT_TYPE from the intrinsic + module ISO_FORTRAN_ENV. + Result: `count` shall be an integer scalar and indicate the current count + of event variables. + }]; + + let arguments = (ins Arg:$event, + Arg, "", [MemWrite]>:$stat); + let results = (outs AnyInteger:$count); + let assemblyFormat = [{ + $event + (`stat` $stat^ )? + attr-dict `:` functional-type(operands, results) + }]; +} + #endif // FORTRAN_DIALECT_MIF_MIF_OPS diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 43c23ba28fa9e7..16f2f0e1863d82 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -307,6 +307,12 @@ static constexpr IntrinsicHandler handlers[]{ &I::genEtime, {{{"values", asBox}, {"time", asBox}}}, /*isElemental=*/false}, + {"event_query", + &I::genEventQuery, + {{{"event", asAddr}, + {"count", asAddr}, + {"stat", asAddr, handleDynamicOptional}}}, + /*isElemental=*/false}, {"execute_command_line", &I::genExecuteCommandLine, {{{"command", asBox}, @@ -4036,6 +4042,20 @@ IntrinsicLibrary::genEtime(std::optional resultType, return {}; } +// EVENT_QUERY +void IntrinsicLibrary::genEventQuery(llvm::ArrayRef args) { + assert(args.size() == 3); + + mlir::Value eventVarPtr = fir::getBase(args[0]); + mlir::Value count = fir::getBase(args[1]); + mlir::Value stat = fir::getBase(args[2]); + + mlir::Type countTy = fir::unwrapPassByRefType(count.getType()); + mlir::Value res = + mif::EventQueryOp::create(builder, loc, countTy, eventVarPtr, stat); + fir::StoreOp::create(builder, loc, res, count); +} + // EXIT void IntrinsicLibrary::genExit(llvm::ArrayRef args) { assert(args.size() == 1); diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp index 9f3a701571f315..56f86c9d8f7834 100644 --- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp +++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp @@ -1671,6 +1671,48 @@ struct MIFEventPostOpConversion } }; +/// Convert mif.event_query operation to runtime call of 'prif_event_query' +struct MIFEventQueryOpConversion + : public mlir::OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + mlir::LogicalResult + matchAndRewrite(mif::EventQueryOp op, + mlir::PatternRewriter &rewriter) const override { + auto mod = op->template getParentOfType(); + fir::FirOpBuilder builder(rewriter, mod); + mlir::Location loc = op.getLoc(); + + mlir::Type ptrTy = getBuiltinCptrType(builder, loc); + mlir::Type i64Ty = builder.getI64Type(); + mlir::Type errmsgTy = getPRIFErrmsgType(builder); + mlir::FunctionType ftype = mlir::FunctionType::get( + builder.getContext(), + /*inputs*/ + {builder.getRefType(ptrTy), builder.getRefType(i64Ty), + getPRIFStatType(builder)}, + /*results*/ {}); + mlir::func::FuncOp funcOp = + builder.createFunction(loc, getPRIFProcName("event_query"), ftype); + + mlir::Value count = builder.createTemporary(loc, i64Ty); + mlir::Value stat = op.getStat(); + if (!stat) + stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder)); + + mlir::Value cptrEvent = + convertRefTypeToCPtrType(builder, loc, op.getEvent()); + llvm::SmallVector args = fir::runtime::createArguments( + builder, loc, ftype, cptrEvent, count, stat); + fir::CallOp::create(builder, loc, funcOp, args); + + count = fir::LoadOp::create(builder, loc, count).getResult(); + count = builder.createConvert(loc, op.getType(), count); + rewriter.replaceOp(op, count); + return mlir::success(); + } +}; + static void genCoarrayHandle(fir::FirOpBuilder &builder, mlir::ModuleOp mod, fir::DeclareOp op) { builder.setInsertionPointAfter(op); @@ -1746,16 +1788,16 @@ void mif::populateMIFOpConversionPatterns( mlir::RewritePatternSet &patterns) { patterns.insert(patterns.getContext(), &dl, &converter); - patterns.insert( + patterns.insert< + MIFInitOpConversion, MIFThisImageOpConversion, MIFNumImagesOpConversion, + MIFSyncAllOpConversion, MIFSyncImagesOpConversion, + MIFSyncMemoryOpConversion, MIFSyncTeamOpConversion, + MIFCoBroadcastOpConversion, MIFCoMaxOpConversion, MIFCoMinOpConversion, + MIFCoSumOpConversion, MIFFormTeamOpConversion, MIFChangeTeamOpConversion, + MIFGetTeamOpConversion, MIFTeamNumberOpConversion, + MIFDeallocCoarrayOpConversion, MIFCoshapeOpConversion, + MIFLcoboundOpConversion, MIFUcoboundOpConversion, + MIFImageIndexOpConversion, MIFEventPostOpConversion, + MIFEventWaitOpConversion, MIFEventQueryOpConversion>( patterns.getContext()); } diff --git a/flang/test/Fir/MIF/event_query01.mlir b/flang/test/Fir/MIF/event_query01.mlir new file mode 100644 index 00000000000000..16c87245d6f35b --- /dev/null +++ b/flang/test/Fir/MIF/event_query01.mlir @@ -0,0 +1,241 @@ +// RUN: fir-opt --mif-convert %s | FileCheck %s + + +func.func @_QPquery_base() { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_baseEcount"}> + %2:2 = hlfir.declare %1 uniq_name("_QFquery_baseEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.address_of(@_QFquery_baseEev) : !fir.ref>, corank:1>> + %4:2 = hlfir.declare %3 uniq_name("_QFquery_baseEev") : (!fir.ref>, corank:1>>) -> (!fir.ref>, corank:1>>, !fir.ref>, corank:1>>) + %5 = fir.load %4#0 : !fir.ref>, corank:1>> + %6 = fir.box_addr %5 : (!fir.box>, corank:1>) -> !fir.heap> + %7 = mif.event_query %6 : (!fir.heap>) -> i32 + fir.store %7 to %2#0 : !fir.ref + return +} +func.func @_QPquery_with_stat() { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_with_statEcount"}> + %2:2 = hlfir.declare %1 uniq_name("_QFquery_with_statEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.address_of(@_QFquery_with_statEev) : !fir.ref>, corank:1>> + %4:2 = hlfir.declare %3 uniq_name("_QFquery_with_statEev") : (!fir.ref>, corank:1>>) -> (!fir.ref>, corank:1>>, !fir.ref>, corank:1>>) + %5 = fir.alloca i32 <{bindc_name = "stat", uniq_name = "_QFquery_with_statEstat"}> + %6:2 = hlfir.declare %5 uniq_name("_QFquery_with_statEstat") : (!fir.ref) -> (!fir.ref, !fir.ref) + %7 = fir.load %4#0 : !fir.ref>, corank:1>> + %8 = fir.box_addr %7 : (!fir.box>, corank:1>) -> !fir.heap> + %9 = mif.event_query %8 stat %6#0 : (!fir.heap>, !fir.ref) -> i32 + fir.store %9 to %2#0 : !fir.ref + return +} +func.func @_QPquery_with_kinds() { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.alloca i32 <{bindc_name = "c4", uniq_name = "_QFquery_with_kindsEc4"}> + %2:2 = hlfir.declare %1 uniq_name("_QFquery_with_kindsEc4") : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca i64 <{bindc_name = "c8", uniq_name = "_QFquery_with_kindsEc8"}> + %4:2 = hlfir.declare %3 uniq_name("_QFquery_with_kindsEc8") : (!fir.ref) -> (!fir.ref, !fir.ref) + %5 = fir.address_of(@_QFquery_with_kindsEev) : !fir.ref>, corank:1>> + %6:2 = hlfir.declare %5 uniq_name("_QFquery_with_kindsEev") : (!fir.ref>, corank:1>>) -> (!fir.ref>, corank:1>>, !fir.ref>, corank:1>>) + %7 = fir.address_of(@_QMiso_fortran_env_implECint16) : !fir.ref + %8:2 = hlfir.declare %7 uniq_name("_QMiso_fortran_env_implECint16") fortran_attrs : (!fir.ref) -> (!fir.ref, !fir.ref) + %9 = fir.address_of(@_QMiso_fortran_env_implECint32) : !fir.ref + %10:2 = hlfir.declare %9 uniq_name("_QMiso_fortran_env_implECint32") fortran_attrs : (!fir.ref) -> (!fir.ref, !fir.ref) + %11 = fir.address_of(@_QMiso_fortran_env_implECint64) : !fir.ref + %12:2 = hlfir.declare %11 uniq_name("_QMiso_fortran_env_implECint64") fortran_attrs : (!fir.ref) -> (!fir.ref, !fir.ref) + %13 = fir.alloca i16 <{bindc_name = "s2", uniq_name = "_QFquery_with_kindsEs2"}> + %14:2 = hlfir.declare %13 uniq_name("_QFquery_with_kindsEs2") : (!fir.ref) -> (!fir.ref, !fir.ref) + %15 = fir.alloca i32 <{bindc_name = "s4", uniq_name = "_QFquery_with_kindsEs4"}> + %16:2 = hlfir.declare %15 uniq_name("_QFquery_with_kindsEs4") : (!fir.ref) -> (!fir.ref, !fir.ref) + %17 = fir.alloca i64 <{bindc_name = "s8", uniq_name = "_QFquery_with_kindsEs8"}> + %18:2 = hlfir.declare %17 uniq_name("_QFquery_with_kindsEs8") : (!fir.ref) -> (!fir.ref, !fir.ref) + %19 = fir.load %6#0 : !fir.ref>, corank:1>> + %20 = fir.box_addr %19 : (!fir.box>, corank:1>) -> !fir.heap> + %21 = mif.event_query %20 : (!fir.heap>) -> i32 + fir.store %21 to %2#0 : !fir.ref + %22 = fir.load %6#0 : !fir.ref>, corank:1>> + %23 = fir.box_addr %22 : (!fir.box>, corank:1>) -> !fir.heap> + %24 = mif.event_query %23 : (!fir.heap>) -> i64 + fir.store %24 to %4#0 : !fir.ref + %25 = fir.load %6#0 : !fir.ref>, corank:1>> + %26 = fir.box_addr %25 : (!fir.box>, corank:1>) -> !fir.heap> + %27 = mif.event_query %26 stat %14#0 : (!fir.heap>, !fir.ref) -> i32 + fir.store %27 to %2#0 : !fir.ref + %28 = fir.load %6#0 : !fir.ref>, corank:1>> + %29 = fir.box_addr %28 : (!fir.box>, corank:1>) -> !fir.heap> + %30 = mif.event_query %29 stat %16#0 : (!fir.heap>, !fir.ref) -> i32 + fir.store %30 to %2#0 : !fir.ref + %31 = fir.load %6#0 : !fir.ref>, corank:1>> + %32 = fir.box_addr %31 : (!fir.box>, corank:1>) -> !fir.heap> + %33 = mif.event_query %32 stat %18#0 : (!fir.heap>, !fir.ref) -> i64 + fir.store %33 to %4#0 : !fir.ref + return +} +fir.global linkonce_odr @_QMiso_fortran_envECcharacter_kinds(dense<[1, 2, 4]> : tensor<3xi32>) <{alignment = 64 : i64}> constant : !fir.array<3xi32> +fir.global internal @_QFquery_baseEev : !fir.box>, corank:1> { + %0 = fir.zero_bits !fir.heap> + %1 = fir.embox %0 : (!fir.heap>) -> !fir.box>, corank:1> + fir.has_value %1 : !fir.box>, corank:1> +} +func.func @__mif_save_coarrays_allocate() { + %0 = fir.alloca !fir.array<0xi64> + %1 = fir.alloca !fir.array<1xi64> + %2 = fir.alloca !fir.array<0xi64> + %3 = fir.alloca !fir.array<1xi64> + %4 = fir.alloca !fir.array<0xi64> + %5 = fir.alloca !fir.array<1xi64> + %6 = mif.init -> i32 + %7 = fir.address_of(@_QFquery_baseEev) : !fir.ref>, corank:1>> + %c1_i64 = arith.constant 1 : i64 + %c1_i64_0 = arith.constant 1 : i64 + %c0 = arith.constant 0 : index + %8 = fir.coordinate_of %5, %c0 : (!fir.ref>, index) -> !fir.ref + fir.store %c1_i64_0 to %8 : !fir.ref + %9 = fir.embox %5 : (!fir.ref>) -> !fir.box> + %c1_i64_1 = arith.constant 1 : i64 + %10 = fir.embox %4 : (!fir.ref>) -> !fir.box> + mif.alloc_coarray %7 lcobounds %9 ucobounds %10 uniq_name("_QFquery_baseEev") : (!fir.ref>, corank:1>>, !fir.box>, !fir.box>) -> () + %11 = fir.address_of(@_QFquery_with_statEev) : !fir.ref>, corank:1>> + %c1_i64_2 = arith.constant 1 : i64 + %c1_i64_3 = arith.constant 1 : i64 + %c0_4 = arith.constant 0 : index + %12 = fir.coordinate_of %3, %c0_4 : (!fir.ref>, index) -> !fir.ref + fir.store %c1_i64_3 to %12 : !fir.ref + %13 = fir.embox %3 : (!fir.ref>) -> !fir.box> + %c1_i64_5 = arith.constant 1 : i64 + %14 = fir.embox %2 : (!fir.ref>) -> !fir.box> + mif.alloc_coarray %11 lcobounds %13 ucobounds %14 uniq_name("_QFquery_with_statEev") : (!fir.ref>, corank:1>>, !fir.box>, !fir.box>) -> () + %15 = fir.address_of(@_QFquery_with_kindsEev) : !fir.ref>, corank:1>> + %c1_i64_6 = arith.constant 1 : i64 + %c1_i64_7 = arith.constant 1 : i64 + %c0_8 = arith.constant 0 : index + %16 = fir.coordinate_of %1, %c0_8 : (!fir.ref>, index) -> !fir.ref + fir.store %c1_i64_7 to %16 : !fir.ref + %17 = fir.embox %1 : (!fir.ref>) -> !fir.box> + %c1_i64_9 = arith.constant 1 : i64 + %18 = fir.embox %0 : (!fir.ref>) -> !fir.box> + mif.alloc_coarray %15 lcobounds %17 ucobounds %18 uniq_name("_QFquery_with_kindsEev") : (!fir.ref>, corank:1>>, !fir.box>, !fir.box>) -> () + return +} + +// CHECK-LABEL: func.func @_QPquery_base() { +// CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_1:.*]] = fir.alloca i64 +// CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_3:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_baseEcount"}> +// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_baseEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_5:.*]] = fir.address_of(@_QFquery_baseEev) : {{.*}} +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] uniq_name("_QFquery_baseEev") : {{.*}} +// CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_6]]#0 : {{.*}} +// CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_9:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_11:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_12:.*]] = fir.coordinate_of %[[VAL_0]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_10]] to %[[VAL_12]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[VAL_0]], %[[VAL_1]], %[[VAL_9]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_14]] to %[[VAL_4]]#0 : !fir.ref +// CHECK: return +// CHECK: } + +// CHECK-LABEL: func.func @_QPquery_with_stat() { +// CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_1:.*]] = fir.alloca i64 +// CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_3:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_with_statEcount"}> +// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_with_statEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_5:.*]] = fir.address_of(@_QFquery_with_statEev) : {{.*}} +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] uniq_name("_QFquery_with_statEev") : {{.*}} +// CHECK: %[[VAL_7:.*]] = fir.alloca i32 <{bindc_name = "stat", uniq_name = "_QFquery_with_statEstat"}> +// CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_7]] uniq_name("_QFquery_with_statEstat") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_6]]#0 : {{.*}} +// CHECK: %[[VAL_10:.*]] = fir.box_addr %[[VAL_9]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_12:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_0]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_11]] to %[[VAL_13]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[VAL_0]], %[[VAL_1]], %[[VAL_8]]#0) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_15]] to %[[VAL_4]]#0 : !fir.ref +// CHECK: return +// CHECK: } + +// CHECK-LABEL: func.func @_QPquery_with_kinds() { +// CHECK: %[[CPTR0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[CNT0:.*]] = fir.alloca i64 +// CHECK: %[[CPTR1:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[CNT1:.*]] = fir.alloca i64 +// CHECK: %[[CPTR2:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[CNT2:.*]] = fir.alloca i64 +// CHECK: %[[CPTR3:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[CNT3:.*]] = fir.alloca i64 +// CHECK: %[[CPTR4:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[CNT4:.*]] = fir.alloca i64 +// CHECK: %[[VAL_10:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_11:.*]] = fir.alloca i32 <{bindc_name = "c4", uniq_name = "_QFquery_with_kindsEc4"}> +// CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] uniq_name("_QFquery_with_kindsEc4") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_13:.*]] = fir.alloca i64 <{bindc_name = "c8", uniq_name = "_QFquery_with_kindsEc8"}> +// CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_13]] uniq_name("_QFquery_with_kindsEc8") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_15:.*]] = fir.address_of(@_QFquery_with_kindsEev) : {{.*}} +// CHECK: %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_15]] uniq_name("_QFquery_with_kindsEev") : {{.*}} +// CHECK: %[[VAL_23:.*]] = fir.alloca i16 <{bindc_name = "s2", uniq_name = "_QFquery_with_kindsEs2"}> +// CHECK: %[[VAL_24:.*]]:2 = hlfir.declare %[[VAL_23]] uniq_name("_QFquery_with_kindsEs2") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_25:.*]] = fir.alloca i32 <{bindc_name = "s4", uniq_name = "_QFquery_with_kindsEs4"}> +// CHECK: %[[VAL_26:.*]]:2 = hlfir.declare %[[VAL_25]] uniq_name("_QFquery_with_kindsEs4") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_27:.*]] = fir.alloca i64 <{bindc_name = "s8", uniq_name = "_QFquery_with_kindsEs8"}> +// CHECK: %[[VAL_28:.*]]:2 = hlfir.declare %[[VAL_27]] uniq_name("_QFquery_with_kindsEs8") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_16]]#0 : {{.*}} +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_29]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_31:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_33:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_34:.*]] = fir.coordinate_of %[[CPTR4]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_32]] to %[[VAL_34]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[CPTR4]], %[[CNT4]], %[[VAL_31]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_35:.*]] = fir.load %[[CNT4]] : !fir.ref +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_36]] to %[[VAL_12]]#0 : !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.load %[[VAL_16]]#0 : {{.*}} +// CHECK: %[[VAL_38:.*]] = fir.box_addr %[[VAL_37]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_39:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_41:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_42:.*]] = fir.coordinate_of %[[CPTR3]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_40]] to %[[VAL_42]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[CPTR3]], %[[CNT3]], %[[VAL_39]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_43:.*]] = fir.load %[[CNT3]] : !fir.ref +// CHECK: fir.store %[[VAL_43]] to %[[VAL_14]]#0 : !fir.ref +// CHECK: %[[VAL_44:.*]] = fir.load %[[VAL_16]]#0 : {{.*}} +// CHECK: %[[VAL_45:.*]] = fir.box_addr %[[VAL_44]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_46:.*]] = fir.convert %[[VAL_45]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_47:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_48:.*]] = fir.coordinate_of %[[CPTR2]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_46]] to %[[VAL_48]] : !fir.ref +// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_24]]#0 : (!fir.ref) -> !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[CPTR2]], %[[CNT2]], %[[VAL_49]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_50:.*]] = fir.load %[[CNT2]] : !fir.ref +// CHECK: %[[VAL_51:.*]] = fir.convert %[[VAL_50]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_51]] to %[[VAL_12]]#0 : !fir.ref +// CHECK: %[[VAL_52:.*]] = fir.load %[[VAL_16]]#0 : {{.*}} +// CHECK: %[[VAL_53:.*]] = fir.box_addr %[[VAL_52]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_53]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_55:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_56:.*]] = fir.coordinate_of %[[CPTR1]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_54]] to %[[VAL_56]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[CPTR1]], %[[CNT1]], %[[VAL_26]]#0) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_57:.*]] = fir.load %[[CNT1]] : !fir.ref +// CHECK: %[[VAL_58:.*]] = fir.convert %[[VAL_57]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_58]] to %[[VAL_12]]#0 : !fir.ref +// CHECK: %[[VAL_59:.*]] = fir.load %[[VAL_16]]#0 : {{.*}} +// CHECK: %[[VAL_60:.*]] = fir.box_addr %[[VAL_59]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_61:.*]] = fir.convert %[[VAL_60]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_62:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_63:.*]] = fir.coordinate_of %[[CPTR0]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_61]] to %[[VAL_63]] : !fir.ref +// CHECK: %[[VAL_64:.*]] = fir.convert %[[VAL_28]]#0 : (!fir.ref) -> !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[CPTR0]], %[[CNT0]], %[[VAL_64]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_65:.*]] = fir.load %[[CNT0]] : !fir.ref +// CHECK: fir.store %[[VAL_65]] to %[[VAL_14]]#0 : !fir.ref +// CHECK: return +// CHECK: } diff --git a/flang/test/Fir/MIF/event_query02.mlir b/flang/test/Fir/MIF/event_query02.mlir new file mode 100644 index 00000000000000..4e91e2c1e3e973 --- /dev/null +++ b/flang/test/Fir/MIF/event_query02.mlir @@ -0,0 +1,642 @@ +// RUN: fir-opt --mif-convert %s | FileCheck %s + +func.func @_QPquery_array_element() { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_array_elementEcount"}> + %2:2 = hlfir.declare %1 uniq_name("_QFquery_array_elementEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.address_of(@_QFquery_array_elementEev) : !fir.ref>>, corank:1>> + %4:2 = hlfir.declare %3 uniq_name("_QFquery_array_elementEev") : (!fir.ref>>, corank:1>>) -> (!fir.ref>>, corank:1>>, !fir.ref>>, corank:1>>) + %5 = fir.load %4#0 : !fir.ref>>, corank:1>> + %c2 = arith.constant 2 : index + %6 = hlfir.designate %5 (%c2) : (!fir.box>>, corank:1>, index) -> !fir.ref> + %7 = mif.event_query %6 : (!fir.ref>) -> i32 + fir.store %7 to %2#0 : !fir.ref + return +} + +func.func @_QPquery_array_in_loop() { + %0 = fir.dummy_scope : !fir.dscope + %c4 = arith.constant 4 : index + %1 = fir.alloca !fir.array<4xi32> <{bindc_name = "counts", uniq_name = "_QFquery_array_in_loopEcounts"}> + %2 = fir.shape %c4 : (index) -> !fir.shape<1> + %3:2 = hlfir.declare %1(%2) uniq_name("_QFquery_array_in_loopEcounts") : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) + %4 = fir.address_of(@_QFquery_array_in_loopEev) : !fir.ref>>, corank:1>> + %5:2 = hlfir.declare %4 uniq_name("_QFquery_array_in_loopEev") : (!fir.ref>>, corank:1>>) -> (!fir.ref>>, corank:1>>, !fir.ref>>, corank:1>>) + %6 = fir.alloca i32 <{bindc_name = "i", uniq_name = "_QFquery_array_in_loopEi"}> + %7:2 = hlfir.declare %6 uniq_name("_QFquery_array_in_loopEi") : (!fir.ref) -> (!fir.ref, !fir.ref) + %c4_0 = arith.constant 4 : index + %8 = fir.alloca !fir.array<4xi32> <{bindc_name = "stats", uniq_name = "_QFquery_array_in_loopEstats"}> + %9 = fir.shape %c4_0 : (index) -> !fir.shape<1> + %10:2 = hlfir.declare %8(%9) uniq_name("_QFquery_array_in_loopEstats") : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) + %c1_i32 = arith.constant 1 : i32 + %c4_i32 = arith.constant 4 : i32 + %c1_i32_1 = arith.constant 1 : i32 + fir.do_loop %arg0 = %c1_i32 to %c4_i32 step %c1_i32_1 : i32 { + fir.store %arg0 to %7#0 : !fir.ref + %22 = fir.load %5#0 : !fir.ref>>, corank:1>> + %23 = fir.load %7#0 : !fir.ref + %24 = fir.convert %23 : (i32) -> i64 + %25 = hlfir.designate %22 (%24) : (!fir.box>>, corank:1>, i64) -> !fir.ref> + %26 = fir.load %7#0 : !fir.ref + %27 = fir.convert %26 : (i32) -> i64 + %28 = hlfir.designate %3#0 (%27) : (!fir.ref>, i64) -> !fir.ref + %29 = fir.load %7#0 : !fir.ref + %30 = fir.convert %29 : (i32) -> i64 + %31 = hlfir.designate %10#0 (%30) : (!fir.ref>, i64) -> !fir.ref + %32 = mif.event_query %25 stat %31 : (!fir.ref>, !fir.ref) -> i32 + fir.store %32 to %28 : !fir.ref + } + %11 = fir.convert %c1_i32 : (i32) -> index + %12 = fir.convert %c4_i32 : (i32) -> index + %13 = fir.convert %c1_i32_1 : (i32) -> index + %c0 = arith.constant 0 : index + %14 = arith.subi %12, %11 : index + %15 = arith.addi %14, %13 : index + %16 = arith.divsi %15, %13 : index + %17 = arith.cmpi slt, %16, %c0 : index + %18 = arith.select %17, %c0, %16 : index + %19 = arith.muli %18, %13 : index + %20 = arith.addi %11, %19 : index + %21 = fir.convert %20 : (index) -> i32 + fir.store %21 to %7#0 : !fir.ref + return +} + +func.func @_QPquery_allocatable() { + %0 = fir.alloca !fir.array<0xi64> + %1 = fir.alloca !fir.array<1xi64> + %2 = fir.dummy_scope : !fir.dscope + %3 = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_allocatableEcount"}> + %4:2 = hlfir.declare %3 uniq_name("_QFquery_allocatableEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) + %5 = fir.alloca !fir.box>, corank:1> <{bindc_name = "ev", uniq_name = "_QFquery_allocatableEev"}> + %6 = fir.zero_bits !fir.heap> + %7 = fir.embox %6 : (!fir.heap>) -> !fir.box>, corank:1> + fir.store %7 to %5 : !fir.ref>, corank:1>> + %8:2 = hlfir.declare %5 uniq_name("_QFquery_allocatableEev") fortran_attrs : (!fir.ref>, corank:1>>) -> (!fir.ref>, corank:1>>, !fir.ref>, corank:1>>) + %9 = fir.alloca i32 <{bindc_name = "stat", uniq_name = "_QFquery_allocatableEstat"}> + %10:2 = hlfir.declare %9 uniq_name("_QFquery_allocatableEstat") : (!fir.ref) -> (!fir.ref, !fir.ref) + %11 = fir.absent !fir.box + %c1_i64 = arith.constant 1 : i64 + %c0 = arith.constant 0 : index + %12 = fir.coordinate_of %1, %c0 : (!fir.ref>, index) -> !fir.ref + fir.store %c1_i64 to %12 : !fir.ref + %13 = fir.embox %1 : (!fir.ref>) -> !fir.box> + %14 = fir.embox %0 : (!fir.ref>) -> !fir.box> + mif.alloc_coarray %8#0 lcobounds %13 ucobounds %14 errmsg %11 uniq_name("_QFquery_allocatableEev") : (!fir.ref>, corank:1>>, !fir.box>, !fir.box>, !fir.box) -> () + %15 = fir.load %8#0 : !fir.ref>, corank:1>> + %16 = fir.box_addr %15 : (!fir.box>, corank:1>) -> !fir.heap> + %17 = mif.event_query %16 : (!fir.heap>) -> i32 + fir.store %17 to %4#0 : !fir.ref + %18 = fir.load %8#0 : !fir.ref>, corank:1>> + %19 = fir.box_addr %18 : (!fir.box>, corank:1>) -> !fir.heap> + %20 = mif.event_query %19 stat %10#0 : (!fir.heap>, !fir.ref) -> i32 + fir.store %20 to %4#0 : !fir.ref + %21 = fir.absent !fir.box + %22 = fir.absent !fir.ref + mif.dealloc_coarray %8#0 stat %22 errmsg %21 : (!fir.ref>, corank:1>>, !fir.ref, !fir.box) -> () + %23 = fir.load %8#0 : !fir.ref>, corank:1>> + %24 = fir.box_addr %23 : (!fir.box>, corank:1>) -> !fir.heap> + %25 = fir.convert %24 : (!fir.heap>) -> i64 + %c0_i64 = arith.constant 0 : i64 + %26 = arith.cmpi ne, %25, %c0_i64 : i64 + fir.if %26 { + %27 = fir.absent !fir.box + %28 = fir.absent !fir.ref + mif.dealloc_coarray %8#0 stat %28 errmsg %27 : (!fir.ref>, corank:1>>, !fir.ref, !fir.box) -> () + } + return +} + +func.func @_QPquery_allocatable_array(%arg0: !fir.ref {fir.bindc_name = "n", fir.fortran_attrs = #fir.var_attrs, fir.read_only}) { + %0 = fir.alloca !fir.array<0xi64> + %1 = fir.alloca !fir.array<1xi64> + %2 = fir.dummy_scope : !fir.dscope + %3 = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_allocatable_arrayEcount"}> + %4:2 = hlfir.declare %3 uniq_name("_QFquery_allocatable_arrayEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) + %5 = fir.alloca !fir.box>>, corank:1> <{bindc_name = "ev", uniq_name = "_QFquery_allocatable_arrayEev"}> + %6 = fir.zero_bits !fir.heap>> + %c0 = arith.constant 0 : index + %7 = fir.shape %c0 : (index) -> !fir.shape<1> + %8 = fir.embox %6(%7) : (!fir.heap>>, !fir.shape<1>) -> !fir.box>>, corank:1> + fir.store %8 to %5 : !fir.ref>>, corank:1>> + %9:2 = hlfir.declare %5 uniq_name("_QFquery_allocatable_arrayEev") fortran_attrs : (!fir.ref>>, corank:1>>) -> (!fir.ref>>, corank:1>>, !fir.ref>>, corank:1>>) + %10 = fir.alloca i32 <{bindc_name = "i", uniq_name = "_QFquery_allocatable_arrayEi"}> + %11:2 = hlfir.declare %10 uniq_name("_QFquery_allocatable_arrayEi") : (!fir.ref) -> (!fir.ref, !fir.ref) + %12:2 = hlfir.declare %arg0 dummy_scope %2 arg 1 uniq_name("_QFquery_allocatable_arrayEn") fortran_attrs : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %13 = fir.absent !fir.box + %c1 = arith.constant 1 : index + %14 = fir.load %12#0 : !fir.ref + %c0_i32 = arith.constant 0 : i32 + %15 = fir.convert %9#0 : (!fir.ref>>, corank:1>>) -> !fir.ref> + %16 = fir.convert %c1 : (index) -> i64 + %17 = fir.convert %14 : (i32) -> i64 + fir.call @_FortranAAllocatableSetBounds(%15, %c0_i32, %16, %17) fastmath : (!fir.ref>, i32, i64, i64) -> () + %c1_i64 = arith.constant 1 : i64 + %c0_0 = arith.constant 0 : index + %18 = fir.coordinate_of %1, %c0_0 : (!fir.ref>, index) -> !fir.ref + fir.store %c1_i64 to %18 : !fir.ref + %19 = fir.embox %1 : (!fir.ref>) -> !fir.box> + %20 = fir.embox %0 : (!fir.ref>) -> !fir.box> + mif.alloc_coarray %9#0 lcobounds %19 ucobounds %20 errmsg %13 uniq_name("_QFquery_allocatable_arrayEev") : (!fir.ref>>, corank:1>>, !fir.box>, !fir.box>, !fir.box) -> () + %c1_i32 = arith.constant 1 : i32 + %21 = fir.load %12#0 : !fir.ref + %c1_i32_1 = arith.constant 1 : i32 + fir.do_loop %arg1 = %c1_i32 to %21 step %c1_i32_1 : i32 { + fir.store %arg1 to %11#0 : !fir.ref + %39 = fir.load %9#0 : !fir.ref>>, corank:1>> + %40 = fir.load %11#0 : !fir.ref + %41 = fir.convert %40 : (i32) -> i64 + %42 = hlfir.designate %39 (%41) : (!fir.box>>, corank:1>, i64) -> !fir.ref> + %43 = mif.event_query %42 : (!fir.ref>) -> i32 + fir.store %43 to %4#0 : !fir.ref + } + %22 = fir.convert %c1_i32 : (i32) -> index + %23 = fir.convert %21 : (i32) -> index + %24 = fir.convert %c1_i32_1 : (i32) -> index + %c0_2 = arith.constant 0 : index + %25 = arith.subi %23, %22 : index + %26 = arith.addi %25, %24 : index + %27 = arith.divsi %26, %24 : index + %28 = arith.cmpi slt, %27, %c0_2 : index + %29 = arith.select %28, %c0_2, %27 : index + %30 = arith.muli %29, %24 : index + %31 = arith.addi %22, %30 : index + %32 = fir.convert %31 : (index) -> i32 + fir.store %32 to %11#0 : !fir.ref + %33 = fir.absent !fir.box + %34 = fir.absent !fir.ref + mif.dealloc_coarray %9#0 stat %34 errmsg %33 : (!fir.ref>>, corank:1>>, !fir.ref, !fir.box) -> () + %35 = fir.load %9#0 : !fir.ref>>, corank:1>> + %36 = fir.box_addr %35 : (!fir.box>>, corank:1>) -> !fir.heap>> + %37 = fir.convert %36 : (!fir.heap>>) -> i64 + %c0_i64 = arith.constant 0 : i64 + %38 = arith.cmpi ne, %37, %c0_i64 : i64 + fir.if %38 { + %39 = fir.absent !fir.box + %40 = fir.absent !fir.ref + mif.dealloc_coarray %9#0 stat %40 errmsg %39 : (!fir.ref>>, corank:1>>, !fir.ref, !fir.box) -> () + } + return +} + +func.func @_QPquery_class_allocatable() { + %0 = fir.alloca !fir.array<0xi64> + %1 = fir.alloca !fir.array<1xi64> + %2 = fir.dummy_scope : !fir.dscope + %3 = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_class_allocatableEcount"}> + %4:2 = hlfir.declare %3 uniq_name("_QFquery_class_allocatableEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) + %5 = fir.alloca !fir.class>, corank:1> <{bindc_name = "ev", uniq_name = "_QFquery_class_allocatableEev"}> + %6 = fir.zero_bits !fir.heap> + %7 = fir.embox %6 : (!fir.heap>) -> !fir.class>, corank:1> + fir.store %7 to %5 : !fir.ref>, corank:1>> + %8:2 = hlfir.declare %5 uniq_name("_QFquery_class_allocatableEev") fortran_attrs : (!fir.ref>, corank:1>>) -> (!fir.ref>, corank:1>>, !fir.ref>, corank:1>>) + %9 = fir.absent !fir.box + %10 = fir.type_desc !fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}> + %c0_i32 = arith.constant 0 : i32 + %c0_i32_0 = arith.constant 0 : i32 + %11 = fir.convert %8#0 : (!fir.ref>, corank:1>>) -> !fir.ref> + %12 = fir.convert %10 : (!fir.tdesc>) -> !fir.ref + fir.call @_FortranAAllocatableInitDerivedForAllocate(%11, %12, %c0_i32, %c0_i32_0) fastmath : (!fir.ref>, !fir.ref, i32, i32) -> () + %c1_i64 = arith.constant 1 : i64 + %c0 = arith.constant 0 : index + %13 = fir.coordinate_of %1, %c0 : (!fir.ref>, index) -> !fir.ref + fir.store %c1_i64 to %13 : !fir.ref + %14 = fir.embox %1 : (!fir.ref>) -> !fir.box> + %15 = fir.embox %0 : (!fir.ref>) -> !fir.box> + mif.alloc_coarray %8#0 lcobounds %14 ucobounds %15 errmsg %9 uniq_name("_QFquery_class_allocatableEev") : (!fir.ref>, corank:1>>, !fir.box>, !fir.box>, !fir.box) -> () + %16 = fir.load %8#0 : !fir.ref>, corank:1>> + %17 = mif.event_query %16 : (!fir.class>, corank:1>) -> i32 + fir.store %17 to %4#0 : !fir.ref + %18 = fir.load %8#0 : !fir.ref>, corank:1>> + %19 = fir.box_addr %18 : (!fir.class>, corank:1>) -> !fir.heap> + %20 = fir.convert %19 : (!fir.heap>) -> i64 + %c0_i64 = arith.constant 0 : i64 + %21 = arith.cmpi ne, %20, %c0_i64 : i64 + fir.if %21 { + %22 = fir.absent !fir.box + %23 = fir.absent !fir.ref + mif.dealloc_coarray %8#0 stat %23 errmsg %22 : (!fir.ref>, corank:1>>, !fir.ref, !fir.box) -> () + } + return +} + +// CHECK-LABEL: func.func @_QPquery_array_element() { +// CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_1:.*]] = fir.alloca i64 +// CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_3:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_array_elementEcount"}> +// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_array_elementEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_5:.*]] = fir.address_of(@_QFquery_array_elementEev) : {{.*}} +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] uniq_name("_QFquery_array_elementEev") : {{.*}} +// CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_6]]#0 : {{.*}} +// CHECK: %[[C2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_7]] (%[[C2]]) : ({{.*}}, index) -> !fir.ref> +// CHECK: %[[VAL_9:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (!fir.ref>) -> i64 +// CHECK: %[[VAL_11:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_12:.*]] = fir.coordinate_of %[[VAL_0]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_10]] to %[[VAL_12]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[VAL_0]], %[[VAL_1]], %[[VAL_9]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_14]] to %[[VAL_4]]#0 : !fir.ref +// CHECK: return +// CHECK: } + +// CHECK-LABEL: func.func @_QPquery_array_in_loop() { +// CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_1:.*]] = fir.alloca i64 +// CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[C4:.*]] = arith.constant 4 : index +// CHECK: %[[VAL_3:.*]] = fir.alloca !fir.array<4xi32> <{bindc_name = "counts", uniq_name = "_QFquery_array_in_loopEcounts"}> +// CHECK: %[[VAL_4:.*]] = fir.shape %[[C4]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_4]]) uniq_name("_QFquery_array_in_loopEcounts") : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +// CHECK: %[[VAL_6:.*]] = fir.address_of(@_QFquery_array_in_loopEev) : {{.*}} +// CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] uniq_name("_QFquery_array_in_loopEev") : {{.*}} +// CHECK: %[[VAL_8:.*]] = fir.alloca i32 <{bindc_name = "i", uniq_name = "_QFquery_array_in_loopEi"}> +// CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] uniq_name("_QFquery_array_in_loopEi") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[C4_0:.*]] = arith.constant 4 : index +// CHECK: %[[VAL_10:.*]] = fir.alloca !fir.array<4xi32> <{bindc_name = "stats", uniq_name = "_QFquery_array_in_loopEstats"}> +// CHECK: %[[VAL_11:.*]] = fir.shape %[[C4_0]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]](%[[VAL_11]]) uniq_name("_QFquery_array_in_loopEstats") : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +// CHECK: %[[C1_I32:.*]] = arith.constant 1 : i32 +// CHECK: %[[C4_I32:.*]] = arith.constant 4 : i32 +// CHECK: %[[C1_I32_1:.*]] = arith.constant 1 : i32 +// CHECK: fir.do_loop %[[ARG0:.*]] = %[[C1_I32]] to %[[C4_I32]] step %[[C1_I32_1]] : i32 { +// CHECK: fir.store %[[ARG0]] to %[[VAL_9]]#0 : !fir.ref +// CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_7]]#0 : {{.*}} +// CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref +// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i32) -> i64 +// CHECK: %[[VAL_27:.*]] = hlfir.designate %[[VAL_24]] (%[[VAL_26]]) : ({{.*}}, i64) -> !fir.ref> +// CHECK: %[[VAL_28:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (i32) -> i64 +// CHECK: %[[VAL_30:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_29]]) : (!fir.ref>, i64) -> !fir.ref +// CHECK: %[[VAL_31:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i32) -> i64 +// CHECK: %[[VAL_33:.*]] = hlfir.designate %[[VAL_12]]#0 (%[[VAL_32]]) : (!fir.ref>, i64) -> !fir.ref +// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_27]] : (!fir.ref>) -> i64 +// CHECK: %[[VAL_35:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_36:.*]] = fir.coordinate_of %[[VAL_0]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_34]] to %[[VAL_36]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[VAL_0]], %[[VAL_1]], %[[VAL_33]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_37:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_38]] to %[[VAL_30]] : !fir.ref +// CHECK: } +// CHECK: %[[VAL_13:.*]] = fir.convert %[[C1_I32]] : (i32) -> index +// CHECK: %[[VAL_14:.*]] = fir.convert %[[C4_I32]] : (i32) -> index +// CHECK: %[[VAL_15:.*]] = fir.convert %[[C1_I32_1]] : (i32) -> index +// CHECK: %[[C0:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_14]], %[[VAL_13]] : index +// CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_16]], %[[VAL_15]] : index +// CHECK: %[[VAL_18:.*]] = arith.divsi %[[VAL_17]], %[[VAL_15]] : index +// CHECK: %[[VAL_19:.*]] = arith.cmpi slt, %[[VAL_18]], %[[C0]] : index +// CHECK: %[[VAL_20:.*]] = arith.select %[[VAL_19]], %[[C0]], %[[VAL_18]] : index +// CHECK: %[[VAL_21:.*]] = arith.muli %[[VAL_20]], %[[VAL_15]] : index +// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_13]], %[[VAL_21]] : index +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (index) -> i32 +// CHECK: fir.store %[[VAL_23]] to %[[VAL_9]]#0 : !fir.ref +// CHECK: return +// CHECK: } + +// CHECK-LABEL: func.func @_QPquery_allocatable() { +// CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_1:.*]] = fir.alloca i64 +// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_3:.*]] = fir.alloca i64 +// CHECK: %[[VAL_4:.*]] = fir.alloca i64 +// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{{.*}}> +// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.boxproc<(!fir.ref, !fir.ref, !fir.box>) -> ()> +// CHECK: %[[VAL_8:.*]] = fir.alloca !fir.array<0xi64> +// CHECK: %[[VAL_9:.*]] = fir.alloca !fir.array<1xi64> +// CHECK: %[[VAL_10:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_11:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_allocatableEcount"}> +// CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] uniq_name("_QFquery_allocatableEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_13:.*]] = fir.alloca {{.*}} <{bindc_name = "ev", uniq_name = "_QFquery_allocatableEev"}> +// CHECK: %[[VAL_14:.*]] = fir.zero_bits !fir.heap> +// CHECK: %[[VAL_15:.*]] = fir.embox %[[VAL_14]] : {{.*}} +// CHECK: fir.store %[[VAL_15]] to %[[VAL_13]] : {{.*}} +// CHECK: %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_13]] uniq_name("_QFquery_allocatableEev") fortran_attrs : {{.*}} +// CHECK: %[[VAL_17:.*]] = fir.alloca i32 <{bindc_name = "stat", uniq_name = "_QFquery_allocatableEstat"}> +// CHECK: %[[VAL_18:.*]]:2 = hlfir.declare %[[VAL_17]] uniq_name("_QFquery_allocatableEstat") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_19:.*]] = fir.absent !fir.box +// CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64 +// CHECK: %[[C0:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_20:.*]] = fir.coordinate_of %[[VAL_9]], %[[C0]] : (!fir.ref>, index) -> !fir.ref +// CHECK: fir.store %[[C1_I64]] to %[[VAL_20]] : !fir.ref +// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_9]] : (!fir.ref>) -> !fir.box> +// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_8]] : (!fir.ref>) -> !fir.box> +// CHECK: %[[VAL_23:.*]] = fir.zero_bits (!fir.ref, !fir.ref, !fir.box>) -> () +// CHECK: %[[VAL_24:.*]] = fir.emboxproc %[[VAL_23]] : {{.*}} +// CHECK: fir.store %[[VAL_24]] to %[[VAL_7]] : {{.*}} +// CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_16]]#0 : {{.*}} +// CHECK: %[[VAL_26:.*]] = fir.box_elesize %[[VAL_25]] : ({{.*}}) -> i64 +// CHECK: fir.store %[[VAL_26]] to %[[VAL_4]] : !fir.ref +// CHECK: %[[VAL_27:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_28:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_21]] : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_22]] : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_7]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_6]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_19]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_allocate_coarray(%[[VAL_29]], %[[VAL_30]], %[[VAL_4]], %[[VAL_31]], %[[VAL_32]], %[[VAL_5]], %[[VAL_27]], %[[VAL_33]], %[[VAL_28]]) : {{.*}} +// CHECK: %[[VAL_34:.*]] = fir.address_of(@_QFquery_allocatableEev_coarray_handle) : {{.*}} +// CHECK: fir.copy %[[VAL_6]] to %[[VAL_34]] : {{.*}} +// CHECK: %[[VAL_35:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_36:.*]] = fir.coordinate_of %[[VAL_5]], __address : {{.*}} +// CHECK: %[[VAL_37:.*]] = fir.load %[[VAL_36]] : !fir.ref +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_16]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_37]] : (i64) -> !fir.llvm_ptr +// CHECK: fir.call @_FortranAAllocatableSetBaseAddr(%[[VAL_38]], %[[VAL_39]]) : (!fir.ref>, !fir.llvm_ptr) -> () +// CHECK: %[[VAL_40:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref> +// CHECK: %[[LINE:.*]] = arith.constant {{[0-9]+}} : i32 +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_16]]#0 : ({{.*}}) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_40]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAInitialize(%[[VAL_41]], %[[VAL_42]], %[[LINE]]) : (!fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_43:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_44:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_19]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_sync_all(%[[VAL_44]], %[[VAL_45]], %[[VAL_43]]) : (!fir.ref, !fir.box>, !fir.box>) -> () +// CHECK: %[[VAL_46:.*]] = fir.load %[[VAL_16]]#0 : {{.*}} +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_46]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_48:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_50:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_51:.*]] = fir.coordinate_of %[[VAL_2]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_49]] to %[[VAL_51]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[VAL_2]], %[[VAL_3]], %[[VAL_48]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_52:.*]] = fir.load %[[VAL_3]] : !fir.ref +// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_52]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_53]] to %[[VAL_12]]#0 : !fir.ref +// CHECK: %[[VAL_54:.*]] = fir.load %[[VAL_16]]#0 : {{.*}} +// CHECK: %[[VAL_55:.*]] = fir.box_addr %[[VAL_54]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_56:.*]] = fir.convert %[[VAL_55]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_57:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_58:.*]] = fir.coordinate_of %[[VAL_0]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_56]] to %[[VAL_58]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[VAL_0]], %[[VAL_1]], %[[VAL_18]]#0) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_59:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_60:.*]] = fir.convert %[[VAL_59]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_60]] to %[[VAL_12]]#0 : !fir.ref +// CHECK: %[[VAL_61:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_62:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_63:.*]] = fir.address_of(@_QFquery_allocatableEev_coarray_handle) : {{.*}} +// CHECK: %[[VAL_64:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_65:.*]] = fir.convert %[[VAL_63]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_66:.*]] = fir.convert %[[VAL_61]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_deallocate_coarray(%[[VAL_65]], %[[VAL_62]], %[[VAL_66]], %[[VAL_64]]) : (!fir.ref, !fir.ref, !fir.box>, !fir.box>) -> () +// CHECK: %[[VAL_67:.*]] = fir.absent !fir.ref>, corank:1>> +// CHECK: %[[VAL_68:.*]] = fir.convert %[[VAL_16]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_69:.*]] = fir.convert %[[VAL_67]] : ({{.*}}) -> !fir.llvm_ptr +// CHECK: fir.call @_FortranAPointerAssociateScalar(%[[VAL_68]], %[[VAL_69]]) : (!fir.ref>, !fir.llvm_ptr) -> () +// CHECK: %[[VAL_70:.*]] = fir.load %[[VAL_16]]#0 : {{.*}} +// CHECK: %[[VAL_71:.*]] = fir.box_addr %[[VAL_70]] : ({{.*}}) -> !fir.heap> +// CHECK: %[[VAL_72:.*]] = fir.convert %[[VAL_71]] : (!fir.heap>) -> i64 +// CHECK: %[[C0_I64:.*]] = arith.constant 0 : i64 +// CHECK: %[[VAL_73:.*]] = arith.cmpi ne, %[[VAL_72]], %[[C0_I64]] : i64 +// CHECK: fir.if %[[VAL_73]] { +// CHECK: %[[VAL_74:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_75:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_76:.*]] = fir.address_of(@_QFquery_allocatableEev_coarray_handle) : {{.*}} +// CHECK: %[[VAL_77:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_78:.*]] = fir.convert %[[VAL_76]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_79:.*]] = fir.convert %[[VAL_74]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_deallocate_coarray(%[[VAL_78]], %[[VAL_75]], %[[VAL_79]], %[[VAL_77]]) : (!fir.ref, !fir.ref, !fir.box>, !fir.box>) -> () +// CHECK: %[[VAL_80:.*]] = fir.absent !fir.ref>, corank:1>> +// CHECK: %[[VAL_81:.*]] = fir.convert %[[VAL_16]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_82:.*]] = fir.convert %[[VAL_80]] : ({{.*}}) -> !fir.llvm_ptr +// CHECK: fir.call @_FortranAPointerAssociateScalar(%[[VAL_81]], %[[VAL_82]]) : (!fir.ref>, !fir.llvm_ptr) -> () +// CHECK: } +// CHECK: return +// CHECK: } + +// CHECK-LABEL: func.func @_QPquery_allocatable_array +// CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_1:.*]] = fir.alloca i64 +// CHECK: %[[VAL_2:.*]] = fir.alloca i64 +// CHECK: %[[VAL_3:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_4:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{{.*}}> +// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.boxproc<(!fir.ref, !fir.ref, !fir.box>) -> ()> +// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.array<0xi64> +// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.array<1xi64> +// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_9:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_allocatable_arrayEcount"}> +// CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_9]] uniq_name("_QFquery_allocatable_arrayEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_11:.*]] = fir.alloca {{.*}} <{bindc_name = "ev", uniq_name = "_QFquery_allocatable_arrayEev"}> +// CHECK: %[[VAL_12:.*]] = fir.zero_bits !fir.heap>> +// CHECK: %[[C0:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_13:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_14:.*]] = fir.embox %[[VAL_12]](%[[VAL_13]]) : {{.*}} +// CHECK: fir.store %[[VAL_14]] to %[[VAL_11]] : {{.*}} +// CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_11]] uniq_name("_QFquery_allocatable_arrayEev") fortran_attrs : {{.*}} +// CHECK: %[[VAL_16:.*]] = fir.alloca i32 <{bindc_name = "i", uniq_name = "_QFquery_allocatable_arrayEi"}> +// CHECK: %[[VAL_17:.*]]:2 = hlfir.declare %[[VAL_16]] uniq_name("_QFquery_allocatable_arrayEi") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_18:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_8]] arg 1 uniq_name("_QFquery_allocatable_arrayEn") fortran_attrs : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_19:.*]] = fir.absent !fir.box +// CHECK: %[[C1:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_18]]#0 : !fir.ref +// CHECK: %[[C0_I32:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_15]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_22:.*]] = fir.convert %[[C1]] : (index) -> i64 +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (i32) -> i64 +// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_21]], %[[C0_I32]], %[[VAL_22]], %[[VAL_23]]) fastmath : (!fir.ref>, i32, i64, i64) -> () +// CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64 +// CHECK: %[[C0_0:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_24:.*]] = fir.coordinate_of %[[VAL_7]], %[[C0_0]] : (!fir.ref>, index) -> !fir.ref +// CHECK: fir.store %[[C1_I64]] to %[[VAL_24]] : !fir.ref +// CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_7]] : (!fir.ref>) -> !fir.box> +// CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_6]] : (!fir.ref>) -> !fir.box> +// CHECK: %[[VAL_27:.*]] = fir.zero_bits (!fir.ref, !fir.ref, !fir.box>) -> () +// CHECK: %[[VAL_28:.*]] = fir.emboxproc %[[VAL_27]] : {{.*}} +// CHECK: fir.store %[[VAL_28]] to %[[VAL_5]] : {{.*}} +// CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_15]]#0 : {{.*}} +// CHECK: %[[VAL_30:.*]] = fir.box_elesize %[[VAL_29]] : ({{.*}}) -> i64 +// CHECK: %[[VAL_31:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref> +// CHECK: %[[LINE:.*]] = arith.constant {{[0-9]+}} : i32 +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_29]] : ({{.*}}) -> !fir.box +// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_31]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_34:.*]] = fir.call @_FortranASize(%[[VAL_32]], %[[VAL_33]], %[[LINE]]) : (!fir.box, !fir.ref, i32) -> i64 +// CHECK: %[[VAL_35:.*]] = arith.muli %[[VAL_30]], %[[VAL_34]] : i64 +// CHECK: fir.store %[[VAL_35]] to %[[VAL_2]] : !fir.ref +// CHECK: %[[VAL_36:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_25]] : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_26]] : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_5]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_4]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_19]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_allocate_coarray(%[[VAL_38]], %[[VAL_39]], %[[VAL_2]], %[[VAL_40]], %[[VAL_41]], %[[VAL_3]], %[[VAL_36]], %[[VAL_42]], %[[VAL_37]]) : {{.*}} +// CHECK: %[[VAL_43:.*]] = fir.address_of(@_QFquery_allocatable_arrayEev_coarray_handle) : {{.*}} +// CHECK: fir.copy %[[VAL_4]] to %[[VAL_43]] : {{.*}} +// CHECK: %[[VAL_44:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_45:.*]] = fir.coordinate_of %[[VAL_3]], __address : {{.*}} +// CHECK: %[[VAL_46:.*]] = fir.load %[[VAL_45]] : !fir.ref +// CHECK: %[[VAL_47:.*]] = fir.convert %[[VAL_15]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (i64) -> !fir.llvm_ptr +// CHECK: fir.call @_FortranAAllocatableSetBaseAddr(%[[VAL_47]], %[[VAL_48]]) : (!fir.ref>, !fir.llvm_ptr) -> () +// CHECK: %[[VAL_49:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref> +// CHECK: %[[LINE_2:.*]] = arith.constant {{[0-9]+}} : i32 +// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_15]]#0 : ({{.*}}) -> !fir.box +// CHECK: %[[VAL_51:.*]] = fir.convert %[[VAL_49]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAInitialize(%[[VAL_50]], %[[VAL_51]], %[[LINE_2]]) : (!fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_52:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_53:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_19]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_sync_all(%[[VAL_53]], %[[VAL_54]], %[[VAL_52]]) : (!fir.ref, !fir.box>, !fir.box>) -> () +// CHECK: %[[C1_I32:.*]] = arith.constant 1 : i32 +// CHECK: %[[VAL_55:.*]] = fir.load %[[VAL_18]]#0 : !fir.ref +// CHECK: %[[C1_I32_3:.*]] = arith.constant 1 : i32 +// CHECK: fir.do_loop %[[ARG1:.*]] = %[[C1_I32]] to %[[VAL_55]] step %[[C1_I32_3]] : i32 { +// CHECK: fir.store %[[ARG1]] to %[[VAL_17]]#0 : !fir.ref +// CHECK: %[[VAL_80:.*]] = fir.load %[[VAL_15]]#0 : {{.*}} +// CHECK: %[[VAL_81:.*]] = fir.load %[[VAL_17]]#0 : !fir.ref +// CHECK: %[[VAL_82:.*]] = fir.convert %[[VAL_81]] : (i32) -> i64 +// CHECK: %[[VAL_83:.*]] = hlfir.designate %[[VAL_80]] (%[[VAL_82]]) : ({{.*}}, i64) -> !fir.ref> +// CHECK: %[[VAL_84:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_85:.*]] = fir.convert %[[VAL_83]] : (!fir.ref>) -> i64 +// CHECK: %[[VAL_86:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_87:.*]] = fir.coordinate_of %[[VAL_0]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_85]] to %[[VAL_87]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[VAL_0]], %[[VAL_1]], %[[VAL_84]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_88:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_89:.*]] = fir.convert %[[VAL_88]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_89]] to %[[VAL_10]]#0 : !fir.ref +// CHECK: } +// CHECK: %[[VAL_56:.*]] = fir.convert %[[C1_I32]] : (i32) -> index +// CHECK: %[[VAL_57:.*]] = fir.convert %[[VAL_55]] : (i32) -> index +// CHECK: %[[VAL_58:.*]] = fir.convert %[[C1_I32_3]] : (i32) -> index +// CHECK: %[[C0_4:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_59:.*]] = arith.subi %[[VAL_57]], %[[VAL_56]] : index +// CHECK: %[[VAL_60:.*]] = arith.addi %[[VAL_59]], %[[VAL_58]] : index +// CHECK: %[[VAL_61:.*]] = arith.divsi %[[VAL_60]], %[[VAL_58]] : index +// CHECK: %[[VAL_62:.*]] = arith.cmpi slt, %[[VAL_61]], %[[C0_4]] : index +// CHECK: %[[VAL_63:.*]] = arith.select %[[VAL_62]], %[[C0_4]], %[[VAL_61]] : index +// CHECK: %[[VAL_64:.*]] = arith.muli %[[VAL_63]], %[[VAL_58]] : index +// CHECK: %[[VAL_65:.*]] = arith.addi %[[VAL_56]], %[[VAL_64]] : index +// CHECK: %[[VAL_66:.*]] = fir.convert %[[VAL_65]] : (index) -> i32 +// CHECK: fir.store %[[VAL_66]] to %[[VAL_17]]#0 : !fir.ref +// CHECK: %[[VAL_67:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_68:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_69:.*]] = fir.address_of(@_QFquery_allocatable_arrayEev_coarray_handle) : {{.*}} +// CHECK: %[[VAL_70:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_71:.*]] = fir.convert %[[VAL_69]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_72:.*]] = fir.convert %[[VAL_67]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_deallocate_coarray(%[[VAL_71]], %[[VAL_68]], %[[VAL_72]], %[[VAL_70]]) : (!fir.ref, !fir.ref, !fir.box>, !fir.box>) -> () +// CHECK: %[[VAL_73:.*]] = fir.absent !fir.ref>>, corank:1>> +// CHECK: %[[VAL_74:.*]] = fir.convert %[[VAL_15]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_75:.*]] = fir.convert %[[VAL_73]] : ({{.*}}) -> !fir.llvm_ptr +// CHECK: fir.call @_FortranAPointerAssociateScalar(%[[VAL_74]], %[[VAL_75]]) : (!fir.ref>, !fir.llvm_ptr) -> () +// CHECK: %[[VAL_76:.*]] = fir.load %[[VAL_15]]#0 : {{.*}} +// CHECK: %[[VAL_77:.*]] = fir.box_addr %[[VAL_76]] : ({{.*}}) -> !fir.heap>> +// CHECK: %[[VAL_78:.*]] = fir.convert %[[VAL_77]] : ({{.*}}) -> i64 +// CHECK: %[[C0_I64:.*]] = arith.constant 0 : i64 +// CHECK: %[[VAL_79:.*]] = arith.cmpi ne, %[[VAL_78]], %[[C0_I64]] : i64 +// CHECK: fir.if %[[VAL_79]] { +// CHECK: %[[VAL_80:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_81:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_82:.*]] = fir.address_of(@_QFquery_allocatable_arrayEev_coarray_handle) : {{.*}} +// CHECK: %[[VAL_83:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_84:.*]] = fir.convert %[[VAL_82]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_85:.*]] = fir.convert %[[VAL_80]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_deallocate_coarray(%[[VAL_84]], %[[VAL_81]], %[[VAL_85]], %[[VAL_83]]) : (!fir.ref, !fir.ref, !fir.box>, !fir.box>) -> () +// CHECK: %[[VAL_86:.*]] = fir.absent !fir.ref>>, corank:1>> +// CHECK: %[[VAL_87:.*]] = fir.convert %[[VAL_15]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_88:.*]] = fir.convert %[[VAL_86]] : ({{.*}}) -> !fir.llvm_ptr +// CHECK: fir.call @_FortranAPointerAssociateScalar(%[[VAL_87]], %[[VAL_88]]) : (!fir.ref>, !fir.llvm_ptr) -> () +// CHECK: } +// CHECK: return +// CHECK: } + +// CHECK-LABEL: func.func @_QPquery_class_allocatable() { +// CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_1:.*]] = fir.alloca i64 +// CHECK: %[[VAL_2:.*]] = fir.alloca i64 +// CHECK: %[[VAL_3:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_4:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_prif_coarray_handle_type{{.*}}> +// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.boxproc<(!fir.ref, !fir.ref, !fir.box>) -> ()> +// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.array<0xi64> +// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.array<1xi64> +// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_9:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_class_allocatableEcount"}> +// CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_9]] uniq_name("_QFquery_class_allocatableEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_11:.*]] = fir.alloca !fir.class<{{.*}}> <{bindc_name = "ev", uniq_name = "_QFquery_class_allocatableEev"}> +// CHECK: %[[VAL_12:.*]] = fir.zero_bits !fir.heap> +// CHECK: %[[VAL_13:.*]] = fir.embox %[[VAL_12]] : ({{.*}}) -> !fir.class<{{.*}}> +// CHECK: fir.store %[[VAL_13]] to %[[VAL_11]] : {{.*}} +// CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_11]] uniq_name("_QFquery_class_allocatableEev") fortran_attrs : {{.*}} +// CHECK: %[[VAL_15:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_16:.*]] = fir.type_desc !fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}> +// CHECK: %[[C0_I32:.*]] = arith.constant 0 : i32 +// CHECK: %[[C0_I32_0:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_14]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_16]] : ({{.*}}) -> !fir.ref +// CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[VAL_17]], %[[VAL_18]], %[[C0_I32]], %[[C0_I32_0]]) fastmath : (!fir.ref>, !fir.ref, i32, i32) -> () +// CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64 +// CHECK: %[[C0:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_19:.*]] = fir.coordinate_of %[[VAL_7]], %[[C0]] : (!fir.ref>, index) -> !fir.ref +// CHECK: fir.store %[[C1_I64]] to %[[VAL_19]] : !fir.ref +// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_7]] : (!fir.ref>) -> !fir.box> +// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_6]] : (!fir.ref>) -> !fir.box> +// CHECK: %[[VAL_22:.*]] = fir.zero_bits (!fir.ref, !fir.ref, !fir.box>) -> () +// CHECK: %[[VAL_23:.*]] = fir.emboxproc %[[VAL_22]] : {{.*}} +// CHECK: fir.store %[[VAL_23]] to %[[VAL_5]] : {{.*}} +// CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_14]]#0 : {{.*}} +// CHECK: %[[VAL_25:.*]] = fir.box_elesize %[[VAL_24]] : ({{.*}}) -> i64 +// CHECK: fir.store %[[VAL_25]] to %[[VAL_2]] : !fir.ref +// CHECK: %[[VAL_26:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_27:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_20]] : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_21]] : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_5]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_15]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_allocate_coarray(%[[VAL_28]], %[[VAL_29]], %[[VAL_2]], %[[VAL_30]], %[[VAL_31]], %[[VAL_3]], %[[VAL_26]], %[[VAL_32]], %[[VAL_27]]) : {{.*}} +// CHECK: %[[VAL_33:.*]] = fir.address_of(@_QFquery_class_allocatableEev_coarray_handle) : {{.*}} +// CHECK: fir.copy %[[VAL_4]] to %[[VAL_33]] : {{.*}} +// CHECK: %[[VAL_34:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_35:.*]] = fir.coordinate_of %[[VAL_3]], __address : {{.*}} +// CHECK: %[[VAL_36:.*]] = fir.load %[[VAL_35]] : !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_14]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_36]] : (i64) -> !fir.llvm_ptr +// CHECK: fir.call @_FortranAAllocatableSetBaseAddr(%[[VAL_37]], %[[VAL_38]]) : (!fir.ref>, !fir.llvm_ptr) -> () +// CHECK: %[[VAL_39:.*]] = fir.address_of(@_QQcl{{.*}}) : !fir.ref> +// CHECK: %[[LINE:.*]] = arith.constant {{[0-9]+}} : i32 +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_14]]#0 : ({{.*}}) -> !fir.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAInitialize(%[[VAL_40]], %[[VAL_41]], %[[LINE]]) : (!fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_42:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_43:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_44:.*]] = fir.convert %[[VAL_15]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_sync_all(%[[VAL_43]], %[[VAL_44]], %[[VAL_42]]) : (!fir.ref, !fir.box>, !fir.box>) -> () +// CHECK: %[[VAL_45:.*]] = fir.load %[[VAL_14]]#0 : {{.*}} +// CHECK: %[[VAL_46:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_45]] : (!fir.class<{{.*}}>) -> !fir.heap> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> i64 +// CHECK: %[[VAL_49:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> +// CHECK: %[[VAL_50:.*]] = fir.coordinate_of %[[VAL_0]], __address : (!fir.ref>) -> !fir.ref +// CHECK: fir.store %[[VAL_48]] to %[[VAL_50]] : !fir.ref +// CHECK: fir.call @_QMprifPprif_event_query(%[[VAL_0]], %[[VAL_1]], %[[VAL_46]]) : (!fir.ref>, !fir.ref, !fir.ref) -> () +// CHECK: %[[VAL_51:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_51]] : (i64) -> i32 +// CHECK: fir.store %[[VAL_52]] to %[[VAL_10]]#0 : !fir.ref +// CHECK: %[[VAL_53:.*]] = fir.load %[[VAL_14]]#0 : {{.*}} +// CHECK: %[[VAL_54:.*]] = fir.box_addr %[[VAL_53]] : (!fir.class<{{.*}}>) -> !fir.heap> +// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_54]] : (!fir.heap>) -> i64 +// CHECK: %[[C0_I64:.*]] = arith.constant 0 : i64 +// CHECK: %[[VAL_56:.*]] = arith.cmpi ne, %[[VAL_55]], %[[C0_I64]] : i64 +// CHECK: fir.if %[[VAL_56]] { +// CHECK: %[[VAL_57:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_58:.*]] = fir.absent !fir.ref +// CHECK: %[[VAL_59:.*]] = fir.address_of(@_QFquery_class_allocatableEev_coarray_handle) : {{.*}} +// CHECK: %[[VAL_60:.*]] = fir.absent !fir.box> +// CHECK: %[[VAL_61:.*]] = fir.convert %[[VAL_59]] : {{.*}} -> !fir.ref +// CHECK: %[[VAL_62:.*]] = fir.convert %[[VAL_57]] : (!fir.box) -> !fir.box> +// CHECK: fir.call @_QMprifPprif_deallocate_coarray(%[[VAL_61]], %[[VAL_58]], %[[VAL_62]], %[[VAL_60]]) : (!fir.ref, !fir.ref, !fir.box>, !fir.box>) -> () +// CHECK: %[[VAL_63:.*]] = fir.absent !fir.ref> +// CHECK: %[[VAL_64:.*]] = fir.convert %[[VAL_14]]#0 : ({{.*}}) -> !fir.ref> +// CHECK: %[[VAL_65:.*]] = fir.convert %[[VAL_63]] : ({{.*}}) -> !fir.llvm_ptr +// CHECK: fir.call @_FortranAPointerAssociateScalar(%[[VAL_64]], %[[VAL_65]]) : (!fir.ref>, !fir.llvm_ptr) -> () +// CHECK: } +// CHECK: return +// CHECK: } diff --git a/flang/test/Lower/MIF/event_query01.f90 b/flang/test/Lower/MIF/event_query01.f90 new file mode 100644 index 00000000000000..8c1b671e9028ea --- /dev/null +++ b/flang/test/Lower/MIF/event_query01.f90 @@ -0,0 +1,105 @@ +! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY +! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY + +! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable. + +subroutine query_base() + use iso_fortran_env, only: event_type + type(event_type), save :: ev[*] + integer :: count + call event_query(ev, count) +end subroutine + +! COARRAY-LABEL: func.func @_QPquery_base() { +! COARRAY: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! COARRAY: %[[VAL_1:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_baseEcount"}> +! COARRAY: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] uniq_name("_QFquery_baseEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_3:.*]] = fir.address_of(@_QFquery_baseEev) : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_baseEev") : {{.*}} +! COARRAY: %[[VAL_5:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_6:.*]] = fir.box_addr %[[VAL_5]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_7:.*]] = mif.event_query %[[VAL_6]] : (!fir.heap>) -> i32 +! COARRAY: fir.store %[[VAL_7]] to %[[VAL_2]]#0 : !fir.ref +! COARRAY: return +! COARRAY: } + + +subroutine query_with_stat() + use iso_fortran_env, only: event_type + type(event_type), save :: ev[*] + integer :: count, stat + call event_query(ev, count, stat) +end subroutine + +! COARRAY-LABEL: func.func @_QPquery_with_stat() { +! COARRAY: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! COARRAY: %[[VAL_1:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_with_statEcount"}> +! COARRAY: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] uniq_name("_QFquery_with_statEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_3:.*]] = fir.address_of(@_QFquery_with_statEev) : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_with_statEev") : {{.*}} +! COARRAY: %[[VAL_5:.*]] = fir.alloca i32 <{bindc_name = "stat", uniq_name = "_QFquery_with_statEstat"}> +! COARRAY: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] uniq_name("_QFquery_with_statEstat") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_7:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_9:.*]] = mif.event_query %[[VAL_8]] stat %[[VAL_6]]#0 : (!fir.heap>, !fir.ref) -> i32 +! COARRAY: fir.store %[[VAL_9]] to %[[VAL_2]]#0 : !fir.ref +! COARRAY: return +! COARRAY: } + +subroutine query_with_kinds() + use iso_fortran_env, only: event_type, int16, int32, int64 + type(event_type), save :: ev[*] + integer(int32) :: c4 + integer(int64) :: c8 + integer(int16) :: s2 + integer(int32) :: s4 + integer(int64) :: s8 + call event_query(ev, c4) + call event_query(ev, c8) + call event_query(ev, c4, s2) + call event_query(ev, c4, s4) + call event_query(ev, c8, s8) +end subroutine + +! COARRAY-LABEL: func.func @_QPquery_with_kinds() { +! COARRAY: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! COARRAY: %[[VAL_1:.*]] = fir.alloca i32 <{bindc_name = "c4", uniq_name = "_QFquery_with_kindsEc4"}> +! COARRAY: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] uniq_name("_QFquery_with_kindsEc4") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_3:.*]] = fir.alloca i64 <{bindc_name = "c8", uniq_name = "_QFquery_with_kindsEc8"}> +! COARRAY: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_with_kindsEc8") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_5:.*]] = fir.address_of(@_QFquery_with_kindsEev) : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] uniq_name("_QFquery_with_kindsEev") : {{.*}} +! COARRAY: %[[VAL_7:.*]] = fir.address_of(@_QMiso_fortran_env_implECint16) : !fir.ref +! COARRAY: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_7]] uniq_name("_QMiso_fortran_env_implECint16") fortran_attrs : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_9:.*]] = fir.address_of(@_QMiso_fortran_env_implECint32) : !fir.ref +! COARRAY: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_9]] uniq_name("_QMiso_fortran_env_implECint32") fortran_attrs : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_11:.*]] = fir.address_of(@_QMiso_fortran_env_implECint64) : !fir.ref +! COARRAY: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] uniq_name("_QMiso_fortran_env_implECint64") fortran_attrs : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_13:.*]] = fir.alloca i16 <{bindc_name = "s2", uniq_name = "_QFquery_with_kindsEs2"}> +! COARRAY: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_13]] uniq_name("_QFquery_with_kindsEs2") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_15:.*]] = fir.alloca i32 <{bindc_name = "s4", uniq_name = "_QFquery_with_kindsEs4"}> +! COARRAY: %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_15]] uniq_name("_QFquery_with_kindsEs4") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_17:.*]] = fir.alloca i64 <{bindc_name = "s8", uniq_name = "_QFquery_with_kindsEs8"}> +! COARRAY: %[[VAL_18:.*]]:2 = hlfir.declare %[[VAL_17]] uniq_name("_QFquery_with_kindsEs8") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_19:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_20:.*]] = fir.box_addr %[[VAL_19]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_21:.*]] = mif.event_query %[[VAL_20]] : (!fir.heap>) -> i32 +! COARRAY: fir.store %[[VAL_21]] to %[[VAL_2]]#0 : !fir.ref +! COARRAY: %[[VAL_22:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_23:.*]] = fir.box_addr %[[VAL_22]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_24:.*]] = mif.event_query %[[VAL_23]] : (!fir.heap>) -> i64 +! COARRAY: fir.store %[[VAL_24]] to %[[VAL_4]]#0 : !fir.ref +! COARRAY: %[[VAL_25:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_26:.*]] = fir.box_addr %[[VAL_25]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_27:.*]] = mif.event_query %[[VAL_26]] stat %[[VAL_14]]#0 : (!fir.heap>, !fir.ref) -> i32 +! COARRAY: fir.store %[[VAL_27]] to %[[VAL_2]]#0 : !fir.ref +! COARRAY: %[[VAL_28:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_29:.*]] = fir.box_addr %[[VAL_28]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_30:.*]] = mif.event_query %[[VAL_29]] stat %[[VAL_16]]#0 : (!fir.heap>, !fir.ref) -> i32 +! COARRAY: fir.store %[[VAL_30]] to %[[VAL_2]]#0 : !fir.ref +! COARRAY: %[[VAL_31:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_32:.*]] = fir.box_addr %[[VAL_31]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_33:.*]] = mif.event_query %[[VAL_32]] stat %[[VAL_18]]#0 : (!fir.heap>, !fir.ref) -> i64 +! COARRAY: fir.store %[[VAL_33]] to %[[VAL_4]]#0 : !fir.ref +! COARRAY: return +! COARRAY: } diff --git a/flang/test/Lower/MIF/event_query02.f90 b/flang/test/Lower/MIF/event_query02.f90 new file mode 100644 index 00000000000000..5406edad735ab9 --- /dev/null +++ b/flang/test/Lower/MIF/event_query02.f90 @@ -0,0 +1,266 @@ +! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s --check-prefixes=COARRAY +! RUN: not %flang_fc1 -emit-hlfir %s 2>&1 | FileCheck %s --check-prefixes=NOCOARRAY + +! NOCOARRAY: Not yet implemented: Multi-image features are experimental and are disabled by default, use '-fcoarray' to enable. + +subroutine query_array_element() + use iso_fortran_env, only: event_type + type(event_type), save :: ev(3)[*] + integer :: count + call event_query(ev(2), count) +end subroutine + +! COARRAY-LABEL: func.func @_QPquery_array_element() { +! COARRAY: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! COARRAY: %[[VAL_1:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_array_elementEcount"}> +! COARRAY: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] uniq_name("_QFquery_array_elementEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_3:.*]] = fir.address_of(@_QFquery_array_elementEev) : !fir.ref>>, corank:1>> +! COARRAY: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_array_elementEev") : {{.*}} +! COARRAY: %[[VAL_5:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref>>, corank:1>> +! COARRAY: %[[C2:.*]] = arith.constant 2 : index +! COARRAY: %[[VAL_6:.*]] = hlfir.designate %[[VAL_5]] (%[[C2]]) {{.*}} -> !fir.ref> +! COARRAY: %[[VAL_7:.*]] = mif.event_query %[[VAL_6]] : (!fir.ref>) -> i32 +! COARRAY: fir.store %[[VAL_7]] to %[[VAL_2]]#0 : !fir.ref +! COARRAY: return + +subroutine query_array_in_loop() + use iso_fortran_env, only: event_type + type(event_type), save :: ev(4)[*] + integer :: counts(4), stats(4), i + do i = 1, 4 + call event_query(ev(i), counts(i), stats(i)) + end do +end subroutine + +! COARRAY-LABEL: func.func @_QPquery_array_in_loop() { +! COARRAY: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! COARRAY: %[[C4:.*]] = arith.constant 4 : index +! COARRAY: %[[VAL_1:.*]] = fir.alloca !fir.array<4xi32> <{bindc_name = "counts", uniq_name = "_QFquery_array_in_loopEcounts"}> +! COARRAY: %[[VAL_2:.*]] = fir.shape %[[C4]] : (index) -> !fir.shape<1> +! COARRAY: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_2]]) uniq_name("_QFquery_array_in_loopEcounts") : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! COARRAY: %[[VAL_4:.*]] = fir.address_of(@_QFquery_array_in_loopEev) : !fir.ref>>, corank:1>> +! COARRAY: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] uniq_name("_QFquery_array_in_loopEev") : {{.*}} +! COARRAY: %[[VAL_6:.*]] = fir.alloca i32 <{bindc_name = "i", uniq_name = "_QFquery_array_in_loopEi"}> +! COARRAY: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] uniq_name("_QFquery_array_in_loopEi") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[C4_0:.*]] = arith.constant 4 : index +! COARRAY: %[[VAL_8:.*]] = fir.alloca !fir.array<4xi32> <{bindc_name = "stats", uniq_name = "_QFquery_array_in_loopEstats"}> +! COARRAY: %[[VAL_9:.*]] = fir.shape %[[C4_0]] : (index) -> !fir.shape<1> +! COARRAY: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]](%[[VAL_9]]) uniq_name("_QFquery_array_in_loopEstats") : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! COARRAY: %[[C1_I32:.*]] = arith.constant 1 : i32 +! COARRAY: %[[C4_I32:.*]] = arith.constant 4 : i32 +! COARRAY: %[[C1_I32_1:.*]] = arith.constant 1 : i32 +! COARRAY: fir.do_loop %[[ARG0:.*]] = %[[C1_I32]] to %[[C4_I32]] step %[[C1_I32_1]] : i32 { +! COARRAY: fir.store %[[ARG0]] to %[[VAL_7]]#0 : !fir.ref +! COARRAY: %[[VAL_22:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref>>, corank:1>> +! COARRAY: %[[VAL_23:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref +! COARRAY: %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (i32) -> i64 +! COARRAY: %[[VAL_25:.*]] = hlfir.designate %[[VAL_22]] (%[[VAL_24]]) {{.*}} -> !fir.ref> +! COARRAY: %[[VAL_26:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref +! COARRAY: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i32) -> i64 +! COARRAY: %[[VAL_28:.*]] = hlfir.designate %[[VAL_3]]#0 (%[[VAL_27]]) {{.*}} -> !fir.ref +! COARRAY: %[[VAL_29:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref +! COARRAY: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i32) -> i64 +! COARRAY: %[[VAL_31:.*]] = hlfir.designate %[[VAL_10]]#0 (%[[VAL_30]]) {{.*}} -> !fir.ref +! COARRAY: %[[VAL_32:.*]] = mif.event_query %[[VAL_25]] stat %[[VAL_31]] : (!fir.ref>, !fir.ref) -> i32 +! COARRAY: fir.store %[[VAL_32]] to %[[VAL_28]] : !fir.ref +! COARRAY: } +! COARRAY: %[[VAL_11:.*]] = fir.convert %[[C1_I32]] : (i32) -> index +! COARRAY: %[[VAL_12:.*]] = fir.convert %[[C4_I32]] : (i32) -> index +! COARRAY: %[[VAL_13:.*]] = fir.convert %[[C1_I32_1]] : (i32) -> index +! COARRAY: %[[C0:.*]] = arith.constant 0 : index +! COARRAY: %[[VAL_14:.*]] = arith.subi %[[VAL_12]], %[[VAL_11]] : index +! COARRAY: %[[VAL_15:.*]] = arith.addi %[[VAL_14]], %[[VAL_13]] : index +! COARRAY: %[[VAL_16:.*]] = arith.divsi %[[VAL_15]], %[[VAL_13]] : index +! COARRAY: %[[VAL_17:.*]] = arith.cmpi slt, %[[VAL_16]], %[[C0]] : index +! COARRAY: %[[VAL_18:.*]] = arith.select %[[VAL_17]], %[[C0]], %[[VAL_16]] : index +! COARRAY: %[[VAL_19:.*]] = arith.muli %[[VAL_18]], %[[VAL_13]] : index +! COARRAY: %[[VAL_20:.*]] = arith.addi %[[VAL_11]], %[[VAL_19]] : index +! COARRAY: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (index) -> i32 +! COARRAY: fir.store %[[VAL_21]] to %[[VAL_7]]#0 : !fir.ref +! COARRAY: return + +subroutine query_allocatable() + use iso_fortran_env, only: event_type + type(event_type), allocatable :: ev[:] + integer :: count, stat + allocate(ev[*]) + call event_query(ev, count) + call event_query(ev, count, stat) + deallocate(ev) +end subroutine + +! COARRAY-LABEL: func.func @_QPquery_allocatable() { +! COARRAY: %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64> +! COARRAY: %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64> +! COARRAY: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! COARRAY: %[[VAL_3:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_allocatableEcount"}> +! COARRAY: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_allocatableEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_5:.*]] = fir.alloca !fir.box>, corank:1> {{.*}}uniq_name = "_QFquery_allocatableEev"{{.*}} +! COARRAY: %[[VAL_6:.*]] = fir.zero_bits !fir.heap> +! COARRAY: %[[VAL_7:.*]] = fir.embox %[[VAL_6]] : ({{.*}}) -> !fir.box>, corank:1> +! COARRAY: fir.store %[[VAL_7]] to %[[VAL_5]] : {{.*}} +! COARRAY: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_5]] uniq_name("_QFquery_allocatableEev") fortran_attrs : {{.*}} +! COARRAY: %[[VAL_9:.*]] = fir.alloca i32 <{bindc_name = "stat", uniq_name = "_QFquery_allocatableEstat"}> +! COARRAY: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_9]] uniq_name("_QFquery_allocatableEstat") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_11:.*]] = fir.absent !fir.box +! COARRAY: %[[C1_I64:.*]] = arith.constant 1 : i64 +! COARRAY: %[[C0:.*]] = arith.constant 0 : index +! COARRAY: %[[VAL_12:.*]] = fir.coordinate_of %[[VAL_1]], %[[C0]] : (!fir.ref>, index) -> !fir.ref +! COARRAY: fir.store %[[C1_I64]] to %[[VAL_12]] : !fir.ref +! COARRAY: %[[VAL_13:.*]] = fir.embox %[[VAL_1]] : (!fir.ref>) -> !fir.box> +! COARRAY: %[[VAL_14:.*]] = fir.embox %[[VAL_0]] : (!fir.ref>) -> !fir.box> +! COARRAY: mif.alloc_coarray %[[VAL_8]]#0 lcobounds %[[VAL_13]] ucobounds %[[VAL_14]] errmsg %[[VAL_11]] uniq_name("_QFquery_allocatableEev") : {{.*}} +! COARRAY: %[[VAL_15:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_16:.*]] = fir.box_addr %[[VAL_15]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_17:.*]] = mif.event_query %[[VAL_16]] : (!fir.heap>) -> i32 +! COARRAY: fir.store %[[VAL_17]] to %[[VAL_4]]#0 : !fir.ref +! COARRAY: %[[VAL_18:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_19:.*]] = fir.box_addr %[[VAL_18]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_20:.*]] = mif.event_query %[[VAL_19]] stat %[[VAL_10]]#0 : (!fir.heap>, !fir.ref) -> i32 +! COARRAY: fir.store %[[VAL_20]] to %[[VAL_4]]#0 : !fir.ref +! COARRAY: %[[VAL_21:.*]] = fir.absent !fir.box +! COARRAY: %[[VAL_22:.*]] = fir.absent !fir.ref +! COARRAY: mif.dealloc_coarray %[[VAL_8]]#0 stat %[[VAL_22]] errmsg %[[VAL_21]] : {{.*}} +! COARRAY: %[[VAL_23:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_24:.*]] = fir.box_addr %[[VAL_23]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.heap>) -> i64 +! COARRAY: %[[C0_I64:.*]] = arith.constant 0 : i64 +! COARRAY: %[[VAL_26:.*]] = arith.cmpi ne, %[[VAL_25]], %[[C0_I64]] : i64 +! COARRAY: fir.if %[[VAL_26]] { +! COARRAY: %[[VAL_27:.*]] = fir.absent !fir.box +! COARRAY: %[[VAL_28:.*]] = fir.absent !fir.ref +! COARRAY: mif.dealloc_coarray %[[VAL_8]]#0 stat %[[VAL_28]] errmsg %[[VAL_27]] : {{.*}} +! COARRAY: } +! COARRAY: return + +subroutine query_allocatable_array(n) + use iso_fortran_env, only: event_type + integer, intent(in) :: n + type(event_type), allocatable :: ev(:)[:] + integer :: count, i + allocate(ev(n)[*]) + do i = 1, n + call event_query(ev(i), count) + end do + deallocate(ev) +end subroutine + +! COARRAY-LABEL: func.func @_QPquery_allocatable_array( +! COARRAY-SAME: %[[ARG0:.*]]: !fir.ref {fir.bindc_name = "n", fir.fortran_attrs = #fir.var_attrs, fir.read_only}) { +! COARRAY: %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64> +! COARRAY: %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64> +! COARRAY: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! COARRAY: %[[VAL_3:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_allocatable_arrayEcount"}> +! COARRAY: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_allocatable_arrayEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_5:.*]] = fir.alloca !fir.box>>, corank:1> {{.*}}uniq_name = "_QFquery_allocatable_arrayEev"{{.*}} +! COARRAY: %[[VAL_6:.*]] = fir.zero_bits !fir.heap>> +! COARRAY: %[[C0:.*]] = arith.constant 0 : index +! COARRAY: %[[VAL_7:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1> +! COARRAY: %[[VAL_8:.*]] = fir.embox %[[VAL_6]](%[[VAL_7]]) : {{.*}} -> !fir.box>>, corank:1> +! COARRAY: fir.store %[[VAL_8]] to %[[VAL_5]] : {{.*}} +! COARRAY: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_5]] uniq_name("_QFquery_allocatable_arrayEev") fortran_attrs : {{.*}} +! COARRAY: %[[VAL_10:.*]] = fir.alloca i32 <{bindc_name = "i", uniq_name = "_QFquery_allocatable_arrayEi"}> +! COARRAY: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] uniq_name("_QFquery_allocatable_arrayEi") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_12:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_2]] arg 1 uniq_name("_QFquery_allocatable_arrayEn") fortran_attrs : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_13:.*]] = fir.absent !fir.box +! COARRAY: %[[C1:.*]] = arith.constant 1 : index +! COARRAY: %[[VAL_14:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref +! COARRAY: %[[C0_I32:.*]] = arith.constant 0 : i32 +! COARRAY: %[[VAL_15:.*]] = fir.convert %[[VAL_9]]#0 : {{.*}} -> !fir.ref> +! COARRAY: %[[VAL_16:.*]] = fir.convert %[[C1]] : (index) -> i64 +! COARRAY: %[[VAL_17:.*]] = fir.convert %[[VAL_14]] : (i32) -> i64 +! COARRAY: fir.call @_FortranAAllocatableSetBounds(%[[VAL_15]], %[[C0_I32]], %[[VAL_16]], %[[VAL_17]]) fastmath : (!fir.ref>, i32, i64, i64) -> () +! COARRAY: %[[C1_I64:.*]] = arith.constant 1 : i64 +! COARRAY: %[[C0_0:.*]] = arith.constant 0 : index +! COARRAY: %[[VAL_18:.*]] = fir.coordinate_of %[[VAL_1]], %[[C0_0]] : (!fir.ref>, index) -> !fir.ref +! COARRAY: fir.store %[[C1_I64]] to %[[VAL_18]] : !fir.ref +! COARRAY: %[[VAL_19:.*]] = fir.embox %[[VAL_1]] : (!fir.ref>) -> !fir.box> +! COARRAY: %[[VAL_20:.*]] = fir.embox %[[VAL_0]] : (!fir.ref>) -> !fir.box> +! COARRAY: mif.alloc_coarray %[[VAL_9]]#0 lcobounds %[[VAL_19]] ucobounds %[[VAL_20]] errmsg %[[VAL_13]] uniq_name("_QFquery_allocatable_arrayEev") : {{.*}} +! COARRAY: %[[C1_I32:.*]] = arith.constant 1 : i32 +! COARRAY: %[[VAL_21:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref +! COARRAY: %[[C1_I32_1:.*]] = arith.constant 1 : i32 +! COARRAY: fir.do_loop %[[ARG1:.*]] = %[[C1_I32]] to %[[VAL_21]] step %[[C1_I32_1]] : i32 { +! COARRAY: fir.store %[[ARG1]] to %[[VAL_11]]#0 : !fir.ref +! COARRAY: %[[VAL_39:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref>>, corank:1>> +! COARRAY: %[[VAL_40:.*]] = fir.load %[[VAL_11]]#0 : !fir.ref +! COARRAY: %[[VAL_41:.*]] = fir.convert %[[VAL_40]] : (i32) -> i64 +! COARRAY: %[[VAL_42:.*]] = hlfir.designate %[[VAL_39]] (%[[VAL_41]]) {{.*}} -> !fir.ref> +! COARRAY: %[[VAL_43:.*]] = mif.event_query %[[VAL_42]] : (!fir.ref>) -> i32 +! COARRAY: fir.store %[[VAL_43]] to %[[VAL_4]]#0 : !fir.ref +! COARRAY: } +! COARRAY: %[[VAL_22:.*]] = fir.convert %[[C1_I32]] : (i32) -> index +! COARRAY: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (i32) -> index +! COARRAY: %[[VAL_24:.*]] = fir.convert %[[C1_I32_1]] : (i32) -> index +! COARRAY: %[[C0_2:.*]] = arith.constant 0 : index +! COARRAY: %[[VAL_25:.*]] = arith.subi %[[VAL_23]], %[[VAL_22]] : index +! COARRAY: %[[VAL_26:.*]] = arith.addi %[[VAL_25]], %[[VAL_24]] : index +! COARRAY: %[[VAL_27:.*]] = arith.divsi %[[VAL_26]], %[[VAL_24]] : index +! COARRAY: %[[VAL_28:.*]] = arith.cmpi slt, %[[VAL_27]], %[[C0_2]] : index +! COARRAY: %[[VAL_29:.*]] = arith.select %[[VAL_28]], %[[C0_2]], %[[VAL_27]] : index +! COARRAY: %[[VAL_30:.*]] = arith.muli %[[VAL_29]], %[[VAL_24]] : index +! COARRAY: %[[VAL_31:.*]] = arith.addi %[[VAL_22]], %[[VAL_30]] : index +! COARRAY: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (index) -> i32 +! COARRAY: fir.store %[[VAL_32]] to %[[VAL_11]]#0 : !fir.ref +! COARRAY: %[[VAL_33:.*]] = fir.absent !fir.box +! COARRAY: %[[VAL_34:.*]] = fir.absent !fir.ref +! COARRAY: mif.dealloc_coarray %[[VAL_9]]#0 stat %[[VAL_34]] errmsg %[[VAL_33]] : {{.*}} +! COARRAY: %[[VAL_35:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref>>, corank:1>> +! COARRAY: %[[VAL_36:.*]] = fir.box_addr %[[VAL_35]] : ({{.*}}) -> !fir.heap>> +! COARRAY: %[[VAL_37:.*]] = fir.convert %[[VAL_36]] : ({{.*}}) -> i64 +! COARRAY: %[[C0_I64:.*]] = arith.constant 0 : i64 +! COARRAY: %[[VAL_38:.*]] = arith.cmpi ne, %[[VAL_37]], %[[C0_I64]] : i64 +! COARRAY: fir.if %[[VAL_38]] { +! COARRAY: %[[VAL_39:.*]] = fir.absent !fir.box +! COARRAY: %[[VAL_40:.*]] = fir.absent !fir.ref +! COARRAY: mif.dealloc_coarray %[[VAL_9]]#0 stat %[[VAL_40]] errmsg %[[VAL_39]] : {{.*}} +! COARRAY: } +! COARRAY: return + +subroutine query_class_allocatable() + use iso_fortran_env, only: event_type + class(event_type), allocatable :: ev[:] + integer :: count + allocate(event_type :: ev[*]) + call event_query(ev, count) +end subroutine + +! COARRAY-LABEL: func.func @_QPquery_class_allocatable() { +! COARRAY: %[[VAL_0:.*]] = fir.alloca !fir.array<0xi64> +! COARRAY: %[[VAL_1:.*]] = fir.alloca !fir.array<1xi64> +! COARRAY: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! COARRAY: %[[VAL_3:.*]] = fir.alloca i32 <{bindc_name = "count", uniq_name = "_QFquery_class_allocatableEcount"}> +! COARRAY: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] uniq_name("_QFquery_class_allocatableEcount") : (!fir.ref) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_5:.*]] = fir.alloca !fir.class>, corank:1> {{.*}}uniq_name = "_QFquery_class_allocatableEev"{{.*}} +! COARRAY: %[[VAL_6:.*]] = fir.zero_bits !fir.heap> +! COARRAY: %[[VAL_7:.*]] = fir.embox %[[VAL_6]] : ({{.*}}) -> !fir.class>, corank:1> +! COARRAY: fir.store %[[VAL_7]] to %[[VAL_5]] : {{.*}} +! COARRAY: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_5]] uniq_name("_QFquery_class_allocatableEev") fortran_attrs : {{.*}} +! COARRAY: %[[VAL_9:.*]] = fir.absent !fir.box +! COARRAY: %[[VAL_10:.*]] = fir.type_desc !fir.type<_QM__fortran_builtinsT__builtin_event_type{{.*}}> +! COARRAY: %[[C0_I32:.*]] = arith.constant 0 : i32 +! COARRAY: %[[C0_I32_0:.*]] = arith.constant 0 : i32 +! COARRAY: %[[VAL_11:.*]] = fir.convert %[[VAL_8]]#0 : {{.*}} -> !fir.ref> +! COARRAY: %[[VAL_12:.*]] = fir.convert %[[VAL_10]] : {{.*}} -> !fir.ref +! COARRAY: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[VAL_11]], %[[VAL_12]], %[[C0_I32]], %[[C0_I32_0]]) fastmath : (!fir.ref>, !fir.ref, i32, i32) -> () +! COARRAY: %[[C1_I64:.*]] = arith.constant 1 : i64 +! COARRAY: %[[C0:.*]] = arith.constant 0 : index +! COARRAY: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_1]], %[[C0]] : (!fir.ref>, index) -> !fir.ref +! COARRAY: fir.store %[[C1_I64]] to %[[VAL_13]] : !fir.ref +! COARRAY: %[[VAL_14:.*]] = fir.embox %[[VAL_1]] : (!fir.ref>) -> !fir.box> +! COARRAY: %[[VAL_15:.*]] = fir.embox %[[VAL_0]] : (!fir.ref>) -> !fir.box> +! COARRAY: mif.alloc_coarray %[[VAL_8]]#0 lcobounds %[[VAL_14]] ucobounds %[[VAL_15]] errmsg %[[VAL_9]] uniq_name("_QFquery_class_allocatableEev") : {{.*}} +! COARRAY: %[[VAL_16:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_17:.*]] = mif.event_query %[[VAL_16]] : (!fir.class>, corank:1>) -> i32 +! COARRAY: fir.store %[[VAL_17]] to %[[VAL_4]]#0 : !fir.ref +! COARRAY: %[[VAL_18:.*]] = fir.load %[[VAL_8]]#0 : !fir.ref>, corank:1>> +! COARRAY: %[[VAL_19:.*]] = fir.box_addr %[[VAL_18]] : ({{.*}}) -> !fir.heap> +! COARRAY: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (!fir.heap>) -> i64 +! COARRAY: %[[C0_I64:.*]] = arith.constant 0 : i64 +! COARRAY: %[[VAL_21:.*]] = arith.cmpi ne, %[[VAL_20]], %[[C0_I64]] : i64 +! COARRAY: fir.if %[[VAL_21]] { +! COARRAY: %[[VAL_22:.*]] = fir.absent !fir.box +! COARRAY: %[[VAL_23:.*]] = fir.absent !fir.ref +! COARRAY: mif.dealloc_coarray %[[VAL_8]]#0 stat %[[VAL_23]] errmsg %[[VAL_22]] : {{.*}} +! COARRAY: } +! COARRAY: return From 70905bb025561ba93a8965456baa1f41e8c33a72 Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Tue, 3 Nov 2026 11:11:01 +0100 Subject: [PATCH 2/6] Remove useless variable --- flang/lib/Optimizer/Transforms/MIFOpConversion.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp index 56f86c9d8f7834..50eba9bb6c01f4 100644 --- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp +++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp @@ -1685,7 +1685,6 @@ struct MIFEventQueryOpConversion mlir::Type ptrTy = getBuiltinCptrType(builder, loc); mlir::Type i64Ty = builder.getI64Type(); - mlir::Type errmsgTy = getPRIFErrmsgType(builder); mlir::FunctionType ftype = mlir::FunctionType::get( builder.getContext(), /*inputs*/ From 5d85d5d9b2628e7fb9eea5d4ec40ebc5f29e9855 Mon Sep 17 00:00:00 2001 From: Jean-Didier PAILLEUX Date: Tue, 10 Nov 2026 11:59:42 +0100 Subject: [PATCH 3/6] Update flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td Co-authored-by: Dan Bonachea --- flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td index 5100a2d72978df..64786aef7f4d5a 100644 --- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td @@ -647,8 +647,8 @@ def mif_EventWaitOp : mif_Op<"event_wait", [AttrSizedOperandSegments]> { def mif_EventQueryOp : mif_Op<"event_query", []> { let summary = "Query the count of an event on the calling image."; let description = [{ - Argument: `event` shall be a coarray of type EVENT_TYPE from the intrinsic - module ISO_FORTRAN_ENV. + Argument: `event` shall be a noncoindexed variable of type EVENT_TYPE from the + intrinsic module ISO_FORTRAN_ENV. Result: `count` shall be an integer scalar and indicate the current count of event variables. }]; From b28dc1fafd5e4c930fdca528408dce9237acc06b Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Tue, 10 Nov 2026 17:02:02 +0100 Subject: [PATCH 4/6] Applying Eugene's feedback - New test with CSE - New Note in MIFOps.td - Adding missing checkCoarrayEnabled --- .../flang/Optimizer/Dialect/MIF/MIFOps.td | 11 +++- flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 1 + .../Optimizer/Transforms/MIFOpConversion.cpp | 4 +- flang/test/Fir/MIF/event_query03.mlir | 50 +++++++++++++++++++ 4 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 flang/test/Fir/MIF/event_query03.mlir diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td index 64786aef7f4d5a..bebe8ed6ba6e25 100644 --- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td @@ -602,6 +602,13 @@ def mif_DeallocCoarrayOp // consistency semantics of surrounding accesses in the multi-image execution. // For now we've modeled this by *deliberately* omitting mlir::MemoryEffects // on these operations, to ensure analysis treats these ops conservatively. +// +// EVENT QUERY is not an image control statement, but it is an atomic +// observation of the event variable (F23 16.9.82 p3), whose value other +// images may change at any time. +// Two queries therefore don't necessarily return the same value, and an +// unused query cannot be erased either, since it must still error-terminate +// when it fails without STAT. It follows the same modeling as above. //===----------------------------------------------------------------------===// def mif_EventPostOp : mif_Op<"event_post", [AttrSizedOperandSegments]> { let summary = "Posts an event."; @@ -650,11 +657,11 @@ def mif_EventQueryOp : mif_Op<"event_query", []> { Argument: `event` shall be a noncoindexed variable of type EVENT_TYPE from the intrinsic module ISO_FORTRAN_ENV. Result: `count` shall be an integer scalar and indicate the current count - of event variables. + of EVENT. }]; let arguments = (ins Arg:$event, - Arg, "", [MemWrite]>:$stat); + Arg>:$stat); let results = (outs AnyInteger:$count); let assemblyFormat = [{ $event diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 16f2f0e1863d82..463fe7f07dec2b 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -4044,6 +4044,7 @@ IntrinsicLibrary::genEtime(std::optional resultType, // EVENT_QUERY void IntrinsicLibrary::genEventQuery(llvm::ArrayRef args) { + checkCoarrayEnabled(loc, options); assert(args.size() == 3); mlir::Value eventVarPtr = fir::getBase(args[0]); diff --git a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp index 50eba9bb6c01f4..11d8d2458f4eae 100644 --- a/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp +++ b/flang/lib/Optimizer/Transforms/MIFOpConversion.cpp @@ -1695,9 +1695,7 @@ struct MIFEventQueryOpConversion builder.createFunction(loc, getPRIFProcName("event_query"), ftype); mlir::Value count = builder.createTemporary(loc, i64Ty); - mlir::Value stat = op.getStat(); - if (!stat) - stat = fir::AbsentOp::create(builder, loc, getPRIFStatType(builder)); + mlir::Value stat = genStatPRIF(builder, loc, op.getStat()); mlir::Value cptrEvent = convertRefTypeToCPtrType(builder, loc, op.getEvent()); diff --git a/flang/test/Fir/MIF/event_query03.mlir b/flang/test/Fir/MIF/event_query03.mlir new file mode 100644 index 00000000000000..ff66f0e350fb63 --- /dev/null +++ b/flang/test/Fir/MIF/event_query03.mlir @@ -0,0 +1,50 @@ +// RUN: fir-opt --cse --canonicalize %s | FileCheck %s + +// STAT-less mif.event_query ops must be neither merged, hoisted nor erased + +!event_ty = !fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}> + +func.func private @do_sync() + +// Two queries around a fir.call: CSE must not fold the second into the first. +func.func @around_call(%ev: !fir.heap, %a: !fir.ref, %b: !fir.ref) { + %0 = mif.event_query %ev : (!fir.heap) -> i32 + fir.store %0 to %a : !fir.ref + fir.call @do_sync() : () -> () + %1 = mif.event_query %ev : (!fir.heap) -> i32 + fir.store %1 to %b : !fir.ref + return +} +// CHECK-LABEL: func.func @around_call( +// CHECK-SAME: %[[EV:[^:]+]]: !fir.heap<{{.*}}>, %[[A:[^:]+]]: !fir.ref, %[[B:[^:]+]]: !fir.ref) +// CHECK: %[[Q1:.*]] = mif.event_query %[[EV]] +// CHECK-NEXT: fir.store %[[Q1]] to %[[A]] +// CHECK-NEXT: fir.call @do_sync +// CHECK-NEXT: %[[Q2:.*]] = mif.event_query %[[EV]] +// CHECK-NEXT: fir.store %[[Q2]] to %[[B]] + +func.func @around_event_wait(%ev: !fir.heap, %a: !fir.ref, %b: !fir.ref) { + %0 = mif.event_query %ev : (!fir.heap) -> i32 + fir.store %0 to %a : !fir.ref + mif.event_wait %ev : (!fir.heap) -> () + %1 = mif.event_query %ev : (!fir.heap) -> i32 + fir.store %1 to %b : !fir.ref + return +} +// CHECK-LABEL: func.func @around_event_wait( +// CHECK-SAME: %[[EV:[^:]+]]: !fir.heap<{{.*}}>, %[[A:[^:]+]]: !fir.ref, %[[B:[^:]+]]: !fir.ref) +// CHECK: %[[Q1:.*]] = mif.event_query %[[EV]] +// CHECK-NEXT: fir.store %[[Q1]] to %[[A]] +// CHECK-NEXT: mif.event_wait %[[EV]] +// CHECK-NEXT: %[[Q2:.*]] = mif.event_query %[[EV]] +// CHECK-NEXT: fir.store %[[Q2]] to %[[B]] + +func.func @unused_query(%ev: !fir.heap) { + %0 = mif.event_query %ev : (!fir.heap) -> i32 + return +} +// CHECK-LABEL: func.func @unused_query( +// CHECK-SAME: %[[EV:[^:]+]]: !fir.heap<{{.*}}>) +// CHECK: mif.event_query %[[EV]] +// CHECK-NEXT: return + From 47787bb4c3182b132b2a9163ad9c37e0615f374c Mon Sep 17 00:00:00 2001 From: Jean-Didier PAILLEUX Date: Thu, 12 Nov 2026 13:36:32 +0100 Subject: [PATCH 5/6] Update flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td Co-authored-by: Dan Bonachea --- flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td index bebe8ed6ba6e25..5b68192c86f392 100644 --- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td @@ -603,7 +603,7 @@ def mif_DeallocCoarrayOp // For now we've modeled this by *deliberately* omitting mlir::MemoryEffects // on these operations, to ensure analysis treats these ops conservatively. // -// EVENT QUERY is not an image control statement, but it is an atomic +// A call to EVENT_QUERY is not an image control statement, but is an atomic // observation of the event variable (F23 16.9.82 p3), whose value other // images may change at any time. // Two queries therefore don't necessarily return the same value, and an From e6a03a96ab0759739dab3697be6057b6fee582de Mon Sep 17 00:00:00 2001 From: Jean-Didier Pailleux Date: Thu, 12 Nov 2026 20:29:58 +0100 Subject: [PATCH 6/6] Adding more tests + TODO on coindexed COUNT on EVENT_QUERY --- flang/docs/FortranStandardsSupport.md | 2 +- flang/lib/Lower/ConvertCall.cpp | 7 ++++++- flang/test/Fir/MIF/event_query02.mlir | 3 ++- flang/test/Fir/MIF/event_query03.mlir | 2 +- flang/test/Lower/MIF/event_query01.f90 | 22 ++++++++++++++++++++++ flang/test/Lower/MIF/event_query04.f90 | 12 ++++++++++++ 6 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 flang/test/Lower/MIF/event_query04.f90 diff --git a/flang/docs/FortranStandardsSupport.md b/flang/docs/FortranStandardsSupport.md index 762d62da06427e..3805f2252ef65d 100644 --- a/flang/docs/FortranStandardsSupport.md +++ b/flang/docs/FortranStandardsSupport.md @@ -71,7 +71,7 @@ the multi-image execution. The table entries are based on the document [The new | Team arguments to other intrinsics | P | Experimental support via [PRIF](ParallelMultiImageFortranRuntime.md) | | Coarrays allocated in teams | N | Multi-image/Coarray feature | | Critical construct | N | Multi-image/Coarray feature | -| Events | N | Multi-image/Coarray feature | +| Events | P | Experimental support via [PRIF](ParallelMultiImageFortranRuntime.md) | | Intrinsic move_alloc extensions | P | Multi-image/Coarray feature | | Detecting failed and stopped images | N | Multi-image/Coarray feature | | New and enhanced atomic subroutines | N | Multi-image/Coarray feature | diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp index 60596f1368b869..cd43deab13af8b 100644 --- a/flang/lib/Lower/ConvertCall.cpp +++ b/flang/lib/Lower/ConvertCall.cpp @@ -2253,8 +2253,13 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals, // Trying to retrieve the corank of a variable if this is a coarray unsigned corank = 0; if (const Fortran::lower::SomeExpr *expr = - callContext.procRef.UnwrapArgExpr(arg.index())) + callContext.procRef.UnwrapArgExpr(arg.index())) { corank = getCorank(*expr); + if (callContext.getProcedureName() == "event_query" && expr && + Fortran::evaluate::ExtractCoarrayRef(*expr)) + // The only argument that can be coindexed is COUNT. + TODO(loc, "coarray: EVENT_QUERY with coindexed COUNT."); + } if (!arg.value()) { operands.emplace_back(fir::getAbsentIntrinsicArgument()); diff --git a/flang/test/Fir/MIF/event_query02.mlir b/flang/test/Fir/MIF/event_query02.mlir index 4e91e2c1e3e973..810f3182c0a72d 100644 --- a/flang/test/Fir/MIF/event_query02.mlir +++ b/flang/test/Fir/MIF/event_query02.mlir @@ -411,7 +411,8 @@ func.func @_QPquery_class_allocatable() { // CHECK: return // CHECK: } -// CHECK-LABEL: func.func @_QPquery_allocatable_array +// CHECK-LABEL: func.func @_QPquery_allocatable_array( +// CHECK-SAME: %[[ARG0:.*]]: !fir.ref // CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> // CHECK: %[[VAL_1:.*]] = fir.alloca i64 // CHECK: %[[VAL_2:.*]] = fir.alloca i64 diff --git a/flang/test/Fir/MIF/event_query03.mlir b/flang/test/Fir/MIF/event_query03.mlir index ff66f0e350fb63..7dd8863d616fdf 100644 --- a/flang/test/Fir/MIF/event_query03.mlir +++ b/flang/test/Fir/MIF/event_query03.mlir @@ -1,6 +1,6 @@ // RUN: fir-opt --cse --canonicalize %s | FileCheck %s -// STAT-less mif.event_query ops must be neither merged, hoisted nor erased +// STAT-less mif.event_query ops must be neither merged nor erased !event_ty = !fir.type<_QM__fortran_builtinsT__builtin_event_type{_QM__fortran_builtinsT__builtin_event_type.__m1:i64,_QM__fortran_builtinsT__builtin_event_type.__m2:i64,_QM__fortran_builtinsT__builtin_event_type.__m3:i64,_QM__fortran_builtinsT__builtin_event_type.__m4:i64,_QM__fortran_builtinsT__builtin_event_type.__m5:i64,_QM__fortran_builtinsT__builtin_event_type.__m6:i64,_QM__fortran_builtinsT__builtin_event_type.__m7:i64,_QM__fortran_builtinsT__builtin_event_type.__m8:i64}> diff --git a/flang/test/Lower/MIF/event_query01.f90 b/flang/test/Lower/MIF/event_query01.f90 index 8c1b671e9028ea..9bcbaf6495bde6 100644 --- a/flang/test/Lower/MIF/event_query01.f90 +++ b/flang/test/Lower/MIF/event_query01.f90 @@ -103,3 +103,25 @@ subroutine query_with_kinds() ! COARRAY: fir.store %[[VAL_33]] to %[[VAL_4]]#0 : !fir.ref ! COARRAY: return ! COARRAY: } + +subroutine query_optional_stat(count, stat) + use iso_fortran_env, only: event_type + type(event_type), save :: ev[*] + integer :: count + integer(2), optional :: stat + call event_query(ev, count, stat) +end subroutine + +! COARRAY-LABEL: @_QPquery_optional_stat( +! COARRAY-SAME: %[[ARG_0:.*]]: !fir.ref {fir.bindc_name = "count"}, %[[ARG_1:.*]]: !fir.ref {fir.bindc_name = "stat", fir.optional}) { +! COARRAY: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! COARRAY: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG_0]] dummy_scope %[[VAL_0]] arg 1 uniq_name("_QFquery_optional_statEcount") : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_2:.*]] = fir.address_of(@_QFquery_optional_statEev) : !fir.ref]]>, corank:1>> +! COARRAY: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] uniq_name("_QFquery_optional_statEev") : (!fir.ref, corank:1>>) -> (!fir.ref, corank:1>>, !fir.ref, corank:1>>) +! COARRAY: %[[VAL_4:.*]]:2 = hlfir.declare %[[ARG_1]] dummy_scope %[[VAL_0]] arg 2 uniq_name("_QFquery_optional_statEstat") fortran_attrs : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! COARRAY: %[[VAL_5:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref, corank:1>> +! COARRAY: %[[VAL_6:.*]] = fir.box_addr %[[VAL_5]] : (!fir.box, corank:1>) -> !fir.heap<[[EVT]]> +! COARRAY: %[[VAL_7:.*]] = mif.event_query %[[VAL_6]] stat %[[VAL_4]]#0 : (!fir.heap<[[EVT]]>, !fir.ref) -> i32 +! COARRAY: fir.store %[[VAL_7]] to %[[VAL_1]]#0 : !fir.ref +! COARRAY: return +! COARRAY: } diff --git a/flang/test/Lower/MIF/event_query04.f90 b/flang/test/Lower/MIF/event_query04.f90 new file mode 100644 index 00000000000000..0f3c98695000ea --- /dev/null +++ b/flang/test/Lower/MIF/event_query04.f90 @@ -0,0 +1,12 @@ +! RUN: not %flang_fc1 -emit-hlfir -fcoarray %s -o - 2>&1 | FileCheck %s + +!CHECK: not yet implemented: coarray: EVENT_QUERY with coindexed COUNT. + +subroutine query_with_coindex(k) + use iso_fortran_env, only: event_type + type(event_type), save :: ev[*] + integer, save :: count[*] + integer :: i + + call event_query(ev, count[i]) +end subroutine