[Mlir-commits] [clang] [flang] [mlir] [flang][flang-driver][mlir][OpenMP] atomic control support (PR #143441)

Anchu Rajendran S llvmlistbot at llvm.org
Thu Jul 24 07:42:26 PDT 2025


https://github.com/anchuraj updated https://github.com/llvm/llvm-project/pull/143441

>From 0fb6d522bdb9c3cf441fd4af96d1467c9c42c91e Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Wed, 4 Jun 2025 15:12:49 -0500
Subject: [PATCH 1/6] [flang][flang-driver] atomic control support

---
 clang/include/clang/Driver/Options.td         | 22 +++++-----
 flang/include/flang/Frontend/TargetOptions.h  |  5 +++
 .../Optimizer/Dialect/Support/FIRContext.h    | 14 +++++++
 flang/lib/Frontend/CompilerInvocation.cpp     | 12 ++++++
 flang/lib/Lower/Bridge.cpp                    |  6 +++
 .../Optimizer/Dialect/Support/FIRContext.cpp  | 40 +++++++++++++++++++
 .../Lower/OpenMP/atomic-control-options.f90   | 37 +++++++++++++++++
 .../mlir/Dialect/OpenMP/OpenMPAttrDefs.td     | 14 +++++++
 mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td |  8 ++--
 mlir/test/Dialect/OpenMP/ops.mlir             |  9 +++++
 10 files changed, 153 insertions(+), 14 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/atomic-control-options.f90

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 916400efdb449..fa248381583cd 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2320,21 +2320,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=">,
@@ -5360,9 +5360,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 f55d866435997..c4a12f5b07edb 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -512,6 +512,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 92aae792248c5..8661f3057ec66 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -6733,6 +6733,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/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 8cf18b43450ab..be114ea4fb631 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -1750,9 +1750,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 4c50ed3230976..71273b21f96c7 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
 }
 

>From 76c54b67e40628346d280544d49a93ac929a2711 Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Wed, 11 Jun 2025 13:58:07 -0500
Subject: [PATCH 2/6] R2: Making Atomic control non-optional

---
 mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td |   2 +-
 .../OpenMPToLLVM/convert-to-llvmir.mlir       |   2 +-
 mlir/test/Dialect/OpenMP/canonicalize.mlir    |  10 +-
 mlir/test/Dialect/OpenMP/invalid.mlir         |  46 +++----
 mlir/test/Dialect/OpenMP/ops.mlir             | 127 +++++++++---------
 .../Target/LLVMIR/openmp-llvm-invalid.mlir    |   8 +-
 mlir/test/Target/LLVMIR/openmp-llvm.mlir      |  98 +++++++-------
 .../openmp-target-nesting-in-host-ops.mlir    |   2 +-
 mlir/test/Target/LLVMIR/openmp-todo.mlir      |   2 +-
 9 files changed, 148 insertions(+), 149 deletions(-)

diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index be114ea4fb631..bd89bf5d27680 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -1753,7 +1753,7 @@ def AtomicUpdateOp : OpenMP_Op<"atomic.update", traits = [
   let arguments = !con(
       (ins Arg<OpenMP_PointerLikeType,
                "Address of variable to be updated", [MemRead, MemWrite]>:$x,
-          OptionalAttr<AtomicControlAttr>:$atomic_control),
+          AtomicControlAttr:$atomic_control),
       clausesArgs);
 
   // Override region definition.
diff --git a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir
index d69de998346b5..0b2445d0a0d18 100644
--- a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir
+++ b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir
@@ -133,7 +133,7 @@ func.func @atomic_update() {
     %1 = arith.constant 1 : i32
     %2 = arith.addi %arg0, %1  : i32
     omp.yield(%2 : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 llvm.mlir.global internal @_QFsEc() : i32 {
diff --git a/mlir/test/Dialect/OpenMP/canonicalize.mlir b/mlir/test/Dialect/OpenMP/canonicalize.mlir
index de6c931ecc5fd..2492010c4d3c7 100644
--- a/mlir/test/Dialect/OpenMP/canonicalize.mlir
+++ b/mlir/test/Dialect/OpenMP/canonicalize.mlir
@@ -4,7 +4,7 @@ func.func @update_no_op(%x : memref<i32>) {
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval : i32):
     omp.yield(%xval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -17,7 +17,7 @@ func.func @update_write_op(%x : memref<i32>, %value: i32) {
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval : i32):
     omp.yield(%value : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -33,7 +33,7 @@ func.func @update_normal(%x : memref<i32>, %value: i32) {
   ^bb0(%xval : i32):
     %newval = arith.addi %xval, %value : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -50,7 +50,7 @@ func.func @update_unnecessary_computations(%x: memref<i32>) {
   ^bb0(%xval: i32):
     %newval = arith.addi %xval, %c0 : i32
     omp.yield(%newval: i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -65,7 +65,7 @@ func.func @update_unnecessary_computations(%x: memref<i32>) {
   ^bb0(%xval: i32):
     %newval = arith.muli %xval, %c0 : i32
     omp.yield(%newval: i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index 5088f2dfa7d7a..cae51c8acb69e 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -1040,7 +1040,7 @@ func.func @omp_atomic_update1(%x: memref<i32>, %expr: f32) {
   ^bb0(%xval: f32):
     %newval = llvm.fadd %xval, %expr : f32
     omp.yield (%newval : f32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1053,7 +1053,7 @@ func.func @omp_atomic_update2(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.terminator
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1065,7 +1065,7 @@ func.func @omp_atomic_update3(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1077,7 +1077,7 @@ func.func @omp_atomic_update4(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1089,7 +1089,7 @@ func.func @omp_atomic_update5(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1101,7 +1101,7 @@ func.func @omp_atomic_update6(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval, %expr : i32, i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1113,7 +1113,7 @@ func.func @omp_atomic_update7(%x: memref<i32>, %expr: i32, %y: f32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%y: f32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1125,7 +1125,7 @@ func.func @omp_atomic_update8(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32, %tmp: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1137,7 +1137,7 @@ func.func @omp_atomic_update(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1149,7 +1149,7 @@ func.func @omp_atomic_update(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1161,7 +1161,7 @@ func.func @omp_atomic_update(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
@@ -1197,12 +1197,12 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.update %x : memref<i32> {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.terminator
   }
   return
@@ -1230,7 +1230,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.terminator
   }
   return
@@ -1245,7 +1245,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.write %x = %expr : memref<i32>, i32
     omp.terminator
   }
@@ -1273,7 +1273,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>,
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %y : memref<i32>, memref<i32>, i32
     omp.terminator
   }
@@ -1289,7 +1289,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>,
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.terminator
   }
 }
@@ -1314,7 +1314,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1329,7 +1329,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1344,7 +1344,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1359,7 +1359,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1374,7 +1374,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1389,7 +1389,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x memory_order(seq_cst) : memref<i32>, memref<i32>, i32
   }
   return
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 71273b21f96c7..dfd714b8d890b 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -1371,7 +1371,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   // CHECK: omp.atomic.update %[[XBOOL]] : memref<i1>
   // CHECK-NEXT: (%[[XVAL:.*]]: i1):
   // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.and %[[XVAL]], %[[EXPRBOOL]] : i1
@@ -1380,57 +1380,57 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i1):
     %newval = llvm.and %xval, %exprBool : i1
     omp.yield(%newval : i1)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   // CHECK: omp.atomic.update %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.shl %[[XVAL]], %[[EXPR]] : i32
   // CHECK-NEXT:   omp.yield(%[[NEWVAL]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval: i32):
     %newval = llvm.shl %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   // CHECK: omp.atomic.update %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.intr.smax(%[[XVAL]], %[[EXPR]]) : (i32, i32) -> i32
   // CHECK-NEXT:   omp.yield(%[[NEWVAL]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval: i32):
     %newval = llvm.intr.smax(%xval, %expr) : (i32, i32) -> i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update %[[XBOOL]] : memref<i1>
   // CHECK-NEXT: (%[[XVAL:.*]]: i1):
   // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.icmp "eq" %[[XVAL]], %[[EXPRBOOL]] : i1
   // CHECK-NEXT:   omp.yield(%[[NEWVAL]] : i1)
-  // }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   omp.atomic.update %xBool : memref<i1> {
   ^bb0(%xval: i1):
     %newval = llvm.icmp "eq" %xval, %exprBool : i1
     omp.yield(%newval : i1)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update %[[X]] : memref<i32> {
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   omp.yield(%[[XVAL]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval:i32):
     omp.yield(%xval:i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update %[[X]] : memref<i32> {
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   omp.yield(%{{.+}} : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   %const = arith.constant 42 : i32
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval:i32):
     omp.yield(%const:i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1440,7 +1440,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update hint(uncontended) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1450,7 +1450,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update hint(contended) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1460,7 +1460,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update hint(nonspeculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1470,7 +1470,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update hint(speculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1480,7 +1480,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update hint(uncontended, nonspeculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1490,7 +1490,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update hint(contended, nonspeculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1500,7 +1500,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update hint(uncontended, speculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1510,7 +1510,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update hint(contended, speculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1520,7 +1520,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update memory_order(seq_cst) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1530,7 +1530,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update memory_order(release) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1540,7 +1540,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update memory_order(relaxed) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1550,7 +1550,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // CHECK: omp.atomic.update hint(uncontended, speculative) memory_order(seq_cst) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1560,17 +1560,16 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   // 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>}
+  // CHECK-NEXT: } {atomic_control = #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>}
-
+  } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true, amdgpu_fine_grained_memory = true, amdgpu_remote_memory = true>}
   return
 }
 
@@ -1582,7 +1581,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture{
@@ -1590,7 +1589,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   // CHECK: omp.atomic.capture {
@@ -1599,7 +1598,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: }
   omp.atomic.capture{
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
@@ -1607,7 +1606,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
   // CHECK: omp.atomic.capture {
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
@@ -1623,7 +1622,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(none) {
@@ -1631,7 +1630,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1640,7 +1639,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(uncontended) {
@@ -1648,7 +1647,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1657,7 +1656,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(contended) {
@@ -1665,7 +1664,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1674,7 +1673,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(nonspeculative) {
@@ -1682,7 +1681,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1691,7 +1690,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(speculative) {
@@ -1699,7 +1698,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1708,7 +1707,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(uncontended, nonspeculative) {
@@ -1716,7 +1715,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1725,7 +1724,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(contended, nonspeculative) {
@@ -1733,7 +1732,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1742,7 +1741,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(uncontended, speculative) {
@@ -1750,7 +1749,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1759,7 +1758,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(contended, speculative) {
@@ -1767,7 +1766,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1776,7 +1775,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(seq_cst) {
@@ -1784,7 +1783,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1793,7 +1792,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(acq_rel) {
@@ -1801,7 +1800,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1810,7 +1809,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(acquire) {
@@ -1818,7 +1817,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1827,7 +1826,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(release) {
@@ -1835,7 +1834,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1844,7 +1843,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(relaxed) {
@@ -1852,7 +1851,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1861,7 +1860,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(contended, speculative) memory_order(seq_cst) {
@@ -1869,7 +1868,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -2653,14 +2652,14 @@ func.func @opaque_pointers_atomic_rwu(%v: !llvm.ptr, %x: !llvm.ptr) {
   // CHECK: omp.atomic.update %[[x]] : !llvm.ptr {
   // CHECK-NEXT: ^{{[[:alnum:]]+}}(%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   omp.yield(%[[XVAL]] : i32)
-  // CHECK-NEXT: }
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
   omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   %val = llvm.load %x : !llvm.ptr -> i32
   omp.atomic.write %v = %val : !llvm.ptr, i32
   omp.atomic.update %x : !llvm.ptr {
     ^bb0(%xval: i32):
       omp.yield(%xval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir b/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir
index 41bc5c4ba525f..00f53864b5fa7 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir
@@ -9,7 +9,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %expr: i32) {
     %t2 = llvm.sdiv %t1, %expr : i32
     %newval = llvm.add %xval, %t2 : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   llvm.return
 }
 
@@ -24,7 +24,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.mul %expr, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   llvm.return
 }
 
@@ -41,7 +41,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %v: !llvm.ptr,
     ^bb0(%xval: i32):
       %newval = llvm.mul %expr, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
   llvm.return
 }
@@ -59,7 +59,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %v: !llvm.ptr,
       %t2 = llvm.sdiv %t1, %expr : i32
       %newval = llvm.add %xval, %t2 : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
   llvm.return
 }
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
index 3f4dcd5e24c56..4179ad820190d 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
@@ -1460,13 +1460,13 @@ llvm.func @omp_atomic_update(%x:!llvm.ptr, %expr: i32, %xbool: !llvm.ptr, %exprb
   ^bb0(%xval: i32):
     %newval = llvm.mul %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   // CHECK: atomicrmw add ptr %[[x]], i32 %[[expr]] monotonic
   omp.atomic.update %x : !llvm.ptr {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   llvm.return
 }
 
@@ -1561,7 +1561,7 @@ llvm.func @_QPomp_atomic_update_complex() {
       %15 = llvm.insertvalue %12, %14[0] : !llvm.struct<(f32, f32)>
       %16 = llvm.insertvalue %13, %15[1] : !llvm.struct<(f32, f32)>
       omp.yield(%16 : !llvm.struct<(f32, f32)>)
-    }
+    } {atomic_control = #omp.atomic_control<>}
    llvm.return
 }
 
@@ -1621,7 +1621,7 @@ llvm.func @_QPomp_atomic_capture_complex() {
         %19 = llvm.insertvalue %16, %18[0] : !llvm.struct<(f32, f32)>
         %20 = llvm.insertvalue %17, %19[1] : !llvm.struct<(f32, f32)>
         omp.yield(%20 : !llvm.struct<(f32, f32)>)
-      }
+      } {atomic_control = #omp.atomic_control<>}
       omp.atomic.read %1 = %3 : !llvm.ptr, !llvm.ptr, !llvm.struct<(f32, f32)>
     }
     llvm.return
@@ -1663,7 +1663,7 @@ llvm.func @omp_atomic_update_ordering(%x:!llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.shl %expr, %xval : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   llvm.return
 }
 
@@ -1681,7 +1681,7 @@ llvm.func @omp_atomic_update_ordering(%x:!llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.shl %xval, %expr : i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   llvm.return
 }
 
@@ -1699,7 +1699,7 @@ llvm.func @omp_atomic_update_intrinsic(%x:!llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = "llvm.intr.smax"(%xval, %expr) : (i32, i32) -> i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   // CHECK: %[[t1:.*]] = call i32 @llvm.umax.i32(i32 %[[x_old:.*]], i32 %[[expr]])
   // CHECK: store i32 %[[t1]], ptr %[[x_new:.*]]
   // CHECK: %[[t2:.*]] = load i32, ptr %[[x_new]]
@@ -1708,7 +1708,7 @@ llvm.func @omp_atomic_update_intrinsic(%x:!llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = "llvm.intr.umax"(%xval, %expr) : (i32, i32) -> i32
     omp.yield(%newval : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   llvm.return
 }
 
@@ -1730,7 +1730,7 @@ llvm.func @atomic_update_cmpxchg(%arg0: !llvm.ptr, %arg1: !llvm.ptr) {
     %2 = llvm.fadd %1, %0 : f32
     %3 = llvm.fptosi %2 : f32 to i32
     omp.yield(%3 : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   llvm.return
 }
 
@@ -1749,7 +1749,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1761,7 +1761,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.sub %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1773,7 +1773,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.and %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1785,7 +1785,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.or %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1797,7 +1797,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.xor %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1812,7 +1812,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.mul %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1827,7 +1827,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.sdiv %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1842,7 +1842,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.udiv %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1857,7 +1857,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.shl %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1872,7 +1872,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.lshr %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1887,7 +1887,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.ashr %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1902,7 +1902,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.smax"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1917,7 +1917,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.smin"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1932,7 +1932,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.umax"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1947,7 +1947,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.umin"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1962,7 +1962,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: f32):
       %newval = llvm.fadd %xval, %exprf : f32
       omp.yield(%newval : f32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %vf = %xf : !llvm.ptr, !llvm.ptr, f32
   }
 
@@ -1977,7 +1977,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: f32):
       %newval = llvm.fsub %xval, %exprf : f32
       omp.yield(%newval : f32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
     omp.atomic.read %vf = %xf : !llvm.ptr, !llvm.ptr, f32
   }
 
@@ -1999,7 +1999,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[res:.*]] = atomicrmw sub ptr %[[x]], i32 %[[expr]] monotonic
@@ -2010,7 +2010,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.sub %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[res:.*]] = atomicrmw and ptr %[[x]], i32 %[[expr]] monotonic
@@ -2021,7 +2021,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.and %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[res:.*]] = atomicrmw or ptr %[[x]], i32 %[[expr]] monotonic
@@ -2032,7 +2032,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.or %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[res:.*]] = atomicrmw xor ptr %[[x]], i32 %[[expr]] monotonic
@@ -2043,7 +2043,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.xor %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2058,7 +2058,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.mul %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2073,7 +2073,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.sdiv %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2088,7 +2088,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.udiv %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2103,7 +2103,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.shl %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2118,7 +2118,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.lshr %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2133,7 +2133,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.ashr %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2148,7 +2148,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.smax"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2163,7 +2163,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.smin"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2178,7 +2178,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.umax"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2193,7 +2193,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.umin"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2209,7 +2209,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: f32):
       %newval = llvm.fadd %xval, %exprf : f32
       omp.yield(%newval : f32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2225,7 +2225,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: f32):
       %newval = llvm.fsub %xval, %exprf : f32
       omp.yield(%newval : f32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   llvm.return
@@ -2263,7 +2263,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] acquire
@@ -2274,7 +2274,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] release
@@ -2285,7 +2285,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] monotonic
@@ -2296,7 +2296,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] acq_rel
@@ -2307,7 +2307,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
 
   llvm.return
@@ -3053,7 +3053,7 @@ llvm.func @omp_opaque_pointers(%arg0 : !llvm.ptr, %arg1: !llvm.ptr, %expr: i32)
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
   }
   llvm.return
 }
diff --git a/mlir/test/Target/LLVMIR/openmp-target-nesting-in-host-ops.mlir b/mlir/test/Target/LLVMIR/openmp-target-nesting-in-host-ops.mlir
index cbf273b887bc7..a9a4ffd533136 100644
--- a/mlir/test/Target/LLVMIR/openmp-target-nesting-in-host-ops.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-target-nesting-in-host-ops.mlir
@@ -110,7 +110,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    }
+    } {atomic_control = #omp.atomic_control<>}
 
     llvm.return
   }
diff --git a/mlir/test/Target/LLVMIR/openmp-todo.mlir b/mlir/test/Target/LLVMIR/openmp-todo.mlir
index 2fa4470bb8300..692487c21c587 100644
--- a/mlir/test/Target/LLVMIR/openmp-todo.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-todo.mlir
@@ -19,7 +19,7 @@ llvm.func @atomic_hint(%v : !llvm.ptr, %x : !llvm.ptr, %expr : i32) {
   ^bb0(%arg0: i32):
     %result = llvm.add %arg0, %expr : i32
     omp.yield(%result : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
 
   llvm.return
 }

>From 14fa76f47cf9d6d14e8300400a822082d91a35f3 Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Wed, 11 Jun 2025 14:11:02 -0500
Subject: [PATCH 3/6] R3: Addressing review comments

---
 flang/include/flang/Frontend/TargetOptions.h       |  2 +-
 .../flang/Optimizer/Dialect/Support/FIRContext.h   |  4 ++--
 flang/lib/Optimizer/Dialect/Support/FIRContext.cpp | 14 +++-----------
 flang/test/Fir/convert-to-llvm-openmp-and-fir.fir  |  4 ++--
 mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td |  3 ++-
 5 files changed, 10 insertions(+), 17 deletions(-)

diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h
index 26256fd775f11..dd29b4e3e8b08 100644
--- a/flang/include/flang/Frontend/TargetOptions.h
+++ b/flang/include/flang/Frontend/TargetOptions.h
@@ -54,7 +54,7 @@ class TargetOptions {
   /// Print verbose assembly
   bool asmVerbose = false;
 
-  /// Atomic Control Options for AMD GPU
+  /// Atomic control options for AMD gpu
   bool amdgpuIgnoreDenormalMode = false;
   bool amdgpuRemoteMemory = false;
   bool amdgpuFineGrainedMemory = false;
diff --git a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
index ac563bcc402c7..ac5fd33874db8 100644
--- a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
+++ b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
@@ -58,7 +58,7 @@ 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
+// Setters and getters for atomic control options.
 void setAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod);
 bool getAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod);
 void setAmdgpuFineGrainedMemory(mlir::ModuleOp mod);
@@ -70,7 +70,7 @@ bool getAmdgpuRemoteMemory(mlir::ModuleOp mod);
 /// module `mod` is still live.
 void setTuneCPU(mlir::ModuleOp mod, llvm::StringRef cpu);
 
-// set Atomic control options for amd gpu.
+// set atomic control options for AMD gpu.
 void setAmdgpuAtomicControlOptions(mlir::ModuleOp mod,
                                    bool amdgpuIgnoreDenormalMode,
                                    bool amdgpuNoFineGrainedMemory,
diff --git a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
index b961793dbdfd5..297a4c7a39e44 100644
--- a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
+++ b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
@@ -96,10 +96,7 @@ void fir::setAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod) {
 }
 
 bool fir::getAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod) {
-  if (auto attr =
-          mod->getAttrOfType<mlir::UnitAttr>(amdgpuIgnoreDenormalModeName))
-    return true;
-  return false;
+  return mod->hasAttrOfType<mlir::UnitAttr>(amdgpuIgnoreDenormalModeName);
 }
 
 static constexpr const char *amdgpuFineGrainedMemoryName =
@@ -110,10 +107,7 @@ void fir::setAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
 }
 
 bool fir::getAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
-  if (auto attr =
-          mod->getAttrOfType<mlir::UnitAttr>(amdgpuFineGrainedMemoryName))
-    return true;
-  return false;
+  return mod->hasAttrOfType<mlir::UnitAttr>(amdgpuFineGrainedMemoryName);
 }
 static constexpr const char *amdgpuRemoteMemoryName =
     "fir.amdgpu.remote.memory";
@@ -123,9 +117,7 @@ void fir::setAmdgpuRemoteMemory(mlir::ModuleOp mod) {
 }
 
 bool fir::getAmdgpuRemoteMemory(mlir::ModuleOp mod) {
-  if (auto attr = mod->getAttrOfType<mlir::UnitAttr>(amdgpuRemoteMemoryName))
-    return true;
-  return false;
+  return mod->hasAttrOfType<mlir::UnitAttr>(amdgpuRemoteMemoryName);
 }
 
 llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) {
diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
index 24e5cad84b709..47c00d489c200 100644
--- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
+++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
@@ -619,7 +619,7 @@ func.func @_QPs() {
     %c1_i32 = arith.constant 1 : i32
     %1 = arith.addi %arg0, %c1_i32 : i32
     omp.yield(%1 : i32)
-  }
+  } {atomic_control = #omp.atomic_control<>}
   return
 }
 fir.global internal @_QFsEc : i32 {
@@ -634,7 +634,7 @@ fir.global internal @_QFsEc : i32 {
 // CHECK:      %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32
 // CHECK:      %[[OUT_VAL:.*]] = llvm.add %[[IN_VAL]], %[[CONST_1]]  : i32
 // CHECK:      omp.yield(%[[OUT_VAL]] : i32)
-// CHECK:    }
+// CHECK:    } {atomic_control = #omp.atomic_control<>}
 // CHECK:    llvm.return
 // CHECK:  }
 // CHECK:  llvm.mlir.global internal @[[GLOBAL]]() {{.*}} : i32 {
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
index 84887dfd2c6f9..61861173ae875 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
@@ -58,7 +58,8 @@ def FlagsAttr : OpenMP_Attr<"Flags", "flags"> {
 // AtomicControlAttr
 //===----------------------------------------------------------------------===//
 
-// Runtime library flags attribute that holds information for lowering to LLVM.
+// Atomic control attributes hold information about architectural
+// characteristics which are required for lowering atomic operations.
 def AtomicControlAttr : OpenMP_Attr<"AtomicControl", "atomic_control"> {
   let parameters =
       (ins DefaultValuedParameter<"bool", "false">:$amdgpu_ignore_denormal_mode,

>From 5a840cd77811e85ed70b9946dde0e4b20edf0706 Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Mon, 23 Jun 2025 12:14:19 -0500
Subject: [PATCH 4/6] R4: Addressing review comments

---
 flang/include/flang/Frontend/TargetOptions.h  |  6 ++--
 .../Optimizer/Dialect/Support/FIRContext.h    | 18 ++++------
 flang/lib/Frontend/CompilerInvocation.cpp     | 20 +++++------
 flang/lib/Lower/Bridge.cpp                    | 12 +++----
 flang/lib/Lower/OpenMP/Atomic.cpp             |  8 ++++-
 .../Optimizer/Dialect/Support/FIRContext.cpp  | 34 +++++++++----------
 .../Lower/OpenMP/atomic-control-options.f90   | 16 ++++-----
 .../mlir/Dialect/OpenMP/OpenMPAttrDefs.td     |  6 ++--
 mlir/test/Dialect/OpenMP/ops.mlir             |  4 +--
 9 files changed, 60 insertions(+), 64 deletions(-)

diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h
index dd29b4e3e8b08..6ef5338acdc6e 100644
--- a/flang/include/flang/Frontend/TargetOptions.h
+++ b/flang/include/flang/Frontend/TargetOptions.h
@@ -55,9 +55,9 @@ class TargetOptions {
   bool asmVerbose = false;
 
   /// Atomic control options for AMD gpu
-  bool amdgpuIgnoreDenormalMode = false;
-  bool amdgpuRemoteMemory = false;
-  bool amdgpuFineGrainedMemory = false;
+  bool ignoreDenormalMode = false;
+  bool remoteMemory = false;
+  bool fineGrainedMemory = 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 ac5fd33874db8..273b4683b6d9c 100644
--- a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
+++ b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
@@ -59,23 +59,17 @@ void setTargetCPU(mlir::ModuleOp mod, llvm::StringRef cpu);
 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);
+void setIgnoreDenormalMode(mlir::ModuleOp mod);
+bool getIgnoreDenormalMode(mlir::ModuleOp mod);
+void setFineGrainedMemory(mlir::ModuleOp mod);
+bool getFineGrainedMemory(mlir::ModuleOp mod);
+void setRemoteMemory(mlir::ModuleOp mod);
+bool getRemoteMemory(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 c4a12f5b07edb..fbac8eeb80c89 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -512,17 +512,15 @@ 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);
-  }
+  opts.ignoreDenormalMode = args.hasFlag(
+      clang::driver::options::OPT_fatomic_ignore_denormal_mode,
+      clang::driver::options::OPT_fno_atomic_ignore_denormal_mode, false);
+  opts.fineGrainedMemory = args.hasFlag(
+      clang::driver::options::OPT_fatomic_fine_grained_memory,
+      clang::driver::options::OPT_fno_atomic_fine_grained_memory, false);
+  opts.remoteMemory =
+      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))
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 8661f3057ec66..19d928671f871 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -6733,12 +6733,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);
+  if (targetOpts.ignoreDenormalMode)
+    fir::setIgnoreDenormalMode(*module);
+  if (targetOpts.fineGrainedMemory)
+    fir::setFineGrainedMemory(*module);
+  if (targetOpts.remoteMemory)
+    fir::setRemoteMemory(*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/Atomic.cpp b/flang/lib/Lower/OpenMP/Atomic.cpp
index 9a233d2d8cb08..36ebd7b6d2320 100644
--- a/flang/lib/Lower/OpenMP/Atomic.cpp
+++ b/flang/lib/Lower/OpenMP/Atomic.cpp
@@ -635,9 +635,15 @@ genAtomicUpdate(lower::AbstractConverter &converter,
     }
   }
 
+  mlir::ModuleOp module = builder.getModule();
+  mlir::omp::AtomicControlAttr atomicControlAttr =
+      mlir::omp::AtomicControlAttr::get(
+          builder.getContext(), fir::getAtomicIgnoreDenormalMode(module),
+          fir::getAtomicFineGrainedMemory(module),
+          fir::getAtomicRemoteMemory(module));
   builder.restoreInsertionPoint(atomicAt);
   auto updateOp = mlir::omp::AtomicUpdateOp::create(
-      builder, loc, atomAddr, hint, makeMemOrderAttr(converter, memOrder));
+      builder, loc, atomAddr, atomicControlAttr, hint, makeMemOrderAttr(converter, memOrder));
 
   mlir::Region &region = updateOp->getRegion(0);
   mlir::Block *block = builder.createBlock(&region, {}, {atomType}, {loc});
diff --git a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
index 297a4c7a39e44..e3599204f5e2c 100644
--- a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
+++ b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
@@ -88,36 +88,34 @@ 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) {
+static constexpr const char *ignoreDenormalModeName =
+    "fir.ignore.denormal.mode";
+void fir::setIgnoreDenormalMode(mlir::ModuleOp mod) {
   auto *ctx = mod.getContext();
-  mod->setAttr(amdgpuIgnoreDenormalModeName, mlir::UnitAttr::get(ctx));
+  mod->setAttr(ignoreDenormalModeName, mlir::UnitAttr::get(ctx));
 }
 
-bool fir::getAmdgpuIgnoreDenormalMode(mlir::ModuleOp mod) {
-  return mod->hasAttrOfType<mlir::UnitAttr>(amdgpuIgnoreDenormalModeName);
+bool fir::getIgnoreDenormalMode(mlir::ModuleOp mod) {
+  return mod->hasAttrOfType<mlir::UnitAttr>(ignoreDenormalModeName);
 }
 
-static constexpr const char *amdgpuFineGrainedMemoryName =
-    "fir.amdgpu.fine.grained.memory";
-void fir::setAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
+static constexpr const char *fineGrainedMemoryName = "fir.fine.grained.memory";
+void fir::setFineGrainedMemory(mlir::ModuleOp mod) {
   auto *ctx = mod.getContext();
-  mod->setAttr(amdgpuFineGrainedMemoryName, mlir::UnitAttr::get(ctx));
+  mod->setAttr(fineGrainedMemoryName, mlir::UnitAttr::get(ctx));
 }
 
-bool fir::getAmdgpuFineGrainedMemory(mlir::ModuleOp mod) {
-  return mod->hasAttrOfType<mlir::UnitAttr>(amdgpuFineGrainedMemoryName);
+bool fir::getFineGrainedMemory(mlir::ModuleOp mod) {
+  return mod->hasAttrOfType<mlir::UnitAttr>(fineGrainedMemoryName);
 }
-static constexpr const char *amdgpuRemoteMemoryName =
-    "fir.amdgpu.remote.memory";
-void fir::setAmdgpuRemoteMemory(mlir::ModuleOp mod) {
+static constexpr const char *remoteMemoryName = "fir.remote.memory";
+void fir::setRemoteMemory(mlir::ModuleOp mod) {
   auto *ctx = mod.getContext();
-  mod->setAttr(amdgpuRemoteMemoryName, mlir::UnitAttr::get(ctx));
+  mod->setAttr(remoteMemoryName, mlir::UnitAttr::get(ctx));
 }
 
-bool fir::getAmdgpuRemoteMemory(mlir::ModuleOp mod) {
-  return mod->hasAttrOfType<mlir::UnitAttr>(amdgpuRemoteMemoryName);
+bool fir::getRemoteMemory(mlir::ModuleOp mod) {
+  return mod->hasAttrOfType<mlir::UnitAttr>(remoteMemoryName);
 }
 
 llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) {
diff --git a/flang/test/Lower/OpenMP/atomic-control-options.f90 b/flang/test/Lower/OpenMP/atomic-control-options.f90
index 1eb0f617f365e..8f86a151b3713 100644
--- a/flang/test/Lower/OpenMP/atomic-control-options.f90
+++ b/flang/test/Lower/OpenMP/atomic-control-options.f90
@@ -9,25 +9,25 @@ program test
     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>}
+    !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control<ignore_denormal_mode = true>}
     !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref<i32> {
-    !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<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>}
+    !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control<fine_grained_memory = true>}
     !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
-    !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_remote_memory = true>}
+    !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<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>}
+    !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control<ignore_denormal_mode = true>}
     !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref<i32> {
-    !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true>}
+    !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control<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>}
+    !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control<fine_grained_memory = true>}
     !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref<i32> {
-    !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<amdgpu_remote_memory = true>}
+    !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control<remote_memory = true>}
     !$omp target parallel num_threads(threads)
     !$omp atomic capture
         A = A + B
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
index 61861173ae875..0fefe7e017e94 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
@@ -62,9 +62,9 @@ def FlagsAttr : OpenMP_Attr<"Flags", "flags"> {
 // characteristics which are required for lowering atomic operations.
 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);
+      (ins DefaultValuedParameter<"bool", "false">:$ignore_denormal_mode,
+          DefaultValuedParameter<"bool", "false">:$fine_grained_memory,
+          DefaultValuedParameter<"bool", "false">:$remote_memory);
 
   let assemblyFormat = "`<` struct(params) `>`";
 }
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index dfd714b8d890b..44878f1bf7156 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -1565,11 +1565,11 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   // CHECK: omp.atomic.update %[[X]] : memref<i32> {
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   omp.yield(%{{.+}} : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true, amdgpu_fine_grained_memory = true, amdgpu_remote_memory = true>}
+  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<ignore_denormal_mode = true, fine_grained_memory = true, remote_memory = true>}
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval:i32):
     omp.yield(%const:i32)
-  } {atomic_control = #omp.atomic_control<amdgpu_ignore_denormal_mode = true, amdgpu_fine_grained_memory = true, amdgpu_remote_memory = true>}
+  } {atomic_control = #omp.atomic_control<ignore_denormal_mode = true, fine_grained_memory = true, remote_memory = true>}
   return
 }
 

>From bb992e8d510cb7c83a01b24d11fa2134c9a57aff Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Wed, 2 Jul 2025 11:26:03 -0500
Subject: [PATCH 5/6] R5: Addressing review comments

---
 flang/include/flang/Frontend/TargetOptions.h  |   8 +-
 .../Optimizer/Dialect/Support/FIRContext.h    |  25 +++-
 flang/lib/Frontend/CompilerInvocation.cpp     |   6 +-
 flang/lib/Lower/Bridge.cpp                    |  10 +-
 flang/lib/Lower/OpenMP/Atomic.cpp             |   3 +-
 .../Optimizer/Dialect/Support/FIRContext.cpp  |  55 +++++---
 .../Fir/convert-to-llvm-openmp-and-fir.fir    |   4 +-
 .../mlir/Dialect/OpenMP/OpenMPAttrDefs.td     |  30 ++---
 mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td |   2 +-
 .../OpenMPToLLVM/convert-to-llvmir.mlir       |   2 +-
 mlir/test/Dialect/OpenMP/canonicalize.mlir    |  10 +-
 mlir/test/Dialect/OpenMP/invalid.mlir         |  46 +++----
 mlir/test/Dialect/OpenMP/ops.mlir             | 122 +++++++++---------
 .../Target/LLVMIR/openmp-llvm-invalid.mlir    |   8 +-
 mlir/test/Target/LLVMIR/openmp-llvm.mlir      |  98 +++++++-------
 .../openmp-target-nesting-in-host-ops.mlir    |   2 +-
 mlir/test/Target/LLVMIR/openmp-todo.mlir      |   2 +-
 17 files changed, 230 insertions(+), 203 deletions(-)

diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h
index 6ef5338acdc6e..f6e5634d5a995 100644
--- a/flang/include/flang/Frontend/TargetOptions.h
+++ b/flang/include/flang/Frontend/TargetOptions.h
@@ -54,10 +54,10 @@ class TargetOptions {
   /// Print verbose assembly
   bool asmVerbose = false;
 
-  /// Atomic control options for AMD gpu
-  bool ignoreDenormalMode = false;
-  bool remoteMemory = false;
-  bool fineGrainedMemory = false;
+  /// Atomic control options
+  bool atomicIgnoreDenormalMode = false;
+  bool atomicRemoteMemory = false;
+  bool atomicFineGrainedMemory = 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 273b4683b6d9c..c0c0b744206cd 100644
--- a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
+++ b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
@@ -58,13 +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 setIgnoreDenormalMode(mlir::ModuleOp mod);
-bool getIgnoreDenormalMode(mlir::ModuleOp mod);
-void setFineGrainedMemory(mlir::ModuleOp mod);
-bool getFineGrainedMemory(mlir::ModuleOp mod);
-void setRemoteMemory(mlir::ModuleOp mod);
-bool getRemoteMemory(mlir::ModuleOp mod);
+/// Sets whether Denormal Mode can be ignored or not for lowering of floating
+/// point atomic operations.
+void setAtomicIgnoreDenormalMode(mlir::ModuleOp mod, bool value);
+/// Gets whether Denormal Mode can be ignored or not for lowering of floating
+/// point atomic operations.
+bool getAtomicIgnoreDenormalMode(mlir::ModuleOp mod);
+/// Sets whether fine grained memory can be used or not for lowering of atomic
+/// operations.
+void setAtomicFineGrainedMemory(mlir::ModuleOp mod, bool value);
+/// Gets whether fine grained memory can be used or not for lowering of atomic
+/// operations.
+bool getAtomicFineGrainedMemory(mlir::ModuleOp mod);
+/// Sets whether remote memory can be used or not for lowering of atomic
+/// operations.
+void setAtomicRemoteMemory(mlir::ModuleOp mod, bool value);
+/// Gets whether remote memory can be used or not for lowering of atomic
+/// operations.
+bool getAtomicRemoteMemory(mlir::ModuleOp mod);
 
 /// Set the tune CPU for the module. `cpu` must not be deallocated while
 /// module `mod` is still live.
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index fbac8eeb80c89..111c5aa48726f 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -512,13 +512,13 @@ static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) {
           args.getLastArg(clang::driver::options::OPT_triple))
     opts.triple = a->getValue();
 
-  opts.ignoreDenormalMode = args.hasFlag(
+  opts.atomicIgnoreDenormalMode = args.hasFlag(
       clang::driver::options::OPT_fatomic_ignore_denormal_mode,
       clang::driver::options::OPT_fno_atomic_ignore_denormal_mode, false);
-  opts.fineGrainedMemory = args.hasFlag(
+  opts.atomicFineGrainedMemory = args.hasFlag(
       clang::driver::options::OPT_fatomic_fine_grained_memory,
       clang::driver::options::OPT_fno_atomic_fine_grained_memory, false);
-  opts.remoteMemory =
+  opts.atomicRemoteMemory =
       args.hasFlag(clang::driver::options::OPT_fatomic_remote_memory,
                    clang::driver::options::OPT_fno_atomic_remote_memory, false);
 
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 19d928671f871..ac3669c907fbc 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -6733,12 +6733,10 @@ Fortran::lower::LoweringBridge::LoweringBridge(
   fir::setKindMapping(*module, kindMap);
   fir::setTargetCPU(*module, targetMachine.getTargetCPU());
   fir::setTuneCPU(*module, targetOpts.cpuToTuneFor);
-  if (targetOpts.ignoreDenormalMode)
-    fir::setIgnoreDenormalMode(*module);
-  if (targetOpts.fineGrainedMemory)
-    fir::setFineGrainedMemory(*module);
-  if (targetOpts.remoteMemory)
-    fir::setRemoteMemory(*module);
+  fir::setAtomicIgnoreDenormalMode(*module,
+                                   targetOpts.atomicIgnoreDenormalMode);
+  fir::setAtomicFineGrainedMemory(*module, targetOpts.atomicFineGrainedMemory);
+  fir::setAtomicRemoteMemory(*module, targetOpts.atomicRemoteMemory);
   fir::setTargetFeatures(*module, targetMachine.getTargetFeatureString());
   fir::support::setMLIRDataLayout(*module, targetMachine.createDataLayout());
   fir::setIdent(*module, Fortran::common::getFlangFullVersion());
diff --git a/flang/lib/Lower/OpenMP/Atomic.cpp b/flang/lib/Lower/OpenMP/Atomic.cpp
index 36ebd7b6d2320..d4f83f57bd5d4 100644
--- a/flang/lib/Lower/OpenMP/Atomic.cpp
+++ b/flang/lib/Lower/OpenMP/Atomic.cpp
@@ -643,7 +643,8 @@ genAtomicUpdate(lower::AbstractConverter &converter,
           fir::getAtomicRemoteMemory(module));
   builder.restoreInsertionPoint(atomicAt);
   auto updateOp = mlir::omp::AtomicUpdateOp::create(
-      builder, loc, atomAddr, atomicControlAttr, hint, makeMemOrderAttr(converter, memOrder));
+      builder, loc, atomAddr, atomicControlAttr, hint,
+      makeMemOrderAttr(converter, memOrder));
 
   mlir::Region &region = updateOp->getRegion(0);
   mlir::Block *block = builder.createBlock(&region, {}, {atomType}, {loc});
diff --git a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
index e3599204f5e2c..c9c921008597d 100644
--- a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
+++ b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
@@ -88,34 +88,51 @@ void fir::setTuneCPU(mlir::ModuleOp mod, llvm::StringRef cpu) {
   mod->setAttr(tuneCpuName, mlir::StringAttr::get(ctx, cpu));
 }
 
-static constexpr const char *ignoreDenormalModeName =
-    "fir.ignore.denormal.mode";
-void fir::setIgnoreDenormalMode(mlir::ModuleOp mod) {
-  auto *ctx = mod.getContext();
-  mod->setAttr(ignoreDenormalModeName, mlir::UnitAttr::get(ctx));
+static constexpr const char *atomicIgnoreDenormalModeName =
+    "fir.atomic_ignore_denormal_mode";
+void fir::setAtomicIgnoreDenormalMode(mlir::ModuleOp mod, bool value) {
+  if (value) {
+    auto *ctx = mod.getContext();
+    mod->setAttr(atomicIgnoreDenormalModeName, mlir::UnitAttr::get(ctx));
+  } else {
+    if (mod->hasAttr(atomicIgnoreDenormalModeName))
+      mod->removeAttr(atomicIgnoreDenormalModeName);
+  }
 }
 
-bool fir::getIgnoreDenormalMode(mlir::ModuleOp mod) {
-  return mod->hasAttrOfType<mlir::UnitAttr>(ignoreDenormalModeName);
+bool fir::getAtomicIgnoreDenormalMode(mlir::ModuleOp mod) {
+  return mod->hasAttrOfType<mlir::UnitAttr>(atomicIgnoreDenormalModeName);
 }
 
-static constexpr const char *fineGrainedMemoryName = "fir.fine.grained.memory";
-void fir::setFineGrainedMemory(mlir::ModuleOp mod) {
-  auto *ctx = mod.getContext();
-  mod->setAttr(fineGrainedMemoryName, mlir::UnitAttr::get(ctx));
+static constexpr const char *atomicFineGrainedMemoryName =
+    "fir.atomic_fine_grained_memory";
+void fir::setAtomicFineGrainedMemory(mlir::ModuleOp mod, bool value) {
+  if (value) {
+    auto *ctx = mod.getContext();
+    mod->setAttr(atomicFineGrainedMemoryName, mlir::UnitAttr::get(ctx));
+  } else {
+    if (mod->hasAttr(atomicFineGrainedMemoryName))
+      mod->removeAttr(atomicFineGrainedMemoryName);
+  }
 }
 
-bool fir::getFineGrainedMemory(mlir::ModuleOp mod) {
-  return mod->hasAttrOfType<mlir::UnitAttr>(fineGrainedMemoryName);
+bool fir::getAtomicFineGrainedMemory(mlir::ModuleOp mod) {
+  return mod->hasAttrOfType<mlir::UnitAttr>(atomicFineGrainedMemoryName);
 }
-static constexpr const char *remoteMemoryName = "fir.remote.memory";
-void fir::setRemoteMemory(mlir::ModuleOp mod) {
-  auto *ctx = mod.getContext();
-  mod->setAttr(remoteMemoryName, mlir::UnitAttr::get(ctx));
+static constexpr const char *atomicRemoteMemoryName =
+    "fir.atomic_remote_memory";
+void fir::setAtomicRemoteMemory(mlir::ModuleOp mod, bool value) {
+  if (value) {
+    auto *ctx = mod.getContext();
+    mod->setAttr(atomicRemoteMemoryName, mlir::UnitAttr::get(ctx));
+  } else {
+    if (mod->hasAttr(atomicRemoteMemoryName))
+      mod->removeAttr(atomicRemoteMemoryName);
+  }
 }
 
-bool fir::getRemoteMemory(mlir::ModuleOp mod) {
-  return mod->hasAttrOfType<mlir::UnitAttr>(remoteMemoryName);
+bool fir::getAtomicRemoteMemory(mlir::ModuleOp mod) {
+  return mod->hasAttrOfType<mlir::UnitAttr>(atomicRemoteMemoryName);
 }
 
 llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) {
diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
index 47c00d489c200..24e5cad84b709 100644
--- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
+++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
@@ -619,7 +619,7 @@ func.func @_QPs() {
     %c1_i32 = arith.constant 1 : i32
     %1 = arith.addi %arg0, %c1_i32 : i32
     omp.yield(%1 : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 fir.global internal @_QFsEc : i32 {
@@ -634,7 +634,7 @@ fir.global internal @_QFsEc : i32 {
 // CHECK:      %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32
 // CHECK:      %[[OUT_VAL:.*]] = llvm.add %[[IN_VAL]], %[[CONST_1]]  : i32
 // CHECK:      omp.yield(%[[OUT_VAL]] : i32)
-// CHECK:    } {atomic_control = #omp.atomic_control<>}
+// CHECK:    }
 // CHECK:    llvm.return
 // CHECK:  }
 // CHECK:  llvm.mlir.global internal @[[GLOBAL]]() {{.*}} : i32 {
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
index 0fefe7e017e94..72ce4c6a21cb3 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
@@ -22,6 +22,21 @@ class OpenMP_Attr<string name, string attrMnemonic, list<Trait> traits = [],
   let mnemonic = attrMnemonic;
 }
 
+//===----------------------------------------------------------------------===//
+// AtomicControlAttr
+//===----------------------------------------------------------------------===//
+
+// Atomic control attributes hold information about architectural
+// characteristics which are required for lowering atomic operations.
+def AtomicControlAttr : OpenMP_Attr<"AtomicControl", "atomic_control"> {
+  let parameters =
+      (ins DefaultValuedParameter<"bool", "false">:$ignore_denormal_mode,
+          DefaultValuedParameter<"bool", "false">:$fine_grained_memory,
+          DefaultValuedParameter<"bool", "false">:$remote_memory);
+
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
 //===----------------------------------------------------------------------===//
 // DeclareTargetAttr
 //===----------------------------------------------------------------------===//
@@ -54,21 +69,6 @@ def FlagsAttr : OpenMP_Attr<"Flags", "flags"> {
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
-//===----------------------------------------------------------------------===//
-// AtomicControlAttr
-//===----------------------------------------------------------------------===//
-
-// Atomic control attributes hold information about architectural
-// characteristics which are required for lowering atomic operations.
-def AtomicControlAttr : OpenMP_Attr<"AtomicControl", "atomic_control"> {
-  let parameters =
-      (ins DefaultValuedParameter<"bool", "false">:$ignore_denormal_mode,
-          DefaultValuedParameter<"bool", "false">:$fine_grained_memory,
-          DefaultValuedParameter<"bool", "false">:$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 bd89bf5d27680..be114ea4fb631 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -1753,7 +1753,7 @@ def AtomicUpdateOp : OpenMP_Op<"atomic.update", traits = [
   let arguments = !con(
       (ins Arg<OpenMP_PointerLikeType,
                "Address of variable to be updated", [MemRead, MemWrite]>:$x,
-          AtomicControlAttr:$atomic_control),
+          OptionalAttr<AtomicControlAttr>:$atomic_control),
       clausesArgs);
 
   // Override region definition.
diff --git a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir
index 0b2445d0a0d18..d69de998346b5 100644
--- a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir
+++ b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir
@@ -133,7 +133,7 @@ func.func @atomic_update() {
     %1 = arith.constant 1 : i32
     %2 = arith.addi %arg0, %1  : i32
     omp.yield(%2 : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 llvm.mlir.global internal @_QFsEc() : i32 {
diff --git a/mlir/test/Dialect/OpenMP/canonicalize.mlir b/mlir/test/Dialect/OpenMP/canonicalize.mlir
index 2492010c4d3c7..de6c931ecc5fd 100644
--- a/mlir/test/Dialect/OpenMP/canonicalize.mlir
+++ b/mlir/test/Dialect/OpenMP/canonicalize.mlir
@@ -4,7 +4,7 @@ func.func @update_no_op(%x : memref<i32>) {
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval : i32):
     omp.yield(%xval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -17,7 +17,7 @@ func.func @update_write_op(%x : memref<i32>, %value: i32) {
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval : i32):
     omp.yield(%value : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -33,7 +33,7 @@ func.func @update_normal(%x : memref<i32>, %value: i32) {
   ^bb0(%xval : i32):
     %newval = arith.addi %xval, %value : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -50,7 +50,7 @@ func.func @update_unnecessary_computations(%x: memref<i32>) {
   ^bb0(%xval: i32):
     %newval = arith.addi %xval, %c0 : i32
     omp.yield(%newval: i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -65,7 +65,7 @@ func.func @update_unnecessary_computations(%x: memref<i32>) {
   ^bb0(%xval: i32):
     %newval = arith.muli %xval, %c0 : i32
     omp.yield(%newval: i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index cae51c8acb69e..5088f2dfa7d7a 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -1040,7 +1040,7 @@ func.func @omp_atomic_update1(%x: memref<i32>, %expr: f32) {
   ^bb0(%xval: f32):
     %newval = llvm.fadd %xval, %expr : f32
     omp.yield (%newval : f32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1053,7 +1053,7 @@ func.func @omp_atomic_update2(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.terminator
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1065,7 +1065,7 @@ func.func @omp_atomic_update3(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1077,7 +1077,7 @@ func.func @omp_atomic_update4(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1089,7 +1089,7 @@ func.func @omp_atomic_update5(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1101,7 +1101,7 @@ func.func @omp_atomic_update6(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval, %expr : i32, i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1113,7 +1113,7 @@ func.func @omp_atomic_update7(%x: memref<i32>, %expr: i32, %y: f32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%y: f32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1125,7 +1125,7 @@ func.func @omp_atomic_update8(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32, %tmp: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1137,7 +1137,7 @@ func.func @omp_atomic_update(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1149,7 +1149,7 @@ func.func @omp_atomic_update(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1161,7 +1161,7 @@ func.func @omp_atomic_update(%x: memref<i32>, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield (%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
@@ -1197,12 +1197,12 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.update %x : memref<i32> {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.terminator
   }
   return
@@ -1230,7 +1230,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.terminator
   }
   return
@@ -1245,7 +1245,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.write %x = %expr : memref<i32>, i32
     omp.terminator
   }
@@ -1273,7 +1273,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>,
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %y : memref<i32>, memref<i32>, i32
     omp.terminator
   }
@@ -1289,7 +1289,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>,
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield (%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.terminator
   }
 }
@@ -1314,7 +1314,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1329,7 +1329,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1344,7 +1344,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1359,7 +1359,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1374,7 +1374,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   return
@@ -1389,7 +1389,7 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x memory_order(seq_cst) : memref<i32>, memref<i32>, i32
   }
   return
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 44878f1bf7156..8c846cde1a3ca 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -1371,7 +1371,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   // CHECK: omp.atomic.update %[[XBOOL]] : memref<i1>
   // CHECK-NEXT: (%[[XVAL:.*]]: i1):
   // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.and %[[XVAL]], %[[EXPRBOOL]] : i1
@@ -1380,57 +1380,57 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i1):
     %newval = llvm.and %xval, %exprBool : i1
     omp.yield(%newval : i1)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   // CHECK: omp.atomic.update %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.shl %[[XVAL]], %[[EXPR]] : i32
   // CHECK-NEXT:   omp.yield(%[[NEWVAL]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval: i32):
     %newval = llvm.shl %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   // CHECK: omp.atomic.update %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.intr.smax(%[[XVAL]], %[[EXPR]]) : (i32, i32) -> i32
   // CHECK-NEXT:   omp.yield(%[[NEWVAL]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval: i32):
     %newval = llvm.intr.smax(%xval, %expr) : (i32, i32) -> i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update %[[XBOOL]] : memref<i1>
   // CHECK-NEXT: (%[[XVAL:.*]]: i1):
   // CHECK-NEXT:   %[[NEWVAL:.*]] = llvm.icmp "eq" %[[XVAL]], %[[EXPRBOOL]] : i1
   // CHECK-NEXT:   omp.yield(%[[NEWVAL]] : i1)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   omp.atomic.update %xBool : memref<i1> {
   ^bb0(%xval: i1):
     %newval = llvm.icmp "eq" %xval, %exprBool : i1
     omp.yield(%newval : i1)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update %[[X]] : memref<i32> {
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   omp.yield(%[[XVAL]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval:i32):
     omp.yield(%xval:i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update %[[X]] : memref<i32> {
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   omp.yield(%{{.+}} : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   %const = arith.constant 42 : i32
   omp.atomic.update %x : memref<i32> {
   ^bb0(%xval:i32):
     omp.yield(%const:i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1440,7 +1440,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update hint(uncontended) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1450,7 +1450,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update hint(contended) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1460,7 +1460,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update hint(nonspeculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1470,7 +1470,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update hint(speculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1480,7 +1480,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update hint(uncontended, nonspeculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1490,7 +1490,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update hint(contended, nonspeculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1500,7 +1500,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update hint(uncontended, speculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1510,7 +1510,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update hint(contended, speculative) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1520,7 +1520,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update memory_order(seq_cst) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1530,7 +1530,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update memory_order(release) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1540,7 +1540,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update memory_order(relaxed) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1550,7 +1550,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update hint(uncontended, speculative) memory_order(seq_cst) %[[X]] : memref<i32>
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1560,7 +1560,7 @@ func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>,
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   // CHECK: omp.atomic.update %[[X]] : memref<i32> {
   // CHECK-NEXT: (%[[XVAL:.*]]: i32):
@@ -1581,7 +1581,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture{
@@ -1589,7 +1589,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
   // CHECK: omp.atomic.capture {
@@ -1598,7 +1598,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: }
   omp.atomic.capture{
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
@@ -1606,7 +1606,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
   // CHECK: omp.atomic.capture {
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
@@ -1622,7 +1622,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(none) {
@@ -1630,7 +1630,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1639,7 +1639,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(uncontended) {
@@ -1647,7 +1647,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1656,7 +1656,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(contended) {
@@ -1664,7 +1664,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1673,7 +1673,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(nonspeculative) {
@@ -1681,7 +1681,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1690,7 +1690,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(speculative) {
@@ -1698,7 +1698,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1707,7 +1707,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(uncontended, nonspeculative) {
@@ -1715,7 +1715,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1724,7 +1724,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(contended, nonspeculative) {
@@ -1732,7 +1732,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1741,7 +1741,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(uncontended, speculative) {
@@ -1749,7 +1749,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1758,7 +1758,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(contended, speculative) {
@@ -1766,7 +1766,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1775,7 +1775,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(seq_cst) {
@@ -1783,7 +1783,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1792,7 +1792,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(acq_rel) {
@@ -1800,7 +1800,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1809,7 +1809,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(acquire) {
@@ -1817,7 +1817,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1826,7 +1826,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(release) {
@@ -1834,7 +1834,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1843,7 +1843,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture memory_order(relaxed) {
@@ -1851,7 +1851,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -1860,7 +1860,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
   // CHECK-NEXT: (%[[xval:.*]]: i32):
   // CHECK-NEXT:   %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32
   // CHECK-NEXT:   omp.yield(%[[newval]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i32
   // CHECK-NEXT: }
   omp.atomic.capture hint(contended, speculative) memory_order(seq_cst) {
@@ -1868,7 +1868,7 @@ func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : memref<i32>, memref<i32>, i32
   }
 
@@ -2652,14 +2652,14 @@ func.func @opaque_pointers_atomic_rwu(%v: !llvm.ptr, %x: !llvm.ptr) {
   // CHECK: omp.atomic.update %[[x]] : !llvm.ptr {
   // CHECK-NEXT: ^{{[[:alnum:]]+}}(%[[XVAL:.*]]: i32):
   // CHECK-NEXT:   omp.yield(%[[XVAL]] : i32)
-  // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>}
+  // CHECK-NEXT: }
   omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   %val = llvm.load %x : !llvm.ptr -> i32
   omp.atomic.write %v = %val : !llvm.ptr, i32
   omp.atomic.update %x : !llvm.ptr {
     ^bb0(%xval: i32):
       omp.yield(%xval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   return
 }
 
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir b/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir
index 00f53864b5fa7..41bc5c4ba525f 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir
@@ -9,7 +9,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %expr: i32) {
     %t2 = llvm.sdiv %t1, %expr : i32
     %newval = llvm.add %xval, %t2 : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   llvm.return
 }
 
@@ -24,7 +24,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.mul %expr, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   llvm.return
 }
 
@@ -41,7 +41,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %v: !llvm.ptr,
     ^bb0(%xval: i32):
       %newval = llvm.mul %expr, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
   llvm.return
 }
@@ -59,7 +59,7 @@ llvm.func @omp_atomic_update_multiple_step_update(%x: !llvm.ptr, %v: !llvm.ptr,
       %t2 = llvm.sdiv %t1, %expr : i32
       %newval = llvm.add %xval, %t2 : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
   llvm.return
 }
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
index 4179ad820190d..3f4dcd5e24c56 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
@@ -1460,13 +1460,13 @@ llvm.func @omp_atomic_update(%x:!llvm.ptr, %expr: i32, %xbool: !llvm.ptr, %exprb
   ^bb0(%xval: i32):
     %newval = llvm.mul %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   // CHECK: atomicrmw add ptr %[[x]], i32 %[[expr]] monotonic
   omp.atomic.update %x : !llvm.ptr {
   ^bb0(%xval: i32):
     %newval = llvm.add %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   llvm.return
 }
 
@@ -1561,7 +1561,7 @@ llvm.func @_QPomp_atomic_update_complex() {
       %15 = llvm.insertvalue %12, %14[0] : !llvm.struct<(f32, f32)>
       %16 = llvm.insertvalue %13, %15[1] : !llvm.struct<(f32, f32)>
       omp.yield(%16 : !llvm.struct<(f32, f32)>)
-    } {atomic_control = #omp.atomic_control<>}
+    }
    llvm.return
 }
 
@@ -1621,7 +1621,7 @@ llvm.func @_QPomp_atomic_capture_complex() {
         %19 = llvm.insertvalue %16, %18[0] : !llvm.struct<(f32, f32)>
         %20 = llvm.insertvalue %17, %19[1] : !llvm.struct<(f32, f32)>
         omp.yield(%20 : !llvm.struct<(f32, f32)>)
-      } {atomic_control = #omp.atomic_control<>}
+      }
       omp.atomic.read %1 = %3 : !llvm.ptr, !llvm.ptr, !llvm.struct<(f32, f32)>
     }
     llvm.return
@@ -1663,7 +1663,7 @@ llvm.func @omp_atomic_update_ordering(%x:!llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.shl %expr, %xval : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   llvm.return
 }
 
@@ -1681,7 +1681,7 @@ llvm.func @omp_atomic_update_ordering(%x:!llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = llvm.shl %xval, %expr : i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   llvm.return
 }
 
@@ -1699,7 +1699,7 @@ llvm.func @omp_atomic_update_intrinsic(%x:!llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = "llvm.intr.smax"(%xval, %expr) : (i32, i32) -> i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   // CHECK: %[[t1:.*]] = call i32 @llvm.umax.i32(i32 %[[x_old:.*]], i32 %[[expr]])
   // CHECK: store i32 %[[t1]], ptr %[[x_new:.*]]
   // CHECK: %[[t2:.*]] = load i32, ptr %[[x_new]]
@@ -1708,7 +1708,7 @@ llvm.func @omp_atomic_update_intrinsic(%x:!llvm.ptr, %expr: i32) {
   ^bb0(%xval: i32):
     %newval = "llvm.intr.umax"(%xval, %expr) : (i32, i32) -> i32
     omp.yield(%newval : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   llvm.return
 }
 
@@ -1730,7 +1730,7 @@ llvm.func @atomic_update_cmpxchg(%arg0: !llvm.ptr, %arg1: !llvm.ptr) {
     %2 = llvm.fadd %1, %0 : f32
     %3 = llvm.fptosi %2 : f32 to i32
     omp.yield(%3 : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
   llvm.return
 }
 
@@ -1749,7 +1749,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1761,7 +1761,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.sub %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1773,7 +1773,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.and %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1785,7 +1785,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.or %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1797,7 +1797,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.xor %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1812,7 +1812,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.mul %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1827,7 +1827,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.sdiv %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1842,7 +1842,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.udiv %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1857,7 +1857,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.shl %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1872,7 +1872,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.lshr %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1887,7 +1887,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = llvm.ashr %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1902,7 +1902,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.smax"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1917,7 +1917,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.smin"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1932,7 +1932,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.umax"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1947,7 +1947,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.umin"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i32
   }
 
@@ -1962,7 +1962,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: f32):
       %newval = llvm.fadd %xval, %exprf : f32
       omp.yield(%newval : f32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %vf = %xf : !llvm.ptr, !llvm.ptr, f32
   }
 
@@ -1977,7 +1977,7 @@ llvm.func @omp_atomic_capture_prefix_update(
     ^bb0(%xval: f32):
       %newval = llvm.fsub %xval, %exprf : f32
       omp.yield(%newval : f32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
     omp.atomic.read %vf = %xf : !llvm.ptr, !llvm.ptr, f32
   }
 
@@ -1999,7 +1999,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[res:.*]] = atomicrmw sub ptr %[[x]], i32 %[[expr]] monotonic
@@ -2010,7 +2010,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.sub %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[res:.*]] = atomicrmw and ptr %[[x]], i32 %[[expr]] monotonic
@@ -2021,7 +2021,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.and %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[res:.*]] = atomicrmw or ptr %[[x]], i32 %[[expr]] monotonic
@@ -2032,7 +2032,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.or %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[res:.*]] = atomicrmw xor ptr %[[x]], i32 %[[expr]] monotonic
@@ -2043,7 +2043,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.xor %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2058,7 +2058,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.mul %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2073,7 +2073,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.sdiv %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2088,7 +2088,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.udiv %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2103,7 +2103,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.shl %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2118,7 +2118,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.lshr %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2133,7 +2133,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = llvm.ashr %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2148,7 +2148,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.smax"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2163,7 +2163,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.smin"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2178,7 +2178,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.umax"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2193,7 +2193,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: i32):
       %newval = "llvm.intr.umin"(%xval, %expr) : (i32, i32) -> i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2209,7 +2209,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: f32):
       %newval = llvm.fadd %xval, %exprf : f32
       omp.yield(%newval : f32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[xval:.*]] = phi i32
@@ -2225,7 +2225,7 @@ llvm.func @omp_atomic_capture_postfix_update(
     ^bb0(%xval: f32):
       %newval = llvm.fsub %xval, %exprf : f32
       omp.yield(%newval : f32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   llvm.return
@@ -2263,7 +2263,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] acquire
@@ -2274,7 +2274,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] release
@@ -2285,7 +2285,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] monotonic
@@ -2296,7 +2296,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   // CHECK: %[[res:.*]] = atomicrmw add ptr %[[x]], i32 %[[expr]] acq_rel
@@ -2307,7 +2307,7 @@ llvm.func @omp_atomic_capture_misc(
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
 
   llvm.return
@@ -3053,7 +3053,7 @@ llvm.func @omp_opaque_pointers(%arg0 : !llvm.ptr, %arg1: !llvm.ptr, %expr: i32)
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
   }
   llvm.return
 }
diff --git a/mlir/test/Target/LLVMIR/openmp-target-nesting-in-host-ops.mlir b/mlir/test/Target/LLVMIR/openmp-target-nesting-in-host-ops.mlir
index a9a4ffd533136..cbf273b887bc7 100644
--- a/mlir/test/Target/LLVMIR/openmp-target-nesting-in-host-ops.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-target-nesting-in-host-ops.mlir
@@ -110,7 +110,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memo
     ^bb0(%xval: i32):
       %newval = llvm.add %xval, %expr : i32
       omp.yield(%newval : i32)
-    } {atomic_control = #omp.atomic_control<>}
+    }
 
     llvm.return
   }
diff --git a/mlir/test/Target/LLVMIR/openmp-todo.mlir b/mlir/test/Target/LLVMIR/openmp-todo.mlir
index 692487c21c587..2fa4470bb8300 100644
--- a/mlir/test/Target/LLVMIR/openmp-todo.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-todo.mlir
@@ -19,7 +19,7 @@ llvm.func @atomic_hint(%v : !llvm.ptr, %x : !llvm.ptr, %expr : i32) {
   ^bb0(%arg0: i32):
     %result = llvm.add %arg0, %expr : i32
     omp.yield(%result : i32)
-  } {atomic_control = #omp.atomic_control<>}
+  }
 
   llvm.return
 }

>From a456168f1d80476314f10c8e18903c52a7086d4f Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Thu, 24 Jul 2025 09:32:30 -0500
Subject: [PATCH 6/6] R6: Addressing review comments

---
 flang/lib/Optimizer/Dialect/Support/FIRContext.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
index c9c921008597d..c2e0afe122b4e 100644
--- a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
+++ b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
@@ -90,6 +90,7 @@ void fir::setTuneCPU(mlir::ModuleOp mod, llvm::StringRef cpu) {
 
 static constexpr const char *atomicIgnoreDenormalModeName =
     "fir.atomic_ignore_denormal_mode";
+
 void fir::setAtomicIgnoreDenormalMode(mlir::ModuleOp mod, bool value) {
   if (value) {
     auto *ctx = mod.getContext();
@@ -101,11 +102,12 @@ void fir::setAtomicIgnoreDenormalMode(mlir::ModuleOp mod, bool value) {
 }
 
 bool fir::getAtomicIgnoreDenormalMode(mlir::ModuleOp mod) {
-  return mod->hasAttrOfType<mlir::UnitAttr>(atomicIgnoreDenormalModeName);
+  return mod->hasAttr(atomicIgnoreDenormalModeName);
 }
 
 static constexpr const char *atomicFineGrainedMemoryName =
     "fir.atomic_fine_grained_memory";
+
 void fir::setAtomicFineGrainedMemory(mlir::ModuleOp mod, bool value) {
   if (value) {
     auto *ctx = mod.getContext();
@@ -117,10 +119,12 @@ void fir::setAtomicFineGrainedMemory(mlir::ModuleOp mod, bool value) {
 }
 
 bool fir::getAtomicFineGrainedMemory(mlir::ModuleOp mod) {
-  return mod->hasAttrOfType<mlir::UnitAttr>(atomicFineGrainedMemoryName);
+  return mod->hasAttr(atomicFineGrainedMemoryName);
 }
+
 static constexpr const char *atomicRemoteMemoryName =
     "fir.atomic_remote_memory";
+
 void fir::setAtomicRemoteMemory(mlir::ModuleOp mod, bool value) {
   if (value) {
     auto *ctx = mod.getContext();
@@ -132,7 +136,7 @@ void fir::setAtomicRemoteMemory(mlir::ModuleOp mod, bool value) {
 }
 
 bool fir::getAtomicRemoteMemory(mlir::ModuleOp mod) {
-  return mod->hasAttrOfType<mlir::UnitAttr>(atomicRemoteMemoryName);
+  return mod->hasAttr(atomicRemoteMemoryName);
 }
 
 llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) {



More information about the Mlir-commits mailing list