diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index c81f64deff7bc..841617bd47a3c 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4172,7 +4172,7 @@ def CIR_ThrowOp : CIR_Op<"throw"> { // Atomic operations //===----------------------------------------------------------------------===// -def CIR_AtomicXchg : CIR_Op<"atomic.xchg", [ +def CIR_AtomicXchgOp : CIR_Op<"atomic.xchg", [ AllTypesMatch<["result", "val"]>, TypesMatchWith<"type of 'val' must match the pointee type of 'ptr'", "ptr", "val", "mlir::cast($_self).getPointee()"> @@ -4190,9 +4190,7 @@ def CIR_AtomicXchg : CIR_Op<"atomic.xchg", [ Example: ```mlir - %res = cir.atomic.xchg(%ptr : !cir.ptr, - %val : !u64i, - seq_cst) : !u64i + %res = cir.atomic.xchg seq_cst %ptr, %val : !cir.ptr -> !u64i ``` }]; @@ -4207,12 +4205,16 @@ def CIR_AtomicXchg : CIR_Op<"atomic.xchg", [ let assemblyFormat = [{ $mem_order (`volatile` $is_volatile^)? $ptr `,` $val - `:` qualified(type($ptr)) `->` type($result) attr-dict + `:` functional-type(operands, results) attr-dict }]; } -def CIR_AtomicCmpXchg : CIR_Op<"atomic.cmpxchg", [ - AllTypesMatch<["old", "expected", "desired"]> +def CIR_AtomicCmpXchgOp : CIR_Op<"atomic.cmpxchg", [ + AllTypesMatch<["old", "expected", "desired"]>, + TypesMatchWith<"type of 'expected' must match the pointee type of 'ptr'", + "ptr", "expected", "mlir::cast($_self).getPointee()">, + TypesMatchWith<"type of 'desired' must match the pointee type of 'ptr'", + "ptr", "desired", "mlir::cast($_self).getPointee()"> ]> { let summary = "Atomic compare and exchange"; let description = [{ @@ -4245,12 +4247,11 @@ def CIR_AtomicCmpXchg : CIR_Op<"atomic.cmpxchg", [ Example: ```mlir - %old, %success = cir.atomic.cmpxchg(%ptr : !cir.ptr, - %expected : !u64i, - %desired : !u64i, - success = seq_cst, - failure = seq_cst) weak - : (!u64i, !cir.bool) + %old, %success = cir.atomic.cmpxchg weak seq_cst %ptr, %expected, %desired + : (!cir.ptr, !u64i, !u64i) -> (!u64i, !cir.bool) + %old, %success = cir.atomic.cmpxchg weak success(seq_cst) failure(acquire) + %ptr, %expected, %desired + : (!cir.ptr, !u64i, !u64i) -> (!u64i, !cir.bool) ``` }]; let results = (outs CIR_AnyType:$old, CIR_BoolType:$success); @@ -4264,20 +4265,13 @@ def CIR_AtomicCmpXchg : CIR_Op<"atomic.cmpxchg", [ UnitAttr:$is_volatile); let assemblyFormat = [{ - `(` - $ptr `:` qualified(type($ptr)) `,` - $expected `:` type($expected) `,` - $desired `:` type($desired) `,` - `success` `=` $succ_order `,` - `failure` `=` $fail_order - `)` - (`align` `(` $alignment^ `)`)? (`weak` $weak^)? + custom($succ_order, $fail_order) + $ptr `,` $expected `,` $desired + (`align` `(` $alignment^ `)`)? (`volatile` $is_volatile^)? - `:` `(` type($old) `,` type($success) `)` attr-dict + `:` functional-type(operands, results) attr-dict }]; - - let hasVerifier = 1; } #endif // CLANG_CIR_DIALECT_IR_CIROPS_TD diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index 0f4d6d20afc52..a9983f882e28c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -255,7 +255,7 @@ static void emitAtomicCmpXchg(CIRGenFunction &cgf, AtomicExpr *e, bool isWeak, mlir::Value expected = builder.createLoad(loc, val1); mlir::Value desired = builder.createLoad(loc, val2); - auto cmpxchg = cir::AtomicCmpXchg::create( + auto cmpxchg = cir::AtomicCmpXchgOp::create( builder, loc, expected.getType(), builder.getBoolTy(), ptr.getPointer(), expected, desired, cir::MemOrderAttr::get(&cgf.getMLIRContext(), successOrder), @@ -404,7 +404,7 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__c11_atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: case AtomicExpr::AO__atomic_exchange: - opName = cir::AtomicXchg::getOperationName(); + opName = cir::AtomicXchgOp::getOperationName(); break; case AtomicExpr::AO__opencl_atomic_init: diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index cdd4e3c96ca98..d2f94f3e2bd14 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -235,6 +235,54 @@ static void printOmittedTerminatorRegion(mlir::OpAsmPrinter &printer, /*printBlockTerminators=*/!omitRegionTerm(region)); } +static mlir::ParseResult +parseAtomicCmpXchgMemOrder(mlir::OpAsmParser &parser, + cir::MemOrderAttr &successOrder, + cir::MemOrderAttr &failureOrder) { + auto parseMemOrder = [&](cir::MemOrderAttr *output) -> mlir::ParseResult { + mlir::SMLoc loc = parser.getCurrentLocation(); + llvm::StringRef memOrderStr; + if (parser.parseKeyword(&memOrderStr)) + return failure(); + std::optional memOrder = symbolizeMemOrder(memOrderStr); + if (!memOrder.has_value()) + return parser.emitError(loc, "unknown memory order \"") + << memOrderStr << "\""; + *output = cir::MemOrderAttr::get(parser.getContext(), *memOrder); + return success(); + }; + + if (parser.parseOptionalKeyword("success")) { + // No "success" keyword found. successOrder and failureOrder will have the + // same value. + if (parseMemOrder(&successOrder)) + return failure(); + failureOrder = successOrder; + return success(); + } + + if (parser.parseLParen() || parseMemOrder(&successOrder) || + parser.parseRParen()) + return failure(); + + if (parser.parseKeyword("failure") || parser.parseLParen() || + parseMemOrder(&failureOrder) || parser.parseRParen()) + return failure(); + + return success(); +} + +static void printAtomicCmpXchgMemOrder(mlir::OpAsmPrinter &printer, + cir::AtomicCmpXchgOp &op, + cir::MemOrderAttr successOrder, + cir::MemOrderAttr failureOrder) { + if (successOrder.getValue() == failureOrder.getValue()) + printer << stringifyMemOrder(successOrder.getValue()); + else + printer << "success(" << stringifyMemOrder(successOrder.getValue()) << ") " + << "failure(" << stringifyMemOrder(failureOrder.getValue()) << ")"; +} + //===----------------------------------------------------------------------===// // AllocaOp //===----------------------------------------------------------------------===// @@ -2846,20 +2894,6 @@ mlir::LogicalResult cir::ThrowOp::verify() { return failure(); } -//===----------------------------------------------------------------------===// -// AtomicCmpXchg -//===----------------------------------------------------------------------===// - -LogicalResult cir::AtomicCmpXchg::verify() { - mlir::Type pointeeType = getPtr().getType().getPointee(); - - if (pointeeType != getExpected().getType() || - pointeeType != getDesired().getType()) - return emitOpError("ptr, expected and desired types must match"); - - return success(); -} - //===----------------------------------------------------------------------===// // TypeInfoAttr //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 1ff8cc55b57fa..d6dc787f7786a 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -694,8 +694,8 @@ getLLVMMemOrder(std::optional memorder) { llvm_unreachable("unknown memory order"); } -mlir::LogicalResult CIRToLLVMAtomicCmpXchgLowering::matchAndRewrite( - cir::AtomicCmpXchg op, OpAdaptor adaptor, +mlir::LogicalResult CIRToLLVMAtomicCmpXchgOpLowering::matchAndRewrite( + cir::AtomicCmpXchgOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { mlir::Value expected = adaptor.getExpected(); mlir::Value desired = adaptor.getDesired(); @@ -719,8 +719,8 @@ mlir::LogicalResult CIRToLLVMAtomicCmpXchgLowering::matchAndRewrite( return mlir::success(); } -mlir::LogicalResult CIRToLLVMAtomicXchgLowering::matchAndRewrite( - cir::AtomicXchg op, OpAdaptor adaptor, +mlir::LogicalResult CIRToLLVMAtomicXchgOpLowering::matchAndRewrite( + cir::AtomicXchgOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { assert(!cir::MissingFeatures::atomicSyncScopeID()); mlir::LLVM::AtomicOrdering llvmOrder = getLLVMMemOrder(adaptor.getMemOrder()); diff --git a/clang/test/CIR/CodeGen/atomic.c b/clang/test/CIR/CodeGen/atomic.c index 76289c597a2b5..440010a0b6938 100644 --- a/clang/test/CIR/CodeGen/atomic.c +++ b/clang/test/CIR/CodeGen/atomic.c @@ -211,7 +211,7 @@ void c11_atomic_cmpxchg_strong(_Atomic(int) *ptr, int *expected, int desired) { __c11_atomic_compare_exchange_strong(ptr, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); - // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg(%{{.+}} : !cir.ptr, %{{.+}} : !s32i, %{{.+}} : !s32i, success = seq_cst, failure = acquire) align(4) : (!s32i, !cir.bool) + // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool // CIR-NEXT: cir.if %[[FAILED]] { // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr @@ -249,7 +249,7 @@ void c11_atomic_cmpxchg_weak(_Atomic(int) *ptr, int *expected, int desired) { __c11_atomic_compare_exchange_weak(ptr, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); - // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg(%{{.+}} : !cir.ptr, %{{.+}} : !s32i, %{{.+}} : !s32i, success = seq_cst, failure = acquire) align(4) weak : (!s32i, !cir.bool) + // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg weak success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool // CIR-NEXT: cir.if %[[FAILED]] { // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr @@ -286,7 +286,7 @@ void atomic_cmpxchg(int *ptr, int *expected, int *desired) { // OGCG-LABEL: @atomic_cmpxchg __atomic_compare_exchange(ptr, expected, desired, /*weak=*/0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); - // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg(%{{.+}} : !cir.ptr, %{{.+}} : !s32i, %{{.+}} : !s32i, success = seq_cst, failure = acquire) align(4) : (!s32i, !cir.bool) + // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool // CIR-NEXT: cir.if %[[FAILED]] { // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr @@ -317,7 +317,7 @@ void atomic_cmpxchg(int *ptr, int *expected, int *desired) { // OGCG-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1 __atomic_compare_exchange(ptr, expected, desired, /*weak=*/1, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); - // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg(%{{.+}} : !cir.ptr, %{{.+}} : !s32i, %{{.+}} : !s32i, success = seq_cst, failure = acquire) align(4) weak : (!s32i, !cir.bool) + // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg weak success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool // CIR-NEXT: cir.if %[[FAILED]] { // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr @@ -354,7 +354,7 @@ void atomic_cmpxchg_n(int *ptr, int *expected, int desired) { // OGCG-LABEL: @atomic_cmpxchg_n __atomic_compare_exchange_n(ptr, expected, desired, /*weak=*/0, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); - // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg(%{{.+}} : !cir.ptr, %{{.+}} : !s32i, %{{.+}} : !s32i, success = seq_cst, failure = acquire) align(4) : (!s32i, !cir.bool) + // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool // CIR-NEXT: cir.if %[[FAILED]] { // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr @@ -385,7 +385,7 @@ void atomic_cmpxchg_n(int *ptr, int *expected, int desired) { // OGCG-NEXT: store i8 %[[SUCCESS_2]], ptr %{{.+}}, align 1 __atomic_compare_exchange_n(ptr, expected, desired, /*weak=*/1, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); - // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg(%{{.+}} : !cir.ptr, %{{.+}} : !s32i, %{{.+}} : !s32i, success = seq_cst, failure = acquire) align(4) weak : (!s32i, !cir.bool) + // CIR: %[[OLD:.+]], %[[SUCCESS:.+]] = cir.atomic.cmpxchg weak success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} align(4) : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) // CIR-NEXT: %[[FAILED:.+]] = cir.unary(not, %[[SUCCESS]]) : !cir.bool, !cir.bool // CIR-NEXT: cir.if %[[FAILED]] { // CIR-NEXT: cir.store align(4) %[[OLD]], %{{.+}} : !s32i, !cir.ptr @@ -427,12 +427,12 @@ void c11_atomic_exchange(_Atomic(int) *ptr, int value) { __c11_atomic_exchange(ptr, value, __ATOMIC_RELEASE); __c11_atomic_exchange(ptr, value, __ATOMIC_ACQ_REL); __c11_atomic_exchange(ptr, value, __ATOMIC_SEQ_CST); - // CIR: %{{.+}} = cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg consume %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg acquire %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg release %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : !cir.ptr -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg consume %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg acquire %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg release %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4 @@ -460,12 +460,12 @@ void atomic_exchange(int *ptr, int *value, int *old) { __atomic_exchange(ptr, value, old, __ATOMIC_RELEASE); __atomic_exchange(ptr, value, old, __ATOMIC_ACQ_REL); __atomic_exchange(ptr, value, old, __ATOMIC_SEQ_CST); - // CIR: %{{.+}} = cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg consume %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg acquire %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg release %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : !cir.ptr -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg consume %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg acquire %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg release %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4 @@ -493,12 +493,12 @@ void atomic_exchange_n(int *ptr, int value) { __atomic_exchange_n(ptr, value, __ATOMIC_RELEASE); __atomic_exchange_n(ptr, value, __ATOMIC_ACQ_REL); __atomic_exchange_n(ptr, value, __ATOMIC_SEQ_CST); - // CIR: %{{.+}} = cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg consume %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg acquire %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg release %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - // CIR: %{{.+}} = cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : !cir.ptr -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg consume %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg acquire %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg release %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + // CIR: %{{.+}} = cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4 // LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} acquire, align 4 diff --git a/clang/test/CIR/IR/atomic.cir b/clang/test/CIR/IR/atomic.cir index 85207633a5294..52449d9c78a11 100644 --- a/clang/test/CIR/IR/atomic.cir +++ b/clang/test/CIR/IR/atomic.cir @@ -5,17 +5,30 @@ cir.func @atomic_xchg(%ptr: !cir.ptr, %val: !s32i) { // CHECK-LABEL: @atomic_xchg - %0 = cir.atomic.xchg relaxed %ptr, %val : !cir.ptr -> !s32i - // CHECK: cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - %1 = cir.atomic.xchg consume %ptr, %val : !cir.ptr -> !s32i - // CHECK: cir.atomic.xchg consume %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - %2 = cir.atomic.xchg acquire %ptr, %val : !cir.ptr -> !s32i - // CHECK: cir.atomic.xchg acquire %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - %3 = cir.atomic.xchg release %ptr, %val : !cir.ptr -> !s32i - // CHECK: cir.atomic.xchg release %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - %4 = cir.atomic.xchg acq_rel %ptr, %val : !cir.ptr -> !s32i - // CHECK: cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : !cir.ptr -> !s32i - %5 = cir.atomic.xchg seq_cst %ptr, %val : !cir.ptr -> !s32i - // CHECK: cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : !cir.ptr -> !s32i + %0 = cir.atomic.xchg relaxed %ptr, %val : (!cir.ptr, !s32i) -> !s32i + // CHECK: cir.atomic.xchg relaxed %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + %1 = cir.atomic.xchg consume %ptr, %val : (!cir.ptr, !s32i) -> !s32i + // CHECK: cir.atomic.xchg consume %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + %2 = cir.atomic.xchg acquire %ptr, %val : (!cir.ptr, !s32i) -> !s32i + // CHECK: cir.atomic.xchg acquire %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + %3 = cir.atomic.xchg release %ptr, %val : (!cir.ptr, !s32i) -> !s32i + // CHECK: cir.atomic.xchg release %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + %4 = cir.atomic.xchg acq_rel %ptr, %val : (!cir.ptr, !s32i) -> !s32i + // CHECK: cir.atomic.xchg acq_rel %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + %5 = cir.atomic.xchg seq_cst %ptr, %val : (!cir.ptr, !s32i) -> !s32i + // CHECK: cir.atomic.xchg seq_cst %{{.+}}, %{{.+}} : (!cir.ptr, !s32i) -> !s32i + cir.return +} + +cir.func @atomic_cmpxchg(%ptr: !cir.ptr, %expected: !s32i, %desired: !s32i) { + // CHECK-LABEL: @atomic_cmpxchg + %0, %1 = cir.atomic.cmpxchg relaxed %ptr, %expected, %desired : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + // CHECK: cir.atomic.cmpxchg relaxed %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + %2, %3 = cir.atomic.cmpxchg weak relaxed %ptr, %expected, %desired : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + // CHECK: cir.atomic.cmpxchg weak relaxed %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + %4, %5 = cir.atomic.cmpxchg success(seq_cst) failure(acquire) %ptr, %expected, %desired : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + // CHECK: cir.atomic.cmpxchg success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + %6, %7 = cir.atomic.cmpxchg weak success(seq_cst) failure(acquire) %ptr, %expected, %desired : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + // CHECK: cir.atomic.cmpxchg weak success(seq_cst) failure(acquire) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) cir.return } diff --git a/clang/test/CIR/IR/invalid-atomic.cir b/clang/test/CIR/IR/invalid-atomic.cir new file mode 100644 index 0000000000000..d0879efec4112 --- /dev/null +++ b/clang/test/CIR/IR/invalid-atomic.cir @@ -0,0 +1,29 @@ +// RUN: cir-opt %s -verify-diagnostics -split-input-file + +!s32i = !cir.int + +cir.func @f1(%ptr: !cir.ptr, %expected: !s32i, %desired: !s32i) { + // expected-error @below {{custom op 'cir.atomic.cmpxchg' expected valid keyword}} + %0, %1 = cir.atomic.cmpxchg %ptr, %expected, %desired : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + cir.return +} + +// ----- + +!s32i = !cir.int + +cir.func @f2(%ptr: !cir.ptr, %expected: !s32i, %desired: !s32i) { + // expected-error @below {{unknown memory order "relax"}} + %0, %1 = cir.atomic.cmpxchg relax %ptr, %expected, %desired : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + cir.return +} + +// ----- + +!s32i = !cir.int + +cir.func @f3(%ptr: !cir.ptr, %expected: !s32i, %desired: !s32i) { + // expected-error @below {{custom op 'cir.atomic.cmpxchg' expected 'failure'}} + %0, %1 = cir.atomic.cmpxchg success(relaxed) %ptr, %expected, %desired : (!cir.ptr, !s32i, !s32i) -> (!s32i, !cir.bool) + cir.return +}