[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
Mon Jul 13 06:23:38 PDT 2026
================
@@ -5370,6 +5370,99 @@ convertFCmpPredicateToAtomicCompareOp(LLVM::FCmpPredicate predicate) {
}
}
+/// Result of matching the decomposed complex equality pattern inside an atomic
+/// compare region.
+struct ComplexComparePattern {
+ bool isComplex = false;
+ bool isNE = false; // `or` of the field compares => NE (unsupported).
+ mlir::Value eAggregate; // The complex expected value (`e`).
+ bool isXBinopExpr = false; // True if x is the first fcmp operand.
+};
+
+/// Detect a decomposed complex equality comparison in an atomic compare region:
+/// %re_x = llvm.extractvalue %xval[0]
+/// %re_e = llvm.extractvalue %eStruct[0]
+/// %cmp_re = llvm.fcmp "oeq" %re_x, %re_e
+/// %im_x = llvm.extractvalue %xval[1]
+/// %im_e = llvm.extractvalue %eStruct[1]
+/// %cmp_im = llvm.fcmp "oeq" %im_x, %im_e
+/// %cmp = llvm.and %cmp_re, %cmp_im (llvm.or would be NE)
+/// It is recognised by an and/or whose operands are both fcmps operating on
+/// extractvalues, one chain rooted at the block argument (x) and the other at
+/// the expected complex value (e).
+static ComplexComparePattern detectComplexCompareEq(Block &block) {
+ ComplexComparePattern result;
+ auto traceToAggregate = [](mlir::Value v) -> mlir::Value {
+ if (auto extractOp = v.getDefiningOp<LLVM::ExtractValueOp>())
+ return extractOp.getContainer();
+ return nullptr;
+ };
+ for (Operation &op : block.getOperations()) {
+ if (!isa<LLVM::AndOp, LLVM::OrOp>(op))
+ continue;
+ auto lhsFcmp = op.getOperand(0).getDefiningOp<LLVM::FCmpOp>();
+ auto rhsFcmp = op.getOperand(1).getDefiningOp<LLVM::FCmpOp>();
+ if (!lhsFcmp || !rhsFcmp)
+ continue;
+ mlir::Value lhsAgg0 = traceToAggregate(lhsFcmp.getOperand(0));
+ mlir::Value lhsAgg1 = traceToAggregate(lhsFcmp.getOperand(1));
+ bool lhsXIsOp0 = (lhsAgg0 == block.getArgument(0));
+ bool lhsXIsOp1 = (lhsAgg1 == block.getArgument(0));
+ if (!lhsXIsOp0 && !lhsXIsOp1)
+ continue;
+ mlir::Value eAggregate = lhsXIsOp0 ? lhsAgg1 : lhsAgg0;
+ if (!eAggregate)
+ continue;
+ result.isComplex = true;
+ result.isNE = isa<LLVM::OrOp>(op);
+ result.eAggregate = eAggregate;
+ result.isXBinopExpr = lhsXIsOp0;
+ break;
+ }
+ 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
----------------
tblah wrote:
This has the same problem we discussed here: https://github.com/llvm/llvm-project/pull/184761#discussion_r3130007915
https://github.com/llvm/llvm-project/pull/202315
More information about the flang-commits
mailing list