Skip to content

Commit 99a804b

Browse files
authored
[CIR] Implement ::verify for cir.atomic.xchg and cir.atomic.cmp_xchg (#1431)
Implements `::verify` for operations cir.atomic.xchg and cir.atomic.cmp_xchg I believe the existing regression tests don't get to the CIR level type check failure and I was not able to implement a case that does. Most attempts of reproducing cir.atomic.xchg type check failure were along the lines of: ``` int a; long long b,c; __atomic_exchange(&a, &b, &c, memory_order_seq_cst); ``` And they seem to never trigger the failure on `::verify` because they fail earlier in function parameter checking: ``` exmp.cpp:7:27: error: cannot initialize a parameter of type 'int *' with an rvalue of type 'long long *' 7 | __atomic_exchange(&a, &b, &c, memory_order_seq_cst); | ^~ ``` Closes #1378 .
1 parent 8cb8395 commit 99a804b

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

+2-2
Original file line numberDiff line numberDiff line change
@@ -5634,7 +5634,7 @@ def AtomicXchg : CIR_Op<"atomic.xchg", [AllTypesMatch<["result", "val"]>]> {
56345634
`:` type($result) attr-dict
56355635
}];
56365636

5637-
let hasVerifier = 0;
5637+
let hasVerifier = 1;
56385638
}
56395639

56405640
def MemScope_SingleThread : I32EnumAttrCase<"MemScope_SingleThread",
@@ -5691,7 +5691,7 @@ def AtomicCmpXchg : CIR_Op<"atomic.cmp_xchg",
56915691
`:` `(` type($old) `,` type($cmp) `)` attr-dict
56925692
}];
56935693

5694-
let hasVerifier = 0;
5694+
let hasVerifier = 1;
56955695
}
56965696

56975697
def AtomicFence : CIR_Op<"atomic.fence"> {

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,29 @@ LogicalResult cir::ContinueOp::verify() {
469469
return success();
470470
}
471471

472+
//===----------------------------------------------------------------------===//
473+
// AtomicXchg
474+
//===----------------------------------------------------------------------===//
475+
LogicalResult cir::AtomicXchg::verify() {
476+
if (getPtr().getType().getPointee() != getVal().getType())
477+
return emitOpError("ptr type and val type must match");
478+
479+
return success();
480+
}
481+
482+
//===----------------------------------------------------------------------===//
483+
// AtomicCmpXchg
484+
//===----------------------------------------------------------------------===//
485+
LogicalResult cir::AtomicCmpXchg::verify() {
486+
auto pointeeType = getPtr().getType().getPointee();
487+
488+
if (pointeeType != getExpected().getType() or
489+
pointeeType != getDesired().getType())
490+
return emitOpError("ptr, expected and desired types must match");
491+
492+
return success();
493+
}
494+
472495
//===----------------------------------------------------------------------===//
473496
// CastOp
474497
//===----------------------------------------------------------------------===//

clang/test/CIR/IR/invalid.cir

+20
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,26 @@ cir.func @bad_fetch(%x: !cir.ptr<!cir.float>, %y: !cir.float) -> () {
10781078

10791079
// -----
10801080

1081+
!u32i = !cir.int<u, 32>
1082+
!u64i = !cir.int<u, 64>
1083+
cir.func @bad_xchg(%x: !cir.ptr<!u32i>, %y: !u64i) -> () {
1084+
// expected-error@+1 {{ptr type and val type must match}}
1085+
%13 = cir.atomic.xchg(%x: !cir.ptr<!u32i>, %y: !u64i, seq_cst) : !u64i
1086+
cir.return
1087+
}
1088+
1089+
// -----
1090+
1091+
!u32i = !cir.int<u, 32>
1092+
!u64i = !cir.int<u, 64>
1093+
cir.func @bad_cmp_xchg(%x: !cir.ptr<!u32i>, %y: !u64i, %z: !u64i) -> () {
1094+
// expected-error@+1 {{ptr, expected and desired types must match}}
1095+
%14, %15 = cir.atomic.cmp_xchg(%x : !cir.ptr<!u32i>, %y : !u64i, %z : !u64i, success = seq_cst, failure = seq_cst) align(8) weak : (!u64i, !cir.bool)
1096+
cir.return
1097+
}
1098+
1099+
// -----
1100+
10811101
cir.func @bad_operands_for_nowrap(%x: !cir.float, %y: !cir.float) {
10821102
// expected-error@+1 {{only operations on integer values may have nsw/nuw flags}}
10831103
%0 = cir.binop(add, %x, %y) nsw : !cir.float

0 commit comments

Comments
 (0)