[flang-commits] [flang] [llvm] [mlir] [flang][OpenMP] Support for "atomic compare capture" (PR #202315)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Fri Aug 7 08:23:31 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 =
----------------
tblah wrote:
I don't understand this 100% so feel free to disagree
https://github.com/llvm/llvm-project/pull/202315
More information about the flang-commits
mailing list