[Mlir-commits] [flang] [mlir] [Flang] [OpenMP] atomic compare (PR #184761)
Tom Eccles
llvmlistbot at llvm.org
Wed Apr 15 08:04:24 PDT 2026
================
@@ -4459,6 +4460,270 @@ convertOmpAtomicCapture(omp::AtomicCaptureOp atomicCaptureOp,
return success();
}
+/// Helper to extract the OMPAtomicCompareOp from an integer comparison
+/// predicate. Returns std::nullopt for unsupported predicates.
+static std::optional<llvm::omp::OMPAtomicCompareOp>
+convertICmpPredicateToAtomicCompareOp(LLVM::ICmpPredicate predicate) {
+ switch (predicate) {
+ case LLVM::ICmpPredicate::eq:
+ return llvm::omp::OMPAtomicCompareOp::EQ;
+ case LLVM::ICmpPredicate::slt:
+ case LLVM::ICmpPredicate::ult:
+ return llvm::omp::OMPAtomicCompareOp::MIN;
+ case LLVM::ICmpPredicate::sgt:
+ case LLVM::ICmpPredicate::ugt:
+ return llvm::omp::OMPAtomicCompareOp::MAX;
+ default:
+ return std::nullopt;
+ }
+}
+
+/// Helper to extract the OMPAtomicCompareOp from a floating-point comparison
+/// predicate. Returns std::nullopt for unsupported predicates.
+static std::optional<llvm::omp::OMPAtomicCompareOp>
+convertFCmpPredicateToAtomicCompareOp(LLVM::FCmpPredicate predicate) {
+ switch (predicate) {
+ case LLVM::FCmpPredicate::oeq:
+ case LLVM::FCmpPredicate::ueq:
+ return llvm::omp::OMPAtomicCompareOp::EQ;
+ case LLVM::FCmpPredicate::olt:
+ case LLVM::FCmpPredicate::ult:
+ return llvm::omp::OMPAtomicCompareOp::MIN;
+ case LLVM::FCmpPredicate::ogt:
+ case LLVM::FCmpPredicate::ugt:
+ return llvm::omp::OMPAtomicCompareOp::MAX;
+ default:
+ return std::nullopt;
+ }
+}
+
+/// Converts an omp.atomic.compare operation to LLVM IR.
+///
+/// if (x == e) x = d
+/// The region contains a comparison + select pattern:
+/// ^bb0(%xval: T):
+/// %cmp = llvm.icmp/fcmp <pred> %xval, %e : T
+/// %sel = llvm.select %cmp, %d, %xval : i1, T
+/// omp.yield(%sel : T)
+///
+/// From MLIR extract:
+/// 1) comparison operator
+/// 2) expected value (e)
+/// 3) desired value (d)
+/// These are passed to OpenMPIRBuilder::createAtomicCompare which generates
+/// the actual cmpxchg / atomicrmw instruction.
+///
+static LogicalResult
+convertOmpAtomicCompare(omp::AtomicCompareOp atomicCompareOp,
+ llvm::IRBuilderBase &builder,
+ LLVM::ModuleTranslation &moduleTranslation) {
+ llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
+ if (failed(checkImplementationStatus(*atomicCompareOp)))
+ return failure();
+
+ Region ®ion = atomicCompareOp.getRegion();
+ Block &block = region.front();
+
+ // Determine element type from the region block argument
+ llvm::Type *llvmXElementType =
+ moduleTranslation.convertType(block.getArgument(0).getType());
+ if (!llvmXElementType)
+ return atomicCompareOp.emitError(
+ "unable to determine element type for atomic compare");
+
+ llvm::Value *llvmX = moduleTranslation.lookupValue(atomicCompareOp.getX());
+ llvm::OpenMPIRBuilder::AtomicOpValue llvmAtomicX = {llvmX, llvmXElementType,
+ false, false};
----------------
tblah wrote:
```suggestion
/*IsSigned=*/false, /*IsVolatile=*/false};
```
Fortran integers are signed, and I think flang does support volatile. Flang support aside, this should not produce incorrect results for any valid mlir input: either fail with a useful error message or produce correct code.
https://github.com/llvm/llvm-project/pull/184761
More information about the Mlir-commits
mailing list