From 4816fb9bc0761d8761798300bb419db0072c9d04 Mon Sep 17 00:00:00 2001 From: Anchu Rajendran Date: Wed, 4 Jun 2025 15:12:49 -0500 Subject: [PATCH 1/5] [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 8e38f0062140e..c1c7929b0c15d 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2303,21 +2303,21 @@ def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group, defm atomic_remote_memory : BoolFOption<"atomic-remote-memory", LangOpts<"AtomicRemoteMemory">, DefaultFalse, - PosFlag, - NegFlag, - BothFlags<[], [ClangOption], " atomic operations on remote memory">>; + PosFlag, + NegFlag, + BothFlags<[], [ClangOption, FlangOption], " atomic operations on remote memory">>; defm atomic_fine_grained_memory : BoolFOption<"atomic-fine-grained-memory", LangOpts<"AtomicFineGrainedMemory">, DefaultFalse, - PosFlag, - NegFlag, - BothFlags<[], [ClangOption], " atomic operations on fine-grained memory">>; + PosFlag, + NegFlag, + BothFlags<[], [ClangOption, FlangOption], " atomic operations on fine-grained memory">>; defm atomic_ignore_denormal_mode : BoolFOption<"atomic-ignore-denormal-mode", LangOpts<"AtomicIgnoreDenormalMode">, DefaultFalse, - PosFlag, - NegFlag, - BothFlags<[], [ClangOption], " atomic operations to ignore denormal mode">>; + PosFlag, + NegFlag, + 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=">, @@ -5314,9 +5314,9 @@ defm amdgpu_precise_memory_op " precise memory mode (AMDGPU only)">; def munsafe_fp_atomics : Flag<["-"], "munsafe-fp-atomics">, - Visibility<[ClangOption, CC1Option]>, Alias; + Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>, Alias; def mno_unsafe_fp_atomics : Flag<["-"], "mno-unsafe-fp-atomics">, - Visibility<[ClangOption]>, Alias; + Visibility<[ClangOption, FlangOption]>, Alias; def faltivec : Flag<["-"], "faltivec">, Group; def fno_altivec : Flag<["-"], "fno-altivec">, 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 30d81f3daa969..00f854b905c72 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -496,6 +496,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 ff35840a6668c..acbfad589dfbb 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -6666,6 +6666,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(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(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(amdgpuRemoteMemoryName)) + return true; + return false; +} + llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) { if (auto attr = mod->getAttrOfType(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 { + !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control} + !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref { + !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control} + !FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref { + !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control} + !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref { + !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control} + !$omp target parallel num_threads(threads) + !$omp atomic + A = A + 1 + !$omp end target parallel + !UNSAFE-FP-ATOMICS: omp.atomic.update %{{.*}} : !fir.ref { + !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control} + !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref { + !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control} + !FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref { + !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control} + !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref { + !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control} + !$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 ac80926053a2d..375e35a146f78 100644 --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -1543,9 +1543,11 @@ def AtomicUpdateOp : OpenMP_Op<"atomic.update", traits = [ operations. }] # clausesDescription; - let arguments = !con((ins Arg:$x), clausesArgs); + let arguments = !con( + (ins Arg:$x, + OptionalAttr:$atomic_control), + clausesArgs); // Override region definition. let regions = (region SizedRegion<1>:$region); diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir index 47cfc5278a5d0..e377b7aab3e43 100644 --- a/mlir/test/Dialect/OpenMP/ops.mlir +++ b/mlir/test/Dialect/OpenMP/ops.mlir @@ -1562,6 +1562,15 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, omp.yield(%newval : i32) } + // CHECK: omp.atomic.update %[[X]] : memref { + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: omp.yield(%{{.+}} : i32) + // CHECK-NEXT: } {atomic_control_attr = #omp.atomic_control} + omp.atomic.update %x : memref { + ^bb0(%xval:i32): + omp.yield(%const:i32) + } {atomic_control_attr = #omp.atomic_control} + return } From 63d3b489ce5d1210172f8bc1d3b18d81ff52886d Mon Sep 17 00:00:00 2001 From: Anchu Rajendran Date: Wed, 11 Jun 2025 13:58:07 -0500 Subject: [PATCH 2/5] 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 375e35a146f78..399f7fa6e78f0 100644 --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -1546,7 +1546,7 @@ def AtomicUpdateOp : OpenMP_Op<"atomic.update", traits = [ let arguments = !con( (ins Arg:$x, - OptionalAttr:$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) { omp.atomic.update %x : memref { ^bb0(%xval : i32): omp.yield(%xval : i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -17,7 +17,7 @@ func.func @update_write_op(%x : memref, %value: i32) { omp.atomic.update %x : memref { ^bb0(%xval : i32): omp.yield(%value : i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -33,7 +33,7 @@ func.func @update_normal(%x : memref, %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) { ^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) { ^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 060b3cd2455a0..afc3830286f30 100644 --- a/mlir/test/Dialect/OpenMP/invalid.mlir +++ b/mlir/test/Dialect/OpenMP/invalid.mlir @@ -1007,7 +1007,7 @@ func.func @omp_atomic_update1(%x: memref, %expr: f32) { ^bb0(%xval: f32): %newval = llvm.fadd %xval, %expr : f32 omp.yield (%newval : f32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1020,7 +1020,7 @@ func.func @omp_atomic_update2(%x: memref, %expr: i32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.terminator - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1032,7 +1032,7 @@ func.func @omp_atomic_update3(%x: memref, %expr: i32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1044,7 +1044,7 @@ func.func @omp_atomic_update4(%x: memref, %expr: i32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1056,7 +1056,7 @@ func.func @omp_atomic_update5(%x: memref, %expr: i32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1068,7 +1068,7 @@ func.func @omp_atomic_update6(%x: memref, %expr: i32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval, %expr : i32, i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1080,7 +1080,7 @@ func.func @omp_atomic_update7(%x: memref, %expr: i32, %y: f32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%y: f32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1092,7 +1092,7 @@ func.func @omp_atomic_update8(%x: memref, %expr: i32) { ^bb0(%xval: i32, %tmp: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1104,7 +1104,7 @@ func.func @omp_atomic_update(%x: memref, %expr: i32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1116,7 +1116,7 @@ func.func @omp_atomic_update(%x: memref, %expr: i32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1128,7 +1128,7 @@ func.func @omp_atomic_update(%x: memref, %expr: i32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} return } @@ -1164,12 +1164,12 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %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 { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} omp.terminator } return @@ -1197,7 +1197,7 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %expr: i32) { ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} omp.terminator } return @@ -1212,7 +1212,7 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %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 omp.terminator } @@ -1240,7 +1240,7 @@ func.func @omp_atomic_capture(%x: memref, %y: memref, %v: memref, ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} omp.atomic.read %v = %y : memref, memref, i32 omp.terminator } @@ -1256,7 +1256,7 @@ func.func @omp_atomic_capture(%x: memref, %y: memref, %v: memref, ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield (%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} omp.terminator } } @@ -1281,7 +1281,7 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %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, memref, i32 } return @@ -1296,7 +1296,7 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %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, memref, i32 } return @@ -1311,7 +1311,7 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %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, memref, i32 } return @@ -1326,7 +1326,7 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %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, memref, i32 } return @@ -1341,7 +1341,7 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %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, memref, i32 } return @@ -1356,7 +1356,7 @@ func.func @omp_atomic_capture(%x: memref, %v: memref, %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, memref, i32 } return diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir index e377b7aab3e43..5aa7befb2dc26 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, %expr : i32, %xBool : memref, ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} // CHECK: omp.atomic.update %[[XBOOL]] : memref // CHECK-NEXT: (%[[XVAL:.*]]: i1): // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.and %[[XVAL]], %[[EXPRBOOL]] : i1 @@ -1380,57 +1380,57 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^bb0(%xval: i1): %newval = llvm.and %xval, %exprBool : i1 omp.yield(%newval : i1) - } + } {atomic_control = #omp.atomic_control<>} // CHECK: omp.atomic.update %[[X]] : memref // 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 { ^bb0(%xval: i32): %newval = llvm.shl %xval, %expr : i32 omp.yield(%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} // CHECK: omp.atomic.update %[[X]] : memref // 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 { ^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 // 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 { ^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 { // CHECK-NEXT: (%[[XVAL:.*]]: i32): // CHECK-NEXT: omp.yield(%[[XVAL]] : i32) - // CHECK-NEXT: } + // CHECK-NEXT: } {atomic_control = #omp.atomic_control<>} omp.atomic.update %x : memref { ^bb0(%xval:i32): omp.yield(%xval:i32) - } + } {atomic_control = #omp.atomic_control<>} // CHECK: omp.atomic.update %[[X]] : memref { // 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 { ^bb0(%xval:i32): omp.yield(%const:i32) - } + } {atomic_control = #omp.atomic_control<>} // CHECK: omp.atomic.update %[[X]] : memref // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1440,7 +1440,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1450,7 +1450,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1460,7 +1460,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1470,7 +1470,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1480,7 +1480,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1490,7 +1490,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1500,7 +1500,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1510,7 +1510,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1520,7 +1520,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1530,7 +1530,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1540,7 +1540,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1550,7 +1550,7 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^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 // CHECK-NEXT: (%[[XVAL:.*]]: i32): @@ -1560,17 +1560,16 @@ func.func @omp_atomic_update(%x : memref, %expr : i32, %xBool : memref, ^bb0(%xval: i32): %newval = llvm.add %xval, %expr : i32 omp.yield(%newval : i32) - } + } {atomic_control = #omp.atomic_control<>} // CHECK: omp.atomic.update %[[X]] : memref { // CHECK-NEXT: (%[[XVAL:.*]]: i32): // CHECK-NEXT: omp.yield(%{{.+}} : i32) - // CHECK-NEXT: } {atomic_control_attr = #omp.atomic_control} + // CHECK-NEXT: } {atomic_control = #omp.atomic_control} omp.atomic.update %x : memref { ^bb0(%xval:i32): omp.yield(%const:i32) - } {atomic_control_attr = #omp.atomic_control} - + } {atomic_control = #omp.atomic_control} return } @@ -1582,7 +1581,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture{ @@ -1590,7 +1589,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } // CHECK: omp.atomic.capture { @@ -1599,7 +1598,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 @@ -1607,7 +1606,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 @@ -1623,7 +1622,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(none) { @@ -1631,7 +1630,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1640,7 +1639,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(uncontended) { @@ -1648,7 +1647,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1657,7 +1656,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(contended) { @@ -1665,7 +1664,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1674,7 +1673,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(nonspeculative) { @@ -1682,7 +1681,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1691,7 +1690,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(speculative) { @@ -1699,7 +1698,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1708,7 +1707,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(uncontended, nonspeculative) { @@ -1716,7 +1715,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1725,7 +1724,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(contended, nonspeculative) { @@ -1733,7 +1732,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1742,7 +1741,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(uncontended, speculative) { @@ -1750,7 +1749,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1759,7 +1758,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(contended, speculative) { @@ -1767,7 +1766,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1776,7 +1775,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture memory_order(seq_cst) { @@ -1784,7 +1783,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1793,7 +1792,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture memory_order(acq_rel) { @@ -1801,7 +1800,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1810,7 +1809,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture memory_order(acquire) { @@ -1818,7 +1817,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1827,7 +1826,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture memory_order(release) { @@ -1835,7 +1834,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1844,7 +1843,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture memory_order(relaxed) { @@ -1852,7 +1851,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 } @@ -1861,7 +1860,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, i32 // CHECK-NEXT: } omp.atomic.capture hint(contended, speculative) memory_order(seq_cst) { @@ -1869,7 +1868,7 @@ func.func @omp_atomic_capture(%v: memref, %x: memref, %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, memref, 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 32f0ba5b105ff..ab7f756bf95f9 100644 --- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir +++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir @@ -1462,13 +1462,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 } @@ -1563,7 +1563,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 } @@ -1623,7 +1623,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 @@ -1665,7 +1665,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 } @@ -1683,7 +1683,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 } @@ -1701,7 +1701,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]] @@ -1710,7 +1710,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 } @@ -1732,7 +1732,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 } @@ -1751,7 +1751,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 } @@ -1763,7 +1763,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 } @@ -1775,7 +1775,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 } @@ -1787,7 +1787,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 } @@ -1799,7 +1799,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 } @@ -1814,7 +1814,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 } @@ -1829,7 +1829,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 } @@ -1844,7 +1844,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 } @@ -1859,7 +1859,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 } @@ -1874,7 +1874,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 } @@ -1889,7 +1889,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 } @@ -1904,7 +1904,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 } @@ -1919,7 +1919,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 } @@ -1934,7 +1934,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 } @@ -1949,7 +1949,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 } @@ -1964,7 +1964,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 } @@ -1979,7 +1979,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 } @@ -2001,7 +2001,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 @@ -2012,7 +2012,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 @@ -2023,7 +2023,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 @@ -2034,7 +2034,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 @@ -2045,7 +2045,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 @@ -2060,7 +2060,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 @@ -2075,7 +2075,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 @@ -2090,7 +2090,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 @@ -2105,7 +2105,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 @@ -2120,7 +2120,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 @@ -2135,7 +2135,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 @@ -2150,7 +2150,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 @@ -2165,7 +2165,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 @@ -2180,7 +2180,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 @@ -2195,7 +2195,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 @@ -2211,7 +2211,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 @@ -2227,7 +2227,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 @@ -2265,7 +2265,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 @@ -2276,7 +2276,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 @@ -2287,7 +2287,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 @@ -2298,7 +2298,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 @@ -2309,7 +2309,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 @@ -3055,7 +3055,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 29725a02c075a..0ec244bf28f33 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 0b1b23ac98e9486d79b69092698623782ee96921 Mon Sep 17 00:00:00 2001 From: Anchu Rajendran Date: Wed, 11 Jun 2025 14:11:02 -0500 Subject: [PATCH 3/5] 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(amdgpuIgnoreDenormalModeName)) - return true; - return false; + return mod->hasAttrOfType(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(amdgpuFineGrainedMemoryName)) - return true; - return false; + return mod->hasAttrOfType(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(amdgpuRemoteMemoryName)) - return true; - return false; + return mod->hasAttrOfType(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 565d104ba013acd7f7e64cc989e774f0f1f34e97 Mon Sep 17 00:00:00 2001 From: Anchu Rajendran Date: Mon, 23 Jun 2025 12:14:19 -0500 Subject: [PATCH 4/5] 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 | 9 ++++- .../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, 61 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 00f854b905c72..63170a6df6960 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -496,17 +496,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 acbfad589dfbb..af6e72aa8cd10 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -6666,12 +6666,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 2ab91b239a3cc..cbc850d67cc4d 100644 --- a/flang/lib/Lower/OpenMP/Atomic.cpp +++ b/flang/lib/Lower/OpenMP/Atomic.cpp @@ -634,9 +634,16 @@ 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 = builder.create( - loc, atomAddr, hint, makeMemOrderAttr(converter, memOrder)); + loc, atomAddr, atomicControlAttr, hint, + makeMemOrderAttr(converter, memOrder)); mlir::Region ®ion = updateOp->getRegion(0); mlir::Block *block = builder.createBlock(®ion, {}, {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(amdgpuIgnoreDenormalModeName); +bool fir::getIgnoreDenormalMode(mlir::ModuleOp mod) { + return mod->hasAttrOfType(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(amdgpuFineGrainedMemoryName); +bool fir::getFineGrainedMemory(mlir::ModuleOp mod) { + return mod->hasAttrOfType(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(amdgpuRemoteMemoryName); +bool fir::getRemoteMemory(mlir::ModuleOp mod) { + return mod->hasAttrOfType(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 { - !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control} + !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control} !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref { - !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control} + !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control} !FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref { - !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control} + !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control} !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref { - !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control} + !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control} !$omp target parallel num_threads(threads) !$omp atomic A = A + 1 !$omp end target parallel !UNSAFE-FP-ATOMICS: omp.atomic.update %{{.*}} : !fir.ref { - !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control} + !UNSAFE-FP-ATOMICS: } {atomic_control = #omp.atomic_control} !IGNORE-DENORMAL: omp.atomic.update %{{.*}} : !fir.ref { - !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control} + !IGNORE-DENORMAL: } {atomic_control = #omp.atomic_control} !FINE-GRAINED-MEMORY: omp.atomic.update %{{.*}} : !fir.ref { - !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control} + !FINE-GRAINED-MEMORY: } {atomic_control = #omp.atomic_control} !REMOTE-MEMORY: omp.atomic.update %{{.*}} : !fir.ref { - !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control} + !REMOTE-MEMORY: } {atomic_control = #omp.atomic_control} !$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 5aa7befb2dc26..9a72ddfc2989d 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, %expr : i32, %xBool : memref, // CHECK: omp.atomic.update %[[X]] : memref { // CHECK-NEXT: (%[[XVAL:.*]]: i32): // CHECK-NEXT: omp.yield(%{{.+}} : i32) - // CHECK-NEXT: } {atomic_control = #omp.atomic_control} + // CHECK-NEXT: } {atomic_control = #omp.atomic_control} omp.atomic.update %x : memref { ^bb0(%xval:i32): omp.yield(%const:i32) - } {atomic_control = #omp.atomic_control} + } {atomic_control = #omp.atomic_control} return } From 23d305883c3c456f094ebb9ec5f40237d5122cc8 Mon Sep 17 00:00:00 2001 From: Anchu Rajendran Date: Wed, 2 Jul 2025 11:26:03 -0500 Subject: [PATCH 5/5] R5: Addressing review comments --- flang/include/flang/Frontend/TargetOptions.h | 8 +-- .../Optimizer/Dialect/Support/FIRContext.h | 22 +++++--- flang/lib/Frontend/CompilerInvocation.cpp | 6 +- flang/lib/Lower/Bridge.cpp | 10 ++-- .../Optimizer/Dialect/Support/FIRContext.cpp | 55 ++++++++++++------- .../mlir/Dialect/OpenMP/OpenMPAttrDefs.td | 30 +++++----- 6 files changed, 77 insertions(+), 54 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..fa61ab64e253d 100644 --- a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h +++ b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h @@ -58,13 +58,21 @@ 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 that Denormal Mode can be ignored 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 that fine grained memory is used for lowering of atomic operations. +void setAtomicFineGrainedMemory(mlir::ModuleOp mod, bool value); +/// Gets whether fine grained memory is used or not for lowering of atomic +/// operations. +bool getAtomicFineGrainedMemory(mlir::ModuleOp mod); +/// Sets that remote memory is used for lowering of atomic operations. +void setAtomicRemoteMemory(mlir::ModuleOp mod, bool value); +/// Gets whether remote memory is 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 63170a6df6960..39021207e897e 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -496,13 +496,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 af6e72aa8cd10..3795ce2e048b6 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -6666,12 +6666,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/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(ignoreDenormalModeName); +bool fir::getAtomicIgnoreDenormalMode(mlir::ModuleOp mod) { + return mod->hasAttrOfType(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(fineGrainedMemoryName); +bool fir::getAtomicFineGrainedMemory(mlir::ModuleOp mod) { + return mod->hasAttrOfType(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(remoteMemoryName); +bool fir::getAtomicRemoteMemory(mlir::ModuleOp mod) { + return mod->hasAttrOfType(atomicRemoteMemoryName); } llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) { 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 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 //===----------------------------------------------------------------------===//