1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %cheri_cc1 -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix N64
3 // RUN: %cheri_purecap_cc1 -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix PURECAP
4 typedef struct {
5   _Bool volatile repr;
6 } atomic_b_t;
7 
8 atomic_b_t value;
9 // N64-LABEL: @atomic_compare_exchange_weak_b(
10 // N64-NEXT:  entry:
11 // N64-NEXT:    [[EXPECTED_ADDR:%.*]] = alloca i8, align 1
12 // N64-NEXT:    [[DESIRED_ADDR:%.*]] = alloca i8, align 1
13 // N64-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[EXPECTED:%.*]] to i8
14 // N64-NEXT:    store i8 [[FROMBOOL]], i8* [[EXPECTED_ADDR]], align 1
15 // N64-NEXT:    [[FROMBOOL1:%.*]] = zext i1 [[DESIRED:%.*]] to i8
16 // N64-NEXT:    store i8 [[FROMBOOL1]], i8* [[DESIRED_ADDR]], align 1
17 // N64-NEXT:    [[TMP0:%.*]] = load i8, i8* [[EXPECTED_ADDR]], align 1
18 // N64-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1
19 // N64-NEXT:    [[TMP1:%.*]] = load i8, i8* [[DESIRED_ADDR]], align 1
20 // N64-NEXT:    [[TOBOOL2:%.*]] = trunc i8 [[TMP1]] to i1
21 // N64-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[TOBOOL]] to i8
22 // N64-NEXT:    [[FROMBOOL4:%.*]] = zext i1 [[TOBOOL2]] to i8
23 // N64-NEXT:    [[TMP2:%.*]] = cmpxchg i8* getelementptr inbounds (%struct.atomic_b_t, %struct.atomic_b_t* @value, i32 0, i32 0), i8 [[FROMBOOL3]], i8 [[FROMBOOL4]] seq_cst seq_cst
24 // N64-NEXT:    [[TMP3:%.*]] = extractvalue { i8, i1 } [[TMP2]], 0
25 // N64-NEXT:    [[TOBOOL5:%.*]] = trunc i8 [[TMP3]] to i1
26 // N64-NEXT:    ret i1 [[TOBOOL5]]
27 //
28 // PURECAP-LABEL: @atomic_compare_exchange_weak_b(
29 // PURECAP-NEXT:  entry:
30 // PURECAP-NEXT:    [[EXPECTED_ADDR:%.*]] = alloca i8, align 1, addrspace(200)
31 // PURECAP-NEXT:    [[DESIRED_ADDR:%.*]] = alloca i8, align 1, addrspace(200)
32 // PURECAP-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[EXPECTED:%.*]] to i8
33 // PURECAP-NEXT:    store i8 [[FROMBOOL]], i8 addrspace(200)* [[EXPECTED_ADDR]], align 1
34 // PURECAP-NEXT:    [[FROMBOOL1:%.*]] = zext i1 [[DESIRED:%.*]] to i8
35 // PURECAP-NEXT:    store i8 [[FROMBOOL1]], i8 addrspace(200)* [[DESIRED_ADDR]], align 1
36 // PURECAP-NEXT:    [[TMP0:%.*]] = load i8, i8 addrspace(200)* [[EXPECTED_ADDR]], align 1
37 // PURECAP-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1
38 // PURECAP-NEXT:    [[TMP1:%.*]] = load i8, i8 addrspace(200)* [[DESIRED_ADDR]], align 1
39 // PURECAP-NEXT:    [[TOBOOL2:%.*]] = trunc i8 [[TMP1]] to i1
40 // PURECAP-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[TOBOOL]] to i8
41 // PURECAP-NEXT:    [[FROMBOOL4:%.*]] = zext i1 [[TOBOOL2]] to i8
42 // PURECAP-NEXT:    [[TMP2:%.*]] = cmpxchg i8 addrspace(200)* getelementptr inbounds (%struct.atomic_b_t, [[STRUCT_ATOMIC_B_T:%.*]] addrspace(200)* @value, i32 0, i32 0), i8 [[FROMBOOL3]], i8 [[FROMBOOL4]] seq_cst seq_cst
43 // PURECAP-NEXT:    [[TMP3:%.*]] = extractvalue { i8, i1 } [[TMP2]], 0
44 // PURECAP-NEXT:    [[TOBOOL5:%.*]] = trunc i8 [[TMP3]] to i1
45 // PURECAP-NEXT:    ret i1 [[TOBOOL5]]
46 //
atomic_compare_exchange_weak_b(_Bool expected,_Bool desired)47 _Bool atomic_compare_exchange_weak_b(_Bool expected, _Bool desired) {
48   return __sync_val_compare_and_swap(&value.repr, expected, desired);
49 }
50 
51 // N64-LABEL: @atomic_swap_b(
52 // N64-NEXT:  entry:
53 // N64-NEXT:    [[DESIRED_ADDR:%.*]] = alloca i8, align 1
54 // N64-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[DESIRED:%.*]] to i8
55 // N64-NEXT:    store i8 [[FROMBOOL]], i8* [[DESIRED_ADDR]], align 1
56 // N64-NEXT:    [[TMP0:%.*]] = load i8, i8* [[DESIRED_ADDR]], align 1
57 // N64-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1
58 // N64-NEXT:    [[FROMBOOL1:%.*]] = zext i1 [[TOBOOL]] to i8
59 // N64-NEXT:    [[TMP1:%.*]] = atomicrmw xchg i8* getelementptr inbounds (%struct.atomic_b_t, %struct.atomic_b_t* @value, i32 0, i32 0), i8 [[FROMBOOL1]] seq_cst
60 // N64-NEXT:    [[TOBOOL2:%.*]] = trunc i8 [[TMP1]] to i1
61 // N64-NEXT:    ret i1 [[TOBOOL2]]
62 //
63 // PURECAP-LABEL: @atomic_swap_b(
64 // PURECAP-NEXT:  entry:
65 // PURECAP-NEXT:    [[DESIRED_ADDR:%.*]] = alloca i8, align 1, addrspace(200)
66 // PURECAP-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[DESIRED:%.*]] to i8
67 // PURECAP-NEXT:    store i8 [[FROMBOOL]], i8 addrspace(200)* [[DESIRED_ADDR]], align 1
68 // PURECAP-NEXT:    [[TMP0:%.*]] = load i8, i8 addrspace(200)* [[DESIRED_ADDR]], align 1
69 // PURECAP-NEXT:    [[TOBOOL:%.*]] = trunc i8 [[TMP0]] to i1
70 // PURECAP-NEXT:    [[FROMBOOL1:%.*]] = zext i1 [[TOBOOL]] to i8
71 // PURECAP-NEXT:    [[TMP1:%.*]] = atomicrmw xchg i8 addrspace(200)* getelementptr inbounds (%struct.atomic_b_t, [[STRUCT_ATOMIC_B_T:%.*]] addrspace(200)* @value, i32 0, i32 0), i8 [[FROMBOOL1]] seq_cst
72 // PURECAP-NEXT:    [[TOBOOL2:%.*]] = trunc i8 [[TMP1]] to i1
73 // PURECAP-NEXT:    ret i1 [[TOBOOL2]]
74 //
atomic_swap_b(_Bool desired)75 _Bool atomic_swap_b(_Bool desired) {
76   return __sync_swap(&value.repr, desired);
77 }
78