================
@@ -738,56 +753,75 @@ static void emitAtomicExprWithDynamicMemOrder(
[&](mlir::OpBuilder &, mlir::Location loc, mlir::OperationState &) {
mlir::Block *switchBlock = builder.getBlock();
- auto emitMemOrderCase = [&](llvm::ArrayRef<cir::MemOrder> caseOrders,
- cir::MemOrder actualOrder) {
- if (caseOrders.empty())
+ auto emitMemOrderCase = [&](llvm::ArrayRef<cir::MemOrder> caseOrders) {
+ // Checking there are same effective memory order for each case.
+ for (int i = 1, e = caseOrders.size(); i < e; i++)
+ assert((getEffectiveAtomicMemOrder(caseOrders[i - 1], isStore,
+ isLoad, isFence) ==
+ getEffectiveAtomicMemOrder(caseOrders[i], isStore, isLoad,
+ isFence)) &&
+ "Effective memory order must be same!");
+ // Emit case label and atomic opeartion if neccessary.
+ if (caseOrders.empty()) {
emitMemOrderDefaultCaseLabel(builder, loc);
- else
+ // There is no good way to report an unsupported memory order at
+ // runtime, hence the fallback to memory_order_relaxed.
+ if (!isFence)
+ emitAtomicOp(cir::MemOrder::Relaxed);
+ } else if (auto actualOrder = getEffectiveAtomicMemOrder(
+ caseOrders[0], isStore, isLoad, isFence)) {
+ // Included in default case.
+ if (!isFence && actualOrder == cir::MemOrder::Relaxed)
+ return;
+ // Creating case operation for effective memory order. If there are
+ // multiple cases in `caseOrders`, the actual order of each case
+ // must be same, this needs to be guaranteed by the caller.
emitMemOrderCaseLabel(builder, loc, order.getType(), caseOrders);
- emitAtomicOp(cgf, e, dest, ptr, val1, val2, isWeakExpr,
orderFailExpr,
- size, actualOrder, scopeConst, scopeValue);
+ emitAtomicOp(actualOrder.value());
+ } else {
+ // Do nothing if (!caseOrders.empty() && !actualOrder)
+ return;
+ }
builder.createBreak(loc);
builder.setInsertionPointToEnd(switchBlock);
};
- // default:
- // Use memory_order_relaxed for relaxed operations and for any memory
- // order value that is not supported. There is no good way to report
- // an unsupported memory order at runtime, hence the fallback to
- // memory_order_relaxed.
- emitMemOrderCase(/*caseOrders=*/{}, cir::MemOrder::Relaxed);
-
- if (!isStore) {
- // case consume:
- // case acquire:
- // memory_order_consume is not implemented; it is always treated
- // like memory_order_acquire. These memory orders are not valid for
- // write-only operations.
- emitMemOrderCase({cir::MemOrder::Consume, cir::MemOrder::Acquire},
- cir::MemOrder::Acquire);
- }
-
- if (!isLoad) {
- // case release:
- // memory_order_release is not valid for read-only operations.
- emitMemOrderCase({cir::MemOrder::Release}, cir::MemOrder::Release);
- }
-
- if (!isLoad && !isStore) {
- // case acq_rel:
- // memory_order_acq_rel is only valid for read-write operations.
- emitMemOrderCase({cir::MemOrder::AcquireRelease},
- cir::MemOrder::AcquireRelease);
- }
-
- // case seq_cst:
- emitMemOrderCase({cir::MemOrder::SequentiallyConsistent},
- cir::MemOrder::SequentiallyConsistent);
+ emitMemOrderCase(/*default:*/ {});
+ emitMemOrderCase({cir::MemOrder::Relaxed});
+ emitMemOrderCase({cir::MemOrder::Consume, cir::MemOrder::Acquire});
+ emitMemOrderCase({cir::MemOrder::Release});
+ emitMemOrderCase({cir::MemOrder::AcquireRelease});
+ emitMemOrderCase({cir::MemOrder::SequentiallyConsistent});
builder.createYield(loc);
});
}
+void CIRGenFunction::emitAtomicExprWithMemOrder(
+ const Expr *memOrder, bool isStore, bool isLoad, bool isFence,
+ llvm::function_ref<void(cir::MemOrder)> emitAtomicOp) {
+ // Emit the memory order operand, and try to evaluate it as a constant.
+ Expr::EvalResult eval;
+ if (memOrder->EvaluateAsInt(eval, getContext())) {
+ uint64_t constOrder = eval.Val.getInt().getZExtValue();
+ // We should not ever get to a case where the ordering isn't a valid CABI
+ // value, but it's hard to enforce that in general.
+ if (!cir::isValidCIRAtomicOrderingCABI(constOrder))
+ return;
+ cir::MemOrder oriOrder = static_cast<cir::MemOrder>(constOrder);
+ if (auto actualOrder =
----------------
Lancern wrote:
```suggestion
if (std::optional<cir::MemOrder> actualOrder =
```
https://github.com/llvm/llvm-project/pull/172455
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits