[flang-commits] [flang] [llvm] [mlir] [flang][OpenMP] Support for "atomic compare capture" (PR #202315)

via flang-commits flang-commits at lists.llvm.org
Wed Aug 12 01:03:46 PDT 2026


================
@@ -5422,45 +5422,92 @@ static ComplexComparePattern detectComplexCompareEq(Block &block) {
   return result;
 }
 
-/// Emit a bitcast-to-integer `cmpxchg` for a complex (struct-typed) atomic
-/// compare. The expected/desired complex values are spilled to allocas and
-/// reloaded as an integer of the same width, then compared and swapped. Returns
-/// the cmpxchg (result type `{iN, i1}`); `maxAlign` receives the alignment used
-/// so callers can reinterpret the captured old value through memory.
-static llvm::AtomicCmpXchgInst *
-emitComplexAtomicCmpXchg(llvm::IRBuilderBase &builder, llvm::Value *llvmX,
-                         llvm::Type *complexTy, llvm::Value *eVal,
-                         llvm::Value *dVal, llvm::AtomicOrdering atomicOrdering,
-                         bool isWeak, llvm::Align &maxAlign) {
+/// Emit an IEEE-754-correct `cmpxchg` for a complex (struct-typed) atomic
+/// compare with `fcmp oeq`. The old value of X is returned (as the complex struct
+/// type) in \p oldComplex and the success flag (i1) in \p cmpOk.
+static void emitComplexAtomicCmpXchg(llvm::IRBuilderBase &builder,
+                                     llvm::Value *llvmX, llvm::Type *complexTy,
+                                     llvm::Value *eVal, llvm::Value *dVal,
+                                     llvm::AtomicOrdering atomicOrdering,
+                                     bool isWeak, llvm::Value *&oldComplex,
+                                     llvm::Value *&cmpOk) {
   const llvm::DataLayout &DL =
       builder.GetInsertBlock()->getModule()->getDataLayout();
   unsigned totalBits = DL.getTypeStoreSizeInBits(complexTy).getFixedValue();
   llvm::IntegerType *intTy =
       llvm::IntegerType::get(builder.getContext(), totalBits);
   llvm::Align complexAlign = DL.getABITypeAlign(complexTy);
   llvm::Align intAlign = DL.getABITypeAlign(intTy);
-  maxAlign = std::max(complexAlign, intAlign);
+  llvm::Align maxAlign = std::max(complexAlign, intAlign);
 
-  llvm::AllocaInst *eAlloca =
-      builder.CreateAlloca(complexTy, nullptr, "cmplx.e");
-  eAlloca->setAlignment(maxAlign);
+  // Spill D to obtain its integer bit pattern for the swap value.
   llvm::AllocaInst *dAlloca =
       builder.CreateAlloca(complexTy, nullptr, "cmplx.d");
   dAlloca->setAlignment(maxAlign);
-
-  builder.CreateAlignedStore(eVal, eAlloca, maxAlign);
-  llvm::Value *eInt =
-      builder.CreateAlignedLoad(intTy, eAlloca, maxAlign, "cmplx.e.int");
   builder.CreateAlignedStore(dVal, dAlloca, maxAlign);
   llvm::Value *dInt =
       builder.CreateAlignedLoad(intTy, dAlloca, maxAlign, "cmplx.d.int");
 
+  // Load the current value of X atomically and reinterpret it as complex.
+  llvm::LoadInst *xCurr =
----------------
SunilKuravinakop wrote:

The codex review was correct in pointing out that fail ordering was being missed out  in one of the scenarios for complex types. With the latest changes that I have "pushed" this is being handled.
Thank you.

https://github.com/llvm/llvm-project/pull/202315


More information about the flang-commits mailing list