[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