Skip to content

[flang][flang-driver][mlir][OpenMP] atomic control support #143441

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 24, 2025

Conversation

anchuraj
Copy link
Contributor

@anchuraj anchuraj commented Jun 9, 2025

Atomic Control Options are used to specify architectural characteristics to help lowering of atomic operations. The options used are:
-f[no-]atomic-remote-memory, -f[no-]atomic-fine-grained-memory,
-f[no-]atomic-ignore-denormal-mode.
Legacy option -m[no-]unsafe-fp-atomics is aliased to
-f[no-]ignore-denormal-mode.
More details can be found in #102569. This PR implements the frontend support for these options with OpenMP atomic in flang.

Backend changes are available in the draft PR: #143769 which will be raised after this merged.

@anchuraj anchuraj requested review from skatrak, tblah and kparzysz June 9, 2025 21:02
@llvmbot llvmbot added clang Clang issues not falling into any other category flang:driver mlir flang Flang issues not falling into any other category mlir:openmp flang:fir-hlfir flang:openmp labels Jun 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 9, 2025

@llvm/pr-subscribers-mlir-llvm
@llvm/pr-subscribers-flang-openmp
@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-clang

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

Author: Anchu Rajendran S (anchuraj)

Changes

Atomic Control Options are used to specify architectural characteristics to help lowering of atomic operations. The options used are:
-f[no-]atomic-remote-memory, -f[no-]atomic-fine-grained-memory,
-f[no-]atomic-ignore-denormal-mode.
Legacy option -m[no-]unsafe-fp-atomics is aliased to
-f[no-]ignore-denormal-mode.
More details can be found in #102569. This PR implements the frontend support for these options with OpenMP atomic in flang


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

11 Files Affected:

  • (modified) clang/include/clang/Driver/Options.td (+11-11)
  • (modified) flang/include/flang/Frontend/TargetOptions.h (+5)
  • (modified) flang/include/flang/Optimizer/Dialect/Support/FIRContext.h (+14)
  • (modified) flang/lib/Frontend/CompilerInvocation.cpp (+12)
  • (modified) flang/lib/Lower/Bridge.cpp (+6)
  • (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+6-1)
  • (modified) flang/lib/Optimizer/Dialect/Support/FIRContext.cpp (+40)
  • (added) flang/test/Lower/OpenMP/atomic-control-options.f90 (+37)
  • (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td (+14)
  • (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td (+5-3)
  • (modified) mlir/test/Dialect/OpenMP/ops.mlir (+9)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index fd6deb22d404e..c6d8f9106341a 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2299,21 +2299,21 @@ def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>,
 
 defm atomic_remote_memory : BoolFOption<"atomic-remote-memory",
   LangOpts<"AtomicRemoteMemory">, DefaultFalse,
-  PosFlag<SetTrue, [], [ClangOption, CC1Option], "May have">,
-  NegFlag<SetFalse, [], [ClangOption], "Assume no">,
-  BothFlags<[], [ClangOption], " atomic operations on remote memory">>;
+  PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "May have">,
+  NegFlag<SetFalse, [], [ClangOption, FlangOption], "Assume no">,
+  BothFlags<[], [ClangOption, FlangOption], " atomic operations on remote memory">>;
 
 defm atomic_fine_grained_memory : BoolFOption<"atomic-fine-grained-memory",
   LangOpts<"AtomicFineGrainedMemory">, DefaultFalse,
-  PosFlag<SetTrue, [], [ClangOption, CC1Option], "May have">,
-  NegFlag<SetFalse, [], [ClangOption], "Assume no">,
-  BothFlags<[], [ClangOption], " atomic operations on fine-grained memory">>;
+  PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "May have">,
+  NegFlag<SetFalse, [], [ClangOption, FlangOption], "Assume no">,
+  BothFlags<[], [ClangOption, FlangOption], " atomic operations on fine-grained memory">>;
 
 defm atomic_ignore_denormal_mode : BoolFOption<"atomic-ignore-denormal-mode",
   LangOpts<"AtomicIgnoreDenormalMode">, DefaultFalse,
-  PosFlag<SetTrue, [], [ClangOption, CC1Option], "Allow">,
-  NegFlag<SetFalse, [], [ClangOption], "Disallow">,
-  BothFlags<[], [ClangOption], " atomic operations to ignore denormal mode">>;
+  PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Allow">,
+  NegFlag<SetFalse, [], [ClangOption, FlangOption], "Disallow">,
+  BothFlags<[], [ClangOption, FlangOption], " atomic operations to ignore denormal mode">>;
 
 defm memory_profile : OptInCC1FFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">;
 def fmemory_profile_EQ : Joined<["-"], "fmemory-profile=">,
@@ -5270,9 +5270,9 @@ defm amdgpu_precise_memory_op
                   " precise memory mode (AMDGPU only)">;
 
 def munsafe_fp_atomics : Flag<["-"], "munsafe-fp-atomics">,
-  Visibility<[ClangOption, CC1Option]>, Alias<fatomic_ignore_denormal_mode>;
+  Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, Alias<fatomic_ignore_denormal_mode>;
 def mno_unsafe_fp_atomics : Flag<["-"], "mno-unsafe-fp-atomics">,
-  Visibility<[ClangOption]>, Alias<fno_atomic_ignore_denormal_mode>;
+  Visibility<[ClangOption, FlangOption]>, Alias<fno_atomic_ignore_denormal_mode>;
 
 def faltivec : Flag<["-"], "faltivec">, Group<f_Group>;
 def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>;
diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h
index 002d8d158abd4..26256fd775f11 100644
--- a/flang/include/flang/Frontend/TargetOptions.h
+++ b/flang/include/flang/Frontend/TargetOptions.h
@@ -53,6 +53,11 @@ class TargetOptions {
 
   /// Print verbose assembly
   bool asmVerbose = false;
+
+  /// Atomic Control Options for AMD GPU
+  bool amdgpuIgnoreDenormalMode = false;
+  bool amdgpuRemoteMemory = false;
+  bool amdgpuFineGrainedMemory = false;
 };
 
 } // end namespace Fortran::frontend
diff --git a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
index 2df14f83c11e1..ac563bcc402c7 100644
--- a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
+++ b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
@@ -58,10 +58,24 @@ void setTargetCPU(mlir::ModuleOp mod, llvm::StringRef cpu);
 /// Get the target CPU string from the Module or return a null reference.
 llvm::StringRef getTargetCPU(mlir::ModuleOp mod);
 
+// Setters and Getters for atomic control options
+void setAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod);
+bool getAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod);
+void setAmdgpuFineGrainedMemory(mlir::ModuleOp mod);
+bool getAmdgpuFineGrainedMemory(mlir::ModuleOp mod);
+void setAmdgpuRemoteMemory(mlir::ModuleOp mod);
+bool getAmdgpuRemoteMemory(mlir::ModuleOp mod);
+
 /// Set the tune CPU for the module. `cpu` must not be deallocated while
 /// module `mod` is still live.
 void setTuneCPU(mlir::ModuleOp mod, llvm::StringRef cpu);
 
+// set Atomic control options for amd gpu.
+void setAmdgpuAtomicControlOptions(mlir::ModuleOp mod,
+                                   bool amdgpuIgnoreDenormalMode,
+                                   bool amdgpuNoFineGrainedMemory,
+                                   bool amdgpuNoRemoteMemory);
+
 /// Get the tune CPU string from the Module or return a null reference.
 llvm::StringRef getTuneCPU(mlir::ModuleOp mod);
 
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 89aaee9f13853..78d44d76744dc 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -494,6 +494,18 @@ static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) {
           args.getLastArg(clang::driver::options::OPT_triple))
     opts.triple = a->getValue();
 
+  if (llvm::Triple(opts.triple).isAMDGPU()) {
+    opts.amdgpuIgnoreDenormalMode = args.hasFlag(
+        clang::driver::options::OPT_fatomic_ignore_denormal_mode,
+        clang::driver::options::OPT_fno_atomic_ignore_denormal_mode, false);
+    opts.amdgpuFineGrainedMemory = args.hasFlag(
+        clang::driver::options::OPT_fatomic_fine_grained_memory,
+        clang::driver::options::OPT_fno_atomic_fine_grained_memory, false);
+    opts.amdgpuRemoteMemory = args.hasFlag(
+        clang::driver::options::OPT_fatomic_remote_memory,
+        clang::driver::options::OPT_fno_atomic_remote_memory, false);
+  }
+
   if (const llvm::opt::Arg *a =
           args.getLastArg(clang::driver::options::OPT_target_cpu))
     opts.cpu = a->getValue();
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 64b16b3abe991..b045556565613 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -6648,6 +6648,12 @@ Fortran::lower::LoweringBridge::LoweringBridge(
   fir::setKindMapping(*module, kindMap);
   fir::setTargetCPU(*module, targetMachine.getTargetCPU());
   fir::setTuneCPU(*module, targetOpts.cpuToTuneFor);
+  if (targetOpts.amdgpuIgnoreDenormalMode)
+    fir::setAmdgpuIgnoreDenormalMode(*module);
+  if (targetOpts.amdgpuFineGrainedMemory)
+    fir::setAmdgpuFineGrainedMemory(*module);
+  if (targetOpts.amdgpuRemoteMemory)
+    fir::setAmdgpuRemoteMemory(*module);
   fir::setTargetFeatures(*module, targetMachine.getTargetFeatureString());
   fir::support::setMLIRDataLayout(*module, targetMachine.createDataLayout());
   fir::setIdent(*module, Fortran::common::getFlangFullVersion());
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6892e571e62a3..bd09073100f1d 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2911,8 +2911,13 @@ static void genAtomicUpdateStatement(
   if (rightHandClauseList)
     genOmpAtomicHintAndMemoryOrderClauses(converter, *rightHandClauseList, hint,
                                           memoryOrder);
+  auto module = firOpBuilder.getModule();
+  auto atomicControlAttr = mlir::omp::AtomicControlAttr::get(
+      firOpBuilder.getContext(), fir::getAmdgpuIgnoreDenormalMode(module),
+      fir::getAmdgpuFineGrainedMemory(module),
+      fir::getAmdgpuRemoteMemory(module));
   atomicUpdateOp = firOpBuilder.create<mlir::omp::AtomicUpdateOp>(
-      currentLocation, lhsAddr, hint, memoryOrder);
+      currentLocation, lhsAddr, atomicControlAttr, hint, memoryOrder);
 
   processOmpAtomicTODO(varType, loc);
 
diff --git a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
index 01c0be66d1ecc..b961793dbdfd5 100644
--- a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
+++ b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
@@ -88,6 +88,46 @@ void fir::setTuneCPU(mlir::ModuleOp mod, llvm::StringRef cpu) {
   mod->setAttr(tuneCpuName, mlir::StringAttr::get(ctx, cpu));
 }
 
+static constexpr const char *amdgpuIgnoreDenormalModeName =
+    "fir.amdgpu.ignore.denormal.mode";
+void fir::setAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod) {
+  auto *ctx = mod.getContext();
+  mod->setAttr(amdgpuIgnoreDenormalModeName, mlir::UnitAttr::get(ctx));
+}
+
+bool fir::getAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod) {
+  if (auto attr =
+          mod->getAttrOfType<mlir::UnitAttr>(amdgpuIgnoreDenormalModeName))
+    return true;
+  return false;
+}
+
+static constexpr const char *amdgpuFineGrainedMemoryName =
+    "fir.amdgpu.fine.grained.memory";
+void fir::setAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
+  auto *ctx = mod.getContext();
+  mod->setAttr(amdgpuFineGrainedMemoryName, mlir::UnitAttr::get(ctx));
+}
+
+bool fir::getAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
+  if (auto attr =
+          mod->getAttrOfType<mlir::UnitAttr>(amdgpuFineGrainedMemoryName))
+    return true;
+  return false;
+}
+static constexpr const char *amdgpuRemoteMemoryName =
+    "fir.amdgpu.remote.memory";
+void fir::setAmdgpuRemoteMemory(mlir::ModuleOp mod) {
+  auto *ctx = mod.getContext();
+  mod->setAttr(amdgpuRemoteMemoryName, mlir::UnitAttr::get(ctx));
+}
+
+bool fir::getAmdgpuRemoteMemory(mlir::ModuleOp mod) {
+  if (auto attr = mod->getAttrOfType<mlir::UnitAttr>(amdgpuRemoteMemoryName))
+    return true;
+  return false;
+}
+
 llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) {
   if (auto attr = mod->getAttrOfType<mlir::StringAttr>(tuneCpuName))
     return attr.getValue();
diff --git a/flang/test/Lower/OpenMP/atomic-control-options.f90 b/flang/test/Lower/OpenMP/atomic-control-options.f90
new file mode 100644
index 0000000000000..1eb0f617f365e
--- /dev/null
+++ b/flang/test/Lower/OpenMP/atomic-control-options.f90
@@ -0,0 +1,37 @@
+! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -munsafe-fp-atomics %s -o - | FileCheck -check-prefix=UNSAFE-FP-ATOMICS %s
+! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -fatomic-ignore-denormal-mode %s -o - | FileCheck -check-prefix=IGNORE-DENORMAL %s
+! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -fatomic-fine-grained-memory %s -o - | FileCheck -check-prefix=FINE-GRAINED-MEMORY %s
+! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -fatomic-remote-memory %s -o - | FileCheck -check-prefix=REMOTE-MEMORY %s
+program test
+    implicit none
+    integer :: A, B, threads
+    threads = 128
+    A = 0
+    B = 0
+    !UNSAFE-FP-ATOMICS: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_fine_grained_memory = true>}
+    !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_remote_memory = true>}
+    !$omp target parallel num_threads(threads)
+    !$omp atomic
+    A =  A + 1
+    !$omp end target parallel
+    !UNSAFE-FP-ATOMICS: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_fine_grained_memory = true>}
+    !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_remote_memory = true>}
+    !$omp target parallel num_threads(threads)
+    !$omp atomic capture
+        A = A + B
+        B = A
+    !$omp end atomic
+    !$omp end target parallel
+end program test
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
index 704d0b2220e8a..84887dfd2c6f9 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
@@ -54,6 +54,20 @@ def FlagsAttr : OpenMP_Attr<"Flags", "flags"> {
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
+//===----------------------------------------------------------------------===//
+// AtomicControlAttr
+//===----------------------------------------------------------------------===//
+
+// Runtime library flags attribute that holds information for lowering to LLVM.
+def AtomicControlAttr : OpenMP_Attr<"AtomicControl", "atomic_control"> {
+  let parameters =
+      (ins DefaultValuedParameter<"bool", "false">:$amdgpu_ignore_denormal_mode,
+          DefaultValuedParameter<"bool", "false">:$amdgpu_fine_grained_memory,
+          DefaultValuedParameter<"bool", "false">:$amdgpu_remote_memory);
+
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
 //===----------------------------------------------------------------------===//
 // TaskDependArrayAttr
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 036c6a6e350a8..d7d14e96233ae 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -1543,9 +1543,11 @@ def AtomicUpdateOp : OpenMP_Op<"atomic.update", traits = [
     operations.
   }] # clausesDescription;
 
-  let arguments = !con((ins Arg<OpenMP_PointerLikeType,
-                                "Address of variable to be updated",
-                                [MemRead, MemWrite]>:$x), clausesArgs);
+  let arguments = !con(
+      (ins Arg<OpenMP_PointerLikeType,
+               "Address of variable to be updated", [MemRead, MemWrite]>:$x,
+          OptionalAttr<AtomicControlAttr>:$atomic_control),
+      clausesArgs);
 
   // Override region definition.
   let regions = (region SizedRegion<1>:$region);
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 47cfc5278a5d0..e377b7aab3e43 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -1562,6 +1562,15 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
     omp.yield(%newval : i32)
   }
 
+  // CHECK: omp.atomic.update %[[X]] : memref<i32> {
+  // CHECK-NEXT: (%[[XVAL:.*]]: i32):
+  // CHECK-NEXT:   omp.yield(%{{.+}} : i32)
+  // CHECK-NEXT: } {atomic_control_attr = #omp.atomic_control<amdgpu_ignore_denormal_mode = true, amdgpu_fine_grained_memory = true, amdgpu_remote_memory = true>}
+  omp.atomic.update %x : memref<i32> {
+  ^bb0(%xval:i32):
+    omp.yield(%const:i32)
+  } {atomic_control_attr = #omp.atomic_control<amdgpu_ignore_denormal_mode = true, amdgpu_fine_grained_memory = true, amdgpu_remote_memory = true>}
+
   return
 }
 

@llvmbot
Copy link
Member

llvmbot commented Jun 9, 2025

@llvm/pr-subscribers-flang-driver

Author: Anchu Rajendran S (anchuraj)

Changes

Atomic Control Options are used to specify architectural characteristics to help lowering of atomic operations. The options used are:
-f[no-]atomic-remote-memory, -f[no-]atomic-fine-grained-memory,
-f[no-]atomic-ignore-denormal-mode.
Legacy option -m[no-]unsafe-fp-atomics is aliased to
-f[no-]ignore-denormal-mode.
More details can be found in #102569. This PR implements the frontend support for these options with OpenMP atomic in flang


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

11 Files Affected:

  • (modified) clang/include/clang/Driver/Options.td (+11-11)
  • (modified) flang/include/flang/Frontend/TargetOptions.h (+5)
  • (modified) flang/include/flang/Optimizer/Dialect/Support/FIRContext.h (+14)
  • (modified) flang/lib/Frontend/CompilerInvocation.cpp (+12)
  • (modified) flang/lib/Lower/Bridge.cpp (+6)
  • (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+6-1)
  • (modified) flang/lib/Optimizer/Dialect/Support/FIRContext.cpp (+40)
  • (added) flang/test/Lower/OpenMP/atomic-control-options.f90 (+37)
  • (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td (+14)
  • (modified) mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td (+5-3)
  • (modified) mlir/test/Dialect/OpenMP/ops.mlir (+9)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index fd6deb22d404e..c6d8f9106341a 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2299,21 +2299,21 @@ def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>,
 
 defm atomic_remote_memory : BoolFOption<"atomic-remote-memory",
   LangOpts<"AtomicRemoteMemory">, DefaultFalse,
-  PosFlag<SetTrue, [], [ClangOption, CC1Option], "May have">,
-  NegFlag<SetFalse, [], [ClangOption], "Assume no">,
-  BothFlags<[], [ClangOption], " atomic operations on remote memory">>;
+  PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "May have">,
+  NegFlag<SetFalse, [], [ClangOption, FlangOption], "Assume no">,
+  BothFlags<[], [ClangOption, FlangOption], " atomic operations on remote memory">>;
 
 defm atomic_fine_grained_memory : BoolFOption<"atomic-fine-grained-memory",
   LangOpts<"AtomicFineGrainedMemory">, DefaultFalse,
-  PosFlag<SetTrue, [], [ClangOption, CC1Option], "May have">,
-  NegFlag<SetFalse, [], [ClangOption], "Assume no">,
-  BothFlags<[], [ClangOption], " atomic operations on fine-grained memory">>;
+  PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "May have">,
+  NegFlag<SetFalse, [], [ClangOption, FlangOption], "Assume no">,
+  BothFlags<[], [ClangOption, FlangOption], " atomic operations on fine-grained memory">>;
 
 defm atomic_ignore_denormal_mode : BoolFOption<"atomic-ignore-denormal-mode",
   LangOpts<"AtomicIgnoreDenormalMode">, DefaultFalse,
-  PosFlag<SetTrue, [], [ClangOption, CC1Option], "Allow">,
-  NegFlag<SetFalse, [], [ClangOption], "Disallow">,
-  BothFlags<[], [ClangOption], " atomic operations to ignore denormal mode">>;
+  PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Allow">,
+  NegFlag<SetFalse, [], [ClangOption, FlangOption], "Disallow">,
+  BothFlags<[], [ClangOption, FlangOption], " atomic operations to ignore denormal mode">>;
 
 defm memory_profile : OptInCC1FFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">;
 def fmemory_profile_EQ : Joined<["-"], "fmemory-profile=">,
@@ -5270,9 +5270,9 @@ defm amdgpu_precise_memory_op
                   " precise memory mode (AMDGPU only)">;
 
 def munsafe_fp_atomics : Flag<["-"], "munsafe-fp-atomics">,
-  Visibility<[ClangOption, CC1Option]>, Alias<fatomic_ignore_denormal_mode>;
+  Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, Alias<fatomic_ignore_denormal_mode>;
 def mno_unsafe_fp_atomics : Flag<["-"], "mno-unsafe-fp-atomics">,
-  Visibility<[ClangOption]>, Alias<fno_atomic_ignore_denormal_mode>;
+  Visibility<[ClangOption, FlangOption]>, Alias<fno_atomic_ignore_denormal_mode>;
 
 def faltivec : Flag<["-"], "faltivec">, Group<f_Group>;
 def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>;
diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h
index 002d8d158abd4..26256fd775f11 100644
--- a/flang/include/flang/Frontend/TargetOptions.h
+++ b/flang/include/flang/Frontend/TargetOptions.h
@@ -53,6 +53,11 @@ class TargetOptions {
 
   /// Print verbose assembly
   bool asmVerbose = false;
+
+  /// Atomic Control Options for AMD GPU
+  bool amdgpuIgnoreDenormalMode = false;
+  bool amdgpuRemoteMemory = false;
+  bool amdgpuFineGrainedMemory = false;
 };
 
 } // end namespace Fortran::frontend
diff --git a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
index 2df14f83c11e1..ac563bcc402c7 100644
--- a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
+++ b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
@@ -58,10 +58,24 @@ void setTargetCPU(mlir::ModuleOp mod, llvm::StringRef cpu);
 /// Get the target CPU string from the Module or return a null reference.
 llvm::StringRef getTargetCPU(mlir::ModuleOp mod);
 
+// Setters and Getters for atomic control options
+void setAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod);
+bool getAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod);
+void setAmdgpuFineGrainedMemory(mlir::ModuleOp mod);
+bool getAmdgpuFineGrainedMemory(mlir::ModuleOp mod);
+void setAmdgpuRemoteMemory(mlir::ModuleOp mod);
+bool getAmdgpuRemoteMemory(mlir::ModuleOp mod);
+
 /// Set the tune CPU for the module. `cpu` must not be deallocated while
 /// module `mod` is still live.
 void setTuneCPU(mlir::ModuleOp mod, llvm::StringRef cpu);
 
+// set Atomic control options for amd gpu.
+void setAmdgpuAtomicControlOptions(mlir::ModuleOp mod,
+                                   bool amdgpuIgnoreDenormalMode,
+                                   bool amdgpuNoFineGrainedMemory,
+                                   bool amdgpuNoRemoteMemory);
+
 /// Get the tune CPU string from the Module or return a null reference.
 llvm::StringRef getTuneCPU(mlir::ModuleOp mod);
 
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 89aaee9f13853..78d44d76744dc 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -494,6 +494,18 @@ static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) {
           args.getLastArg(clang::driver::options::OPT_triple))
     opts.triple = a->getValue();
 
+  if (llvm::Triple(opts.triple).isAMDGPU()) {
+    opts.amdgpuIgnoreDenormalMode = args.hasFlag(
+        clang::driver::options::OPT_fatomic_ignore_denormal_mode,
+        clang::driver::options::OPT_fno_atomic_ignore_denormal_mode, false);
+    opts.amdgpuFineGrainedMemory = args.hasFlag(
+        clang::driver::options::OPT_fatomic_fine_grained_memory,
+        clang::driver::options::OPT_fno_atomic_fine_grained_memory, false);
+    opts.amdgpuRemoteMemory = args.hasFlag(
+        clang::driver::options::OPT_fatomic_remote_memory,
+        clang::driver::options::OPT_fno_atomic_remote_memory, false);
+  }
+
   if (const llvm::opt::Arg *a =
           args.getLastArg(clang::driver::options::OPT_target_cpu))
     opts.cpu = a->getValue();
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 64b16b3abe991..b045556565613 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -6648,6 +6648,12 @@ Fortran::lower::LoweringBridge::LoweringBridge(
   fir::setKindMapping(*module, kindMap);
   fir::setTargetCPU(*module, targetMachine.getTargetCPU());
   fir::setTuneCPU(*module, targetOpts.cpuToTuneFor);
+  if (targetOpts.amdgpuIgnoreDenormalMode)
+    fir::setAmdgpuIgnoreDenormalMode(*module);
+  if (targetOpts.amdgpuFineGrainedMemory)
+    fir::setAmdgpuFineGrainedMemory(*module);
+  if (targetOpts.amdgpuRemoteMemory)
+    fir::setAmdgpuRemoteMemory(*module);
   fir::setTargetFeatures(*module, targetMachine.getTargetFeatureString());
   fir::support::setMLIRDataLayout(*module, targetMachine.createDataLayout());
   fir::setIdent(*module, Fortran::common::getFlangFullVersion());
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6892e571e62a3..bd09073100f1d 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2911,8 +2911,13 @@ static void genAtomicUpdateStatement(
   if (rightHandClauseList)
     genOmpAtomicHintAndMemoryOrderClauses(converter, *rightHandClauseList, hint,
                                           memoryOrder);
+  auto module = firOpBuilder.getModule();
+  auto atomicControlAttr = mlir::omp::AtomicControlAttr::get(
+      firOpBuilder.getContext(), fir::getAmdgpuIgnoreDenormalMode(module),
+      fir::getAmdgpuFineGrainedMemory(module),
+      fir::getAmdgpuRemoteMemory(module));
   atomicUpdateOp = firOpBuilder.create<mlir::omp::AtomicUpdateOp>(
-      currentLocation, lhsAddr, hint, memoryOrder);
+      currentLocation, lhsAddr, atomicControlAttr, hint, memoryOrder);
 
   processOmpAtomicTODO(varType, loc);
 
diff --git a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
index 01c0be66d1ecc..b961793dbdfd5 100644
--- a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
+++ b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
@@ -88,6 +88,46 @@ void fir::setTuneCPU(mlir::ModuleOp mod, llvm::StringRef cpu) {
   mod->setAttr(tuneCpuName, mlir::StringAttr::get(ctx, cpu));
 }
 
+static constexpr const char *amdgpuIgnoreDenormalModeName =
+    "fir.amdgpu.ignore.denormal.mode";
+void fir::setAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod) {
+  auto *ctx = mod.getContext();
+  mod->setAttr(amdgpuIgnoreDenormalModeName, mlir::UnitAttr::get(ctx));
+}
+
+bool fir::getAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod) {
+  if (auto attr =
+          mod->getAttrOfType<mlir::UnitAttr>(amdgpuIgnoreDenormalModeName))
+    return true;
+  return false;
+}
+
+static constexpr const char *amdgpuFineGrainedMemoryName =
+    "fir.amdgpu.fine.grained.memory";
+void fir::setAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
+  auto *ctx = mod.getContext();
+  mod->setAttr(amdgpuFineGrainedMemoryName, mlir::UnitAttr::get(ctx));
+}
+
+bool fir::getAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
+  if (auto attr =
+          mod->getAttrOfType<mlir::UnitAttr>(amdgpuFineGrainedMemoryName))
+    return true;
+  return false;
+}
+static constexpr const char *amdgpuRemoteMemoryName =
+    "fir.amdgpu.remote.memory";
+void fir::setAmdgpuRemoteMemory(mlir::ModuleOp mod) {
+  auto *ctx = mod.getContext();
+  mod->setAttr(amdgpuRemoteMemoryName, mlir::UnitAttr::get(ctx));
+}
+
+bool fir::getAmdgpuRemoteMemory(mlir::ModuleOp mod) {
+  if (auto attr = mod->getAttrOfType<mlir::UnitAttr>(amdgpuRemoteMemoryName))
+    return true;
+  return false;
+}
+
 llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) {
   if (auto attr = mod->getAttrOfType<mlir::StringAttr>(tuneCpuName))
     return attr.getValue();
diff --git a/flang/test/Lower/OpenMP/atomic-control-options.f90 b/flang/test/Lower/OpenMP/atomic-control-options.f90
new file mode 100644
index 0000000000000..1eb0f617f365e
--- /dev/null
+++ b/flang/test/Lower/OpenMP/atomic-control-options.f90
@@ -0,0 +1,37 @@
+! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -munsafe-fp-atomics %s -o - | FileCheck -check-prefix=UNSAFE-FP-ATOMICS %s
+! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -fatomic-ignore-denormal-mode %s -o - | FileCheck -check-prefix=IGNORE-DENORMAL %s
+! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -fatomic-fine-grained-memory %s -o - | FileCheck -check-prefix=FINE-GRAINED-MEMORY %s
+! RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -fatomic-remote-memory %s -o - | FileCheck -check-prefix=REMOTE-MEMORY %s
+program test
+    implicit none
+    integer :: A, B, threads
+    threads = 128
+    A = 0
+    B = 0
+    !UNSAFE-FP-ATOMICS: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_fine_grained_memory = true>}
+    !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_remote_memory = true>}
+    !$omp target parallel num_threads(threads)
+    !$omp atomic
+    A =  A + 1
+    !$omp end target parallel
+    !UNSAFE-FP-ATOMICS: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_fine_grained_memory = true>}
+    !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
+    !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_remote_memory = true>}
+    !$omp target parallel num_threads(threads)
+    !$omp atomic capture
+        A = A + B
+        B = A
+    !$omp end atomic
+    !$omp end target parallel
+end program test
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
index 704d0b2220e8a..84887dfd2c6f9 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
@@ -54,6 +54,20 @@ def FlagsAttr : OpenMP_Attr<"Flags", "flags"> {
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
+//===----------------------------------------------------------------------===//
+// AtomicControlAttr
+//===----------------------------------------------------------------------===//
+
+// Runtime library flags attribute that holds information for lowering to LLVM.
+def AtomicControlAttr : OpenMP_Attr<"AtomicControl", "atomic_control"> {
+  let parameters =
+      (ins DefaultValuedParameter<"bool", "false">:$amdgpu_ignore_denormal_mode,
+          DefaultValuedParameter<"bool", "false">:$amdgpu_fine_grained_memory,
+          DefaultValuedParameter<"bool", "false">:$amdgpu_remote_memory);
+
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
 //===----------------------------------------------------------------------===//
 // TaskDependArrayAttr
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 036c6a6e350a8..d7d14e96233ae 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -1543,9 +1543,11 @@ def AtomicUpdateOp : OpenMP_Op<"atomic.update", traits = [
     operations.
   }] # clausesDescription;
 
-  let arguments = !con((ins Arg<OpenMP_PointerLikeType,
-                                "Address of variable to be updated",
-                                [MemRead, MemWrite]>:$x), clausesArgs);
+  let arguments = !con(
+      (ins Arg<OpenMP_PointerLikeType,
+               "Address of variable to be updated", [MemRead, MemWrite]>:$x,
+          OptionalAttr<AtomicControlAttr>:$atomic_control),
+      clausesArgs);
 
   // Override region definition.
   let regions = (region SizedRegion<1>:$region);
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 47cfc5278a5d0..e377b7aab3e43 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -1562,6 +1562,15 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
     omp.yield(%newval : i32)
   }
 
+  // CHECK: omp.atomic.update %[[X]] : memref<i32> {
+  // CHECK-NEXT: (%[[XVAL:.*]]: i32):
+  // CHECK-NEXT:   omp.yield(%{{.+}} : i32)
+  // CHECK-NEXT: } {atomic_control_attr = #omp.atomic_control<amdgpu_ignore_denormal_mode = true, amdgpu_fine_grained_memory = true, amdgpu_remote_memory = true>}
+  omp.atomic.update %x : memref<i32> {
+  ^bb0(%xval:i32):
+    omp.yield(%const:i32)
+  } {atomic_control_attr = #omp.atomic_control<amdgpu_ignore_denormal_mode = true, amdgpu_fine_grained_memory = true, amdgpu_remote_memory = true>}
+
   return
 }
 

Copy link
Contributor

@tarunprabhu tarunprabhu left a comment

Choose a reason for hiding this comment

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

Thanks for this.

Since you have added both FlangOption and FC1Option in Options.td, could you add a test that checks that the option is handled by the main driver as well as fc1. One that simply checks that the option gets passed down to fc1 from the main driver would be sufficient.

@anchuraj anchuraj force-pushed the atomic-control-frontend branch from c69cca2 to 26d8e64 Compare June 11, 2025 20:09
Copy link

github-actions bot commented Jun 11, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@anchuraj anchuraj force-pushed the atomic-control-frontend branch from 26d8e64 to 6a42a1d Compare June 11, 2025 21:47
@anchuraj
Copy link
Contributor Author

anchuraj commented Jun 11, 2025

Thanks for this.

Since you have added both FlangOption and FC1Option in Options.td, could you add a test that checks that the option is handled by the main driver as well as fc1. One that simply checks that the option gets passed down to fc1 from the main driver would be sufficient.

Hi Thank you very much for reviewing. I have added the driver test case in #143769 (where it checks metadata is added) I will raise it for review after this is merged. I have also updated AtomicControl attribute as non-optional (Though input to the compiler is optional, in cases where no atomic control option is specified, we need to emit metadatas amdgpu.no.remote.memory and amdgpu.no.fine.grained.memory)

@anchuraj anchuraj force-pushed the atomic-control-frontend branch 2 times, most recently from 3499c15 to 74ba59b Compare June 12, 2025 03:14
@anchuraj anchuraj requested a review from tarunprabhu June 12, 2025 05:25
Copy link
Contributor

@tarunprabhu tarunprabhu left a comment

Choose a reason for hiding this comment

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

Other than the one comment, the frontend related parts LGTM, but please wait for someone more familiar with the OpenMP side of things.

@anchuraj anchuraj force-pushed the atomic-control-frontend branch from 74ba59b to 1b93740 Compare June 13, 2025 17:33
@anchuraj anchuraj requested review from NimishMishra and TIFitis June 13, 2025 18:04
@anchuraj anchuraj changed the title [flang][flang-driver] atomic control support [flang][flang-driver][mlir][OpenMP] atomic control support Jun 13, 2025
Copy link
Contributor

@kparzysz kparzysz left a comment

Choose a reason for hiding this comment

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

Please remove 'amdgpu' from variable and function names. These options may be useful for other targets as well.

@anchuraj anchuraj force-pushed the atomic-control-frontend branch 3 times, most recently from 1fdbf81 to fe9a702 Compare June 26, 2025 15:50
@anchuraj
Copy link
Contributor Author

pinging for review

Copy link
Member

@skatrak skatrak left a comment

Choose a reason for hiding this comment

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

Thank you Anchu, I only have some small suggestions and a couple of questions.

@anchuraj anchuraj force-pushed the atomic-control-frontend branch 4 times, most recently from 23d3058 to 7b0683b Compare July 7, 2025 19:25
@anchuraj anchuraj requested a review from skatrak July 7, 2025 19:35
@anchuraj anchuraj force-pushed the atomic-control-frontend branch from 7b0683b to 0b5e9d2 Compare July 8, 2025 20:27
@anchuraj
Copy link
Contributor Author

anchuraj commented Jul 8, 2025

Thank you Anchu, I only have some small suggestions and a couple of questions.

Thank you @skatrak for the review! I have addressed the comments.

@anchuraj anchuraj force-pushed the atomic-control-frontend branch from 0b5e9d2 to 352ae37 Compare July 14, 2025 14:38
Copy link
Member

@skatrak skatrak left a comment

Choose a reason for hiding this comment

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

Thank you Anchu, and excuse me for the long delay taking another look at this. LGTM, only non-blocking nits from me, feel free to merge when you're ready!

@anchuraj anchuraj force-pushed the atomic-control-frontend branch from 352ae37 to a456168 Compare July 24, 2025 14:42
@anchuraj
Copy link
Contributor Author

Thank you Anchu, and excuse me for the long delay taking another look at this. LGTM, only non-blocking nits from me, feel free to merge when you're ready!

Thank you and no worries! .I have addressed your suggestions

@anchuraj anchuraj merged commit f44346d into llvm:main Jul 24, 2025
9 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jul 24, 2025

LLVM Buildbot has detected a new failure on builder flang-aarch64-out-of-tree running on linaro-flang-aarch64-out-of-tree while building clang,flang,mlir at step 11 "test-build-flang-unified-tree-check-flang".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/53/builds/18055

Here is the relevant piece of the build log for the reference
Step 11 (test-build-flang-unified-tree-check-flang) failure: test (failure)
******************** TEST 'Flang :: Lower/OpenMP/atomic-control-options.f90' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
/home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/build_flang/bin/flang -fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -munsafe-fp-atomics /home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90 -o - | /home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/build_llvm/bin/FileCheck -check-prefix=UNSAFE-FP-ATOMICS /home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90 # RUN: at line 1
+ /home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/build_flang/bin/flang -fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -munsafe-fp-atomics /home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90 -o -
error: unable to create target: 'No available targets are compatible with triple "amdgcn-amd-amdhsa"'
+ /home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/build_llvm/bin/FileCheck -check-prefix=UNSAFE-FP-ATOMICS /home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/build_llvm/bin/FileCheck -check-prefix=UNSAFE-FP-ATOMICS /home/tcwg-buildbot/worker/flang-aarch64-out-of-tree/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90

--

********************


@klausler
Copy link
Contributor

llvm-project/main fails to build on x86-64 Linux:

Testing: 
FAIL: Flang :: Lower/OpenMP/atomic-control-options.f90 (1 of 3701)
******************** TEST 'Flang :: Lower/OpenMP/atomic-control-options.f90' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
/home/pklausler/llvm-project/build/x86/gcc/9.3.0/Release/shared/bin/flang -fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -munsafe-fp-atomics /home/pklausler/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90 -o - | /home/pklausler/llvm-project/build/x86/gcc/9.3.0/Release/shared/bin/FileCheck -check-prefix=UNSAFE-FP-ATOMICS /home/pklausler/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90 # RUN: at line 1
+ /home/pklausler/llvm-project/build/x86/gcc/9.3.0/Release/shared/bin/flang -fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -munsafe-fp-atomics /home/pklausler/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90 -o -
+ /home/pklausler/llvm-project/build/x86/gcc/9.3.0/Release/shared/bin/FileCheck -check-prefix=UNSAFE-FP-ATOMICS /home/pklausler/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90
error: unable to create target: 'No available targets are compatible with triple "amdgcn-amd-amdhsa"'
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /home/pklausler/llvm-project/build/x86/gcc/9.3.0/Release/shared/bin/FileCheck -check-prefix=UNSAFE-FP-ATOMICS /home/pklausler/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90

@llvm-ci
Copy link
Collaborator

llvm-ci commented Jul 24, 2025

LLVM Buildbot has detected a new failure on builder ppc64le-flang-rhel-clang running on ppc64le-flang-rhel-test while building clang,flang,mlir at step 6 "test-build-unified-tree-check-flang".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/157/builds/34820

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-flang) failure: test (failure)
******************** TEST 'Flang :: Lower/OpenMP/atomic-control-options.f90' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/flang -fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -munsafe-fp-atomics /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90 -o - | /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/FileCheck -check-prefix=UNSAFE-FP-ATOMICS /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90 # RUN: at line 1
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/flang -fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-device -munsafe-fp-atomics /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90 -o -
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/FileCheck -check-prefix=UNSAFE-FP-ATOMICS /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90
error: unable to create target: 'No available targets are compatible with triple "amdgcn-amd-amdhsa"'
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/FileCheck -check-prefix=UNSAFE-FP-ATOMICS /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Lower/OpenMP/atomic-control-options.f90

--

********************


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category flang:driver flang:fir-hlfir flang:openmp flang Flang issues not falling into any other category mlir:llvm mlir:openmp mlir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants