Skip to content

Commit 1b1a832

Browse files
Icaro-Nuneslanza
authored andcommitted
[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 f2eb0f7 commit 1b1a832

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5643,7 +5643,7 @@ def AtomicXchg : CIR_Op<"atomic.xchg", [AllTypesMatch<["result", "val"]>]> {
56435643
`:` type($result) attr-dict
56445644
}];
56455645

5646-
let hasVerifier = 0;
5646+
let hasVerifier = 1;
56475647
}
56485648

56495649
def MemScope_SingleThread : I32EnumAttrCase<"MemScope_SingleThread",
@@ -5700,7 +5700,7 @@ def AtomicCmpXchg : CIR_Op<"atomic.cmp_xchg",
57005700
`:` `(` type($old) `,` type($cmp) `)` attr-dict
57015701
}];
57025702

5703-
let hasVerifier = 0;
5703+
let hasVerifier = 1;
57045704
}
57055705

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

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

Lines changed: 23 additions & 0 deletions
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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,26 @@ cir.func @bad_fetch(%x: !cir.ptr<!cir.float>, %y: !cir.float) -> () {
10791079

10801080
// -----
10811081

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

0 commit comments

Comments
 (0)