Skip to content

[flang][MIF] Add lowering for EVENT_QUERY - #237317

Open
JDPailleux wants to merge 6 commits into
llvm:mainfrom
SiPearl:mif/event_query
Open

JDPailleux wants to merge 6 commits into
llvm:mainfrom
SiPearl:mif/event_query

Conversation

@JDPailleux

Copy link
Copy Markdown
Contributor

This PR adds lowering support for the EVENT_QUERY intrinsic. It is lowered to a new mif.event_query operation, which is then converted to the corresponding PRIF call.

@llvmorg-github-actions llvmorg-github-actions Bot added flang Flang issues not falling into any other category flang:fir-hlfir labels Oct 30, 2026
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-flang-fir-hlfir

Author: Jean-Didier PAILLEUX (JDPailleux)

Changes

This PR adds lowering support for the EVENT_QUERY intrinsic. It is lowered to a new mif.event_query operation, which is then converted to the corresponding PRIF call.


Patch is 164.69 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/237317.diff

8 Files Affected:

  • (modified) flang/include/flang/Optimizer/Builder/IntrinsicCall.h (+1)
  • (modified) flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td (+19)
  • (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+20)
  • (modified) flang/lib/Optimizer/Transforms/MIFOpConversion.cpp (+53-11)
  • (added) flang/test/Fir/MIF/event_query01.mlir (+241)
  • (added) flang/test/Fir/MIF/event_query02.mlir (+642)
  • (added) flang/test/Lower/MIF/event_query01.f90 (+105)
  • (added) flang/test/Lower/MIF/event_query02.f90 (+266)
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<fir::ExtendedValue> args);
   fir::ExtendedValue genEtime(std::optional<mlir::Type>,
                               mlir::ArrayRef<fir::ExtendedValue> args);
+  void genEventQuery(llvm::ArrayRef<fir::ExtendedValue>);
   mlir::Value genTimef(mlir::Type resultType, llvm::ArrayRef<mlir::Value> args);
   mlir::Value genExponent(mlir::Type, llvm::ArrayRef<mlir::Value>);
   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<AnyRefOrBoxType>:$event,
+      Arg<Optional<AnyReferenceLike>, "", [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<mlir::Type> resultType,
   return {};
 }
 
+// EVENT_QUERY
+void IntrinsicLibrary::genEventQuery(llvm::ArrayRef<fir::ExtendedValue> 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<fir::ExtendedValue> 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<mif::EventQueryOp> {
+  using OpRewritePattern::OpRewritePattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(mif::EventQueryOp op,
+                  mlir::PatternRewriter &rewriter) const override {
+    auto mod = op->template getParentOfType<mlir::ModuleOp>();
+    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<mlir::Value> 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<MIFAllocCoarrayOpConversion>(patterns.getContext(), &dl,
                                                &converter);
-  patterns.insert<MIFInitOpConversion, MIFThisImageOpConversion,
-                  MIFNumImagesOpConversion, MIFSyncAllOpConversion,
-                  MIFSyncImagesOpConversion, MIFSyncMemoryOpConversion,
-                  MIFSyncTeamOpConversion, MIFCoBroadcastOpConversion,
-                  MIFCoMaxOpConversion, MIFCoMinOpConversion,
-                  MIFCoSumOpConversion, MIFFormTeamOpConversion,
-                  MIFChangeTeamOpConversion, MIFGetTeamOpConversion,
-                  MIFTeamNumberOpConversion, MIFDeallocCoarrayOpConversion,
-                  MIFCoshapeOpConversion, MIFLcoboundOpConversion,
-                  MIFUcoboundOpConversion, MIFImageIndexOpConversion,
-                  MIFEventPostOpConversion, MIFEventWaitOpConversion>(
+  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<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %3 = fir.address_of(@_QFquery_baseEev) : !fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>
+  %4:2 = hlfir.declare %3 uniq_name("_QFquery_baseEev") : (!fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>) -> (!fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>, !fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>)
+  %5 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>
+  %6 = fir.box_addr %5 : (!fir.box<!fir.heap<!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}>>, corank:1>) -> !fir.heap<!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}>>
+  %7 = mif.event_query %6 : (!fir.heap<!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}>>) -> i32
+  fir.store %7 to %2#0 : !fir.ref<i32>
+  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<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %3 = fir.address_of(@_QFquery_with_statEev) : !fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>
+  %4:2 = hlfir.declare %3 uniq_name("_QFquery_with_statEev") : (!fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>) -> (!fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>, !fir.ref<!fir.box<!fir.heap<!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}>>, 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<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %7 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>
+  %8 = fir.box_addr %7 : (!fir.box<!fir.heap<!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}>>, corank:1>) -> !fir.heap<!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}>>
+  %9 = mif.event_query %8 stat %6#0 : (!fir.heap<!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}>>, !fir.ref<i32>) -> i32
+  fir.store %9 to %2#0 : !fir.ref<i32>
+  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<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %3 = fir.alloca i64 <{bindc_name = "c8", uniq_name = "_QFquery_with_kindsEc8"}>
+  %4:2 = hlfir.declare %3 uniq_name("_QFquery_with_kindsEc8") : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
+  %5 = fir.address_of(@_QFquery_with_kindsEev) : !fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>
+  %6:2 = hlfir.declare %5 uniq_name("_QFquery_with_kindsEev") : (!fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>) -> (!fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>, !fir.ref<!fir.box<!fir.heap<!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}>>, corank:1>>)
+  %7 = fir.address_of(@_QMiso_fortran_env_implECint16) : !fir.ref<i32>
+  %8:2 = hlfir.declare %7 uniq_name("_QMiso_fortran_env_implECint16") fortran_attrs<parameter> : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %9 = fir.address_of(@_QMiso_fortran_env_implECint32) : !fir.ref<i32>
+  %10:2 = hlfir.declare %9 uniq_name("_QMiso_fortran_env_implECint32") fortran_attrs<parameter> : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %11 = fir.address_of(@_QMiso_fortran_env_implECint64) : !fir.ref<i32>
+  %12:2 = hlfir.declare %11 uniq_name("_QMiso_fortran_env_implECint64") fortran_attrs<parameter> : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %13 = fir.alloca i16 <{bindc_name = "s2", uniq_name = "_QFquery_with_kindsEs2"}>
+  %14:2 = hlfir.declare %13 uniq_name("_QFquery_with_kindsEs2") : (!fir.ref<i16>) -> (!fir.ref<i16>, !fir.ref<i16>)
+  %15 = fir.alloca i32 <{bindc_name = "s4", uniq_name = "_QFquery_with_kindsEs4"}>
+  %16:2 = hlfir.declare %15 uniq_name("_QFquery_with_kindsEs4") : (...
[truncated]

@bonachea bonachea left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work on this @JDPailleux!

I've added one very minor cosmetic request, otherwise LGTM!

I've manually validated correct operation on Linux when integrated with Caffeine's main branch, including passing Caffeine's smoke test augmented with additional coverage for event_query.

JDPailleux and others added 2 commits November 10, 2026 11:59
Co-authored-by: Dan Bonachea <dobonachea@lbl.gov>
- New test with CSE
- New Note in MIFOps.td
- Adding missing checkCoarrayEnabled

@eugeneepshteyn eugeneepshteyn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM + nits

Comment thread flang/test/Fir/MIF/event_query03.mlir Resolved

@MattPD MattPD left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified against b28dc1f.

Assisted-by: GPT-6.1 Sol, Claude Opus 5.5, Claude Fable 5.1.

Comment thread flang/test/Fir/MIF/event_query02.mlir Resolved
@MattPD

MattPD commented Nov 11, 2026

Copy link
Copy Markdown
Member

flang/docs/FortranStandardsSupport.md still lists "Events" as N. With EVENT POST and EVENT WAIT merged and EVENT_QUERY added here, would it make sense to change that row to P, like the other features with experimental PRIF support, either here or in a follow-up?

@bonachea bonachea added flang:coarray Related to the coarray language feature flang:multi-image Related to the multi-image (SPMD) language feature set labels Nov 11, 2026
@bonachea
bonachea requested review from MattPD and bonachea November 12, 2026 23:33

@bonachea bonachea left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for updating the documentation!

I've just manually reconfirmed e6a03a9 still passes integration tests of the EVENT_QUERY feature with the Caffeine main branch.

@MattPD MattPD left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified against e6a03a9.

callContext.procRef.UnwrapArgExpr(arg.index())) {
corank = getCorank(*expr);
if (callContext.getProcedureName() == "event_query" && expr &&
Fortran::evaluate::ExtractCoarrayRef(*expr))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ExtractCoarrayRef follows only the base of the argument's designator, not its subscripts, so this check does not stop a call with a coindexed object nested in a subscript. You can reproduce this by saving the following to repro.f90 and running flang -fcoarray -S -emit-llvm repro.f90 -o -:

subroutine q(k)
  use iso_fortran_env, only: event_type
  integer :: k
  type(event_type), save :: ev[*]
  integer, save :: n[*]
  integer :: a(10)
  call event_query(ev, a(n[k]))
end subroutine

The emitted q_ never reads k. It loads the subscript from the local n and stores the count into that element of a:

  call void @llvm.memcpy.p0.p0.i32(ptr align 8 %3, ptr align 8 @_QFqEn, i32 24, i1 false)
  %7 = getelementptr { ptr, i64, i32, i8, i8, i8, i8 }, ptr %3, i32 0, i32 0
  %8 = load ptr, ptr %7, align 8
  %9 = load i32, ptr %8, align 4
  ...
  %15 = getelementptr nusw nuw i32, ptr %4, i64 %14
  ...
  call void @_QMprifPprif_event_query(ptr %6, ptr %5, ptr null)
  %20 = load i64, ptr %5, align 8
  %21 = trunc i64 %20 to i32
  store i32 %21, ptr %15, align 4

An array element ev(n[k]) as EVENT and s(n[k]) as STAT compile the same way. Without this patch, all three calls stop with not yet implemented: intrinsic: EVENT_QUERY.

The missing image selector isn't specific to EVENT_QUERY: Without this patch, m = a(n[k]) and call system_clock(count=a(n[k])) also load the subscript from the local n. Could the check look for a coindexed object anywhere in each argument, subscripts included, for example with an evaluate::AnyTraverse visitor? Or would you prefer to leave these forms to the coarray access work in #212777?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:coarray Related to the coarray language feature flang:fir-hlfir flang:multi-image Related to the multi-image (SPMD) language feature set flang Flang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants