11// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature
22/// Check that we emit inline atomics rather than library calls for capability-size atomics
3- // RUN: %riscv64_cheri_purecap_cc1 -target-feature +a %s -emit-llvm -o - -disable-O0-optnone -verify | opt -S -mem2reg | FileCheck %s --check-prefixes=PURECAP64
4- // RUN: %riscv64_cheri_cc1 -target-feature +a %s -emit-llvm -o - -disable-O0-optnone -verify | opt -S -mem2reg | FileCheck %s --check-prefixes=HYBRID64
5- // RUN: %riscv32_cheri_purecap_cc1 -target-feature +a %s -emit-llvm -o - -disable-O0-optnone -verify | opt -S -mem2reg | FileCheck %s --check-prefixes=PURECAP32
6- // RUN: %riscv32_cheri_cc1 -target-feature +a %s -emit-llvm -o - -disable-O0-optnone -verify | opt -S -mem2reg | FileCheck %s --check-prefixes=HYBRID32
3+ // RUN: %riscv64_cheri_purecap_cc1 -target-feature +a %s -emit-llvm -o - -disable-O0-optnone -verify=purecap | opt -S -mem2reg | FileCheck %s --check-prefixes=PURECAP64
4+ // RUN: %riscv64_cheri_cc1 -target-feature +a %s -emit-llvm -o - -disable-O0-optnone -verify=hybrid | opt -S -mem2reg | FileCheck %s --check-prefixes=HYBRID64
5+ // RUN: %riscv32_cheri_purecap_cc1 -target-feature +a %s -emit-llvm -o - -disable-O0-optnone -verify=purecap | opt -S -mem2reg | FileCheck %s --check-prefixes=PURECAP32
6+ // RUN: %riscv32_cheri_cc1 -target-feature +a %s -emit-llvm -o - -disable-O0-optnone -verify=hybrid | opt -S -mem2reg | FileCheck %s --check-prefixes=HYBRID32
7+ // purecap-no-diagnostics
78
89#if __CHERI_CAPABILITY_WIDTH__ == 64
910typedef __INT64_TYPE__ cap_size_int ;
@@ -70,9 +71,7 @@ __intcap load_cap(__intcap* i) {
7071// PURECAP64-LABEL: define {{[^@]+}}@loadi128
7172// PURECAP64-SAME: (ptr addrspace(200) noundef [[I:%.*]]) addrspace(200) #[[ATTR0]] {
7273// PURECAP64-NEXT: entry:
73- // PURECAP64-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i128, align 16, addrspace(200)
74- // PURECAP64-NEXT: call void @__atomic_load(i64 noundef 16, ptr addrspace(200) noundef [[I]], ptr addrspace(200) noundef [[ATOMIC_TEMP]], i32 noundef signext 5)
75- // PURECAP64-NEXT: [[TMP0:%.*]] = load i128, ptr addrspace(200) [[ATOMIC_TEMP]], align 16
74+ // PURECAP64-NEXT: [[TMP0:%.*]] = load atomic i128, ptr addrspace(200) [[I]] seq_cst, align 16
7675// PURECAP64-NEXT: ret i128 [[TMP0]]
7776//
7877// HYBRID64-LABEL: define {{[^@]+}}@loadi128
@@ -86,8 +85,8 @@ __intcap load_cap(__intcap* i) {
8685// PURECAP32-LABEL: define {{[^@]+}}@loadi128
8786// PURECAP32-SAME: (ptr addrspace(200) noundef [[I:%.*]]) addrspace(200) #[[ATTR0]] {
8887// PURECAP32-NEXT: entry:
89- // PURECAP32-NEXT: [[CALL :%.*]] = call i64 @__atomic_load_8( ptr addrspace(200) noundef [[I]], i32 noundef 5)
90- // PURECAP32-NEXT: ret i64 [[CALL ]]
88+ // PURECAP32-NEXT: [[TMP0 :%.*]] = load atomic i64, ptr addrspace(200) [[I]] seq_cst, align 8
89+ // PURECAP32-NEXT: ret i64 [[TMP0 ]]
9190//
9291// HYBRID32-LABEL: define {{[^@]+}}@loadi128
9392// HYBRID32-SAME: (ptr noundef [[I:%.*]]) #[[ATTR0]] {
@@ -97,7 +96,7 @@ __intcap load_cap(__intcap* i) {
9796//
9897cap_size_int loadi128 (cap_size_int * i ) {
9998 return __atomic_load_n (i , __ATOMIC_SEQ_CST );
100- // expected -warning@-1{{large atomic operation may incur significant performance penalty}}
99+ // hybrid -warning@-1{{large atomic operation may incur significant performance penalty}}
101100}
102101
103102// PURECAP64-LABEL: define {{[^@]+}}@xchg_long
@@ -159,11 +158,7 @@ __intcap xchg_cap(__intcap* i, __intcap val) {
159158// PURECAP64-LABEL: define {{[^@]+}}@xchg_i128
160159// PURECAP64-SAME: (ptr addrspace(200) noundef [[I:%.*]], i128 noundef [[VAL:%.*]]) addrspace(200) #[[ATTR0]] {
161160// PURECAP64-NEXT: entry:
162- // PURECAP64-NEXT: [[DOTATOMICTMP:%.*]] = alloca i128, align 16, addrspace(200)
163- // PURECAP64-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i128, align 16, addrspace(200)
164- // PURECAP64-NEXT: store i128 [[VAL]], ptr addrspace(200) [[DOTATOMICTMP]], align 16
165- // PURECAP64-NEXT: call void @__atomic_exchange(i64 noundef 16, ptr addrspace(200) noundef [[I]], ptr addrspace(200) noundef [[DOTATOMICTMP]], ptr addrspace(200) noundef [[ATOMIC_TEMP]], i32 noundef signext 5)
166- // PURECAP64-NEXT: [[TMP0:%.*]] = load i128, ptr addrspace(200) [[ATOMIC_TEMP]], align 16
161+ // PURECAP64-NEXT: [[TMP0:%.*]] = atomicrmw xchg ptr addrspace(200) [[I]], i128 [[VAL]] seq_cst, align 16
167162// PURECAP64-NEXT: ret i128 [[TMP0]]
168163//
169164// HYBRID64-LABEL: define {{[^@]+}}@xchg_i128
@@ -179,8 +174,8 @@ __intcap xchg_cap(__intcap* i, __intcap val) {
179174// PURECAP32-LABEL: define {{[^@]+}}@xchg_i128
180175// PURECAP32-SAME: (ptr addrspace(200) noundef [[I:%.*]], i64 noundef [[VAL:%.*]]) addrspace(200) #[[ATTR0]] {
181176// PURECAP32-NEXT: entry:
182- // PURECAP32-NEXT: [[CALL :%.*]] = call i64 @__atomic_exchange_8( ptr addrspace(200) noundef [[I]], i64 noundef [[VAL]], i32 noundef 5)
183- // PURECAP32-NEXT: ret i64 [[CALL ]]
177+ // PURECAP32-NEXT: [[TMP0 :%.*]] = atomicrmw xchg ptr addrspace(200) [[I]], i64 [[VAL]] seq_cst, align 8
178+ // PURECAP32-NEXT: ret i64 [[TMP0 ]]
184179//
185180// HYBRID32-LABEL: define {{[^@]+}}@xchg_i128
186181// HYBRID32-SAME: (ptr noundef [[I:%.*]], i64 noundef [[VAL:%.*]]) #[[ATTR0]] {
@@ -190,7 +185,7 @@ __intcap xchg_cap(__intcap* i, __intcap val) {
190185//
191186cap_size_int xchg_i128 (cap_size_int * i , cap_size_int val ) {
192187 return __atomic_exchange_n (i , val , __ATOMIC_SEQ_CST );
193- // expected -warning@-1{{large atomic operation may incur significant performance penalty}}
188+ // hybrid -warning@-1{{large atomic operation may incur significant performance penalty}}
194189}
195190
196191// PURECAP64-LABEL: define {{[^@]+}}@lock_free_long
@@ -223,8 +218,7 @@ _Bool lock_free_long(long* l) {
223218// PURECAP64-LABEL: define {{[^@]+}}@lock_free_cap
224219// PURECAP64-SAME: (ptr addrspace(200) noundef [[I:%.*]]) addrspace(200) #[[ATTR0]] {
225220// PURECAP64-NEXT: entry:
226- // PURECAP64-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr addrspace(200) noundef [[I]])
227- // PURECAP64-NEXT: ret i1 [[CALL]]
221+ // PURECAP64-NEXT: ret i1 true
228222//
229223// HYBRID64-LABEL: define {{[^@]+}}@lock_free_cap
230224// HYBRID64-SAME: (ptr noundef [[I:%.*]]) #[[ATTR0]] {
@@ -235,8 +229,7 @@ _Bool lock_free_long(long* l) {
235229// PURECAP32-LABEL: define {{[^@]+}}@lock_free_cap
236230// PURECAP32-SAME: (ptr addrspace(200) noundef [[I:%.*]]) addrspace(200) #[[ATTR0]] {
237231// PURECAP32-NEXT: entry:
238- // PURECAP32-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_is_lock_free(i32 noundef 8, ptr addrspace(200) noundef [[I]])
239- // PURECAP32-NEXT: ret i1 [[CALL]]
232+ // PURECAP32-NEXT: ret i1 true
240233//
241234// HYBRID32-LABEL: define {{[^@]+}}@lock_free_cap
242235// HYBRID32-SAME: (ptr noundef [[I:%.*]]) #[[ATTR0]] {
@@ -245,17 +238,17 @@ _Bool lock_free_long(long* l) {
245238// HYBRID32-NEXT: ret i1 [[CALL]]
246239//
247240_Bool lock_free_cap (__intcap * i ) {
248- // TODO: _Static_assert(__atomic_always_lock_free(sizeof(*i), 0), "");
241+ #ifdef __CHERI_PURE_CAPABILITY__
242+ _Static_assert (__atomic_always_lock_free (sizeof (* i ), 0 ), "" );
243+ #endif
249244 return __atomic_is_lock_free (sizeof (* i ), i );
250245}
251246
252247//
253- // FIXME: should return true here
254248// PURECAP64-LABEL: define {{[^@]+}}@lock_free_i128
255249// PURECAP64-SAME: (ptr addrspace(200) noundef [[I:%.*]]) addrspace(200) #[[ATTR0]] {
256250// PURECAP64-NEXT: entry:
257- // PURECAP64-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr addrspace(200) noundef [[I]])
258- // PURECAP64-NEXT: ret i1 [[CALL]]
251+ // PURECAP64-NEXT: ret i1 true
259252//
260253// HYBRID64-LABEL: define {{[^@]+}}@lock_free_i128
261254// HYBRID64-SAME: (ptr noundef [[I:%.*]]) #[[ATTR0]] {
@@ -266,8 +259,7 @@ _Bool lock_free_cap(__intcap* i) {
266259// PURECAP32-LABEL: define {{[^@]+}}@lock_free_i128
267260// PURECAP32-SAME: (ptr addrspace(200) noundef [[I:%.*]]) addrspace(200) #[[ATTR0]] {
268261// PURECAP32-NEXT: entry:
269- // PURECAP32-NEXT: [[CALL:%.*]] = call zeroext i1 @__atomic_is_lock_free(i32 noundef 8, ptr addrspace(200) noundef [[I]])
270- // PURECAP32-NEXT: ret i1 [[CALL]]
262+ // PURECAP32-NEXT: ret i1 true
271263//
272264// HYBRID32-LABEL: define {{[^@]+}}@lock_free_i128
273265// HYBRID32-SAME: (ptr noundef [[I:%.*]]) #[[ATTR0]] {
@@ -276,6 +268,8 @@ _Bool lock_free_cap(__intcap* i) {
276268// HYBRID32-NEXT: ret i1 [[CALL]]
277269//
278270_Bool lock_free_i128 (cap_size_int * i ) {
279- // TODO: _Static_assert(__atomic_always_lock_free(sizeof(*i), 0), "");
271+ #ifdef __CHERI_PURE_CAPABILITY__
272+ _Static_assert (__atomic_always_lock_free (sizeof (* i ), 0 ), "" );
273+ #endif
280274 return __atomic_is_lock_free (sizeof (* i ), i );
281275}
0 commit comments