From 3040c8ceaa1b9fbdd54bf330a508f77c1e029f3d Mon Sep 17 00:00:00 2001 From: Susan Tan Date: Mon, 10 Nov 2025 15:37:55 -0800 Subject: [PATCH 1/6] add cuf allc/allocate mem alloc effect --- .../flang/Optimizer/Dialect/CUF/CUFOps.td | 14 ++++++----- .../AliasAnalysis/cuf-alloc-source-kind.mlir | 22 +++++++++++++++++ .../cuf-allocate-source-kind.mlir | 24 +++++++++++++++++++ 3 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 flang/test/Analysis/AliasAnalysis/cuf-alloc-source-kind.mlir create mode 100644 flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir diff --git a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td index e38738230ffbc..43b383057aa6d 100644 --- a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td +++ b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td @@ -26,8 +26,7 @@ include "mlir/IR/BuiltinAttributes.td" class cuf_Op traits> : Op; -def cuf_AllocOp : cuf_Op<"alloc", [AttrSizedOperandSegments, - MemoryEffects<[MemAlloc]>]> { +def cuf_AllocOp : cuf_Op<"alloc", [AttrSizedOperandSegments]> { let summary = "Allocate an object on device"; let description = [{ @@ -47,7 +46,9 @@ def cuf_AllocOp : cuf_Op<"alloc", [AttrSizedOperandSegments, cuf_DataAttributeAttr:$data_attr ); - let results = (outs fir_ReferenceType:$ptr); + // Value-scoped Allocate on the returned reference + let results = (outs Res]>:$ptr); let assemblyFormat = [{ $in_type (`(` $typeparams^ `:` type($typeparams) `)`)? @@ -84,8 +85,7 @@ def cuf_FreeOp : cuf_Op<"free", [MemoryEffects<[MemFree]>]> { let hasVerifier = 1; } -def cuf_AllocateOp : cuf_Op<"allocate", [AttrSizedOperandSegments, - MemoryEffects<[MemAlloc]>]> { +def cuf_AllocateOp : cuf_Op<"allocate", [AttrSizedOperandSegments]> { let summary = "Perform the device allocation of data of an allocatable"; let description = [{ @@ -94,7 +94,9 @@ def cuf_AllocateOp : cuf_Op<"allocate", [AttrSizedOperandSegments, is initialized before with the standard flang runtime calls. }]; - let arguments = (ins Arg:$box, + // Value-scoped Allocate on the descriptor being allocated + let arguments = (ins Arg, MemRead, MemWrite]>:$box, Arg, "", [MemWrite]>:$errmsg, Optional:$stream, Arg, "", [MemWrite]>:$pinned, diff --git a/flang/test/Analysis/AliasAnalysis/cuf-alloc-source-kind.mlir b/flang/test/Analysis/AliasAnalysis/cuf-alloc-source-kind.mlir new file mode 100644 index 0000000000000..f062dcb3a3360 --- /dev/null +++ b/flang/test/Analysis/AliasAnalysis/cuf-alloc-source-kind.mlir @@ -0,0 +1,22 @@ +// REQUIRES: asserts +// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -debug-only=fir-alias-analysis --mlir-disable-threading 2>&1 | FileCheck %s + +// Verify that a CUF allocation is recognized as SourceKind::Allocate by +// fir::AliasAnalysis::getSource. + +module { + func.func @_QQmain() attributes {fir.bindc_name = "TEST"} { + // Allocate two independent device arrays and tag the results; with + // value-scoped MemAlloc handling in AA, these should be classified as + // Allocate and not alias. + %a = cuf.alloc !fir.box>> {bindc_name = "a1", data_attr = #cuf.cuda, uniq_name = "_QFEa1", test.ptr = "cuf_alloc_a"} -> !fir.ref>>> + %b = cuf.alloc !fir.box>> {bindc_name = "a2", data_attr = #cuf.cuda, uniq_name = "_QFEa2", test.ptr = "cuf_alloc_b"} -> !fir.ref>>> + return + } +} + +// CHECK-LABEL: Testing : "_QQmain" +// Distinct allocations should not alias. +// CHECK: cuf_alloc_a#0 <-> cuf_alloc_b#0: NoAlias + + diff --git a/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir b/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir new file mode 100644 index 0000000000000..201d841b5cde0 --- /dev/null +++ b/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir @@ -0,0 +1,24 @@ +// REQUIRES: asserts +// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -debug-only=fir-alias-analysis --mlir-disable-threading 2>&1 | FileCheck %s + +// Verify that CUF allocation via cuf.allocate is recognized as +// SourceKind::Allocate by fir::AliasAnalysis::getSource on the box value. + +module { + func.func @_QQmain() attributes {fir.bindc_name = "TEST"} { + // Create two independent device boxes and tag their refs. + %a = cuf.alloc !fir.box>> {bindc_name = "a1", data_attr = #cuf.cuda, uniq_name = "_QFEa1", test.ptr = "cuf_allocate_a"} -> !fir.ref>>> + %b = cuf.alloc !fir.box>> {bindc_name = "a2", data_attr = #cuf.cuda, uniq_name = "_QFEa2", test.ptr = "cuf_allocate_b"} -> !fir.ref>>> + // Allocate device data for each descriptor; AA should classify the box + // values (tagged above) as Allocate sources and not alias. + %sa = cuf.allocate %a : !fir.ref>>> {data_attr = #cuf.cuda} -> i32 + %sb = cuf.allocate %b : !fir.ref>>> {data_attr = #cuf.cuda} -> i32 + return + } +} + +// CHECK-LABEL: Testing : "_QQmain" +// Distinct allocations via cuf.allocate should not alias. +// CHECK: cuf_allocate_a#0 <-> cuf_allocate_b#0: NoAlias + + From 9df89a0b3e75cc6551f79f84dbddc77f8697b0a4 Mon Sep 17 00:00:00 2001 From: Susan Tan Date: Mon, 10 Nov 2025 15:40:07 -0800 Subject: [PATCH 2/6] format --- .../flang/Optimizer/Dialect/CUF/CUFOps.td | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td index 43b383057aa6d..f274af787df1a 100644 --- a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td +++ b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td @@ -47,8 +47,8 @@ def cuf_AllocOp : cuf_Op<"alloc", [AttrSizedOperandSegments]> { ); // Value-scoped Allocate on the returned reference - let results = (outs Res]>:$ptr); + let results = + (outs Res]>:$ptr); let assemblyFormat = [{ $in_type (`(` $typeparams^ `:` type($typeparams) `)`)? @@ -95,13 +95,14 @@ def cuf_AllocateOp : cuf_Op<"allocate", [AttrSizedOperandSegments]> { }]; // Value-scoped Allocate on the descriptor being allocated - let arguments = (ins Arg, MemRead, MemWrite]>:$box, - Arg, "", [MemWrite]>:$errmsg, - Optional:$stream, - Arg, "", [MemWrite]>:$pinned, - Arg, "", [MemRead]>:$source, - cuf_DataAttributeAttr:$data_attr, UnitAttr:$hasStat); + let arguments = + (ins Arg, MemRead, MemWrite]>:$box, + Arg, "", [MemWrite]>:$errmsg, + Optional:$stream, + Arg, "", [MemWrite]>:$pinned, + Arg, "", [MemRead]>:$source, + cuf_DataAttributeAttr:$data_attr, UnitAttr:$hasStat); let results = (outs AnyIntegerType:$stat); From f32170a417fbfdb986ed72828fe6dcda950aca04 Mon Sep 17 00:00:00 2001 From: Susan Tan Date: Mon, 10 Nov 2025 16:23:21 -0800 Subject: [PATCH 3/6] remove scope based for cuf.allocate --- .../flang/Optimizer/Dialect/CUF/CUFOps.td | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td index f274af787df1a..2553675ec7fe4 100644 --- a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td +++ b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td @@ -85,7 +85,9 @@ def cuf_FreeOp : cuf_Op<"free", [MemoryEffects<[MemFree]>]> { let hasVerifier = 1; } -def cuf_AllocateOp : cuf_Op<"allocate", [AttrSizedOperandSegments]> { +def cuf_AllocateOp + : cuf_Op<"allocate", [AttrSizedOperandSegments, + MemoryEffects<[MemAlloc]>]> { let summary = "Perform the device allocation of data of an allocatable"; let description = [{ @@ -94,15 +96,12 @@ def cuf_AllocateOp : cuf_Op<"allocate", [AttrSizedOperandSegments]> { is initialized before with the standard flang runtime calls. }]; - // Value-scoped Allocate on the descriptor being allocated - let arguments = - (ins Arg, MemRead, MemWrite]>:$box, - Arg, "", [MemWrite]>:$errmsg, - Optional:$stream, - Arg, "", [MemWrite]>:$pinned, - Arg, "", [MemRead]>:$source, - cuf_DataAttributeAttr:$data_attr, UnitAttr:$hasStat); + let arguments = (ins Arg:$box, + Arg, "", [MemWrite]>:$errmsg, + Optional:$stream, + Arg, "", [MemWrite]>:$pinned, + Arg, "", [MemRead]>:$source, + cuf_DataAttributeAttr:$data_attr, UnitAttr:$hasStat); let results = (outs AnyIntegerType:$stat); From 981b83d931f755aa7ee92f82808737d4b1cd576e Mon Sep 17 00:00:00 2001 From: Susan Tan Date: Wed, 12 Nov 2025 12:19:26 -0800 Subject: [PATCH 4/6] restore cuf.allocate --- flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td index 2553675ec7fe4..07bb47e26b968 100644 --- a/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td +++ b/flang/include/flang/Optimizer/Dialect/CUF/CUFOps.td @@ -85,9 +85,8 @@ def cuf_FreeOp : cuf_Op<"free", [MemoryEffects<[MemFree]>]> { let hasVerifier = 1; } -def cuf_AllocateOp - : cuf_Op<"allocate", [AttrSizedOperandSegments, - MemoryEffects<[MemAlloc]>]> { +def cuf_AllocateOp : cuf_Op<"allocate", [AttrSizedOperandSegments, + MemoryEffects<[MemAlloc]>]> { let summary = "Perform the device allocation of data of an allocatable"; let description = [{ From 2642e97035130f8ff53665c4f0fa966eec7cb903 Mon Sep 17 00:00:00 2001 From: Susan Tan Date: Wed, 12 Nov 2025 12:28:23 -0800 Subject: [PATCH 5/6] change comment --- flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir b/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir index 201d841b5cde0..0730714351316 100644 --- a/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir +++ b/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir @@ -2,7 +2,7 @@ // RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -debug-only=fir-alias-analysis --mlir-disable-threading 2>&1 | FileCheck %s // Verify that CUF allocation via cuf.allocate is recognized as -// SourceKind::Allocate by fir::AliasAnalysis::getSource on the box value. +// SourceKind::Allocate by fir::AliasAnalysis::getSource on the box cuf.alloc allocated module { func.func @_QQmain() attributes {fir.bindc_name = "TEST"} { From ee946b120f722257ed0f90989fc40f009260bc74 Mon Sep 17 00:00:00 2001 From: Susan Tan Date: Wed, 12 Nov 2025 12:35:31 -0800 Subject: [PATCH 6/6] delete cuf allocate --- .../cuf-allocate-source-kind.mlir | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir diff --git a/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir b/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir deleted file mode 100644 index 0730714351316..0000000000000 --- a/flang/test/Analysis/AliasAnalysis/cuf-allocate-source-kind.mlir +++ /dev/null @@ -1,24 +0,0 @@ -// REQUIRES: asserts -// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -debug-only=fir-alias-analysis --mlir-disable-threading 2>&1 | FileCheck %s - -// Verify that CUF allocation via cuf.allocate is recognized as -// SourceKind::Allocate by fir::AliasAnalysis::getSource on the box cuf.alloc allocated - -module { - func.func @_QQmain() attributes {fir.bindc_name = "TEST"} { - // Create two independent device boxes and tag their refs. - %a = cuf.alloc !fir.box>> {bindc_name = "a1", data_attr = #cuf.cuda, uniq_name = "_QFEa1", test.ptr = "cuf_allocate_a"} -> !fir.ref>>> - %b = cuf.alloc !fir.box>> {bindc_name = "a2", data_attr = #cuf.cuda, uniq_name = "_QFEa2", test.ptr = "cuf_allocate_b"} -> !fir.ref>>> - // Allocate device data for each descriptor; AA should classify the box - // values (tagged above) as Allocate sources and not alias. - %sa = cuf.allocate %a : !fir.ref>>> {data_attr = #cuf.cuda} -> i32 - %sb = cuf.allocate %b : !fir.ref>>> {data_attr = #cuf.cuda} -> i32 - return - } -} - -// CHECK-LABEL: Testing : "_QQmain" -// Distinct allocations via cuf.allocate should not alias. -// CHECK: cuf_allocate_a#0 <-> cuf_allocate_b#0: NoAlias - -