[flang-commits] [flang] 33cc998 - [mlir][LLVM] Add LLVM::getLoopAnnotationAttrName() (#224060)

via flang-commits flang-commits at lists.llvm.org
Thu Sep 17 07:51:55 PDT 2026


Author: Scott Manley
Date: 2026-09-17T09:51:50-05:00
New Revision: 33cc998157406abe5c1319e1532bd401dd0aafb6

URL: https://github.com/llvm/llvm-project/commit/33cc998157406abe5c1319e1532bd401dd0aafb6
DIFF: https://github.com/llvm/llvm-project/commit/33cc998157406abe5c1319e1532bd401dd0aafb6.diff

LOG: [mlir][LLVM] Add LLVM::getLoopAnnotationAttrName() (#224060)

Provide a single name for attaching LoopAnnotationAttr as a discardable
attribute and use it in FIR, OpenACC, and CF-to-LLVM lowering instead of
hardcoded "loop_annotation" / Attr::name.

Added: 
    

Modified: 
    flang/lib/Lower/OpenACC.cpp
    flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
    flang/lib/Optimizer/Transforms/FIRToSCF.cpp
    flang/test/Fir/FirToSCF/do-loop.fir
    flang/test/Fir/convert-to-llvm-access-group.fir
    flang/test/Fir/vector-always-cfg.fir
    flang/test/Fir/vector-always.fir
    mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
    mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
    mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp
    mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsLoop.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 7472b01b43e47..9c47b63571a98 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -2670,7 +2670,7 @@ static mlir::acc::LoopOp createLoopOp(
     if (mlir::LLVM::LoopAnnotationAttr la =
             Fortran::lower::genLoopAnnotationAttr(builder.getContext(),
                                                   doStmtEval->dirs))
-      loopOp->setDiscardableAttr(mlir::LLVM::LoopAnnotationAttr::name, la);
+      loopOp->setDiscardableAttr(mlir::LLVM::getLoopAnnotationAttrName(), la);
   }
 
   return loopOp;
@@ -5685,7 +5685,7 @@ mlir::Operation *Fortran::lower::genOpenACCLoopFromDoConstruct(
     if (mlir::LLVM::LoopAnnotationAttr la =
             Fortran::lower::genLoopAnnotationAttr(builder.getContext(),
                                                   doStmtEval->dirs))
-      loopOp->setDiscardableAttr(mlir::LLVM::LoopAnnotationAttr::name, la);
+      loopOp->setDiscardableAttr(mlir::LLVM::getLoopAnnotationAttrName(), la);
   }
 
   return loopOp;

diff  --git a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
index fefee609d817f..b12cabf6cd730 100644
--- a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
+++ b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
@@ -133,7 +133,8 @@ class CfgLoopConv : public mlir::OpRewritePattern<fir::DoLoopOp> {
 
     // Copy loop annotations from the do loop to the loop back edge.
     if (auto ann = loop.getLoopAnnotation())
-      backEdge->setAttr("loop_annotation", *ann);
+      backEdge->setDiscardableAttr(mlir::LLVM::getLoopAnnotationAttrName(),
+                                   *ann);
 
     // Conditional block
     rewriter.setInsertionPointToEnd(conditionalBlock);

diff  --git a/flang/lib/Optimizer/Transforms/FIRToSCF.cpp b/flang/lib/Optimizer/Transforms/FIRToSCF.cpp
index d6393ab53a647..87454a3b3b7cc 100644
--- a/flang/lib/Optimizer/Transforms/FIRToSCF.cpp
+++ b/flang/lib/Optimizer/Transforms/FIRToSCF.cpp
@@ -196,7 +196,8 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
 
     // Copy loop annotations from the fir.do_loop to scf loop op.
     if (auto ann = doLoopOp.getLoopAnnotation())
-      scfLoopOp->setAttr("loop_annotation", *ann);
+      scfLoopOp->setDiscardableAttr(mlir::LLVM::getLoopAnnotationAttrName(),
+                                    *ann);
 
     // Copy any OpenACC parallel dimensions from the fir.do_loop to the scf loop
     // op.

diff  --git a/flang/test/Fir/FirToSCF/do-loop.fir b/flang/test/Fir/FirToSCF/do-loop.fir
index 64307e0541022..76550f0a29513 100644
--- a/flang/test/Fir/FirToSCF/do-loop.fir
+++ b/flang/test/Fir/FirToSCF/do-loop.fir
@@ -411,7 +411,7 @@ func.func @loop_with_unordered_attr(%arg0: !fir.ref<!fir.array<100xi32>>) {
 // CHECK:             %[[VAL_15:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32>
 // CHECK:             %[[VAL_16:.*]] = arith.addi %[[VAL_15]], %[[VAL_14]] : i32
 // CHECK:             fir.store %[[VAL_16]] to %[[VAL_3]] : !fir.ref<i32>
-// CHECK:           } {loop_annotation = #[[$ATTR_1]]}
+// CHECK:           } {llvm.loop_annotation = #[[$ATTR_1]]}
 // CHECK:           return
 // CHECK:         }
 

diff  --git a/flang/test/Fir/convert-to-llvm-access-group.fir b/flang/test/Fir/convert-to-llvm-access-group.fir
index e28f36ffe64ca..e1d103cf4673f 100644
--- a/flang/test/Fir/convert-to-llvm-access-group.fir
+++ b/flang/test/Fir/convert-to-llvm-access-group.fir
@@ -101,7 +101,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vec
     %19 = fir.load %0 {accessGroups = [#access_group]} : !fir.ref<i32>
     %20 = arith.addi %19, %3 overflow<nsw> : i32
     %21 = arith.subi %5, %c1 : index
-    cf.br ^bb1(%20, %21 : i32, index) {loop_annotation = #loop_annotation}
+    cf.br ^bb1(%20, %21 : i32, index) {llvm.loop_annotation = #loop_annotation}
   ^bb3:  // pred: ^bb1
     fir.store %4 to %0 : !fir.ref<i32>
     return

diff  --git a/flang/test/Fir/vector-always-cfg.fir b/flang/test/Fir/vector-always-cfg.fir
index 9bb805538d06d..5ed57edc438e1 100644
--- a/flang/test/Fir/vector-always-cfg.fir
+++ b/flang/test/Fir/vector-always-cfg.fir
@@ -19,7 +19,7 @@ func.func @_QPvector_always() -> i32 {
 ^bb1(%3: index, %4: i32, %5: index):  // 2 preds: ^bb0, ^bb2
   %c0 = arith.constant 0 : index
   %6 = arith.cmpi sgt, %5, %c0 : index
-  cf.cond_br %6, ^bb2, ^bb3 {loop_annotation = #loop_annotation}
+  cf.cond_br %6, ^bb2, ^bb3 {llvm.loop_annotation = #loop_annotation}
 // CHECK:   llvm.cond_br %{{.*}}, ^{{.*}}, ^{{.*}} loop_annotation = #[[ANNOTATION]]
 ^bb2:  // pred: ^bb1
   %7 = arith.addi %3, %c1 : index

diff  --git a/flang/test/Fir/vector-always.fir b/flang/test/Fir/vector-always.fir
index ec06b94a3d0f8..b72fe0ba356d6 100644
--- a/flang/test/Fir/vector-always.fir
+++ b/flang/test/Fir/vector-always.fir
@@ -14,8 +14,8 @@ func.func @_QPvector_always() -> i32 {
     %c1_i32 = arith.constant 1 : i32
     %c10 = arith.constant 10 : index
 // CHECK: cf.cond_br
-// CHECK-NOT: loop_annotation
-// CHECK:   cf.br ^{{.*}} {loop_annotation = #[[ANNOTATION]]}
+// CHECK-NOT: llvm.loop_annotation
+// CHECK:   cf.br ^{{.*}} {llvm.loop_annotation = #[[ANNOTATION]]}
     %8:2 = fir.do_loop %arg0 = %c1 to %c10 step %c1 iter_args(%arg1 = %c1_i32) -> (index, i32) attributes {loopAnnotation = #loop_annotation} {
       fir.result %c1, %c1_i32 : index, i32
     }

diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
index 19dced51e976f..4622384aa0b21 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
@@ -114,4 +114,16 @@ verifyModuleFlagValue(StringAttr key, Attribute value,
 #define GET_ATTRDEF_CLASSES
 #include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.h.inc"
 
+namespace mlir {
+namespace LLVM {
+
+/// Canonical name used when attaching LoopAnnotationAttr as a discardable
+/// attribute on operations that do not declare it inherently.
+inline constexpr llvm::StringLiteral getLoopAnnotationAttrName() {
+  return LoopAnnotationAttr::name;
+}
+
+} // namespace LLVM
+} // namespace mlir
+
 #endif // MLIR_DIALECT_LLVMIR_LLVMATTRS_H_

diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
index 91c72266be1b4..f48cb5385590b 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td
@@ -24,7 +24,9 @@ def LLVM_Dialect : Dialect {
 
   let discardableAttrs = (ins
     /// Attribute encoding size and type of GPU workgroup attributions.
-    "WorkgroupAttributionAttr":$workgroup_attribution
+    "WorkgroupAttributionAttr":$workgroup_attribution,
+    /// Loop metadata attached to operations that do not declare it inherently.
+    "LoopAnnotationAttr":$loop_annotation
   );
 
   let extraClassDeclaration = [{

diff  --git a/mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp b/mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp
index 0544574ae1b12..950f7def31e9b 100644
--- a/mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp
+++ b/mlir/lib/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.cpp
@@ -161,8 +161,8 @@ struct BranchOpLowering : public ConvertOpToLLVMPattern<cf::BranchOp> {
     if (failed(convertedBlock))
       return failure();
     DictionaryAttr attrs = op->getDiscardableAttrDictionary();
-    auto loopAnnotation =
-        op->getAttrOfType<LLVM::LoopAnnotationAttr>("loop_annotation");
+    auto loopAnnotation = op->getAttrOfType<LLVM::LoopAnnotationAttr>(
+        LLVM::getLoopAnnotationAttrName());
     Operation *newOp = rewriter.replaceOpWithNewOp<LLVM::BrOp>(
         op, flattenedAdaptor, loopAnnotation, *convertedBlock);
     // TODO: We should not just forward all attributes like that. But there are
@@ -199,8 +199,8 @@ struct CondBranchOpLowering : public ConvertOpToLLVMPattern<cf::CondBranchOp> {
     if (failed(convertedFalseBlock))
       return failure();
     DictionaryAttr attrs = op->getDiscardableAttrDictionary();
-    auto loopAnnotation =
-        op->getAttrOfType<LLVM::LoopAnnotationAttr>("loop_annotation");
+    auto loopAnnotation = op->getAttrOfType<LLVM::LoopAnnotationAttr>(
+        LLVM::getLoopAnnotationAttrName());
     auto newOp = rewriter.replaceOpWithNewOp<LLVM::CondBrOp>(
         op, llvm::getSingleElement(adaptor.getCondition()),
         flattenedAdaptorTrue, flattenedAdaptorFalse, op.getBranchWeightsAttr(),

diff  --git a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsLoop.cpp b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsLoop.cpp
index 8391071d4b6b8..721762c960465 100644
--- a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsLoop.cpp
+++ b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsLoop.cpp
@@ -101,8 +101,9 @@ static Block::iterator cloneACCRegionIntoForLoop(Region *src, Block *dest,
 /// lowered SCF op so later SCF to CFG/LLVM lowering can emit !llvm.loop
 /// metadata.
 static void copyLoopAnnotationAttr(Operation *from, Operation *to) {
-  if (Attribute ann = from->getDiscardableAttr(LLVM::LoopAnnotationAttr::name))
-    to->setDiscardableAttr(LLVM::LoopAnnotationAttr::name, ann);
+  if (Attribute ann =
+          from->getDiscardableAttr(LLVM::getLoopAnnotationAttrName()))
+    to->setDiscardableAttr(LLVM::getLoopAnnotationAttrName(), ann);
 }
 
 namespace mlir {


        


More information about the flang-commits mailing list