[flang-commits] [flang] [Flang] Propogate fir.declare attributes through cg-rewrite (PR #137207)

via flang-commits flang-commits at lists.llvm.org
Thu Apr 24 09:06:33 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-codegen

Author: Susan Tan (ス-ザン タン) (SusanTan)

<details>
<summary>Changes</summary>

Adds attribute handling during the codegen rewrite of fir.declare operations.

* When a fir.declare operation is not preserved, non-conflicting attributes are attached directly to the associated memref operation.

* When a fir.declare operation is preserved, all attributes are propagated to the corresponding fircg.ext_declare operation.

This enables development based on these attributes. For instance, OpenACC codegen for fir.declare depends on the presence of the acc.declare attribute (added as a lit test)



---
Full diff: https://github.com/llvm/llvm-project/pull/137207.diff


2 Files Affected:

- (modified) flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp (+20-1) 
- (modified) flang/test/Fir/declare-codegen.fir (+19-3) 


``````````diff
diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
index d09d7d397e8b7..0b9de86de1e95 100644
--- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
@@ -281,6 +281,20 @@ class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> {
   matchAndRewrite(fir::DeclareOp declareOp,
                   mlir::PatternRewriter &rewriter) const override {
     if (!preserveDeclare) {
+      auto memrefOp = declareOp.getMemref().getDefiningOp();
+      if (!memrefOp) {
+        rewriter.replaceOp(declareOp, declareOp.getMemref());
+        return mlir::success();
+      }
+
+      // attach metadatas from the fir.declare to its memref (if it's an
+      // operation)
+      mlir::NamedAttrList elidedAttrs =
+          mlir::NamedAttrList{memrefOp->getAttrs()};
+      for (const mlir::NamedAttribute &attr : declareOp->getAttrs())
+        if (!elidedAttrs.get(attr.getName()))
+          memrefOp->setAttr(attr.getName(), attr.getValue());
+
       rewriter.replaceOp(declareOp, declareOp.getMemref());
       return mlir::success();
     }
@@ -299,11 +313,16 @@ class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> {
       else
         return mlir::failure();
     }
-    // FIXME: Add FortranAttrs and CudaAttrs
+
     auto xDeclOp = rewriter.create<fir::cg::XDeclareOp>(
         loc, declareOp.getType(), declareOp.getMemref(), shapeOpers, shiftOpers,
         declareOp.getTypeparams(), declareOp.getDummyScope(),
         declareOp.getUniqName());
+
+    // attach metadatas from fir.declare to fircg.ext_declare
+    for (const mlir::NamedAttribute &attr : declareOp->getAttrs())
+      xDeclOp->setAttr(attr.getName(), attr.getValue());
+
     LLVM_DEBUG(llvm::dbgs()
                << "rewriting " << declareOp << " to " << xDeclOp << '\n');
     rewriter.replaceOp(declareOp, xDeclOp.getOperation()->getResults());
diff --git a/flang/test/Fir/declare-codegen.fir b/flang/test/Fir/declare-codegen.fir
index fe8d84ef2d19f..ad0208219ddf7 100644
--- a/flang/test/Fir/declare-codegen.fir
+++ b/flang/test/Fir/declare-codegen.fir
@@ -23,7 +23,7 @@ func.func private @bar(%arg0: !fir.ref<!fir.array<12x23xi32>>)
 
 // DECL-LABEL: func.func @test(
 // DECL-SAME: %[[arg0:.*]]: !fir.ref<!fir.array<12x23xi32>>) {
-// DECL: fircg.ext_declare
+// DECL: fircg.ext_declare{{.*}}{uniq_name = "_QFarray_numeric_lboundsEx"}
 
 
 func.func @useless_shape_with_duplicate_extent_operand(%arg0: !fir.ref<!fir.array<3x3xf32>>) {
@@ -37,7 +37,7 @@ func.func @useless_shape_with_duplicate_extent_operand(%arg0: !fir.ref<!fir.arra
 // NODECL-NEXT: return
 
 // DECL-LABEL: func.func @useless_shape_with_duplicate_extent_operand(
-// DECL: fircg.ext_declare
+// DECL: fircg.ext_declare{{.*}}{uniq_name = "u"}
 
 // Test DCE does not crash because of unreachable code.
 func.func @unreachable_code(%arg0: !fir.ref<!fir.char<1,10>>) {
@@ -51,4 +51,20 @@ func.func @unreachable_code(%arg0: !fir.ref<!fir.char<1,10>>) {
 // NODECL-LABEL:   func.func @unreachable_code(
 // NODECL-NOT:       uniq_name = "live_code"
 // DECL-LABEL:    func.func @unreachable_code(
-// DECL:             uniq_name = "live_code"
+// DECL:             fircg.ext_declare{{.*}}{uniq_name = "live_code"}
+// DECL:             fir.declare{{.*}}{uniq_name = "dead_code"}
+
+
+// Test that attributes get attached to the memref operation when fir.declare is not preserved
+func.func @test_local_memref() {
+  %0 = fir.alloca !fir.array<10xi32> {uniq_name = "local_array"}
+  %1 = fir.declare %0 {uniq_name = "local_array_declare", acc.declare = #acc.declare<dataClause = acc_create>} : (!fir.ref<!fir.array<10xi32>>) -> !fir.ref<!fir.array<10xi32>>
+  return
+}
+// NODECL-LABEL: func.func @test_local_memref() {
+  
+// Note: the uniq_name is not attached of fir.declare is not preserved because it conflicts with the uniq_name of the memref
+// NODECL: fir.alloca{{.*}}{acc.declare = #acc.declare<dataClause = acc_create>, uniq_name = "local_array"}
+
+// DECL-LABEL: func.func @test_local_memref() {
+// DECL: fircg.ext_declare{{.*}}{acc.declare = #acc.declare<dataClause = acc_create>, uniq_name = "local_array_declare"}

``````````

</details>


https://github.com/llvm/llvm-project/pull/137207


More information about the flang-commits mailing list