diff --git a/benchmarks/alloc/test_err_address.c b/benchmarks/alloc/test_err_address.c new file mode 100644 index 0000000000..a17fef3654 --- /dev/null +++ b/benchmarks/alloc/test_err_address.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + pthread_join(t1, NULL); + + free(arr + sizeof(int)); + + return 0; +} diff --git a/benchmarks/alloc/test_err_double_free_1.c b/benchmarks/alloc/test_err_double_free_1.c new file mode 100644 index 0000000000..3109da881d --- /dev/null +++ b/benchmarks/alloc/test_err_double_free_1.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + pthread_join(t1, NULL); + + free(arr); + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test_err_double_free_2.c b/benchmarks/alloc/test_err_double_free_2.c new file mode 100644 index 0000000000..1c84d0afa9 --- /dev/null +++ b/benchmarks/alloc/test_err_double_free_2.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + arr[0] = 0; + arr[1] = 1; + + free(arr); + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test_err_no_alloc_1.c b/benchmarks/alloc/test_err_no_alloc_1.c new file mode 100644 index 0000000000..f1e57acdcd --- /dev/null +++ b/benchmarks/alloc/test_err_no_alloc_1.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + free(arr); + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr; + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + pthread_join(t1, NULL); + + return 0; +} diff --git a/benchmarks/alloc/test_err_no_alloc_2.c b/benchmarks/alloc/test_err_no_alloc_2.c new file mode 100644 index 0000000000..a16f3a5600 --- /dev/null +++ b/benchmarks/alloc/test_err_no_alloc_2.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr; + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test_err_no_free.c b/benchmarks/alloc/test_err_no_free.c new file mode 100644 index 0000000000..68bcb17b4b --- /dev/null +++ b/benchmarks/alloc/test_err_no_free.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + pthread_join(t1, NULL); + + return 0; +} diff --git a/benchmarks/alloc/test_err_race.c b/benchmarks/alloc/test_err_race.c new file mode 100644 index 0000000000..689dd8e71a --- /dev/null +++ b/benchmarks/alloc/test_err_race.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + free(arr); + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr; + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + arr = malloc(2 * sizeof(int)); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test_err_use_after_free.c b/benchmarks/alloc/test_err_use_after_free.c new file mode 100644 index 0000000000..d382c11a77 --- /dev/null +++ b/benchmarks/alloc/test_err_use_after_free.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + free(arr); + pthread_join(t1, NULL); + + return 0; +} diff --git a/benchmarks/alloc/test_err_use_before_alloc.c b/benchmarks/alloc/test_err_use_before_alloc.c new file mode 100644 index 0000000000..42ce62e0aa --- /dev/null +++ b/benchmarks/alloc/test_err_use_before_alloc.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr; + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + arr = malloc(2 * sizeof(int)); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test_ok_1.c b/benchmarks/alloc/test_ok_1.c new file mode 100644 index 0000000000..bb7a8f189a --- /dev/null +++ b/benchmarks/alloc/test_ok_1.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + arr[0] = 0; + arr[1] = 1; + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + pthread_join(t1, NULL); + + free(arr); + + return 0; +} diff --git a/benchmarks/alloc/test_ok_2.c b/benchmarks/alloc/test_ok_2.c new file mode 100644 index 0000000000..c6416876d3 --- /dev/null +++ b/benchmarks/alloc/test_ok_2.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +void *thread_1(void *arg) +{ + int *arr = *((int**)arg); + arr[0] = 0; + arr[1] = 1; + + free(arr); + + return NULL; +} + +int main() +{ + pthread_t t1; + int *arr = malloc(2 * sizeof(int)); + + pthread_create(&t1, NULL, thread_1, (void*)&arr); + pthread_join(t1, NULL); + + return 0; +} diff --git a/benchmarks/lfds/dglm.c b/benchmarks/lfds/dglm.c index 433433e070..3bb9054cc3 100644 --- a/benchmarks/lfds/dglm.c +++ b/benchmarks/lfds/dglm.c @@ -12,13 +12,13 @@ void *worker(void *arg) intptr_t index = ((intptr_t) arg); - enqueue(index); + enqueue(index); int r = dequeue(); - assert(r != EMPTY); - data[r] = 1; + assert(r != EMPTY); + data[r] = 1; - return NULL; + return NULL; } int main() diff --git a/benchmarks/lfds/dglm.h b/benchmarks/lfds/dglm.h index cdfd845a7b..07f4768375 100644 --- a/benchmarks/lfds/dglm.h +++ b/benchmarks/lfds/dglm.h @@ -11,8 +11,8 @@ #define EMPTY -1 typedef struct Node { - int val; - _Atomic(struct Node*) next; + int val; + _Atomic(struct Node*) next; } Node; _Atomic(Node *) Tail; @@ -20,53 +20,53 @@ _Atomic(Node *) Head; void init() { - Node* node = malloc(sizeof (Node)); - atomic_init(&node->next, NULL); - atomic_init(&Head, node); - atomic_init(&Tail, node); + Node* node = malloc(sizeof (Node)); + atomic_init(&node->next, NULL); + atomic_init(&Head, node); + atomic_init(&Tail, node); } void enqueue(int value) { - Node *tail, *next, *node; + Node *tail, *next, *node; node = malloc(sizeof (Node)); - node->val = value; - atomic_init(&node->next, NULL); + node->val = value; + atomic_init(&node->next, NULL); - while (1) { - tail = atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE); + while (1) { + tail = atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE); assert(tail != NULL); - next = atomic_load_explicit(&tail->next, __ATOMIC_ACQUIRE); + next = atomic_load_explicit(&tail->next, __ATOMIC_ACQUIRE); if (tail == atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE)) { if (next == NULL) { - if (CAS(&tail->next, &next, node)) { - CAS(&Tail, &tail, node); - break; + if (CAS(&tail->next, &next, node)) { + CAS(&Tail, &tail, node); + break; } } else { - CAS(&Tail, &tail, next); + CAS(&Tail, &tail, next); } } - } + } } int dequeue() { - Node *head, *next, *tail; - int result; + Node *head, *next, *tail; + int result; - while (1) { - head = atomic_load_explicit(&Head, __ATOMIC_ACQUIRE); + while (1) { + head = atomic_load_explicit(&Head, __ATOMIC_ACQUIRE); assert(head != NULL); - next = atomic_load_explicit(&head->next, __ATOMIC_ACQUIRE); + next = atomic_load_explicit(&head->next, __ATOMIC_ACQUIRE); - if (head == atomic_load_explicit(&Head, __ATOMIC_ACQUIRE)) { - if (next == NULL) { - result = EMPTY; - break; + if (head == atomic_load_explicit(&Head, __ATOMIC_ACQUIRE)) { + if (next == NULL) { + result = EMPTY; + break; - } else { + } else { result = next->val; if (CAS(&Head, &head, next)) { tail = atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE); @@ -74,12 +74,13 @@ int dequeue() { if (head == tail) { CAS(&Tail, &tail, next); } + // retire(head); free(head); break; } - } - } - } + } + } + } - return result; -} \ No newline at end of file + return result; +} diff --git a/benchmarks/lfds/ms.c b/benchmarks/lfds/ms.c index 23a1cb2cc6..0789f0cfab 100644 --- a/benchmarks/lfds/ms.c +++ b/benchmarks/lfds/ms.c @@ -10,12 +10,12 @@ void *worker(void *arg) intptr_t index = ((intptr_t) arg); - enqueue(index); + enqueue(index); int r = dequeue(); - assert(r != EMPTY); + assert(r != EMPTY); - return NULL; + return NULL; } int main() diff --git a/benchmarks/lfds/ms.h b/benchmarks/lfds/ms.h index 3c2445db9a..2aed559572 100644 --- a/benchmarks/lfds/ms.h +++ b/benchmarks/lfds/ms.h @@ -11,8 +11,8 @@ #define EMPTY -1 typedef struct Node { - int val; - _Atomic(struct Node*) next; + int val; + _Atomic(struct Node*) next; } Node; _Atomic(Node *) Tail; @@ -20,65 +20,66 @@ _Atomic(Node *) Head; void init() { - Node* node = malloc(sizeof (Node)); - atomic_init(&node->next, NULL); - atomic_init(&Head, node); - atomic_init(&Tail, node); + Node* node = malloc(sizeof (Node)); + atomic_init(&node->next, NULL); + atomic_init(&Head, node); + atomic_init(&Tail, node); } void enqueue(int value) { - Node *tail, *next, *node; + Node *tail, *next, *node; node = malloc(sizeof (Node)); - node->val = value; - atomic_init(&node->next, NULL); + node->val = value; + atomic_init(&node->next, NULL); - while (1) { - tail = atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE); - assert(tail != NULL); - next = atomic_load_explicit(&tail->next, __ATOMIC_ACQUIRE); + while (1) { + tail = atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE); + assert(tail != NULL); + next = atomic_load_explicit(&tail->next, __ATOMIC_ACQUIRE); - if (tail == atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE)) { - if (next != NULL) { - CAS(&Tail, &tail, next); - } else { - if (CAS(&tail->next, &next, node)) { - CAS(&Tail, &tail, node); - break; - } - } - } - } + if (tail == atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE)) { + if (next != NULL) { + CAS(&Tail, &tail, next); + } else { + if (CAS(&tail->next, &next, node)) { + CAS(&Tail, &tail, node); + break; + } + } + } + } } int dequeue() { - Node *head, *next, *tail; - int result; + Node *head, *next, *tail; + int result; - while (1) { - head = atomic_load_explicit(&Head, __ATOMIC_ACQUIRE); - assert(head != NULL); - tail = atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE); - assert(tail != NULL); - next = atomic_load_explicit(&head->next, __ATOMIC_ACQUIRE); + while (1) { + head = atomic_load_explicit(&Head, __ATOMIC_ACQUIRE); + assert(head != NULL); + tail = atomic_load_explicit(&Tail, __ATOMIC_ACQUIRE); + assert(tail != NULL); + next = atomic_load_explicit(&head->next, __ATOMIC_ACQUIRE); - if (head == atomic_load_explicit(&Head, __ATOMIC_ACQUIRE)) { - if (next == NULL) { - result = EMPTY; - break; - } else { - if (head == tail) { - CAS(&Tail, &tail, next); - } else { - result = next->val; - if (CAS(&Head, &head, next)) { - //retire(head); + if (head == atomic_load_explicit(&Head, __ATOMIC_ACQUIRE)) { + if (next == NULL) { + result = EMPTY; + break; + } else { + if (head == tail) { + CAS(&Tail, &tail, next); + } else { + result = next->val; + if (CAS(&Head, &head, next)) { + // retire(head); + free(head); break; } - } - } - } - } + } + } + } + } - return result; -} \ No newline at end of file + return result; +} diff --git a/benchmarks/lfds/treiber.c b/benchmarks/lfds/treiber.c index 46e3f0512d..bec6d9cf57 100644 --- a/benchmarks/lfds/treiber.c +++ b/benchmarks/lfds/treiber.c @@ -11,12 +11,12 @@ void *worker(void *arg) intptr_t index = ((intptr_t) arg); - push(index); + push(index); int r = pop(); - assert(r != EMPTY); + assert(r != EMPTY); - return NULL; + return NULL; } int main() diff --git a/benchmarks/lfds/treiber.h b/benchmarks/lfds/treiber.h index f86d6bf359..b13006bf8f 100644 --- a/benchmarks/lfds/treiber.h +++ b/benchmarks/lfds/treiber.h @@ -10,14 +10,15 @@ #define EMPTY -1 typedef struct Node { - int val; - _Atomic(struct Node*) next; + int val; + _Atomic(struct Node*) next; } Node; struct { _Atomic(Node*) node; } TOP; + void init() { atomic_init(&TOP.node, NULL); } @@ -47,10 +48,11 @@ int pop() { } else { z = atomic_load_explicit(&y->next, __ATOMIC_ACQUIRE); if (CAS(&TOP.node, &y, z)) { - // retire(y) + // retire(y); + free(y); break; } } } return y->val; -} \ No newline at end of file +} diff --git a/benchmarks/locks/clh_mutex.c b/benchmarks/locks/clh_mutex.c index 1dfb6b51c4..85968b4fc2 100644 --- a/benchmarks/locks/clh_mutex.c +++ b/benchmarks/locks/clh_mutex.c @@ -37,5 +37,7 @@ int main() assert(sum == NTHREADS); + clh_mutex_destroy(&lock); + return 0; } diff --git a/benchmarks/locks/ticket_awnsb_mutex.c b/benchmarks/locks/ticket_awnsb_mutex.c index 3144c557a7..353eac3640 100644 --- a/benchmarks/locks/ticket_awnsb_mutex.c +++ b/benchmarks/locks/ticket_awnsb_mutex.c @@ -37,5 +37,7 @@ int main() assert(sum == NTHREADS); + ticket_awnsb_mutex_destroy(&lock); + return 0; } diff --git a/benchmarks/locks/ticket_awnsb_mutex.h b/benchmarks/locks/ticket_awnsb_mutex.h index adac88b724..1b3a6a8e7d 100644 --- a/benchmarks/locks/ticket_awnsb_mutex.h +++ b/benchmarks/locks/ticket_awnsb_mutex.h @@ -155,7 +155,7 @@ void ticket_awnsb_mutex_init(ticket_awnsb_mutex_t * self, int maxArrayWaiters) atomic_init(&self->ingress, 0); atomic_init(&self->egress, 0); self->maxArrayWaiters = maxArrayWaiters; - self->waitersArray = (_Atomic(awnsb_node_t *)*)malloc(self->maxArrayWaiters*sizeof(awnsb_node_t *)); + self->waitersArray = (_Atomic(awnsb_node_t *)*)malloc(maxArrayWaiters*sizeof(awnsb_node_t *)); __VERIFIER_loop_bound(DEFAULT_MAX_WAITERS+1); for (int i = 0; i < self->maxArrayWaiters; i++) atomic_init(&self->waitersArray[i], NULL); } diff --git a/benchmarks/miscellaneous/pthread.c b/benchmarks/miscellaneous/pthread.c index 4ef68e95a3..049536a180 100644 --- a/benchmarks/miscellaneous/pthread.c +++ b/benchmarks/miscellaneous/pthread.c @@ -38,9 +38,7 @@ void* thread_join(pthread_t id) //define PTHREAD_PRIO_NONE 0 //define PTHREAD_PRIO_INHERIT 1 //define PTHREAD_PRIO_PROTECT 2 -//define PTHREAD_MUTEX_POLICY_FAIRSHARE_NP 1 -//define PTHREAD_MUTEX_POLICY_FIRSTFIT_NP 3 -void mutex_init(pthread_mutex_t* lock, int type, int protocol, int policy, int prioceiling) +void mutex_init(pthread_mutex_t* lock, int type, int protocol, int prioceiling) { int status; int value; @@ -58,11 +56,6 @@ void mutex_init(pthread_mutex_t* lock, int type, int protocol, int policy, int p status = pthread_mutexattr_getprotocol(&attributes, &value); assert(status == 0);// && value == protocol); - status = pthread_mutexattr_setpolicy_np(&attributes, policy); - assert(status == 0); - status = pthread_mutexattr_getpolicy_np(&attributes, &value); - assert(status == 0);// && value == policy); - status = pthread_mutexattr_setprioceiling(&attributes, prioceiling); assert(status == 0); status = pthread_mutexattr_getprioceiling(&attributes, &value); @@ -104,8 +97,8 @@ void mutex_test() pthread_mutex_t mutex0; pthread_mutex_t mutex1; //TODO Add different behavior based on attributes. - mutex_init(&mutex0, PTHREAD_MUTEX_ERRORCHECK, PTHREAD_PRIO_INHERIT, PTHREAD_MUTEX_POLICY_FAIRSHARE_NP, 1); - mutex_init(&mutex1, PTHREAD_MUTEX_RECURSIVE, PTHREAD_PRIO_PROTECT, PTHREAD_MUTEX_POLICY_FIRSTFIT_NP, 2); + mutex_init(&mutex0, PTHREAD_MUTEX_ERRORCHECK, PTHREAD_PRIO_INHERIT, 1); + mutex_init(&mutex1, PTHREAD_MUTEX_RECURSIVE, PTHREAD_PRIO_PROTECT, 2); { mutex_lock(&mutex0); @@ -229,7 +222,7 @@ void* cond_worker(void* message) void cond_test() { void* message = (void*) 42; - mutex_init(&cond_mutex, PTHREAD_MUTEX_NORMAL, PTHREAD_PRIO_NONE, PTHREAD_MUTEX_POLICY_FIRSTFIT_NP, 0); + mutex_init(&cond_mutex, PTHREAD_MUTEX_NORMAL, PTHREAD_PRIO_NONE, 0); cond_init(&cond); pthread_t worker = thread_create(cond_worker, message); @@ -412,10 +405,59 @@ void key_test() //assert(pthread_equal(latest_thread, worker));//TODO add support for destructors } +// -------- detaching threads + +void* detach_test_worker0(void* ignore) +{ + return NULL; +} + +void* detach_test_detach(void* ignore) +{ + int status; + pthread_t w0 = thread_create(detach_test_worker0, NULL); + status = pthread_detach(w0); + assert(status == 0); + + status = pthread_join(w0, NULL); + assert(status != 0); + return NULL; +} + +void* detach_test_attr(void* ignore) +{ + int status; + int detachstate; + pthread_t w0; + pthread_attr_t w0_attr; + status = pthread_attr_init(&w0_attr); + assert(status == 0); + status = pthread_attr_getdetachstate(&w0_attr, &detachstate); + assert(status == 0 && detachstate == PTHREAD_CREATE_JOINABLE); + status = pthread_attr_setdetachstate(&w0_attr, PTHREAD_CREATE_DETACHED); + assert(status == 0); + status = pthread_attr_getdetachstate(&w0_attr, &detachstate); + assert(status == 0 && detachstate == PTHREAD_CREATE_DETACHED); + status = pthread_create(&w0, &w0_attr, detach_test_worker0, NULL); + assert(status == 0); + pthread_attr_destroy(&w0_attr); + + status = pthread_join(w0, NULL); + assert(status != 0); + return NULL; +} + +void detach_test() +{ + thread_create(detach_test_detach, NULL); + thread_create(detach_test_attr, NULL); +} + int main() { mutex_test(); cond_test(); rwlock_test(); key_test(); + detach_test(); } \ No newline at end of file diff --git a/cat/c11.cat b/cat/c11.cat index 168a8e1d1f..e44177acc0 100644 --- a/cat/c11.cat +++ b/cat/c11.cat @@ -100,4 +100,17 @@ flag ~empty dr as unsequenced_race // This SC semantics is proposed in the paper "Overhauling SC atomics in C11 and OpenCL" section 3.2 // The proposal simplifies the Spartial and provide stronger guarantees let scp = ((SC * SC) & (fsb?; (mo | fr | hb); sbf?)) \ id -acyclic scp as Ssimp \ No newline at end of file +acyclic scp as Ssimp + +(* + * Heap memory safety. + * Base relations: + * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer + * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event + *) +flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race +flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free +flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc +flag ~empty (allocmem \ hb) as use-before-alloc +flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free +flag ~empty [domain(ALLOC * TERMINATION)] \ [domain(allocptr)] as alloc-without-free \ No newline at end of file diff --git a/cat/rc11.cat b/cat/rc11.cat index c12efd50c1..5079e71021 100644 --- a/cat/rc11.cat +++ b/cat/rc11.cat @@ -33,4 +33,17 @@ acyclic (po | rf) as no-thin-air let conflict = ext & ((((W * _) | (_ * W)) & loc) \ ((IW * _) | (_ * IW))) let race = conflict \ (A * A) \ hb \ (hb^-1) -flag ~empty race as racy \ No newline at end of file +flag ~empty race as racy + +(* + * Heap memory safety. + * Base relations: + * allocptr - relates (ALLOC | FREE) -> (FREE) when both events use the same pointer + * allocmem - relates (ALLOC) -> (M) when the second event accesses the memory allocated by the first event + *) +flag ~empty (((ALLOC * FREE) & allocptr) \ hb) as alloc-race +flag ~empty (((FREE * FREE) \ id) & allocptr) as double-free +flag ~empty ([FREE] \ [range(allocptr & (ALLOC * FREE))]) as free-without-alloc +flag ~empty (allocmem \ hb) as use-before-alloc +flag ~empty ((allocmem^-1 ; (allocptr & (ALLOC * FREE))) \ hb) as use-after-free +flag ~empty [domain(ALLOC * TERMINATION)] \ [domain(allocptr)] as alloc-without-free \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/LazyEncodeSets.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/LazyEncodeSets.java index b051493c02..d87711e22a 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/LazyEncodeSets.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/LazyEncodeSets.java @@ -96,6 +96,16 @@ public Boolean visitCASDependency(CASDependency definition) { return doUpdateSelf(definition); } + @Override + public Boolean visitAllocPtr(AllocPtr definition) { + return doUpdateSelf(definition); + } + + @Override + public Boolean visitAllocMem(AllocMem definition) { + return doUpdateSelf(definition); + } + @Override public Boolean visitLinuxCriticalSections(LinuxCriticalSections definition) { return doUpdateSelf(definition); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/ProgramEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/ProgramEncoder.java index b0a6a22432..3317fe54a2 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/ProgramEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/ProgramEncoder.java @@ -199,7 +199,7 @@ public BooleanFormula encodeControlFlow() { List enc = new ArrayList<>(); for(Thread t : program.getThreads()){ enc.add(encodeConsistentThreadCF(t)); - if (IRHelper.isInitThread(t)) { + if (IRHelper.isAuxiliaryThread(t)) { // Init threads are always progressing enc.add(progressEncoder.encodeFairForwardProgress(t)); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java index bee7460ae5..5e5754b69f 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/PropertyEncoder.java @@ -276,23 +276,13 @@ private TrackableFormula encodeProgramSpecification() { case EXISTS -> PROGRAM_SPEC.getSMTVariable(context); }; if (!ASSERT.equals(program.getSpecificationType())) { - encoding = bmgr.and(encoding, encodeProgramTermination()); + Event termination = program.getThreadEvents(Termination.class).stream().findFirst() + .orElseThrow(() -> new IllegalArgumentException("Malformed program: missing the termination event")); + encoding = bmgr.and(encoding, context.execution(termination)); } return new TrackableFormula(trackingLiteral, encoding); } - private BooleanFormula encodeProgramTermination() { - final BooleanFormulaManager bmgr = context.getBooleanFormulaManager(); - final BooleanFormula exitReached = bmgr.and(program.getThreads().stream() - .map(t -> bmgr.equivalence(context.execution(t.getEntry()), context.execution(t.getExit()))) - .toList()); - final BooleanFormula terminated = program.getThreadEventsWithAllTags(Tag.NONTERMINATION).stream() - .map(CondJump.class::cast) - .map(jump -> bmgr.not(context.jumpTaken(jump))) - .reduce(bmgr.makeTrue(), bmgr::and); - return bmgr.and(exitReached, terminated); - } - // ====================================================================== // ====================================================================== // ======================== CAT Specification ========================== diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java index fbd4a324cf..3d01a0a9fd 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/encoding/WmmEncoder.java @@ -2,15 +2,12 @@ import com.dat3m.dartagnan.configuration.Arch; import com.dat3m.dartagnan.expression.Expression; +import com.dat3m.dartagnan.expression.ExpressionFactory; import com.dat3m.dartagnan.expression.integers.IntLiteral; import com.dat3m.dartagnan.program.Program; import com.dat3m.dartagnan.program.analysis.ReachingDefinitionsAnalysis; import com.dat3m.dartagnan.program.event.*; -import com.dat3m.dartagnan.program.event.core.Load; -import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; -import com.dat3m.dartagnan.program.event.core.NamedBarrier; -import com.dat3m.dartagnan.program.event.core.RMWStoreExclusive; -import com.dat3m.dartagnan.program.event.core.InstructionBoundary; +import com.dat3m.dartagnan.program.event.core.*; import com.dat3m.dartagnan.smt.ModelExt; import com.dat3m.dartagnan.utils.Utils; import com.dat3m.dartagnan.utils.dependable.DependencyGraph; @@ -33,10 +30,7 @@ import org.sosy_lab.common.configuration.InvalidConfigurationException; import org.sosy_lab.common.configuration.Option; import org.sosy_lab.common.configuration.Options; -import org.sosy_lab.java_smt.api.BooleanFormula; -import org.sosy_lab.java_smt.api.BooleanFormulaManager; -import org.sosy_lab.java_smt.api.IntegerFormulaManager; -import org.sosy_lab.java_smt.api.NumeralFormula; +import org.sosy_lab.java_smt.api.*; import java.util.*; import java.util.stream.Collectors; @@ -696,6 +690,43 @@ public Void visitCoherence(Coherence coDef) { return null; } + @Override + public Void visitAllocPtr(AllocPtr def) { + final Relation rel = def.getDefinedRelation(); + EncodingContext.EdgeEncoder edge = context.edge(rel); + final ExpressionEncoder exprEncoder = context.getExpressionEncoder(); + encodeSets.get(rel).apply((e1, e2) -> { + TypedFormula ptr1 = (e1 instanceof MemAlloc alloc) + ? context.result(alloc) + : exprEncoder.encodeAt(((MemFree)e1).getAddress(), e1); + TypedFormula ptr2 = exprEncoder.encodeAt(((MemFree) e2).getAddress(), e2); + enc.add(bmgr.equivalence(edge.encode(e1, e2), bmgr.and( + execution(e1, e2), + exprEncoder.equal(ptr1, ptr2)))); + }); + return null; + } + + @Override + public Void visitAllocMem(AllocMem def) { + final Relation rel = def.getDefinedRelation(); + EncodingContext.EdgeEncoder edge = context.edge(rel); + final ExpressionEncoder exprEncoder = context.getExpressionEncoder(); + final ExpressionFactory exprs = context.getExpressionFactory(); + encodeSets.get(rel).apply((e1, e2) -> { + TypedFormula minAddress = context.result((MemAlloc)e1); + TypedFormula size = exprEncoder.encodeAt(((MemAlloc) e1).getAllocationSize(), e1); + TypedFormula maxAddress = exprEncoder.encodeFinal(exprs.makeAdd(minAddress, size)); + TypedFormula address = context.address((MemoryCoreEvent) e2); + enc.add(bmgr.equivalence(edge.encode(e1, e2), bmgr.and( + execution(e1, e2), + (BooleanFormula) exprEncoder.encodeFinal(exprs.makeGTE(address, minAddress, false)).formula(), + (BooleanFormula) exprEncoder.encodeFinal(exprs.makeGT(maxAddress, address, false)).formula() + ))); + }); + return null; + } + @Override public Void visitSyncBarrier(SyncBar syncBar) { final Relation rel = syncBar.getDefinedRelation(); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/IRHelper.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/IRHelper.java index a111e61bd0..bba81817fc 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/IRHelper.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/IRHelper.java @@ -9,6 +9,7 @@ import com.dat3m.dartagnan.program.event.RegWriter; import com.dat3m.dartagnan.program.event.core.CondJump; import com.dat3m.dartagnan.program.event.core.Init; +import com.dat3m.dartagnan.program.event.core.Termination; import com.dat3m.dartagnan.program.event.functions.AbortIf; import com.dat3m.dartagnan.program.event.functions.Return; import com.dat3m.dartagnan.program.event.lang.llvm.LlvmCmpXchg; @@ -22,8 +23,9 @@ public class IRHelper { private IRHelper() {} - public static boolean isInitThread(Thread thread) { - return thread.getEntry().getSuccessor() instanceof Init; + public static boolean isAuxiliaryThread(Thread thread) { + final Event successor = thread.getEntry().getSuccessor(); + return (successor instanceof Init) || (successor instanceof Termination); } public static boolean isBackJump(CondJump jump) { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/Program.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/Program.java index a9fe96555c..680be53f0b 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/Program.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/Program.java @@ -19,7 +19,7 @@ public class Program { private static final TypeFactory types = TypeFactory.getInstance(); - private static final FunctionType initThreadType = types.getFunctionType(types.getVoidType(), List.of()); + private static final FunctionType auxiliaryThreadType = types.getFunctionType(types.getVoidType(), List.of()); public enum SourceLanguage { LITMUS, LLVM, SPV } @@ -204,7 +204,7 @@ public void addInit(MemoryObject object, int offset) { final List paramNames = List.of(); // NOTE: We use different names to avoid symmetry detection treating all inits as symmetric. final String threadName = "Init_" + nextThreadId; - final Thread thread = new Thread(threadName, initThreadType, paramNames, nextThreadId, + final Thread thread = new Thread(threadName, auxiliaryThreadType, paramNames, nextThreadId, EventFactory.newThreadStart(null)); final Event init = EventFactory.newInit(object, offset); thread.append(init); @@ -215,6 +215,15 @@ public void addInit(MemoryObject object, int offset) { addThread(thread); } + public void addTerminationThread() { + final List paramNames = List.of(); + final Thread thread = new Thread("Termination", auxiliaryThreadType, paramNames, nextThreadId, + EventFactory.newThreadStart(null)); + thread.append(EventFactory.newTerminationEvent()); + thread.append(EventFactory.newLabel("END_OF_T" + thread.getId())); + addThread(thread); + } + // Unrolling // ----------------------------------------------------------------------------------------------------------------- diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/ThreadHierarchy.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/ThreadHierarchy.java index edd36d2c5c..1d7551cd85 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/ThreadHierarchy.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/ThreadHierarchy.java @@ -8,7 +8,7 @@ import java.util.List; import java.util.stream.Collectors; -import static com.dat3m.dartagnan.program.IRHelper.isInitThread; +import static com.dat3m.dartagnan.program.IRHelper.isAuxiliaryThread; public interface ThreadHierarchy { String getScope(); @@ -47,7 +47,7 @@ private static String getScopeChain(ThreadHierarchy node) { } static ThreadHierarchy from(Program program) { - final List threads = program.getThreads().stream().filter(t -> !isInitThread(t)).toList(); + final List threads = program.getThreads().stream().filter(t -> !isAuxiliaryThread(t)).toList(); final Group root = new Group("__root", 0, null, new ArrayList<>()); final List scopes; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/ExecutionAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/ExecutionAnalysis.java index 735d12f110..f6ff8d12cb 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/ExecutionAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/ExecutionAnalysis.java @@ -75,7 +75,7 @@ public boolean isImplied(Event start, Event implied) { case OBE -> isSameThread(start, implied); case HSA_OBE -> (implied.getThread() == lowestIdThread || isSameThread(start, implied)); case LOBE -> start.getThread().getId() >= implied.getThread().getId() - && !IRHelper.isInitThread(start.getThread()); + && !IRHelper.isAuxiliaryThread(start.getThread()); case UNFAIR -> strongestImplication; // FALSE }; return implication; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java index 51453e28dd..dbb78b69ca 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AliasAnalysis.java @@ -4,9 +4,8 @@ import com.dat3m.dartagnan.configuration.Arch; import com.dat3m.dartagnan.expression.type.TypeFactory; import com.dat3m.dartagnan.program.Program; -import com.dat3m.dartagnan.program.event.MemoryEvent; -import com.dat3m.dartagnan.program.event.core.Init; -import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; +import com.dat3m.dartagnan.program.Thread; +import com.dat3m.dartagnan.program.event.core.*; import com.dat3m.dartagnan.program.event.metadata.SourceLocation; import com.dat3m.dartagnan.utils.Utils; import com.dat3m.dartagnan.verification.Context; @@ -23,6 +22,7 @@ import java.io.FileWriter; import java.io.IOException; import java.util.*; +import java.util.stream.Collectors; import static com.dat3m.dartagnan.GlobalSettings.getOrCreateOutputDirectory; import static com.dat3m.dartagnan.configuration.OptionNames.*; @@ -35,6 +35,10 @@ public interface AliasAnalysis { boolean mayAlias(MemoryCoreEvent a, MemoryCoreEvent b); + boolean mustObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b); + + boolean mayObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b); + /** * Returns an overapproximation of the MSA points in the byte range of the specified event. *

@@ -140,6 +144,16 @@ public boolean mayAlias(MemoryCoreEvent a, MemoryCoreEvent b) { return a1.mayAlias(a, b) && a2.mayAlias(a, b); } + @Override + public boolean mustObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return a1.mustObjectAlias(a, b) || a2.mustObjectAlias(a, b); + } + + @Override + public boolean mayObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return a1.mayObjectAlias(a, b) && a2.mayObjectAlias(a, b); + } + @Override public List mayMixedSizeAccesses(MemoryCoreEvent a) { final List set1 = a1.mayMixedSizeAccesses(a); @@ -163,39 +177,103 @@ default Graphviz getGraphVisualization() { return null; } - private Graphviz defaultGraph(Program program, Config configuration) { - // Nodes represent sets of events. - // A solid line marks the existence of events that must alias. - // A dashed line marks the existence of events that may alias. - final Map> mayGraph = new HashMap<>(); - final Map> mustGraph = new HashMap<>(); - final List events = program.getThreadEvents(MemoryCoreEvent.class); - for (final MemoryCoreEvent event1 : events) { + private void populateAddressGraph(Map> may, Map> must, + List list1, List list2, + Config configuration) { + for (final MemoryCoreEvent event1 : list1) { final String node1 = repr(event1, configuration); if (node1 == null) { continue; } - final Set maySet = mayGraph.computeIfAbsent(node1, k -> new HashSet<>()); - final Set mustSet = mustGraph.computeIfAbsent(node1, k -> new HashSet<>()); - for (final MemoryCoreEvent event2 : events) { + final Set maySet = may.computeIfAbsent(node1, k -> new HashSet<>()); + final Set mustSet = must.computeIfAbsent(node1, k -> new HashSet<>()); + for (final MemoryCoreEvent event2 : list2) { final String node2 = repr(event2, configuration); - if (node2 != null && node1.compareTo(node2) < 0 && mayAlias(event1, event2)) { + if ((!(event1 instanceof MemFree) && !(event2 instanceof MemFree)) + || (event1 instanceof MemFree && event2 instanceof MemFree)) { + if (event1.getGlobalId() - event2.getGlobalId() >= 0) { + continue; + } + } + if (node2 != null && mayAlias(event1, event2)) { (mustAlias(event1, event2) ? mustSet : maySet).add(node2); } } maySet.removeAll(mustSet); } + } + + private void populateObjectGraph(Map> may, Map> must, + List allocs, List events, Config configuration) { + for (final MemAlloc alloc : allocs) { + final String node1 = repr(alloc, configuration); + final Set maySet = may.computeIfAbsent(node1, k -> new HashSet<>()); + final Set mustSet = must.computeIfAbsent(node1, k -> new HashSet<>()); + for (final MemoryCoreEvent event : events) { + final String node2 = repr(event, configuration); + if (node2 != null && mayObjectAlias(alloc, event)) { + (mustObjectAlias(alloc, event) ? mustSet : maySet).add(node2); + } + } + maySet.removeAll(mustSet); + } + } + + private Graphviz defaultGraph(Program program, Config configuration) { + // Nodes represent sets of events. + // A solid blue line marks the existence of events that must address-alias. + final Map> mustAddressGraph = new HashMap<>(); + // A dashed blue line marks the existence of events that may address-alias. + final Map> mayAddressGraph = new HashMap<>(); + // A solid orange line marks the existence of events that must object-alias. + final Map> mustObjectGraph = new HashMap<>(); + // A dashed orange line marks the existence of events that may object-alias. + final Map> mayObjectGraph = new HashMap<>(); + + final List events = program.getThreadEvents(MemoryCoreEvent.class) + .stream().filter(e -> !(e instanceof MemFree) && !(e instanceof MemAlloc)) + .collect(Collectors.toList()); + final List allocs = program.getThreadEvents(MemAlloc.class); + final List frees = program.getThreadEvents(MemFree.class); + + populateAddressGraph(mayAddressGraph, mustAddressGraph, events, events, configuration); + populateAddressGraph(mayAddressGraph, mustAddressGraph, frees, frees, configuration); + populateAddressGraph(mayAddressGraph, mustAddressGraph, allocs, frees, configuration); + + populateObjectGraph(mayObjectGraph, mustObjectGraph, allocs, events, configuration); // Generates the graphs final var graphviz = new Graphviz(); graphviz.beginGraph("alias"); - graphviz.beginSubgraph("may alias"); + for (final Thread thread : program.getThreads()) { + graphviz.beginSubgraph("Thread" + thread.getId()); + graphviz.setEdgeAttributes("weight=100", "style=invis"); + final List memEvents = thread.getEvents(MemoryCoreEvent.class); + for (int i = 1; i < memEvents.size(); i++) { + final String node1 = repr(memEvents.get(i - 1), configuration); + final String node2 = repr(memEvents.get(i), configuration); + if (node1 == null || node2 == null) { + continue; + } + graphviz.addEdge(node1, node2); + } + graphviz.end(); + } + graphviz.beginSubgraph("may address alias"); graphviz.setEdgeAttributes("color=mediumslateblue", "style=dashed"); - graphviz.addEdges(mayGraph); + graphviz.addEdges(mayAddressGraph); graphviz.end(); - graphviz.beginSubgraph("must alias"); + graphviz.beginSubgraph("must address alias"); graphviz.setEdgeAttributes("color=mediumslateblue"); - graphviz.addEdges(mustGraph); + graphviz.addEdges(mustAddressGraph); + graphviz.end(); + graphviz.beginSubgraph("may object alias"); + graphviz.setEdgeAttributes("color=orangered", "style=dashed"); + graphviz.addEdges(mayObjectGraph); + graphviz.end(); + graphviz.beginSubgraph("must object alias"); + graphviz.setEdgeAttributes("color=orangered"); + graphviz.addEdges(mustObjectGraph); graphviz.end(); graphviz.end(); return graphviz; @@ -220,16 +298,21 @@ private void generateGraph(Program program, Config configuration) { } } - private static String repr(MemoryEvent event, Config configuration) { + private static String repr(MemoryCoreEvent event, Config configuration) { if (!configuration.graphvizShowAll && event instanceof Init) { return null; } + final String type = event instanceof Load ? ": R" + : event instanceof Store ? ": W" + : event instanceof MemAlloc ? ": A" + : event instanceof MemFree ? ": F" + : ""; final SourceLocation location = event.getMetadata(SourceLocation.class); if (configuration.graphvizSplitByThread) { - return location != null ? "\"T" + event.getThread().getId() + esc(location) + "\"" : - "\"T" + event.getThread().getId() + "E" + event.getGlobalId() + "\""; + return location != null ? "\"T" + event.getThread().getId() + esc(location) + type + "\"" : + "\"T" + event.getThread().getId() + "E" + event.getGlobalId() + type + "\""; } - return location != null ? "\"" + esc(location) + "\"" : "\"E" + event.getGlobalId() + "\""; + return location != null ? "\"" + esc(location) + type + "\"" : "\"E" + event.getGlobalId() + type + "\""; } private static String esc(Object object) { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java index 5cceb71159..57a622993e 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/AndersenAliasAnalysis.java @@ -9,9 +9,7 @@ import com.dat3m.dartagnan.program.analysis.SyntacticContextAnalysis; import com.dat3m.dartagnan.program.event.MemoryEvent; import com.dat3m.dartagnan.program.event.RegWriter; -import com.dat3m.dartagnan.program.event.core.Local; -import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; -import com.dat3m.dartagnan.program.event.core.Store; +import com.dat3m.dartagnan.program.event.core.*; import com.dat3m.dartagnan.program.memory.MemoryObject; import com.google.common.base.Preconditions; import com.google.common.base.Supplier; @@ -93,7 +91,19 @@ public boolean mayAlias(MemoryCoreEvent x, MemoryCoreEvent y) { @Override public boolean mustAlias(MemoryCoreEvent x, MemoryCoreEvent y) { - return getMaxAddressSet(x).size() == 1 && getMaxAddressSet(x).containsAll(getMaxAddressSet(y)); + Set lx = getMaxAddressSet(x); + return lx.size() == 1 && lx.equals(getMaxAddressSet(y)); + } + + @Override + public boolean mayObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return !Sets.intersection(getAccessibleObjects(a), getAccessibleObjects(b)).isEmpty(); + } + + @Override + public boolean mustObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + Set objsA = getAccessibleObjects(a); + return objsA.size() == 1 && objsA.equals(getAccessibleObjects(b)); } @Override @@ -106,17 +116,28 @@ public List mayMixedSizeAccesses(MemoryCoreEvent event) { return IntStream.range(1, bytes).boxed().toList(); } - private ImmutableSet getMaxAddressSet(MemoryEvent e) { + private ImmutableSet getMaxAddressSet(MemoryCoreEvent e) { return eventAddressSpaceMap.get(e); } + private Set getAccessibleObjects(MemoryCoreEvent e) { + Set objs = new HashSet<>(); + Set locs = getMaxAddressSet(e); + if (locs != null) { + locs.stream().forEach(l -> objs.add(l.base)); + } + return objs; + } + // ================================ Mixed Size Access Detection ================================ private void detectMixedSizeAccesses() { if (!config.detectMixedSizeAccesses) { return; } - final List events = List.copyOf(eventAddressSpaceMap.keySet()); + final List events = eventAddressSpaceMap.keySet().stream() + .filter(e -> !(e instanceof MemAlloc) && !(e instanceof MemFree)) + .collect(Collectors.toList()); final List> offsets = new ArrayList<>(); for (int i = 0; i < events.size(); i++) { final var set0 = new HashSet(); @@ -171,6 +192,17 @@ private void run(Program program) { } private void processLocs(MemoryCoreEvent e) { + if (e instanceof MemFree) { + return; + } + if (e instanceof MemAlloc a) { + Register r = a.getResultRegister(); + Location base = new Location(a.getAllocatedObject(), 0); + eventAddressSpaceMap.put(a, ImmutableSet.of(base)); + addAddress(r, base); + variables.add(r); + return; + } Expression address = e.getAddress(); // Collect for each v events of form: p = *v, *v = q if (address instanceof Register register) { @@ -306,6 +338,9 @@ private void processResults(Local e) { } private void processResults(MemoryCoreEvent e) { + if (e instanceof MemAlloc) { + return; + } Expression address = e.getAddress(); Set addresses; if (address instanceof Register) { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java index 5f95fc360a..16570e6945 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/EqualityAliasAnalysis.java @@ -1,10 +1,13 @@ package com.dat3m.dartagnan.program.analysis.alias; +import com.dat3m.dartagnan.expression.Expression; +import com.dat3m.dartagnan.program.Function; import com.dat3m.dartagnan.program.Program; import com.dat3m.dartagnan.program.Register; import com.dat3m.dartagnan.program.event.Event; import com.dat3m.dartagnan.program.event.RegWriter; import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; +import com.dat3m.dartagnan.wmm.utils.graph.immutable.ImmutableEventGraph; import com.dat3m.dartagnan.wmm.utils.graph.mutable.MapEventGraph; import com.dat3m.dartagnan.wmm.utils.graph.mutable.MutableEventGraph; @@ -24,62 +27,69 @@ public class EqualityAliasAnalysis implements AliasAnalysis { private final Config config; - private final MutableEventGraph trueSet = new MapEventGraph(); - private final MutableEventGraph falseSet = new MapEventGraph(); + private final ImmutableEventGraph trueSet; public static EqualityAliasAnalysis fromConfig(Program program, Config config) { - return new EqualityAliasAnalysis(config); + return new EqualityAliasAnalysis(program, config); } - private EqualityAliasAnalysis(Config c) { + private EqualityAliasAnalysis(Program program, Config c) { config = checkNotNull(c); + // Precompute + final MutableEventGraph tSet = new MapEventGraph(); + for (final Function f : program.getFunctions()) { + final List events = f.getEvents(MemoryCoreEvent.class); + for (int i = 0; i < events.size(); ++i) { + final MemoryCoreEvent a = events.get(i); + for (int j = i + 1; j < events.size(); ++j) { + final MemoryCoreEvent b = events.get(j); + if (a.getAddress().equals(b.getAddress()) && regNotModified(a, b)) { + tSet.add(a, b); + tSet.add(b, a); + } + } + } + } + trueSet = ImmutableEventGraph.from(tSet); + } + + @Override + public boolean mayAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return true; } @Override public boolean mustAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return (a == b) || trueSet.contains(a, b); + } - if (a.getFunction() != b.getFunction() - || !a.getAddress().equals(b.getAddress())) { - return false; - } else if (a == b) { - return true; - } - // Normalize direction - if (a.getGlobalId() > b.getGlobalId()) { - MemoryCoreEvent temp = a; - a = b; - b = temp; - } + @Override + public boolean mayObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return true; + } - // Check cache - if (trueSet.contains(a, b)) { - return true; - } - if (falseSet.contains(a, b)) { - return false; - } + @Override + public boolean mustObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return false; + } + + @Override + public List mayMixedSizeAccesses(MemoryCoreEvent event) { + return config.defaultMayMixedSizeAccesses(event); + } + private boolean regNotModified(MemoryCoreEvent a, MemoryCoreEvent b) { + final Expression addrA = a.getAddress(); + assert (addrA.equals(b.getAddress()) && a.getFunction() == b.getFunction()); // Establish that address expression evaluates to same value at both events. - Set addrRegs = a.getAddress().getRegs(); + Set addrRegs = addrA.getRegs(); Event e = a.getSuccessor(); while (e != b) { if (e instanceof RegWriter rw && addrRegs.contains(rw.getResultRegister())) { - falseSet.add(a, b); return false; } e = e.getSuccessor(); } - trueSet.add(a, b); - return true; - } - - @Override - public boolean mayAlias(MemoryCoreEvent a, MemoryCoreEvent b) { return true; } - - @Override - public List mayMixedSizeAccesses(MemoryCoreEvent event) { - return config.defaultMayMixedSizeAccesses(event); - } } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java index 3fce6dd842..f922d2b721 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/FieldSensitiveAndersen.java @@ -95,7 +95,18 @@ public boolean mayAlias(MemoryCoreEvent x, MemoryCoreEvent y) { @Override public boolean mustAlias(MemoryCoreEvent x, MemoryCoreEvent y) { Set a = getMaxAddressSet(x); - return a.size() == 1 && a.containsAll(getMaxAddressSet(y)); + return a.size() == 1 && a.equals(getMaxAddressSet(y)); + } + + @Override + public boolean mayObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return !Sets.intersection(getAccessibleObjects(a), getAccessibleObjects(b)).isEmpty(); + } + + @Override + public boolean mustObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + Set objsA = getAccessibleObjects(a); + return objsA.size() == 1 && objsA.equals(getAccessibleObjects(b)); } @Override @@ -114,7 +125,9 @@ private void detectMixedSizeAccesses() { if (!config.detectMixedSizeAccesses) { return; } - final List events = List.copyOf(eventAddressSpaceMap.keySet()); + final List events = eventAddressSpaceMap.keySet().stream() + .filter(e -> !(e instanceof MemAlloc) && !(e instanceof MemFree)) + .collect(toList()); final List> offsets = new ArrayList<>(); for (int i = 0; i < events.size(); i++) { final var set0 = new HashSet(); @@ -152,6 +165,15 @@ private ImmutableSet getMaxAddressSet(MemoryCoreEvent e) { return eventAddressSpaceMap.get(e); } + private Set getAccessibleObjects(MemoryCoreEvent e) { + Set objs = new HashSet<>(); + Set locs = getMaxAddressSet(e); + if (locs != null) { + locs.stream().forEach(l -> objs.add(l.base)); + } + return objs; + } + // ================================ Processing ================================ private void run(Program program) { @@ -193,6 +215,8 @@ protected void processLocs(MemoryCoreEvent e) { } addAllAddresses(l, value.address()); } + } else if (e instanceof MemAlloc a) { + eventAddressSpaceMap.put(a, ImmutableSet.of(new Location(a.getAllocatedObject(), 0))); } else { // Special MemoryEvents that produce no values (e.g. SRCU) will just get skipped } @@ -200,7 +224,7 @@ protected void processLocs(MemoryCoreEvent e) { protected void processRegs(Event e) { - if (!(e instanceof Local || e instanceof ThreadArgument || e instanceof Alloc)) { + if (!(e instanceof Local || e instanceof ThreadArgument || e instanceof MemAlloc)) { return; } assert e instanceof RegWriter; @@ -208,7 +232,7 @@ protected void processRegs(Event e) { final Expression expr; if (e instanceof Local local) { expr = local.getExpr(); - } else if (e instanceof Alloc alloc) { + } else if (e instanceof MemAlloc alloc) { expr = alloc.getAllocatedObject(); } else { final ThreadArgument arg = (ThreadArgument) e; @@ -250,6 +274,9 @@ protected void algorithm(Object variable) { } protected void processResults(MemoryCoreEvent e) { + if (e instanceof MemAlloc) { + return; + } ImmutableSet.Builder addresses = ImmutableSet.builder(); Collector collector = new Collector(e.getAddress()); addresses.addAll(collector.address()); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java index 15bdc25849..cfc1c197a4 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/InclusionBasedPointerAnalysis.java @@ -21,12 +21,14 @@ import com.dat3m.dartagnan.witness.graphviz.Graphviz; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +import com.google.common.collect.Sets; import com.google.common.math.IntMath; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.math.BigInteger; import java.util.*; +import java.util.stream.Collectors; import java.util.stream.IntStream; import static com.google.common.base.Preconditions.checkArgument; @@ -90,6 +92,9 @@ public class InclusionBasedPointerAnalysis implements AliasAnalysis { // Maps memory events to variables representing their pointer set. private final Map addressVariables = new HashMap<>(); + // Maps pointer sets to their accessible memory objects. + private final Map> accessibleObjects = new HashMap<>(); + // Maps memory objects to variables representing their base address. // These Variables should always have empty includes-sets. private final Map objectVariables = new HashMap<>(); @@ -192,6 +197,27 @@ public boolean mustAlias(MemoryCoreEvent x, MemoryCoreEvent y) { isConstant(vx.modifier) && isConstant(vy.modifier); } + @Override + public boolean mayObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + final DerivedVariable va = addressVariables.get(a); + final DerivedVariable vb = addressVariables.get(b); + return va == null || vb == null || !Sets.intersection(accessibleObjects.get(va), accessibleObjects.get(vb)).isEmpty(); + } + + @Override + public boolean mustObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + final DerivedVariable va = addressVariables.get(a); + final DerivedVariable vb = addressVariables.get(b); + if (va == null || vb == null) { + return false; + } + if (va.base == vb.base) { + return true; + } + final Set objsA = accessibleObjects.get(va); + return objsA.size() == 1 && objsA.equals(accessibleObjects.get(vb)); + } + @Override public List mayMixedSizeAccesses(MemoryCoreEvent event) { final List result = mixedAccesses.get(event); @@ -205,7 +231,9 @@ public List mayMixedSizeAccesses(MemoryCoreEvent event) { // ================================ Mixed Size Access Detection ================================ private void detectMixedSizeAccesses() { - final List events = List.copyOf(addressVariables.keySet()); + final List events = addressVariables.keySet().stream() + .filter(e -> !(e instanceof MemAlloc) && !(e instanceof MemFree)) + .collect(Collectors.toList()); final List> offsets = new ArrayList<>(); for (int i = 0; i < events.size(); i++) { final MemoryCoreEvent event0 = events.get(i); @@ -270,6 +298,14 @@ public Graphviz getGraphVisualization() { return graphviz; } + private Set getAccessibleObjects(DerivedVariable address) { + final Set objs = new HashSet<>(); + objs.add(address.base.object); + address.base.includes.forEach(i -> objs.add(i.source.object)); + objs.remove(null); + return objs; + } + // ================================ Processing ================================ private void run(Program program, AliasAnalysis.Config configuration) { @@ -304,6 +340,9 @@ private void run(Program program, AliasAnalysis.Config configuration) { for (final Map.Entry entry : addressVariables.entrySet()) { postProcess(entry); } + for (final DerivedVariable v : addressVariables.values()) { + accessibleObjects.computeIfAbsent(v, k -> getAccessibleObjects(v)); + } objectVariables.clear(); registerVariables.clear(); } @@ -314,7 +353,7 @@ private void processWriter(RegWriter event) { logger.trace("{}", event); final Expression expr = event instanceof Local local ? local.getExpr() : event instanceof ThreadArgument arg ? arg.getCreator().getArguments().get(arg.getIndex()) : - event instanceof Alloc alloc ? alloc.getAllocatedObject() : null; + event instanceof MemAlloc alloc ? alloc.getAllocatedObject() : null; final DerivedVariable value; if (expr != null) { final RegReader reader = event instanceof ThreadArgument arg ? arg.getCreator() : (RegReader) event; @@ -348,6 +387,10 @@ private void processWriter(RegWriter event) { // Also propagates communications to loads, if both directly access the same variable. private void processMemoryEvent(MemoryCoreEvent event) { logger.trace("{}", event); + if (event instanceof MemAlloc alloc) { + addressVariables.put(alloc, derive(objectVariables.get(alloc.getAllocatedObject()))); + return; + } if (event instanceof Load) { // event was already processed in processWriter(RegWriter) return; @@ -462,6 +505,7 @@ private void algorithm(Variable variable, List edges) { // This simplifies alias queries and releases memory resources. private void postProcess(Map.Entry entry) { logger.trace("{}", entry); + final MemoryCoreEvent e = entry.getKey(); final DerivedVariable address = entry.getValue(); if (address == null) { // should have already warned about this event @@ -475,7 +519,7 @@ private void postProcess(Map.Entry entry) { // In a well-structured program, all address expressions refer to at least one memory object. if (logger.isWarnEnabled() && address.base.object == null && address.base.includes.stream().allMatch(i -> i.source.object == null)) { - logger.warn("empty pointer set for {}", synContext.get().getContextInfo(entry.getKey())); + logger.warn("empty pointer set for {}", synContext.get().getContextInfo(e)); } if (address.base.includes.size() != 1) { return; @@ -488,11 +532,21 @@ private void postProcess(Map.Entry entry) { if (!includeEdge.source.object.getClass().equals(MemoryObject.class) || !includeEdge.source.object.hasKnownSize()) { return; } - final int accessSize = types.getMemorySizeInBytes(entry.getKey().getAccessType()); - final int remainingSize = includeEdge.source.object.getKnownSize() - modifier.offset - (accessSize - 1); - for (final Integer a : modifier.alignment) { - if (Math.abs(a) < remainingSize || a < 0 && modifier.offset + a >= 0) { - return; + if (e instanceof MemFree) { + final int remainingSize = includeEdge.source.object.getKnownSize() - modifier.offset; + for (final Integer a : modifier.alignment) { + if (a < remainingSize) { + return; + } + } + } else { + assert !(e instanceof MemAlloc); + final int accessSize = types.getMemorySizeInBytes(e.getAccessType()); + final int remainingSize = includeEdge.source.object.getKnownSize() - modifier.offset - (accessSize - 1); + for (final Integer a : modifier.alignment) { + if (Math.abs(a) < remainingSize || a < 0 && modifier.offset + a >= 0) { + return; + } } } entry.setValue(derive(includeEdge.source, modifier.offset, List.of())); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/VirtualAliasAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/VirtualAliasAnalysis.java index ad8a31d8da..b0de6fab89 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/VirtualAliasAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/analysis/alias/VirtualAliasAnalysis.java @@ -22,11 +22,22 @@ public static AliasAnalysis wrap(AliasAnalysis analysis, Config config) { public boolean mayAlias(MemoryCoreEvent e1, MemoryCoreEvent e2) { return samePhysicalAddress(e1, e2) || wrappedAnalysis.mayAlias(e1, e2); } + @Override public boolean mustAlias(MemoryCoreEvent e1, MemoryCoreEvent e2) { return samePhysicalAddress(e1, e2) || wrappedAnalysis.mustAlias(e1, e2); } + @Override + public boolean mayObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return true; + } + + @Override + public boolean mustObjectAlias(MemoryCoreEvent a, MemoryCoreEvent b) { + return false; + } + @Override public List mayMixedSizeAccesses(MemoryCoreEvent event) { return config.defaultMayMixedSizeAccesses(event); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java index 7b61d8feb7..3a87e3d82b 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java @@ -37,12 +37,10 @@ import com.dat3m.dartagnan.program.event.functions.VoidFunctionCall; import com.dat3m.dartagnan.program.event.lang.catomic.*; import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadCreate; +import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadDetach; import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadJoin; import com.dat3m.dartagnan.program.event.lang.linux.*; import com.dat3m.dartagnan.program.event.lang.llvm.*; -import com.dat3m.dartagnan.program.event.lang.pthread.InitLock; -import com.dat3m.dartagnan.program.event.lang.pthread.Lock; -import com.dat3m.dartagnan.program.event.lang.pthread.Unlock; import com.dat3m.dartagnan.program.event.lang.spirv.*; import com.dat3m.dartagnan.program.event.lang.svcomp.*; import com.dat3m.dartagnan.program.memory.MemoryObject; @@ -56,6 +54,7 @@ public class EventFactory { private static final ExpressionFactory expressions = ExpressionFactory.getInstance(); private static final TypeFactory types = TypeFactory.getInstance(); + private static final Termination terminationEvent = new Termination(); // Static class private EventFactory() { @@ -113,17 +112,21 @@ public static Event newTerminator(Function function, String... tags) { // ------------------------------------------ Memory events ------------------------------------------ - public static Alloc newAlloc(Register register, Type allocType, Expression arraySize, + public static MemAlloc newAlloc(Register register, Type allocType, Expression arraySize, boolean isHeapAlloc, boolean doesZeroOutMemory) { final Expression defaultAlignment = expressions.makeValue(8, types.getArchType()); return newAlignedAlloc(register, allocType, arraySize, defaultAlignment, isHeapAlloc, doesZeroOutMemory); } - public static Alloc newAlignedAlloc(Register register, Type allocType, Expression arraySize, Expression alignment, + public static MemAlloc newAlignedAlloc(Register register, Type allocType, Expression arraySize, Expression alignment, boolean isHeapAlloc, boolean doesZeroOutMemory) { arraySize = expressions.makeCast(arraySize, types.getArchType(), false); alignment = expressions.makeCast(alignment, types.getArchType(), false); - return new Alloc(register, allocType, arraySize, alignment, isHeapAlloc, doesZeroOutMemory); + return new MemAlloc(register, allocType, arraySize, alignment, isHeapAlloc, doesZeroOutMemory); + } + + public static MemFree newFree(Expression address) { + return new MemFree(address); } public static Load newLoad(Register register, Expression address) { @@ -174,6 +177,10 @@ public static Init newInit(MemoryObject base, int offset) { return init; } + public static Termination newTerminationEvent() { + return terminationEvent; + } + public static ValueFunctionCall newValueFunctionCall(Register resultRegister, Function function, List arguments) { return new ValueFunctionCall(resultRegister, function.getFunctionType(), function, arguments); } @@ -333,6 +340,10 @@ public static DynamicThreadJoin newDynamicThreadJoin(Register resultRegister, Ex return new DynamicThreadJoin(resultRegister, tidExpr); } + public static DynamicThreadDetach newDynamicThreadDetach(Register statusReg, Expression tidExpr) { + return new DynamicThreadDetach(statusReg, tidExpr); + } + public static ThreadCreate newThreadCreate(List arguments) { return new ThreadCreate(arguments); } @@ -383,28 +394,6 @@ public static Xchg newXchg(Register register, Expression address, Expression sto } } - // ============================================================================================= - // ========================================== Pthread ========================================== - // ============================================================================================= - - public static class Pthread { - private Pthread() { - } - - public static InitLock newInitLock(String name, Expression address, Expression ignoreAttributes) { - //TODO store attributes inside mutex object - return new InitLock(name, address, expressions.makeZero(types.getArchType())); - } - - public static Lock newLock(String name, Expression address) { - return new Lock(name, address); - } - - public static Unlock newUnlock(String name, Expression address) { - return new Unlock(name, address); - } - } - // ============================================================================================= // ========================================== Atomics ========================================== // ============================================================================================= diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventVisitor.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventVisitor.java index 165f9d17a7..7d735fa39e 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventVisitor.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventVisitor.java @@ -17,9 +17,6 @@ import com.dat3m.dartagnan.program.event.lang.catomic.*; import com.dat3m.dartagnan.program.event.lang.linux.*; import com.dat3m.dartagnan.program.event.lang.llvm.*; -import com.dat3m.dartagnan.program.event.lang.pthread.InitLock; -import com.dat3m.dartagnan.program.event.lang.pthread.Lock; -import com.dat3m.dartagnan.program.event.lang.pthread.Unlock; import com.dat3m.dartagnan.program.event.lang.spirv.*; import com.dat3m.dartagnan.program.event.lang.svcomp.BeginAtomic; import com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic; @@ -47,7 +44,7 @@ public interface EventVisitor { default T visitLoad(Load e) { return visitMemCoreEvent(e); } default T visitStore(Store e) { return visitMemCoreEvent(e); } default T visitInit(Init e) { return visitStore(e); } - default T visitAlloc(Alloc e) { return visitEvent(e); } + default T visitAlloc(MemAlloc e) { return visitEvent(e); } // RMW core events default T visitRMWStore(RMWStore e) { return visitStore(e); } default T visitRMWStoreExclusive(RMWStoreExclusive e) { return visitStore(e); } @@ -56,11 +53,6 @@ public interface EventVisitor { // ============================== Language-level events ============================== - // ------------------ Pthread Events ------------------ - default T visitInitLock(InitLock e) { return visitMemEvent(e); } - default T visitLock(Lock e) { return visitMemEvent(e); } - default T visitUnlock(Unlock e) { return visitMemEvent(e); } - // ------------------ Common Events ------------------ default T visitStoreExclusive(StoreExclusive e) { return visitMemEvent(e); } default T visitXchg(Xchg xchg) { return visitMemEvent(xchg); }; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/Tag.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/Tag.java index 83a3ef54c3..8c81baf888 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/Tag.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/Tag.java @@ -22,6 +22,9 @@ private Tag() { } public static final String FENCE = "F"; public static final String STRONG = "STRONG"; // TODO: Maybe move to C11 or IMM? public static final String RMW = "RMW"; + public static final String ALLOC = "ALLOC"; + public static final String FREE = "FREE"; + public static final String TERMINATION = "TERMINATION"; // ---------- Internally used tags (not referenced in CAT) ---------- public static final String EXCL = "__EXCL"; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemAlloc.java similarity index 80% rename from dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java rename to dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemAlloc.java index 60e450ec32..db1bf5abfa 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Alloc.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemAlloc.java @@ -9,23 +9,21 @@ import com.dat3m.dartagnan.expression.type.IntegerType; import com.dat3m.dartagnan.expression.type.TypeFactory; import com.dat3m.dartagnan.program.Register; -import com.dat3m.dartagnan.program.event.AbstractEvent; -import com.dat3m.dartagnan.program.event.EventVisitor; -import com.dat3m.dartagnan.program.event.RegReader; -import com.dat3m.dartagnan.program.event.RegWriter; +import com.dat3m.dartagnan.program.event.*; import com.dat3m.dartagnan.program.memory.MemoryObject; import com.google.common.base.Preconditions; import org.sosy_lab.java_smt.api.BooleanFormula; import java.math.BigInteger; import java.util.HashSet; +import java.util.List; import java.util.Set; /* - Alloc represents any dynamic allocation performed in the program, i.e., both heap and stack allocations. + MemAlloc represents any dynamic allocation performed in the program, i.e., both heap and stack allocations. Each allocation has a type and an array size (equals 1 for simple allocations). */ -public final class Alloc extends AbstractEvent implements RegReader, RegWriter { +public final class MemAlloc extends AbstractMemoryCoreEvent implements RegWriter { private Register resultRegister; private Type allocationType; private Expression arraySize; @@ -36,8 +34,9 @@ public final class Alloc extends AbstractEvent implements RegReader, RegWriter { // This will be set at the end of the program processing. private transient MemoryObject allocatedObject; - public Alloc(Register resultRegister, Type allocType, Expression arraySize, Expression alignment, boolean isHeapAllocation, - boolean doesZeroOutMemory) { + public MemAlloc(Register resultRegister, Type allocType, Expression arraySize, Expression alignment, + boolean isHeapAllocation, boolean doesZeroOutMemory) { + super(resultRegister, TypeFactory.getInstance().getArchType()); Preconditions.checkArgument(resultRegister.getType() == TypeFactory.getInstance().getPointerType()); Preconditions.checkArgument(arraySize.getType() instanceof IntegerType); Preconditions.checkArgument(alignment.getType() instanceof IntegerType); @@ -47,18 +46,26 @@ public Alloc(Register resultRegister, Type allocType, Expression arraySize, Expr this.allocationType = allocType; this.isHeapAllocation = isHeapAllocation; this.doesZeroOutMemory = doesZeroOutMemory; + removeTags(Tag.MEMORY); + if (isHeapAllocation) { + addTags(Tag.VISIBLE, Tag.ALLOC); + } } - private Alloc(Alloc other) { + private MemAlloc(MemAlloc other) { super(other); Preconditions.checkState(other.allocatedObject == null, - "Cannot copy Alloc events after memory allocation was performed."); + "Cannot copy MemAlloc events after memory allocation was performed."); this.resultRegister = other.resultRegister; this.allocationType = other.allocationType; this.arraySize = other.arraySize; this.alignment = other.alignment; this.isHeapAllocation = other.isHeapAllocation; this.doesZeroOutMemory = other.doesZeroOutMemory; + removeTags(Tag.MEMORY); + if (isHeapAllocation) { + addTags(Tag.VISIBLE, Tag.ALLOC); + } } @Override @@ -75,7 +82,10 @@ private Alloc(Alloc other) { public boolean isSimpleAllocation() { return (arraySize instanceof IntLiteral size && size.isOne()); } public boolean isArrayAllocation() { return !isSimpleAllocation(); } - public void setAllocatedObject(MemoryObject obj) { this.allocatedObject = obj; } + public void setAllocatedObject(MemoryObject obj) { + this.allocatedObject = obj; + this.address = obj; + } // WARNING: This should only be accessed after program processing. public MemoryObject getAllocatedObject() { Preconditions.checkState(allocatedObject != null, @@ -122,7 +132,7 @@ protected String defaultString() { } @Override - public Alloc getCopy() { return new Alloc(this); } + public MemAlloc getCopy() { return new MemAlloc(this); } @Override public T accept(EventVisitor visitor) { @@ -136,4 +146,9 @@ public BooleanFormula encodeExec(EncodingContext ctx) { ctx.getExpressionEncoder().equalAt(ctx.result(this), this, getAllocatedObject(), this) ); } + + @Override + public List getMemoryAccesses() { + return List.of(new MemoryAccess(address, accessType, MemoryAccess.Mode.OTHER)); + } } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java new file mode 100644 index 0000000000..b032fb3fa2 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/MemFree.java @@ -0,0 +1,35 @@ +package com.dat3m.dartagnan.program.event.core; + +import com.dat3m.dartagnan.expression.Expression; +import com.dat3m.dartagnan.expression.type.TypeFactory; +import com.dat3m.dartagnan.program.event.MemoryAccess; +import com.dat3m.dartagnan.program.event.Tag; + +import java.util.List; + + +public final class MemFree extends AbstractMemoryCoreEvent { + public MemFree(Expression address) { + super(address, TypeFactory.getInstance().getArchType()); + removeTags(Tag.MEMORY); + addTags(Tag.FREE); + } + + @Override + public MemFree getCopy() { + MemFree other = new MemFree(address); + other.setFunction(this.getFunction()); + other.copyAllMetadataFrom(this); + return other; + } + + @Override + public List getMemoryAccesses() { + return List.of(new MemoryAccess(address, accessType, MemoryAccess.Mode.OTHER)); + } + + @Override + protected String defaultString() { + return String.format("free(%s)", address); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Termination.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Termination.java new file mode 100644 index 0000000000..0302d744e7 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/core/Termination.java @@ -0,0 +1,40 @@ +package com.dat3m.dartagnan.program.event.core; + +import com.dat3m.dartagnan.encoding.EncodingContext; +import com.dat3m.dartagnan.exception.ProgramProcessingException; +import com.dat3m.dartagnan.program.Program; +import com.dat3m.dartagnan.program.event.Tag; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.BooleanFormulaManager; + +public class Termination extends GenericVisibleEvent { + + public Termination() { + super("Termination", Tag.TERMINATION); + } + + @Override + public GenericVisibleEvent getCopy() { + throw new ProgramProcessingException("Termination event cannot be copied"); + } + + @Override + public boolean cfImpliesExec() { + return false; + } + + @Override + public BooleanFormula encodeExec(EncodingContext ctx) { + Program program = getThread().getProgram(); + final BooleanFormulaManager bmgr = ctx.getBooleanFormulaManager(); + final BooleanFormula exitReached = bmgr.and(program.getThreads().stream() + .filter(t -> !t.equals(getThread())) + .map(t -> bmgr.equivalence(ctx.execution(t.getEntry()), ctx.execution(t.getExit()))) + .toList()); + final BooleanFormula terminated = program.getThreadEventsWithAllTags(Tag.NONTERMINATION).stream() + .map(CondJump.class::cast) + .map(jump -> bmgr.not(ctx.jumpTaken(jump))) + .reduce(bmgr.makeTrue(), bmgr::and); + return bmgr.implication(ctx.execution(this), bmgr.and(ctx.controlFlow(this), exitReached, terminated)); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/dat3m/DynamicThreadDetach.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/dat3m/DynamicThreadDetach.java new file mode 100644 index 0000000000..68204e01e7 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/dat3m/DynamicThreadDetach.java @@ -0,0 +1,63 @@ +package com.dat3m.dartagnan.program.event.lang.dat3m; + +import com.dat3m.dartagnan.expression.Expression; +import com.dat3m.dartagnan.expression.ExpressionVisitor; +import com.dat3m.dartagnan.program.Register; +import com.dat3m.dartagnan.program.event.AbstractEvent; +import com.dat3m.dartagnan.program.event.Event; +import com.dat3m.dartagnan.program.event.RegReader; +import com.dat3m.dartagnan.program.event.RegWriter; + +import java.util.HashSet; +import java.util.Set; + +public final class DynamicThreadDetach extends AbstractEvent implements RegWriter, RegReader { + + private Register status; + private Expression tid; + + public DynamicThreadDetach(Register statusRegister, Expression tidExpression) { + this.status = statusRegister; + this.tid = tidExpression; + } + + private DynamicThreadDetach(DynamicThreadDetach copy) { + super(copy); + this.status = copy.status; + this.tid = copy.tid; + } + + public Expression getTid() { + return tid; + } + + @Override + protected String defaultString() { + return String.format("%s <- DynamicThreadDetach(%s)", status, tid); + } + + @Override + public Event getCopy() { + return new DynamicThreadDetach(this); + } + + @Override + public Register getResultRegister() { + return status; + } + + @Override + public void setResultRegister(Register reg) { + status = reg; + } + + @Override + public Set getRegisterReads() { + return Register.collectRegisterReads(tid, Register.UsageType.OTHER, new HashSet<>()); + } + + @Override + public void transformExpressions(ExpressionVisitor exprTransformer) { + tid = tid.accept(exprTransformer); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/dat3m/DynamicThreadJoin.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/dat3m/DynamicThreadJoin.java index fc9ab387da..07571f72b5 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/dat3m/DynamicThreadJoin.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/dat3m/DynamicThreadJoin.java @@ -29,10 +29,11 @@ The status register shall be large enough to accommodate all error values (bv8 s public class DynamicThreadJoin extends AbstractEvent implements RegWriter, RegReader, BlockingEvent { public enum Status { - SUCCESS(0), // The join was successful - INVALID_TID(1), // The provided tid does not match with a joinable thread - INVALID_RETURN_TYPE(2); // The provided tid is valid, but the return type of that thread does not match + SUCCESS(0), // The join was successful. + INVALID_TID(1), // The provided tid does not match with any of the spawned threads. + INVALID_RETURN_TYPE(2), // The provided tid is valid, but the return type of that thread does not match // with the expected return type. + DETACHED_THREAD(3); // The provided tid belongs to a non-joinable thread. final int errorCode; public int getErrorCode() { return errorCode; } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/pthread/InitLock.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/pthread/InitLock.java deleted file mode 100644 index b377db8142..0000000000 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/pthread/InitLock.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.dat3m.dartagnan.program.event.lang.pthread; - -import com.dat3m.dartagnan.expression.Expression; -import com.dat3m.dartagnan.program.event.EventVisitor; -import com.dat3m.dartagnan.program.event.common.StoreBase; - -import static com.dat3m.dartagnan.program.event.Tag.C11.MO_SC; - -public class InitLock extends StoreBase { - - private final String name; - - public InitLock(String name, Expression address, Expression value) { - super(address, value, MO_SC); - this.name = name; - } - - private InitLock(InitLock other) { - super(other); - this.name = other.name; - } - - @Override - public String defaultString() { - return "pthread_mutex_init(&" + name + ", " + value + ")"; - } - - @Override - public InitLock getCopy() { - return new InitLock(this); - } - - @Override - public T accept(EventVisitor visitor) { - return visitor.visitInitLock(this); - } -} \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/pthread/Lock.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/pthread/Lock.java deleted file mode 100644 index f536121a5a..0000000000 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/pthread/Lock.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.dat3m.dartagnan.program.event.lang.pthread; - -import com.dat3m.dartagnan.expression.Expression; -import com.dat3m.dartagnan.expression.ExpressionFactory; -import com.dat3m.dartagnan.expression.type.TypeFactory; -import com.dat3m.dartagnan.program.event.EventVisitor; -import com.dat3m.dartagnan.program.event.common.StoreBase; - -import static com.dat3m.dartagnan.program.event.Tag.C11.MO_SC; - -public class Lock extends StoreBase { - - private final String name; - - public Lock(String name, Expression address) { - super(address, ExpressionFactory.getInstance().makeOne(TypeFactory.getInstance().getArchType()), MO_SC); - this.name = name; - } - - private Lock(Lock other) { - super(other); - this.name = other.name; - } - - @Override - public String defaultString() { - return "pthread_mutex_lock(&" + name + ")"; - } - - @Override - public Lock getCopy() { - return new Lock(this); - } - - @Override - public T accept(EventVisitor visitor) { - return visitor.visitLock(this); - } -} \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/pthread/Unlock.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/pthread/Unlock.java deleted file mode 100644 index b54e466bb7..0000000000 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/pthread/Unlock.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.dat3m.dartagnan.program.event.lang.pthread; - -import com.dat3m.dartagnan.expression.Expression; -import com.dat3m.dartagnan.expression.ExpressionFactory; -import com.dat3m.dartagnan.expression.type.TypeFactory; -import com.dat3m.dartagnan.program.event.EventVisitor; -import com.dat3m.dartagnan.program.event.common.StoreBase; - -import static com.dat3m.dartagnan.program.event.Tag.C11.MO_SC; - -public class Unlock extends StoreBase { - - private final String name; - - public Unlock(String name, Expression address) { - super(address, ExpressionFactory.getInstance().makeZero(TypeFactory.getInstance().getArchType()), MO_SC); - this.name = name; - } - - private Unlock(Unlock other) { - super(other); - this.name = other.name; - } - - @Override - public String defaultString() { - return "pthread_mutex_unlock(&" + name + ")"; - } - - @Override - public Unlock getCopy() { - return new Unlock(this); - } - - @Override - public T accept(EventVisitor visitor) { - return visitor.visitUnlock(this); - } -} \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/Memory.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/Memory.java index 9c009a2766..c165d9f111 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/Memory.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/Memory.java @@ -5,7 +5,7 @@ import com.dat3m.dartagnan.expression.Type; import com.dat3m.dartagnan.expression.type.IntegerType; import com.dat3m.dartagnan.expression.type.TypeFactory; -import com.dat3m.dartagnan.program.event.core.Alloc; +import com.dat3m.dartagnan.program.event.core.MemAlloc; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; @@ -47,7 +47,7 @@ public MemoryObject allocate(int size) { } // Generates a new, dynamically allocated memory object. - public MemoryObject allocate(Alloc allocationSite) { + public MemoryObject allocate(MemAlloc allocationSite) { Preconditions.checkNotNull(allocationSite); final MemoryObject memoryObject = new MemoryObject(nextIndex++, allocationSite.getAllocationSize(), allocationSite.getAlignment(), allocationSite, ptrType); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/MemoryObject.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/MemoryObject.java index 2f7da6b292..71137dfad8 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/MemoryObject.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/memory/MemoryObject.java @@ -8,7 +8,7 @@ import com.dat3m.dartagnan.expression.base.LeafExpressionBase; import com.dat3m.dartagnan.expression.integers.IntLiteral; import com.dat3m.dartagnan.expression.type.*; -import com.dat3m.dartagnan.program.event.core.Alloc; +import com.dat3m.dartagnan.program.event.core.MemAlloc; import com.google.common.base.Preconditions; import java.util.*; @@ -26,7 +26,7 @@ public class MemoryObject extends LeafExpressionBase { private final int id; private final Expression size; private final Expression alignment; - private final Alloc allocationSite; + private final MemAlloc allocationSite; private String name = null; private boolean isThreadLocal = false; @@ -34,7 +34,7 @@ public class MemoryObject extends LeafExpressionBase { private final Map initialValues = new TreeMap<>(); - MemoryObject(int id, Expression size, Expression alignment, Alloc allocationSite, Type ptrType) { + MemoryObject(int id, Expression size, Expression alignment, MemAlloc allocationSite, Type ptrType) { super(ptrType); final TypeFactory types = TypeFactory.getInstance(); Preconditions.checkArgument(size.getType() instanceof IntegerType, "Size %s must be of integer type.", size); @@ -54,7 +54,7 @@ public class MemoryObject extends LeafExpressionBase { public boolean isStaticallyAllocated() { return allocationSite == null; } public boolean isDynamicallyAllocated() { return !isStaticallyAllocated(); } - public Alloc getAllocationSite() { return allocationSite; } + public MemAlloc getAllocationSite() { return allocationSite; } public boolean isThreadLocal() { return this.isThreadLocal; } public void setIsThreadLocal(boolean value) { this.isThreadLocal = value;} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/AssignmentInlining.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/AssignmentInlining.java index 42b29eb3e1..9e5edc5374 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/AssignmentInlining.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/AssignmentInlining.java @@ -78,6 +78,7 @@ public Expression visitRegister(Register reg) { // A usage counter may be missing for assignments of the form "r = f(r)" // which do not allow for substituting r for f(r) in later usages. usageCounter.containsKey(lastAssignment) + && preDominatorTree.contains(curEvent) && preDominatorTree.isDominatedBy(curEvent, lastAssignment) && !curEvent.hasTag(Tag.NOOPT) // Inline if the expression is only used once or if it leads to simplifications. diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java index fda3d8f8c2..632dde35eb 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/CoreCodeVerification.java @@ -33,8 +33,8 @@ public static CoreCodeVerification fromConfig(Configuration config) { private static final Set> CORE_CLASSES = new HashSet<>(Arrays.asList( Load.class, Store.class, Init.class, GenericMemoryEvent.class, GenericVisibleEvent.class, CondJump.class, IfAsJump.class, ExecutionStatus.class, Label.class, Local.class, - Skip.class, RMWStore.class, RMWStoreExclusive.class, Alloc.class, - Assume.class, Assert.class, InstructionBoundary.class, + Skip.class, RMWStore.class, RMWStoreExclusive.class, MemAlloc.class, MemFree.class, + Assume.class, Assert.class, InstructionBoundary.class, Termination.class, ThreadCreate.class, ThreadJoin.class, ThreadArgument.class, ThreadStart.class, ThreadReturn.class, ControlBarrier.class, NamedBarrier.class, BeginAtomic.class, EndAtomic.class, diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/DeadAssignmentElimination.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/DeadAssignmentElimination.java index e1d50e9589..24f2fbcd18 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/DeadAssignmentElimination.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/DeadAssignmentElimination.java @@ -6,7 +6,7 @@ import com.dat3m.dartagnan.program.event.Event; import com.dat3m.dartagnan.program.event.RegReader; import com.dat3m.dartagnan.program.event.RegWriter; -import com.dat3m.dartagnan.program.event.core.Alloc; +import com.dat3m.dartagnan.program.event.core.MemAlloc; import com.dat3m.dartagnan.program.event.core.Local; import com.google.common.collect.Lists; import org.sosy_lab.common.configuration.Configuration; @@ -69,6 +69,6 @@ private void eliminateDeadAssignments(Function function) { } private boolean isSideEffectFree(Event event) { - return !event.hasTag(VISIBLE) && (event instanceof Local || event instanceof Alloc); + return !event.hasTag(VISIBLE) && (event instanceof Local || event instanceof MemAlloc); } } \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/Intrinsics.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/Intrinsics.java index 7e79f43d45..ee60d3fcb3 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/Intrinsics.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/Intrinsics.java @@ -19,7 +19,6 @@ import com.dat3m.dartagnan.program.event.core.*; import com.dat3m.dartagnan.program.event.functions.FunctionCall; import com.dat3m.dartagnan.program.event.functions.ValueFunctionCall; -import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadCreate; import com.dat3m.dartagnan.program.event.lang.svcomp.BeginAtomic; import com.dat3m.dartagnan.program.memory.MemoryObject; import com.google.common.collect.ImmutableList; @@ -118,6 +117,7 @@ public enum Info { P_THREAD_CREATE("pthread_create", true, false, true, true, Intrinsics::inlinePthreadCreate), P_THREAD_EXIT("pthread_exit", false, false, true, true, Intrinsics::inlinePthreadExit), P_THREAD_JOIN(List.of("pthread_join", "_pthread_join", "__pthread_join"), true, true, false, true, Intrinsics::inlinePthreadJoin), + P_THREAD_DETACH("pthread_detach", true, true, true, true, Intrinsics::inlinePthreadDetach), P_THREAD_BARRIER_WAIT("pthread_barrier_wait", false, false, true, true, Intrinsics::inlineAsZero), P_THREAD_SELF(List.of("pthread_self", "__VERIFIER_tid"), false, false, true, false, null), P_THREAD_EQUAL("pthread_equal", false, false, true, false, Intrinsics::inlinePthreadEqual), @@ -225,7 +225,7 @@ public enum Info { STD_MALLOC("malloc", false, false, true, true, Intrinsics::inlineMalloc), STD_CALLOC("calloc", false, false, true, true, Intrinsics::inlineCalloc), STD_ALIGNED_ALLOC("aligned_alloc", false, false, true, true, Intrinsics::inlineAlignedAlloc), - STD_FREE("free", true, false, true, true, Intrinsics::inlineAsZero),//TODO support free + STD_FREE("free", true, false, true, true, Intrinsics::inlineFree), STD_ASSERT(List.of("__assert_fail", "__assert_rtn"), false, false, false, true, Intrinsics::inlineUserAssert), STD_EXIT("exit", false, false, false, true, Intrinsics::inlineExit), STD_ABORT("abort", false, false, false, true, Intrinsics::inlineExit), @@ -416,21 +416,34 @@ private List inlinePthreadCreate(FunctionCall call) { final List arguments = call.getArguments(); assert arguments.size() == 4; final Expression pidResultAddress = arguments.get(0); - //final Expression attributes = arguments.get(1); + final Expression attributes = arguments.get(1); final Expression targetFunction = arguments.get(2); final Expression argument = arguments.get(3); + final Register attributesRegister = call.getFunction().newUniqueRegister("__pthread_create_attr", getPthreadAttrType()); final Register resultRegister = getResultRegister(call); assert resultRegister.getType() instanceof IntegerType; final Register tidReg = call.getFunction().newUniqueRegister("__tid", types.getArchType()); - final DynamicThreadCreate createEvent = newDynamicThreadCreate(tidReg, PTHREAD_THREAD_TYPE, targetFunction, List.of(argument)); + final Event createEvent = newDynamicThreadCreate(tidReg, PTHREAD_THREAD_TYPE, targetFunction, List.of(argument)); + final Label skipAttrLabel = newLabel("__pthread_create_skip_attr"); + final Label skipDetachLabel = newLabel("__pthread_create_skip_detach"); return eventSequence( createEvent, + newJump(expressions.makeEQ(attributes, expressions.makeGeneralZero(attributes.getType())), skipAttrLabel), + newLoad(attributesRegister, attributes), + // If 'detach' attribute, detach the spawned thread immediately. + // No need to check the status here, as detaching should always succeed. + // resultRegister is reused here and will be overwritten later. + newJumpUnless(testPthreadCreateDetached(attributesRegister), skipDetachLabel), + newDynamicThreadDetach(resultRegister, tidReg), + skipDetachLabel, + // Finally, return the thread ID and the status. + skipAttrLabel, newStore(pidResultAddress, tidReg), // TODO: Allow to return failure value (!= 0) - newLocal(resultRegister, expressions.makeZero((IntegerType) resultRegister.getType())) + newLocal(resultRegister, expressions.makeGeneralZero(resultRegister.getType())) ); } @@ -441,8 +454,8 @@ private List inlinePthreadJoin(FunctionCall call) { final Expression returnAddr = arguments.get(1); final boolean hasReturnAddr = !(returnAddr instanceof IntLiteral lit && lit.isZero()); - final Register resultRegister = getResultRegister(call); - assert resultRegister.getType() instanceof IntegerType; + final Register statusRegister = getResultRegister(call); + final IntegerType statusType = (IntegerType) statusRegister.getType(); final Type joinType = types.getAggregateType(List.of(types.getIntegerType(8), PTHREAD_THREAD_TYPE.getReturnType())); final Register joinReg = call.getFunction().newUniqueRegister("__joinReg", joinType); @@ -453,24 +466,15 @@ private List inlinePthreadJoin(FunctionCall call) { final Expression statusSuccess = expressions.makeValue(SUCCESS.getErrorCode(), (IntegerType) status.getType()); final Expression statusInvalidTId = expressions.makeValue(INVALID_TID.getErrorCode(), (IntegerType) status.getType()); - final Label joinEnd; - final Store storeRetVal; - final CondJump jump; - if (hasReturnAddr) { - joinEnd = newLabel("__pthread_join_end"); - storeRetVal = newStore(returnAddr, retVal); - jump = newJump(expressions.makeNEQ(status, statusSuccess), joinEnd); - } else { - joinEnd = null; - storeRetVal = null; - jump = null; - } + final Label joinEnd = hasReturnAddr ? newLabel("__pthread_join_end") : null; + final Store storeRetVal = hasReturnAddr ? newStore(returnAddr, retVal) : null; + final CondJump jump = hasReturnAddr ? newJump(expressions.makeNEQ(status, statusSuccess), joinEnd) : null; return eventSequence( newDynamicThreadJoin(joinReg, tidExpr), // TODO: We use our internal error codes which do not match with pthread's error codes, // except for the success case (error code == 0). - newLocal(resultRegister, expressions.makeCast(status, resultRegister.getType())), + newLocal(statusRegister, expressions.makeCast(status, statusType)), jump, storeRetVal, joinEnd, @@ -478,6 +482,22 @@ private List inlinePthreadJoin(FunctionCall call) { ); } + private List inlinePthreadDetach(FunctionCall call) { + final List arguments = call.getArguments(); + assert arguments.size() == 1; + final Expression tidExpr = arguments.get(0); + + final Register statusRegister = getResultRegister(call); + final IntegerType statusType = (IntegerType) statusRegister.getType(); + + final Expression statusInvalidTId = expressions.makeValue(INVALID_TID.getErrorCode(), statusType); + + return eventSequence( + newDynamicThreadDetach(statusRegister, tidExpr), + newAssert(expressions.makeNEQ(statusRegister, statusInvalidTId), "Invalid thread id in pthread_detach.") + ); + } + private List inlinePthreadExit(FunctionCall call) { final List arguments = call.getArguments(); assert arguments.size() == 1 && arguments.get(0).getType().equals(PTHREAD_THREAD_TYPE.getReturnType()); @@ -516,26 +536,86 @@ private List inlinePthreadAttr(FunctionCall call) { default -> 2; }; final Register errorRegister = getResultRegisterAndCheckArguments(expectedArguments, call); + final IntegerType errorType = (IntegerType) errorRegister.getType(); final Expression attrAddress = call.getArguments().get(0); + final Expression value = expectedArguments < 2 ? null : call.getArguments().get(1); final boolean initial = suffix.equals("init"); if (initial || suffix.equals("destroy")) { - final Expression flag = expressions.makeValue(initial); + final Expression flag = expressions.makeValue(initial ? 1 : 0, getPthreadAttrType()); return List.of( newStore(attrAddress, flag), assignSuccess(errorRegister) ); } final boolean getter = suffix.startsWith("get"); - checkArgument(getter || suffix.startsWith("set"), "Unrecognized intrinsics \"%s\"", call); - checkArgument(P_THREAD_ATTR.contains(suffix.substring(3))); - //final Register oldValue = call.getFunction().newRegister(types.getBooleanType()); - //final Expression value = call.getArguments().get(1); - return List.of( - //EventFactory.newLoad(oldValue, attrAddress), - assignSuccess(errorRegister) + checkArgument((getter || suffix.startsWith("set")) && P_THREAD_ATTR.contains(suffix.substring(3)), + "Unrecognized intrinsics \"%s\"", call); + final Register oldValue = call.getFunction().newRegister(getPthreadAttrType()); + final Label end = EventFactory.newLabel("__pthread_return"); + final PthreadAttrImplementation impl = switch (suffix.substring(3)) { + case "detachstate" -> inlinePthreadAttrDetachState(oldValue, getter ? null : value, end); + default -> null; + }; + final Expression zero = expressions.makeZero(types.getIntegerType(1)); + final Expression extractInitialized = expressions.makeIntExtract(oldValue, 0, 0); + return eventSequence( + newLocal(errorRegister, expressions.makeValue(PosixErrorCode.EINVAL.getValue(), errorType)), + newLoad(oldValue, attrAddress), + newJump(expressions.makeEQ(extractInitialized, zero), end), + impl == null ? null : impl.errorChecks, + impl == null ? null : newStore(getter ? value : attrAddress, impl.out), + assignSuccess(errorRegister), + end ); } + private IntegerType getPthreadAttrType() { + return types.getIntegerType(2); + } + + private record PthreadAttrImplementation(Expression out, List errorChecks) {} + + private PthreadAttrImplementation inlinePthreadAttrDetachState(Expression oldValue, Expression detachstate, + Label returnEINVAL) { + // POSIX defines these two named constants of type int. + // see https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/pthread.h.html + //TODO values may vary by platform + final long PTHREAD_CREATE_DETACHED = 1; + final long PTHREAD_CREATE_JOINABLE = 0; + final int flagIndex = 1; + final IntegerType attrType = (IntegerType) oldValue.getType(); + final IntegerType valueType = getNativeIntType(); + final Expression createDetached = expressions.makeValue(PTHREAD_CREATE_DETACHED, valueType); + final Expression createJoinable = expressions.makeValue(PTHREAD_CREATE_JOINABLE, valueType); + final List errorChecks = new ArrayList<>(); + final Expression newValue; + if (detachstate == null) { + final Expression zero = expressions.makeZero(types.getIntegerType(1)); + final Expression extractValue = expressions.makeIntExtract(oldValue, flagIndex, flagIndex); + final Expression testValue = expressions.makeNEQ(extractValue, zero); + newValue = expressions.makeITE(testValue, createDetached, createJoinable); + } else { + final long invertedMaskValue = (1L << attrType.getBitWidth()) - (1 << flagIndex) - 1; + final Expression mask = expressions.makeValue(1 << flagIndex, attrType); + final Expression invertedMask = expressions.makeValue(invertedMaskValue, attrType); + final Expression setFlag = expressions.makeIntOr(oldValue, mask); + final Expression resetFlag = expressions.makeIntAnd(oldValue, invertedMask); + final Expression doDetach = expressions.makeEQ(detachstate, createDetached); + final Expression doNotDetach = expressions.makeEQ(detachstate, createJoinable); + final Expression validValue = expressions.makeOr(doDetach, doNotDetach); + errorChecks.add(EventFactory.newJumpUnless(validValue, returnEINVAL)); + newValue = expressions.makeITE(doDetach, setFlag, resetFlag); + } + return new PthreadAttrImplementation(newValue, errorChecks); + } + + private Expression testPthreadCreateDetached(Expression attr) { + final int flagIndex = 1; + final Expression zero = expressions.makeZero(types.getIntegerType(1)); + final Expression extractDetach = expressions.makeIntExtract(attr, flagIndex, flagIndex); + return expressions.makeNEQ(extractDetach, zero); + } + private List inlinePthreadCondInit(FunctionCall call) { //see https://linux.die.net/man/3/pthread_cond_init final Register errorRegister = getResultRegisterAndCheckArguments(2, call); @@ -579,13 +659,15 @@ private List inlinePthreadCondWait(FunctionCall call) { final Register errorRegister = getResultRegisterAndCheckArguments(2, call); //final Expression condAddress = call.getArguments().get(0); final Expression lockAddress = call.getArguments().get(1); - // TODO: implement this without lock/unlock events and get rid of them - return List.of( + final IntegerType type = getPthreadMutexType(); + final Register oldValueRegister = call.getFunction().newUniqueRegister("__pthread_cond_wait", type); + final Register successRegister = call.getFunction().newUniqueRegister("__pthread_cond_wait", types.getBooleanType()); + return eventSequence( // Allow other threads to access the condition variable. - EventFactory.Pthread.newUnlock(lockAddress.toString(), lockAddress), + newPthreadUnlock(oldValueRegister, lockAddress), // This thread would sleep here. Explicit or spurious signals may wake it. // Re-lock. - EventFactory.Pthread.newLock(lockAddress.toString(), lockAddress), + newPthreadLock(oldValueRegister, successRegister, lockAddress), assignSuccess(errorRegister) ); } @@ -597,15 +679,16 @@ private List inlinePthreadCondTimedwait(FunctionCall call) { //final Expression condAddress = call.getArguments().get(0); final Expression lockAddress = call.getArguments().get(1); //final Expression timespec = call.getArguments().get(2); - return List.of( + final IntegerType type = getPthreadMutexType(); + final Register oldValueRegister = call.getFunction().newUniqueRegister("__pthread_cond_timedwait", type); + final Register successRegister = call.getFunction().newUniqueRegister("__pthread_cond_timedwait", types.getBooleanType()); + return eventSequence( // Allow other threads to access the condition variable. - EventFactory.Pthread.newUnlock(lockAddress.toString(), lockAddress), + newPthreadUnlock(oldValueRegister, lockAddress), // This thread would sleep here. Explicit or spurious signals may wake it. // Re-lock. - EventFactory.Pthread.newLock(lockAddress.toString(), lockAddress), - //TODO proper error code: ETIMEDOUT - EventFactory.Svcomp.newNonDetChoice(errorRegister), - EventFactory.newAssume(expressions.makeGTE(errorRegister, expressions.makeZero(errorType), true)) + newPthreadLock(oldValueRegister, successRegister, lockAddress), + newLocal(errorRegister, expressions.makeValue(PosixErrorCode.ETIMEDOUT.getValue(), errorType)) ); } @@ -680,8 +763,7 @@ private List inlinePthreadSetSpecific(FunctionCall call) { private static final List P_THREAD_MUTEXATTR = List.of( "prioceiling", "protocol", - "type", - "policy_np" + "type" ); private List inlinePthreadMutexInit(FunctionCall call) { @@ -689,8 +771,7 @@ private List inlinePthreadMutexInit(FunctionCall call) { //TODO use attributes final Register errorRegister = getResultRegisterAndCheckArguments(2, call); final Expression lockAddress = call.getArguments().get(0); - // FIXME: We currently use bv32 in InitLock, Lock and Unlock. - final IntegerType type = types.getIntegerType(32); + final IntegerType type = getPthreadMutexType(); final Expression unlocked = expressions.makeZero(type); return List.of( EventFactory.Llvm.newStore(lockAddress, unlocked, Tag.C11.MO_RELEASE), @@ -711,24 +792,13 @@ private List inlinePthreadMutexLock(FunctionCall call) { //see https://linux.die.net/man/3/pthread_mutex_lock final Register errorRegister = getResultRegisterAndCheckArguments(1, call); checkArgument(errorRegister.getType() instanceof IntegerType, "Wrong return type for \"%s\"", call); - // FIXME: We currently use bv32 in InitLock, Lock and Unlock. - final IntegerType type = types.getIntegerType(32); - final Register oldValueRegister = call.getFunction().newRegister(type); - final Register successRegister = call.getFunction().newRegister(types.getBooleanType()); + final IntegerType type = getPthreadMutexType(); + final Register oldValueRegister = call.getFunction().newUniqueRegister("__pthread_mutex_lock", type); + final Register successRegister = call.getFunction().newUniqueRegister("__pthread_mutex_lock", types.getBooleanType()); final Expression lockAddress = call.getArguments().get(0); - final Expression locked = expressions.makeOne(type); - final Expression unlocked = expressions.makeZero(type); - final Expression fail = expressions.makeNot(successRegister); - final Label spinLoopHead = EventFactory.newLabel("__spinloop_head"); - final Label spinLoopEnd = EventFactory.newLabel("__spinloop_end"); - // We implement this as a caslocks - return List.of( - spinLoopHead, - EventFactory.Llvm.newCompareExchange(oldValueRegister, successRegister, lockAddress, unlocked, locked, Tag.C11.MO_ACQUIRE, true), - EventFactory.newJump(successRegister, spinLoopEnd), - EventFactory.newGoto(spinLoopHead), - spinLoopEnd, - EventFactory.newLocal(errorRegister, expressions.makeCast(fail, errorRegister.getType())) + return eventSequence( + newPthreadLock(oldValueRegister, successRegister, lockAddress), + assignSuccess(errorRegister) ); } @@ -736,16 +806,13 @@ private List inlinePthreadMutexTryLock(FunctionCall call) { //see https://linux.die.net/man/3/pthread_mutex_trylock final Register errorRegister = getResultRegisterAndCheckArguments(1, call); checkArgument(errorRegister.getType() instanceof IntegerType, "Wrong return type for \"%s\"", call); - // FIXME: We currently use bv32 in InitLock, Lock and Unlock. - final IntegerType type = types.getIntegerType(32); - final Register oldValueRegister = call.getFunction().newRegister(type); - final Register successRegister = call.getFunction().newRegister(types.getBooleanType()); + final IntegerType type = getPthreadMutexType(); + final Register oldValueRegister = call.getFunction().newUniqueRegister("__pthread_mutex_try_lock", type); + final Register successRegister = call.getFunction().newUniqueRegister("__pthread_mutex_try_lock", types.getBooleanType()); final Expression lockAddress = call.getArguments().get(0); - final Expression locked = expressions.makeOne(type); - final Expression unlocked = expressions.makeZero(type); final Expression fail = expressions.makeNot(successRegister); return List.of( - EventFactory.Llvm.newCompareExchange(oldValueRegister, successRegister, lockAddress, unlocked, locked, Tag.C11.MO_ACQUIRE), + newPthreadTryLock(oldValueRegister, successRegister, lockAddress, false), EventFactory.newLocal(errorRegister, expressions.makeCast(fail, errorRegister.getType())) ); } @@ -753,16 +820,11 @@ private List inlinePthreadMutexTryLock(FunctionCall call) { private List inlinePthreadMutexUnlock(FunctionCall call) { //see https://linux.die.net/man/3/pthread_mutex_unlock final Register errorRegister = getResultRegisterAndCheckArguments(1, call); - // FIXME: We currently use bv32 in InitLock, Lock and Unlock. - final IntegerType type = types.getIntegerType(32); - final Register oldValueRegister = call.getFunction().newRegister(type); + final IntegerType type = getPthreadMutexType(); + final Register oldValueRegister = call.getFunction().newUniqueRegister("__pthread_mutex_unlock", type); final Expression lockAddress = call.getArguments().get(0); - final Expression locked = expressions.makeOne(type); - final Expression unlocked = expressions.makeZero(type); return eventSequence( - EventFactory.Llvm.newLoad(oldValueRegister, lockAddress, Tag.C11.MO_RELAXED), - notToInline.contains(AssertionType.USER) ? null : EventFactory.newAssert(expressions.makeEQ(oldValueRegister, locked), "Unlocking an already unlocked mutex"), - EventFactory.Llvm.newStore(lockAddress, unlocked, Tag.C11.MO_RELEASE), + newPthreadUnlock(oldValueRegister, lockAddress), assignSuccess(errorRegister) ); } @@ -791,6 +853,39 @@ private List inlinePthreadMutexAttr(FunctionCall call) { ); } + private List newPthreadUnlock(Register oldValueRegister, Expression address) { + final Expression unlocked = expressions.makeGeneralZero(oldValueRegister.getType()); + final boolean skipCheck = notToInline.contains(AssertionType.USER); + final Event load = skipCheck ? null : EventFactory.Llvm.newLoad(oldValueRegister, address, Tag.C11.MO_RELAXED); + final Expression isLocked = skipCheck ? null : expressions.makeNEQ(oldValueRegister, unlocked); + final Event check = skipCheck ? null : EventFactory.newAssert(isLocked, "Unlocking an already unlocked mutex"); + final Event store = EventFactory.Llvm.newStore(address, unlocked, Tag.C11.MO_RELEASE); + return Arrays.asList(load, check, store); + } + + private Event newPthreadTryLock(Register oldValueRegister, Register successRegister, Expression address, boolean strong) { + final Expression unlocked = expressions.makeGeneralZero(oldValueRegister.getType()); + final Expression locked = expressions.makeOne((IntegerType) oldValueRegister.getType()); + return EventFactory.Llvm.newCompareExchange(oldValueRegister, successRegister, address, unlocked, locked, Tag.C11.MO_ACQUIRE, strong); + } + + private List newPthreadLock(Register oldValueRegister, Register successRegister, Expression address) { + // We implement this as a CAS-spinlock + final Label spinLoopHead = EventFactory.newLabel("__spinloop_head"); + final Label spinLoopEnd = EventFactory.newLabel("__spinloop_end"); + return List.of( + spinLoopHead, + newPthreadTryLock(oldValueRegister, successRegister, address, true), + EventFactory.newJump(successRegister, spinLoopEnd), + EventFactory.newGoto(spinLoopHead), + spinLoopEnd + ); + } + + private IntegerType getPthreadMutexType() { + return types.getIntegerType(1); + } + private static final List P_THREAD_RWLOCK_ATTR = List.of( "pshared" ); @@ -970,6 +1065,12 @@ private List inlinePthreadRwlockAttr(FunctionCall call) { ); } + private List inlineFree(FunctionCall call) { + return List.of( + EventFactory.newFree(call.getArguments().get(0)) + ); + } + private List inlineMalloc(FunctionCall call) { final Register resultRegister = getResultRegisterAndCheckArguments(1, call); final Type allocType = types.getByteType(); @@ -1755,6 +1856,10 @@ private List inlineFfs(FunctionCall call) { return List.of(assignment); } + private IntegerType getNativeIntType() { + return types.getIntegerType(32); + } + private Event assignSuccess(Register errorRegister) { return EventFactory.newLocal(errorRegister, expressions.makeGeneralZero(errorRegister.getType())); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemToReg.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemToReg.java index 4703832749..162cdf589f 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemToReg.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemToReg.java @@ -59,7 +59,7 @@ public void run(Function function) { private Matcher analyze(Function function) { final var matcher = new Matcher(); // Initially, all locally-allocated addresses are potentially promotable. - for (final Alloc allocation : function.getEvents(Alloc.class)) { + for (final MemAlloc allocation : function.getEvents(MemAlloc.class)) { // Allocations will usually not have users. Otherwise, their object is not promotable. if (allocation.getUsers().isEmpty()) { matcher.reachabilityGraph.put(allocation, new HashSet<>()); @@ -81,7 +81,7 @@ private void promoteAll(Function function, Matcher matcher) { // Compute replacement of allocation sites: for (final Map.Entry entry : promotableObjects.entrySet()) { - final Alloc alloc = (Alloc) entry.getKey(); + final MemAlloc alloc = (MemAlloc) entry.getKey(); final List replacement = alloc.doesZeroOutMemory() ? entry.getValue().replacingRegisters.values().stream() .map(reg -> (Event) EventFactory.newLocal(reg, expressions.makeGeneralZero(reg.getType()))) @@ -120,7 +120,7 @@ private void promoteAll(Function function, Matcher matcher) { private Map collectPromotableObjects(Function function, Matcher matcher) { final Map promotableObjects = new HashMap<>(); - for (final Alloc allocation : function.getEvents(Alloc.class)) { + for (final MemAlloc allocation : function.getEvents(MemAlloc.class)) { if (!matcher.reachabilityGraph.containsKey(allocation)) { continue; } @@ -139,7 +139,7 @@ private Map collectPromotableObjects(Function function, M return promotableObjects; } - private Register newRegister(Alloc allocation, Field field) { + private Register newRegister(MemAlloc allocation, Field field) { return allocation.getFunction().newUniqueRegister("__memToReg", field.type); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemoryAllocation.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemoryAllocation.java index 9513849ef4..8513283e15 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemoryAllocation.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/MemoryAllocation.java @@ -5,7 +5,7 @@ import com.dat3m.dartagnan.expression.ExpressionFactory; import com.dat3m.dartagnan.expression.type.TypeFactory; import com.dat3m.dartagnan.program.Program; -import com.dat3m.dartagnan.program.event.core.Alloc; +import com.dat3m.dartagnan.program.event.core.MemAlloc; import com.dat3m.dartagnan.program.memory.MemoryObject; import com.google.common.base.Preconditions; import org.sosy_lab.common.configuration.Configuration; @@ -15,7 +15,7 @@ /* This pass - (1) collects all Alloc events in the program and generates a corresponding MemoryObject + (1) collects all MemAlloc events in the program and generates a corresponding MemoryObject (2) for all MemoryObjects, it generates corresponding Init events if they are required */ @Options @@ -54,7 +54,7 @@ private void processAllocations(Program program) { final ExpressionFactory expressions = ExpressionFactory.getInstance(); // FIXME: We should probably initialize depending on the allocation type of the alloc final Expression zero = expressions.makeZero(TypeFactory.getInstance().getByteType()); - for (Alloc alloc : program.getThreadEvents(Alloc.class)) { + for (MemAlloc alloc : program.getThreadEvents(MemAlloc.class)) { final MemoryObject allocatedObject = program.getMemory().allocate(alloc); alloc.setAllocatedObject(allocatedObject); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/NonterminationDetection.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/NonterminationDetection.java index d26ca148ed..926cedcf71 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/NonterminationDetection.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/NonterminationDetection.java @@ -83,6 +83,7 @@ public void run(Program program) { .forEach(this::instrumentLoop); } + program.addTerminationThread(); IdReassignment.newInstance().run(program); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/PosixErrorCode.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/PosixErrorCode.java new file mode 100644 index 0000000000..4106042b78 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/PosixErrorCode.java @@ -0,0 +1,146 @@ +package com.dat3m.dartagnan.program.processing; + +/** + * Integer-valued error code as used in the GNU/Linux operating system and the C standard library. + */ +enum PosixErrorCode { + SUCCESS, // 0 + EPERM, // 1 Operation not permitted + ENOENT, // 2 No such file or directory + ESRCH, // 3 No such process + EINTR, // 4 Interrupted system call + EIO, // 5 Input/output error + ENXIO, // 6 No such device or address + E2BIG, // 7 Argument list too long + ENOEXEC, // 8 Exec format error + EBADF, // 9 Bad file descriptor + ECHILD, // 10 No child processes + EAGAIN, // 11 Resource temporarily unavailable + ENOMEM, // 12 Cannot allocate memory + EACCES, // 13 Permission denied + EFAULT, // 14 Bad address + ENOTBLK, // 15 Block device required + EBUSY, // 16 Device or resource busy + EEXIST, // 17 File exists + EXDEV, // 18 Invalid cross-device link + ENODEV, // 19 No such device + ENOTDIR, // 20 Not a directory + EISDIR, // 21 Is a directory + EINVAL, // 22 Invalid argument + ENFILE, // 23 Too many open files in system + EMFILE, // 24 Too many open files + ENOTTY, // 25 Inappropriate ioctl for device + ETXTBSY, // 26 Text file busy + EFBIG, // 27 File too large + ENOSPC, // 28 No space left on device + ESPIPE, // 29 Illegal seek + EROFS, // 30 Read-only file system + EMLINK, // 31 Too many links + EPIPE, // 32 Broken pipe + EDOM, // 33 Numerical argument out of domain + ERANGE, // 34 Numerical result out of range + EDEADLK, // 35 Resource deadlock avoided + ENAMETOOLONG, // 36 File name too long + ENOLCK, // 37 No locks available + ENOSYS, // 38 Function not implemented + ENOTEMPTY, // 39 Directory not empty + ELOOP, // 40 Too many levels of symbolic links + E41, + ENOMSG, // 42 No message of desired type + EIDRM, // 43 Identifier removed + ECHRNG, // 44 Channel number out of range + EL2NSYNC, // 45 Level 2 not synchronized + EL3HLT, // 46 Level 3 halted + EL3RST, // 47 Level 3 reset + ELNRNG, // 48 Link number out of range + EUNATCH, // 49 Protocol driver not attached + ENOCSI, // 50 No CSI structure available + EL2HLT, // 51 Level 2 halted + EBADE, // 52 Invalid exchange + EBADR, // 53 Invalid request descriptor + EXFULL, // 54 Exchange full + ENOANO, // 55 No anode + EBADRQC, // 56 Invalid request code + EBADSLT, // 57 Invalid slot + E58, + EBFONT, // 59 Bad font file format + ENOSTR, // 60 Device not a stream + ENODATA, // 61 No data available + ETIME, // 62 Timer expired + ENOSR, // 63 Out of streams resources + ENONET, // 64 Machine is not on the network + ENOPKG, // 65 Package not installed + EREMOTE, // 66 Object is remote + ENOLINK, // 67 Link has been severed + EADV, // 68 Advertise error + ESRMNT, // 69 Srmount error + ECOMM, // 70 Communication error on send + EPROTO, // 71 Protocol error + EMULTIHOP, // 72 Multihop attempted + EDOTDOT, // 73 RFS specific error + EBADMSG, // 74 Bad message + EOVERFLOW, // 75 Value too large for defined data type + ENOTUNIQ, // 76 Name not unique on network + EBADFD, // 77 File descriptor in bad state + EREMCHG, // 78 Remote address changed + ELIBACC, // 79 Can not access a needed shared library + ELIBBAD, // 80 Accessing a corrupted shared library + ELIBSCN, // 81 .lib section in a.out corrupted + ELIBMAX, // 82 Attempting to link in too many shared libraries + ELIBEXEC, // 83 Cannot exec a shared library directly + EILSEQ, // 84 Invalid or incomplete multibyte or wide character + ERESTART, // 85 Interrupted system call should be restarted + ESTRPIPE, // 86 Streams pipe error + EUSERS, // 87 Too many users + ENOTSOCK, // 88 Socket operation on non-socket + EDESTADDRREQ, // 89 Destination address required + EMSGSIZE, // 90 Message too long + EPROTOTYPE, // 91 Protocol wrong type for socket + ENOPROTOOPT, // 92 Protocol not available + EPROTONOSUPPORT, // 93 Protocol not supported + ESOCKTNOSUPPORT, // 94 Socket type not supported + EOPNOTSUPP, // 95 Operation not supported + EPFNOSUPPORT, // 96 Protocol family not supported + EAFNOSUPPORT, // 97 Address family not supported by protocol + EADDRINUSE, // 98 Address already in use + EADDRNOTAVAIL, // 99 Cannot assign requested address + ENETDOWN, // 100 Network is down + ENETUNREACH, // 101 Network is unreachable + ENETRESET, // 102 Network dropped connection on reset + ECONNABORTED, // 103 Software caused connection abort + ECONNRESET, // 104 Connection reset by peer + ENOBUFS, // 105 No buffer space available + EISCONN, // 106 Transport endpoint is already connected + ENOTCONN, // 107 Transport endpoint is not connected + ESHUTDOWN, // 108 Cannot send after transport endpoint shutdown + ETOOMANYREFS, // 109 Too many references: cannot splice + ETIMEDOUT, // 110 Connection timed out + ECONNREFUSED, // 111 Connection refused + EHOSTDOWN, // 112 Host is down + EHOSTUNREACH, // 113 No route to host + EALREADY, // 114 Operation already in progress + EINPROGRESS, // 115 Operation now in progress + ESTALE, // 116 Stale file handle + EUCLEAN, // 117 Structure needs cleaning + ENOTNAM, // 118 Not a XENIX named type file + ENAVAIL, // 119 No XENIX semaphores available + EISNAM, // 120 Is a named type file + EREMOTEIO, // 121 Remote I/O error + EDQUOT, // 122 Disk quota exceeded + ENOMEDIUM, // 123 No medium found + EMEDIUMTYPE, // 124 Wrong medium type + ECANCELED, // 125 Operation canceled + ENOKEY, // 126 Required key not available + EKEYEXPIRED, // 127 Key has expired + EKEYREVOKED, // 128 Key has been revoked + EKEYREJECTED, // 129 Key was rejected by service + EOWNERDEAD, // 130 Owner died + ENOTRECOVERABLE, // 131 State not recoverable + ERFKILL, // 132 Operation not possible due to RF-kill + EHWPOISON, // 133 Memory page has hardware error + ENOTSUP, // 134 Not supported parameter or option + ; + int getValue() { + return ordinal(); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/RemoveDeadNullChecks.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/RemoveDeadNullChecks.java index 451527c495..d54b6412ef 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/RemoveDeadNullChecks.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/RemoveDeadNullChecks.java @@ -13,7 +13,7 @@ import com.dat3m.dartagnan.program.event.EventVisitor; import com.dat3m.dartagnan.program.event.RegReader; import com.dat3m.dartagnan.program.event.RegWriter; -import com.dat3m.dartagnan.program.event.core.Alloc; +import com.dat3m.dartagnan.program.event.core.MemAlloc; import com.dat3m.dartagnan.program.event.core.Local; import com.dat3m.dartagnan.program.memory.MemoryObject; import org.apache.logging.log4j.LogManager; @@ -120,7 +120,7 @@ public Void visitLocal(Local e) { } @Override - public Void visitAlloc(Alloc e) { + public Void visitAlloc(MemAlloc e) { final Sign sign = Sign.POS; signMap.compute(e.getResultRegister(), (key, s) -> s == null ? sign : Sign.meet(s, sign)); return null; diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ThreadCreation.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ThreadCreation.java index 25f3d671f4..8ba1af9081 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ThreadCreation.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/ThreadCreation.java @@ -4,6 +4,7 @@ import com.dat3m.dartagnan.exception.MalformedProgramException; import com.dat3m.dartagnan.expression.*; import com.dat3m.dartagnan.expression.base.LeafExpressionBase; +import com.dat3m.dartagnan.expression.integers.IntBinaryOp; import com.dat3m.dartagnan.expression.integers.IntLiteral; import com.dat3m.dartagnan.expression.processing.ExprTransformer; import com.dat3m.dartagnan.expression.type.AggregateType; @@ -23,6 +24,7 @@ import com.dat3m.dartagnan.program.event.functions.Return; import com.dat3m.dartagnan.program.event.functions.ValueFunctionCall; import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadCreate; +import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadDetach; import com.dat3m.dartagnan.program.event.lang.dat3m.DynamicThreadJoin; import com.dat3m.dartagnan.program.memory.Memory; import com.dat3m.dartagnan.program.memory.MemoryObject; @@ -48,7 +50,7 @@ * LLVM: * This pass handles (reachable) pthread-related function calls. * - each pthread_create call spawns a new Thread object. - * - pthread_join calls are lowered to appropriate synchronization primitives. + * - pthread_join and pthread_detach calls are lowered to appropriate synchronization primitives. * - get_my_tid calls are replaced by constant tid values. * Initially, a single thread from the "main" function is spawned. * Then the pass works iteratively by picking a (newly created) thread and handling all its pthread calls. @@ -81,6 +83,8 @@ public class ThreadCreation implements ProgramProcessor { private final TypeFactory types = TypeFactory.getInstance(); private final ExpressionFactory expressions = ExpressionFactory.getInstance(); private final IntegerType archType = types.getArchType(); + // The thread state consists of two flags: ALIVE and JOINABLE. + private final IntegerType threadStateType = types.getIntegerType(2); private ThreadCreation(Configuration config) throws InvalidConfigurationException { config.inject(this); @@ -101,6 +105,7 @@ public void run(Program program) { final List threads = createThreads(ep); resolvePthreadSelf(program); resolveDynamicThreadJoin(program, threads); + resolveDynamicThreadDetach(program, threads); IdReassignment.newInstance().run(program); resolveTidExpressions(program); } else if (program.getEntrypoint() instanceof Entrypoint.Grid ep) { @@ -110,6 +115,23 @@ public void run(Program program) { logger.info("Number of threads (including main): {}", program.getThreads().size()); } + private static final int ALIVE = 1; + private static final int JOINABLE = 2; + + private Expression threadStateFlag(Expression state, int flag) { + Preconditions.checkArgument(state.getType().equals(threadStateType), "State type mismatch"); + final int bit = switch (flag) { + case ALIVE -> 0; + case JOINABLE -> 1; + default -> throw new IllegalArgumentException("Wrong thread state flag"); + }; + return expressions.makeIntExtract(state, bit, bit); + } + + private Expression threadState(int flags) { + return expressions.makeValue(flags, threadStateType); + } + // ============================================================================================= // =========================================== LLVM ============================================ // ============================================================================================= @@ -141,7 +163,7 @@ private List createThreads(Entrypoint.Simple entrypoint) { allThreads.add(spawnedThread); final List replacement = eventSequence( - newReleaseStore(spawnedThread.comAddress(), expressions.makeTrue()), + newReleaseStore(spawnedThread.comAddress(), threadState(ALIVE | JOINABLE)), createEvent, newLocal(tidRegister, new TIdExpr(archType, spawnedThread.thread())) ); @@ -173,10 +195,11 @@ private void resolveDynamicThreadJoin(Program program, List threadDa final Expression successValue = expressions.makeValue(SUCCESS.getErrorCode(), statusType); final Expression invalidTidValue = expressions.makeValue(INVALID_TID.getErrorCode(), statusType); final Expression invalidRetType = expressions.makeValue(INVALID_RETURN_TYPE.getErrorCode(), statusType); + final Expression detachedThread = expressions.makeValue(DETACHED_THREAD.getErrorCode(), statusType); final Register statusRegister = caller.newRegister("__joinStatus#" + joinCounter, statusType); final Register retValRegister = caller.newRegister("__joinRetVal#" + joinCounter, retValType); - final Register syncRegister = caller.newRegister("__joinSync#" + joinCounter, types.getBooleanType()); + final Register threadStateRegister = caller.newRegister("__joinThreadState#" + joinCounter, threadStateType); // ----- Construct a switch case for each possible tid ----- final Label joinEnd = EventFactory.newLabel("__joinEnd#" + joinCounter); @@ -205,12 +228,17 @@ private void resolveDynamicThreadJoin(Program program, List threadDa EventFactory.newGoto(joinEnd) ); } else { + final Expression isAlive = threadStateFlag(threadStateRegister, ALIVE); + final Expression isJoinable = threadStateFlag(threadStateRegister, JOINABLE); // Successful join caseBody = eventSequence( joinCase, + newLocal(statusRegister, detachedThread), + newLocal(retValRegister, expressions.makeGeneralZero(retValType)), + newAcquireAnd(threadStateRegister, data.comAddress, threadState(ALIVE)), + newJumpUnless(expressions.makeBooleanCast(isJoinable), joinEnd), newThreadJoin(retValRegister, data.thread()), - newAcquireLoad(syncRegister, data.comAddress), - newAssume(expressions.makeNot(syncRegister)), + newAssume(expressions.makeNot(expressions.makeBooleanCast(isAlive))), newLocal(statusRegister, successValue), EventFactory.newGoto(joinEnd) ); @@ -241,6 +269,69 @@ private void resolveDynamicThreadJoin(Program program, List threadDa } } + private void resolveDynamicThreadDetach(Program program, List threadData) { + int detachCounter = 0; + for (DynamicThreadDetach detach : program.getThreadEvents(DynamicThreadDetach.class)) { + final Thread caller = detach.getThread(); + final Expression tidExpr = detach.getTid(); + + final Register statusRegister = detach.getResultRegister(); + final IntegerType statusType = (IntegerType) statusRegister.getType(); + + final Expression successValue = expressions.makeValue(SUCCESS.getErrorCode(), statusType); + final Expression invalidTidValue = expressions.makeValue(INVALID_TID.getErrorCode(), statusType); + final Expression detachedThread = expressions.makeValue(DETACHED_THREAD.getErrorCode(), statusType); + + final Register threadState = caller.newRegister("__detachThreadState#" + detachCounter, threadStateType); + + // ----- Construct a switch case for each possible tid ----- + final Label detachEnd = EventFactory.newLabel("__detachEnd#" + detachCounter); + final Map> tid2detachCases = new LinkedHashMap<>(); + for (ThreadData data : threadData) { + if (!data.isDetachable()) { + continue; + } + + final int tid = data.thread().getId(); + if (tidExpr instanceof IntLiteral iConst && iConst.getValueAsInt() != tid) { + // Little optimization if we detach a constant address + continue; + } + + final Label detachCase = EventFactory.newLabel("__detachT" + tid + "#" + detachCounter); + final Expression isJoinable = threadStateFlag(threadState, JOINABLE); + final Expression isJoinableBoolean = expressions.makeBooleanCast(isJoinable); + final List caseBody = eventSequence( + detachCase, + newRelaxedAnd(threadState, data.comAddress, threadState(ALIVE)), + newLocal(statusRegister, expressions.makeITE(isJoinableBoolean, successValue, detachedThread)), + EventFactory.newGoto(detachEnd) + ); + tid2detachCases.put(new TIdExpr((IntegerType) tidExpr.getType(), data.thread()), caseBody); + } + + // ----- Construct the actual switch (a simple jump table) ----- + final List switchJumpTable = new ArrayList<>(); + for (Expression tid : tid2detachCases.keySet()) { + final Expression eqTid = expressions.makeEQ(tidExpr, tid); + final var label = (Label) tid2detachCases.get(tid).get(0); + switchJumpTable.add(EventFactory.newJump(eqTid, label)); + } + // In the case where no tid matches, we return an error status. + switchJumpTable.add(EventFactory.newLocal(statusRegister, invalidTidValue)); + switchJumpTable.add(EventFactory.newGoto(detachEnd)); + + // ----- Generate actual replacement for the DynamicDetachEvent ----- + final List replacement = eventSequence( + switchJumpTable, + tid2detachCases.values(), + detachEnd + ); + IRHelper.replaceWithMetadata(detach, replacement); + detachCounter++; + } + } + private void resolvePthreadSelf(Program program) { for (FunctionCall call : program.getThreadEvents(FunctionCall.class)) { if (!call.isDirectCall()) { @@ -317,17 +408,19 @@ private ThreadData createLLVMThreadFromFunction(Function function, int tid, Thre // We use accesses to a common memory object to synchronize creator and thread. final MemoryObject comAddress = function.getProgram().getMemory().allocate(1); comAddress.setName("__com_" + function.getName() + "#" + tid); - comAddress.setInitialValue(0, expressions.makeFalse()); + comAddress.setInitialValue(0, threadState(0)); // Sync - final Register startSignal = thread.newRegister("__startT" + tid, types.getBooleanType()); + final Register threadState = thread.newRegister("__threadStateT" + tid, threadStateType); + final Expression isAlive = threadStateFlag(threadState, ALIVE); thread.getEntry().insertAfter(eventSequence( - newAcquireLoad(startSignal, comAddress), - newAssume(startSignal) + newAcquireLoad(threadState, comAddress), + newAssume(expressions.makeBooleanCast(isAlive)) )); // End - threadReturnLabel.insertAfter(newReleaseStore(comAddress, expressions.makeFalse())); + // Reset the ALIVE flag. + threadReturnLabel.insertAfter(newReleaseAnd(threadState, comAddress, threadState(JOINABLE))); creator.setSpawnedThread(thread); return new ThreadData(thread, comAddress); @@ -429,6 +522,30 @@ private List newAcquireLoad(Register resultRegister, Expression address) return compiler.getCompilationResult(acquireLoad); } + private List newRelaxedAnd(Register register, Expression address, Expression value) { + final Event relaxedAnd = compiler.getTarget() == Arch.LKMM ? + EventFactory.Linux.newRMWFetchOp(address, register, value, IntBinaryOp.AND, Tag.Linux.MO_ONCE) : + EventFactory.Atomic.newFetchOp(register, address, value, IntBinaryOp.AND, Tag.C11.MO_RELAXED); + relaxedAnd.setFunction(register.getFunction()); + return compiler.getCompilationResult(relaxedAnd); + } + + private List newReleaseAnd(Register register, Expression address, Expression value) { + final Event releaseAnd = compiler.getTarget() == Arch.LKMM ? + EventFactory.Linux.newRMWFetchOp(address, register, value, IntBinaryOp.AND, Tag.Linux.MO_RELEASE) : + EventFactory.Atomic.newFetchOp(register, address, value, IntBinaryOp.AND, Tag.C11.MO_RELEASE); + releaseAnd.setFunction(register.getFunction()); + return compiler.getCompilationResult(releaseAnd); + } + + private List newAcquireAnd(Register register, Expression address, Expression value) { + final Event acquireAnd = compiler.getTarget() == Arch.LKMM ? + EventFactory.Linux.newRMWFetchOp(address, register, value, IntBinaryOp.AND, Tag.Linux.MO_ACQUIRE) : + EventFactory.Atomic.newFetchOp(register, address, value, IntBinaryOp.AND, Tag.C11.MO_ACQUIRE); + acquireAnd.setFunction(register.getFunction()); + return compiler.getCompilationResult(acquireAnd); + } + // ============================================================================================= // ========================================== SPIR-V =========================================== @@ -511,6 +628,7 @@ private record ThreadData(Thread thread, MemoryObject comAddress) { // We assume all dynamically created threads are joinable. // This is not true for pthread_join in general. public boolean isJoinable() { return isDynamic(); } + public boolean isDetachable() { return isDynamic(); } } // We use this class to refer to thread ids before we have (re)assigned proper ids for all threads. diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorArm7.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorArm7.java index c24b037417..f0fd798bcb 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorArm7.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorArm7.java @@ -1,9 +1,12 @@ package com.dat3m.dartagnan.program.processing.compilation; +import com.dat3m.dartagnan.expression.Expression; import com.dat3m.dartagnan.program.event.Event; +import com.dat3m.dartagnan.program.event.Tag; import com.dat3m.dartagnan.program.event.lang.catomic.*; import com.dat3m.dartagnan.program.event.arch.StoreExclusive; import com.dat3m.dartagnan.program.event.core.*; +import com.dat3m.dartagnan.program.event.lang.linux.LKMMFetchOp; import java.util.List; @@ -30,16 +33,53 @@ public List visitStoreExclusive(StoreExclusive e) { public List visitAtomicLoad(AtomicLoad e) { return eventSequence( newLoad(e.getResultRegister(), e.getAddress()), - AArch64.DMB.newISHBarrier() + isAtomicAcquire(e.getMo()) ? AArch64.DMB.newISHBarrier() : null ); } @Override public List visitAtomicStore(AtomicStore e) { return eventSequence( - AArch64.DMB.newISHBarrier(), + isAtomicRelease(e.getMo()) ? AArch64.DMB.newISHBarrier() : null, newStore(e.getAddress(), e.getMemValue()) ); } + @Override + public List visitAtomicFetchOp(AtomicFetchOp e) { + final Expression value = expressions.makeIntBinary(e.getResultRegister(), e.getOperator(), e.getOperand()); + final Load load = newRMWLoad(e.getResultRegister(), e.getAddress()); + return eventSequence( + load, + isAtomicAcquire(e.getMo()) || isAtomicRelease(e.getMo()) ? AArch64.DMB.newISHBarrier() : null, + newRMWStore(load, e.getAddress(), value) + ); + } + + @Override + public List visitLKMMFetchOp(LKMMFetchOp e) { + final Expression value = expressions.makeIntBinary(e.getResultRegister(), e.getOperator(), e.getOperand()); + final Load load = newRMWLoad(e.getResultRegister(), e.getAddress()); + return eventSequence( + load, + isAtomicAcquire(e.getMo()) || isAtomicRelease(e.getMo()) ? AArch64.DMB.newISHBarrier() : null, + newRMWStore(load, e.getAddress(), value) + ); + } + + private boolean isAtomicAcquire(String mo) { + return switch (mo) { + case Tag.C11.MO_ACQUIRE -> true; + case Tag.C11.MO_RELEASE, Tag.C11.MO_RELAXED -> false; + default -> throw new UnsupportedOperationException("Unsupported memory order"); + }; + } + + private boolean isAtomicRelease(String mo) { + return switch (mo) { + case Tag.C11.MO_RELEASE -> true; + case Tag.C11.MO_ACQUIRE, Tag.C11.MO_RELAXED -> false; + default -> throw new UnsupportedOperationException("Unsupported memory order"); + }; + } } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorArm8.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorArm8.java index afa8b74ed3..f1603c7fd0 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorArm8.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorArm8.java @@ -15,9 +15,6 @@ import com.dat3m.dartagnan.program.event.lang.catomic.*; import com.dat3m.dartagnan.program.event.lang.linux.*; import com.dat3m.dartagnan.program.event.lang.llvm.*; -import com.dat3m.dartagnan.program.event.lang.pthread.InitLock; -import com.dat3m.dartagnan.program.event.lang.pthread.Lock; -import com.dat3m.dartagnan.program.event.lang.pthread.Unlock; import java.util.List; @@ -58,42 +55,6 @@ public List visitXchg(Xchg xchg) { ); } - // ============================================================================================= - // ========================================= PTHREAD =========================================== - // ============================================================================================= - - @Override - public List visitInitLock(InitLock e) { - return eventSequence( - newStoreWithMo(e.getAddress(), e.getMemValue(), ARMv8.MO_REL) - ); - } - - @Override - public List visitLock(Lock e) { - IntegerType type = (IntegerType)e.getAccessType(); - Expression zero = expressions.makeZero(type); - Expression one = expressions.makeOne(type); - Register dummy = e.getFunction().newRegister(type); - // We implement locks as spinlocks which are guaranteed to succeed, i.e. we can use - // assumes. With this we miss a ctrl dependency, but this does not matter - // because the load is an acquire one. - // TODO: Lock events are only used for implementing condvar intrinsic. - // If we have an alternative implementation for that, we can get rid of these events. - return eventSequence( - newRMWLoadExclusiveWithMo(dummy, e.getAddress(), ARMv8.MO_ACQ), - newAssume(expressions.makeEQ(dummy, zero)), - newRMWStoreExclusive(e.getAddress(), one, true) - ); - } - - @Override - public List visitUnlock(Unlock e) { - return eventSequence( - newStoreWithMo(e.getAddress(), expressions.makeZero((IntegerType)e.getAccessType()), ARMv8.MO_REL) - ); - } - // ============================================================================================= // =========================================== LLVM ============================================ // ============================================================================================= diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorBase.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorBase.java index 6283492ecb..b1935becab 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorBase.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorBase.java @@ -1,28 +1,19 @@ package com.dat3m.dartagnan.program.processing.compilation; -import com.dat3m.dartagnan.expression.Expression; import com.dat3m.dartagnan.expression.ExpressionFactory; -import com.dat3m.dartagnan.expression.type.IntegerType; import com.dat3m.dartagnan.expression.type.TypeFactory; import com.dat3m.dartagnan.program.Function; -import com.dat3m.dartagnan.program.Register; import com.dat3m.dartagnan.program.event.Event; import com.dat3m.dartagnan.program.event.EventVisitor; import com.dat3m.dartagnan.program.event.arch.StoreExclusive; import com.dat3m.dartagnan.program.event.arch.tso.TSOXchg; -import com.dat3m.dartagnan.program.event.core.Load; import com.dat3m.dartagnan.program.event.lang.linux.*; import com.dat3m.dartagnan.program.event.lang.llvm.LlvmLoad; import com.dat3m.dartagnan.program.event.lang.llvm.LlvmStore; -import com.dat3m.dartagnan.program.event.lang.pthread.InitLock; -import com.dat3m.dartagnan.program.event.lang.pthread.Lock; -import com.dat3m.dartagnan.program.event.lang.pthread.Unlock; import java.util.Collections; import java.util.List; -import static com.dat3m.dartagnan.program.event.EventFactory.*; - class VisitorBase implements EventVisitor> { protected final TypeFactory types = TypeFactory.getInstance(); @@ -37,48 +28,6 @@ public List visitEvent(Event e) { return Collections.singletonList(e); } - @Override - public List visitInitLock(InitLock e) { - return eventSequence( - newStoreWithMo(e.getAddress(), e.getMemValue(), e.getMo()) - ); - } - - @Override - public List visitLock(Lock e) { - IntegerType type = (IntegerType)e.getAccessType(); - Expression zero = expressions.makeZero(type); - Expression one = expressions.makeOne(type); - Register dummy = e.getFunction().newRegister(type); - Expression address = e.getAddress(); - String mo = e.getMo(); - - Load rmwLoad = newRMWLoadWithMo(dummy, address, mo); - - // We implement locks as spinlocks which are guaranteed to succeed, i.e. we can use - // assumes. With this we miss a ctrl dependency, but this does not matter - // because the load is SC. - // TODO: Lock events are only used for implementing condvar intrinsic. - // If we have an alternative implementation for that, we can get rid of these events. - return eventSequence( - rmwLoad, - newAssume(expressions.makeEQ(dummy, zero)), - newRMWStoreWithMo(rmwLoad, address, one, mo) - ); - } - - @Override - public List visitUnlock(Unlock e) { - IntegerType type = (IntegerType)e.getAccessType(); - Expression zero = expressions.makeZero(type); - Expression address = e.getAddress(); - String mo = e.getMo(); - - return eventSequence( - newStoreWithMo(address, zero, mo) - ); - } - @Override public List visitStoreExclusive(StoreExclusive e) { throw error(e); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorPower.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorPower.java index 7f680aa8c9..aaff241615 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorPower.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorPower.java @@ -13,9 +13,6 @@ import com.dat3m.dartagnan.program.event.lang.catomic.*; import com.dat3m.dartagnan.program.event.lang.linux.*; import com.dat3m.dartagnan.program.event.lang.llvm.*; -import com.dat3m.dartagnan.program.event.lang.pthread.InitLock; -import com.dat3m.dartagnan.program.event.lang.pthread.Lock; -import com.dat3m.dartagnan.program.event.lang.pthread.Unlock; import java.util.List; @@ -55,43 +52,6 @@ public List visitStoreExclusive(StoreExclusive e) { ); } - // ============================================================================================= - // ========================================= PTHREAD =========================================== - // ============================================================================================= - - @Override - public List visitInitLock(InitLock e) { - return eventSequence( - Power.newLwSyncBarrier(), - newStore(e.getAddress(), e.getMemValue())); - } - - @Override - public List visitLock(Lock e) { - IntegerType type = (IntegerType) e.getAccessType(); - Register dummy = e.getFunction().newRegister(type); - Label label = newLabel("FakeDep"); - // We implement locks as spinlocks which are guaranteed to succeed, i.e. we can - // use assumes. The fake control dependency + isync guarantee acquire semantics. - // TODO: Lock events are only used for implementing condvar intrinsic. - // If we have an alternative implementation for that, we can get rid of these events. - return eventSequence( - newRMWLoadExclusive(dummy, e.getAddress()), - newAssume(expressions.makeNot(expressions.makeBooleanCast(dummy))), - Power.newRMWStoreConditional(e.getAddress(), expressions.makeOne(type), true), - // Fake dependency to guarantee acquire semantics - newFakeCtrlDep(dummy, label), - label, - Power.newISyncBarrier()); - } - - @Override - public List visitUnlock(Unlock e) { - return eventSequence( - Power.newLwSyncBarrier(), - newStore(e.getAddress(), expressions.makeZero((IntegerType)e.getAccessType()))); - } - // ============================================================================================= // =========================================== LLVM ============================================ // ============================================================================================= diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorRISCV.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorRISCV.java index 93214c3d94..c58379dbae 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorRISCV.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorRISCV.java @@ -12,9 +12,6 @@ import com.dat3m.dartagnan.program.event.lang.catomic.*; import com.dat3m.dartagnan.program.event.lang.linux.*; import com.dat3m.dartagnan.program.event.lang.llvm.*; -import com.dat3m.dartagnan.program.event.lang.pthread.InitLock; -import com.dat3m.dartagnan.program.event.lang.pthread.Lock; -import com.dat3m.dartagnan.program.event.lang.pthread.Unlock; import java.util.List; @@ -47,45 +44,6 @@ public List visitStoreExclusive(StoreExclusive e) { ); } - // ============================================================================================= - // ========================================= PTHREAD =========================================== - // ============================================================================================= - - @Override - public List visitInitLock(InitLock e) { - return eventSequence( - RISCV.newRWWFence(), - newStore(e.getAddress(), e.getMemValue()) - ); - } - - @Override - public List visitLock(Lock e) { - IntegerType type = (IntegerType)e.getAccessType(); - Register dummy = e.getFunction().newRegister(type); - Expression zero = expressions.makeZero(type); - Expression one = expressions.makeOne(type); - // We implement locks as spinlocks which are guaranteed to succeed, i.e. we can use - // assumes. With this we miss a ctrl dependency, but this does not matter - // because of the fence. - // TODO: Lock events are only used for implementing condvar intrinsic. - // If we have an alternative implementation for that, we can get rid of these events. - return eventSequence( - newRMWLoadExclusive(dummy, e.getAddress()), - newAssume(expressions.makeEQ(dummy, zero)), - newRMWStoreExclusive(e.getAddress(), one, true), - RISCV.newRRWFence() - ); - } - - @Override - public List visitUnlock(Unlock e) { - return eventSequence( - RISCV.newRWWFence(), - newStore(e.getAddress(), expressions.makeZero((IntegerType)e.getAccessType())) - ); - } - // ============================================================================================= // =========================================== LLVM ============================================ // ============================================================================================= diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorTso.java b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorTso.java index 71f354024f..80b4d45f23 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorTso.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/program/processing/compilation/VisitorTso.java @@ -3,7 +3,6 @@ import com.dat3m.dartagnan.expression.Expression; import com.dat3m.dartagnan.expression.Type; import com.dat3m.dartagnan.expression.type.BooleanType; -import com.dat3m.dartagnan.expression.type.IntegerType; import com.dat3m.dartagnan.program.Register; import com.dat3m.dartagnan.program.event.Event; import com.dat3m.dartagnan.program.event.MemoryEvent; @@ -12,9 +11,6 @@ import com.dat3m.dartagnan.program.event.core.*; import com.dat3m.dartagnan.program.event.lang.catomic.*; import com.dat3m.dartagnan.program.event.lang.llvm.*; -import com.dat3m.dartagnan.program.event.lang.pthread.InitLock; -import com.dat3m.dartagnan.program.event.lang.pthread.Lock; -import com.dat3m.dartagnan.program.event.lang.pthread.Unlock; import java.util.List; @@ -38,41 +34,6 @@ public List visitTSOXchg(TSOXchg e) { )); } - // ============================================================================================= - // ========================================= PTHREAD =========================================== - // ============================================================================================= - - public List visitInitLock(InitLock e) { - return eventSequence( - newStore(e.getAddress(), e.getMemValue()), - X86.newMemoryFence() - ); - } - - @Override - public List visitLock(Lock e) { - IntegerType type = (IntegerType)e.getAccessType(); - Register dummy = e.getFunction().newRegister(type); - // We implement locks as spinlocks which are guaranteed to succeed, i.e. we can - // use assumes. Nothing else is needed to guarantee acquire semantics in TSO. - // TODO: Lock events are only used for implementing condvar intrinsic. - // If we have an alternative implementation for that, we can get rid of these events. - Load load = newRMWLoad(dummy, e.getAddress()); - return eventSequence( - load, - newAssume(expressions.makeEQ(dummy, expressions.makeZero(type))), - newRMWStore(load, e.getAddress(), expressions.makeOne(type)) - ); - } - - @Override - public List visitUnlock(Unlock e) { - return eventSequence( - newStore(e.getAddress(), expressions.makeZero((IntegerType)e.getAccessType())), - X86.newMemoryFence() - ); - } - // ============================================================================================= // =========================================== LLVM ============================================ // ============================================================================================= diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/ExecutionGraph.java b/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/ExecutionGraph.java index 55df9bfd03..a6bd78ed1a 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/ExecutionGraph.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/ExecutionGraph.java @@ -265,6 +265,10 @@ private RelationGraph createGraphFromRelation(Relation rel) { graph = new SetIdentityGraph(set); } else if (relClass == Empty.class) { graph = new EmptyGraph(); + } else if (relClass == AllocPtr.class) { + graph = new AllocPtrGraph(); + } else if (relClass == AllocMem.class) { + graph = new AllocMemGraph(); } else { final String error = String.format("Cannot handle relation %s with definition of type %s.", rel, relClass.getSimpleName()); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/basePredicates/AllocMemGraph.java b/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/basePredicates/AllocMemGraph.java new file mode 100644 index 0000000000..767134513e --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/basePredicates/AllocMemGraph.java @@ -0,0 +1,81 @@ +package com.dat3m.dartagnan.solver.caat4wmm.basePredicates; + +import com.dat3m.dartagnan.solver.caat.misc.EdgeDirection; +import com.dat3m.dartagnan.solver.caat.predicates.relationGraphs.Edge; +import com.dat3m.dartagnan.verification.model.EventData; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +public class AllocMemGraph extends StaticWMMGraph { + + private Map> allocmems; + + @Override + public boolean containsById(int id1, int id2) { + if (allocmems.containsKey(id1)) { + return allocmems.get(id1).contains(id2); + } + return false; + } + + @Override + public int size(int id, EdgeDirection dir) { + if (dir == EdgeDirection.OUTGOING) { + return allocmems.containsKey(id) ? allocmems.get(id).size() : 0; + } else { + return (int) allocmems.values().stream() + .filter(sinks -> sinks.contains(id)).count(); + } + } + + @Override + public void repopulate() { + final Map> addressAllocsMap = model.getAddressAllocsMap(); + final Map> addressReadsMap = model.getAddressReadsMap(); + final Map> addressWritesMap = model.getAddressWritesMap(); + allocmems = new HashMap<>(); + for (Map.Entry> allocsEntry : addressAllocsMap.entrySet()) { + final Object address = allocsEntry.getKey(); + final Set allocs = allocsEntry.getValue().stream() + .map(EventData::getId).collect(Collectors.toSet()); + Stream.of(addressReadsMap, addressWritesMap) + .forEach(accessMap -> { + if (accessMap.containsKey(address)) { + final Set accessIds = accessMap.get(address).stream() + .map(EventData::getId).collect(Collectors.toSet()); + allocs.forEach(id -> allocmems.computeIfAbsent(id, k -> new HashSet<>()) + .addAll(accessIds)); + } + }); + } + size = allocmems.values().stream().mapToInt(Set::size).sum(); + } + + @Override + public Stream edgeStream() { + return allocmems.entrySet().stream() + .flatMap(entry -> entry.getValue().stream() + .map(id -> new Edge(entry.getKey(), id))); + } + + @Override + public Stream edgeStream(int id, EdgeDirection dir) { + if (dir == EdgeDirection.OUTGOING) { + if (!allocmems.containsKey(id)) { + return Stream.empty(); + } + return allocmems.get(id).stream().map(i -> new Edge(id, i)); + } else { + return allocmems.entrySet().stream() + .filter(entry -> entry.getValue().contains(id)) + .map(entry -> new Edge(entry.getKey(), id)); + } + } + +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/basePredicates/AllocPtrGraph.java b/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/basePredicates/AllocPtrGraph.java new file mode 100644 index 0000000000..ec4d9a255f --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/basePredicates/AllocPtrGraph.java @@ -0,0 +1,86 @@ +package com.dat3m.dartagnan.solver.caat4wmm.basePredicates; + +import com.dat3m.dartagnan.solver.caat.misc.EdgeDirection; +import com.dat3m.dartagnan.solver.caat.predicates.relationGraphs.Edge; +import com.dat3m.dartagnan.verification.model.EventData; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +public class AllocPtrGraph extends StaticWMMGraph { + + private Map> allocptrs; + + @Override + public boolean containsById(int id1, int id2) { + if (allocptrs.containsKey(id1)) { + return allocptrs.get(id1).contains(id2); + } + return false; + } + + @Override + public int size(int id, EdgeDirection dir) { + if (dir == EdgeDirection.OUTGOING) { + return allocptrs.containsKey(id) ? allocptrs.get(id).size() : 0; + } else { + return (int) allocptrs.values().stream() + .filter(sinks -> sinks.contains(id)).count(); + } + } + + @Override + public void repopulate() { + final Map> addressAllocsMap = model.getAddressAllocsMap(); + final Map> addressFreesMap = model.getAddressFreesMap(); + allocptrs = new HashMap<>(); + // ALLOC -> FREE + for (Map.Entry> allocsEntry : addressAllocsMap.entrySet()) { + final Object address = allocsEntry.getKey(); + if (!addressFreesMap.containsKey(address)) { continue; } + final Set allocs = allocsEntry.getValue(); + final Set frees = addressFreesMap.get(address); + for (EventData a : allocs) { + final Set freeIds = frees.stream() + .map(EventData::getId).collect(Collectors.toSet()); + allocptrs.put(a.getId(), freeIds); + } + } + // FREE -> FREE + for (Set frees : addressFreesMap.values()) { + for (EventData f : frees) { + final Set freeIds = frees.stream() + .map(EventData::getId).collect(Collectors.toSet()); + allocptrs.put(f.getId(), freeIds); + } + final int n = frees.size(); + } + size = allocptrs.values().stream().mapToInt(Set::size).sum(); + } + + @Override + public Stream edgeStream() { + return allocptrs.entrySet().stream() + .flatMap(entry -> entry.getValue().stream() + .map(id -> new Edge(entry.getKey(), id))); + } + + @Override + public Stream edgeStream(int id, EdgeDirection dir) { + if (dir == EdgeDirection.OUTGOING) { + if (!allocptrs.containsKey(id)) { + return Stream.empty(); + } + return allocptrs.get(id).stream().map(i -> new Edge(id, i)); + } else { + return allocptrs.entrySet().stream() + .filter(entry -> entry.getValue().contains(id)) + .map(entry -> new Edge(entry.getKey(), id)); + } + } + +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/utils/DominatorTree.java b/dartagnan/src/main/java/com/dat3m/dartagnan/utils/DominatorTree.java index cc55eaf7f7..9e4bcfd5db 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/utils/DominatorTree.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/utils/DominatorTree.java @@ -48,6 +48,10 @@ public TNode getRoot() { return root; } + public boolean contains(TNode node) { + return immDominator.containsKey(node); + } + public boolean isDominatedBy(TNode node, TNode dominator) { return getNearestCommonDominator(node, dominator) == dominator; } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/EventData.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/EventData.java index b764a35125..6510b42d3b 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/EventData.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/EventData.java @@ -90,6 +90,8 @@ public boolean isExclusive() { public boolean isRMW() { return event.hasTag(RMW); } + public boolean isAlloc() { return event.hasTag(ALLOC); } + public boolean isFree() { return event.hasTag(FREE); } public boolean hasTag(String tag) { return event.hasTag(tag); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModel.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModel.java index 199edfad44..f73a5ff93b 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModel.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModel.java @@ -10,6 +10,8 @@ import com.dat3m.dartagnan.program.event.RegWriter; import com.dat3m.dartagnan.program.event.Tag; import com.dat3m.dartagnan.program.event.core.CondJump; +import com.dat3m.dartagnan.program.event.core.MemAlloc; +import com.dat3m.dartagnan.program.event.core.MemFree; import com.dat3m.dartagnan.program.event.core.MemoryCoreEvent; import com.dat3m.dartagnan.program.event.lang.svcomp.BeginAtomic; import com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic; @@ -58,6 +60,8 @@ public class ExecutionModel { private final Map> addressWritesMap; // This ALSO contains the init writes private final Map addressInitMap; //Note, we could merge the three above maps into a single one that holds writes, reads and init writes. + private final Map> addressAllocsMap; + private final Map> addressFreesMap; private final Map> coherenceMap; @@ -72,6 +76,8 @@ public class ExecutionModel { private Map> addressReadsMapView; private Map> addressWritesMapView; private Map addressInitMapView; + private Map> addressAllocsMapView; + private Map> addressFreesMapView; private Map> coherenceMapView; @@ -88,6 +94,8 @@ private ExecutionModel(EncodingContext c) { addressReadsMap = new HashMap<>(); addressWritesMap = new HashMap<>(); addressInitMap = new HashMap<>(); + addressAllocsMap = new HashMap<>(); + addressFreesMap = new HashMap<>(); eventMap = new EventMap(); coherenceMap = new HashMap<>(); @@ -109,6 +117,8 @@ private void createViews() { addressReadsMapView = Collections.unmodifiableMap(addressReadsMap); addressWritesMapView = Collections.unmodifiableMap(addressWritesMap); addressInitMapView = Collections.unmodifiableMap(addressInitMap); + addressAllocsMapView = Collections.unmodifiableMap(addressAllocsMap); + addressFreesMapView = Collections.unmodifiableMap(addressFreesMap); coherenceMapView = Collections.unmodifiableMap(coherenceMap); } @@ -162,6 +172,12 @@ public Map> getAddressReadsMap() { public Map> getAddressWritesMap() { return addressWritesMapView; } + public Map> getAddressAllocsMap() { + return addressAllocsMapView; + } + public Map> getAddressFreesMap() { + return addressFreesMapView; + } public Map getAddressInitMap() { return addressInitMapView; } @@ -199,6 +215,8 @@ private void extractEventsFromModel() { addressInitMap.clear(); // This one can probably be constant and need not be rebuilt! addressWritesMap.clear(); addressReadsMap.clear(); + addressAllocsMap.clear(); + addressFreesMap.clear(); writeReadsMap.clear(); eventMap.clear(); uninitRegReads.clear(); @@ -208,6 +226,7 @@ private void extractEventsFromModel() { List threadEndIndexList = new ArrayList<>(threadList.size()); Map>> atomicBlockRangesMap = new HashMap<>(); + for (Thread thread : threadList) { List> atomicBlockRanges = atomicBlockRangesMap.computeIfAbsent(thread, key -> new ArrayList<>()); Event e = thread.getEntry(); @@ -303,6 +322,12 @@ private void addEvent(Event e, int globalId, int localId) { // ===== Jumps ===== // We override the meaning of execution here. A jump is executed IFF its condition was true. data.setWasExecuted(irModel.jumpTaken((CondJump) e)); + } else if (data.isAlloc()) { + Object address = checkNotNull(irModel.address(((MemAlloc) e).getAllocatedObject()).value()); + addressAllocsMap.computeIfAbsent(address, k -> new HashSet<>()).add(data); + } else if (data.isFree()) { + Object address = checkNotNull(irModel.address((MemFree) e).value()); + addressFreesMap.computeIfAbsent(address, k -> new HashSet<>()).add(data); } else { //TODO: Maybe add some other events (e.g. assertions) // But for now all non-visible events are simply registered without diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java index 1f68477b18..d2f64326c8 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelManager.java @@ -60,8 +60,8 @@ public ExecutionModelNext buildExecutionModel(EncodingContext context, ModelExt this.wmm = context.getTask().getMemoryModel(); this.domain = new EventDomainNext(executionModel); - extractEvents(); extractMemoryLayout(); + extractEvents(); relModelCache.clear(); relGraphCache.clear(); @@ -110,7 +110,12 @@ private void extractEvents() { private void extractEvent(Event e, ThreadModel tm, int id) { EventModel em; - if (e instanceof MemoryCoreEvent memEvent) { + if (e instanceof MemAlloc alloc) { + final MemoryObjectModel mo = executionModel.getMemoryObjectModel(alloc.getAllocatedObject()); + em = new MemAllocModel(alloc, tm, id, mo); + } else if (e instanceof MemFree free) { + em = new MemFreeModel(free, tm, id, new ValueModel(model.address(free).value())); + } else if (e instanceof MemoryCoreEvent memEvent) { ValueModel address = new ValueModel(model.address(memEvent).value()); ValueModel value = new ValueModel(model.value(memEvent).value()); @@ -151,7 +156,9 @@ private boolean toExtract(Event e) { || e instanceof GenericVisibleEvent || e instanceof Local || e instanceof Assert - || e instanceof CondJump; + || e instanceof CondJump + || (e instanceof MemAlloc alloc && alloc.isHeapAllocation()) + || e instanceof MemFree; } private void extractMemoryLayout() { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelNext.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelNext.java index 3bb6fceaa4..1870a3f229 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelNext.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ExecutionModelNext.java @@ -69,9 +69,10 @@ public List getEventModels() { } public List getVisibleEventModels() { - return eventList.stream() - .filter(e -> e instanceof MemoryEventModel || e instanceof GenericVisibleEventModel) - .toList(); + return eventList.stream().filter(e -> e instanceof MemoryEventModel || + e instanceof GenericVisibleEventModel || + e instanceof MemAllocModel || + e instanceof MemFreeModel).toList(); } public List getEventModelsByFilter(Filter filter) { @@ -86,6 +87,10 @@ public EventModel getEventModelByEvent(Event event) { return eventMap.get(event); } + public MemoryObjectModel getMemoryObjectModel(MemoryObject mo) { + return memoryLayoutMap.get(mo); + } + public Set getRelationModels() { return new HashSet<>(relationMap.values()); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ThreadModel.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ThreadModel.java index 17b4ba567e..3ef9ba9b2d 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ThreadModel.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/ThreadModel.java @@ -1,9 +1,7 @@ package com.dat3m.dartagnan.verification.model; import com.dat3m.dartagnan.program.Thread; -import com.dat3m.dartagnan.verification.model.event.EventModel; -import com.dat3m.dartagnan.verification.model.event.GenericVisibleEventModel; -import com.dat3m.dartagnan.verification.model.event.MemoryEventModel; +import com.dat3m.dartagnan.verification.model.event.*; import java.util.Collections; import java.util.List; @@ -40,8 +38,9 @@ public List getEventModels() { } public List getVisibleEventModels() { - return eventList.stream() - .filter(e -> e instanceof MemoryEventModel || e instanceof GenericVisibleEventModel) - .toList(); + return eventList.stream().filter(e -> e instanceof MemoryEventModel || + e instanceof GenericVisibleEventModel || + e instanceof MemAllocModel || + e instanceof MemFreeModel).toList(); } } \ No newline at end of file diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemAllocModel.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemAllocModel.java new file mode 100644 index 0000000000..6dd0782347 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemAllocModel.java @@ -0,0 +1,24 @@ +package com.dat3m.dartagnan.verification.model.event; + +import com.dat3m.dartagnan.program.event.core.MemAlloc; +import com.dat3m.dartagnan.verification.model.MemoryObjectModel; +import com.dat3m.dartagnan.verification.model.ThreadModel; + + +public class MemAllocModel extends DefaultEventModel implements RegReaderModel, RegWriterModel { + private final MemoryObjectModel memoryObj; + + public MemAllocModel(MemAlloc event, ThreadModel thread, int id, MemoryObjectModel mo) { + super(event, thread, id); + memoryObj = mo; + } + + public MemoryObjectModel getMemoryObject() { + return memoryObj; + } + + @Override + public MemAlloc getEvent() { + return (MemAlloc) event; + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemFreeModel.java b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemFreeModel.java new file mode 100644 index 0000000000..1bd0448c58 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/verification/model/event/MemFreeModel.java @@ -0,0 +1,19 @@ +package com.dat3m.dartagnan.verification.model.event; + +import com.dat3m.dartagnan.program.event.core.MemFree; +import com.dat3m.dartagnan.verification.model.ThreadModel; +import com.dat3m.dartagnan.verification.model.ValueModel; + + +public class MemFreeModel extends DefaultEventModel implements RegReaderModel { + private final ValueModel address; + + public MemFreeModel(MemFree event, ThreadModel thread, int id, ValueModel address) { + super(event, thread, id); + this.address = address; + } + + public ValueModel getAddress() { + return address; + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/witness/graphviz/ExecutionGraphVisualizer.java b/dartagnan/src/main/java/com/dat3m/dartagnan/witness/graphviz/ExecutionGraphVisualizer.java index 7ac470f089..401fe4d142 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/witness/graphviz/ExecutionGraphVisualizer.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/witness/graphviz/ExecutionGraphVisualizer.java @@ -120,7 +120,9 @@ private boolean showModel(EventModel e) { return e instanceof MemoryEventModel || e instanceof GenericVisibleEventModel || e instanceof LocalModel - || e instanceof AssertModel; + || e instanceof AssertModel + || e instanceof MemAllocModel + || e instanceof MemFreeModel; } private void addEvents(ExecutionModelNext model) { @@ -307,7 +309,7 @@ private String eventToNode(EventModel e) { } private String nodeLabel(EventModel e) { - // We have MemEvent + Fence + Local + Assert + // We have MemoryEvent + Alloc + Free + Fence + Termination + Local + Assert String tag = e.getEvent().toString(); if (e instanceof MemoryEventModel mem) { String address = getAddressString(mem.getAccessedAddress()); @@ -317,12 +319,15 @@ private String nodeLabel(EventModel e) { tag = mem instanceof StoreModel ? String.format("W(%s, %s%s)", address, value, moString) : String.format("%s = R(%s%s)", value, address, moString); + } else if (e instanceof MemAllocModel am) { + tag = String.format("%s <- HeapAlloc", getAddressString(am.getMemoryObject().address())); + } else if (e instanceof MemFreeModel fm) { + tag = String.format("Free(%s)", getAddressString(fm.getAddress())); } else if (e instanceof LocalModel lm) { tag = String.format("%s(%s) <- %s", - lm.getEvent().getResultRegister(), - lm.getValue(), - lm.getEvent().getExpr() - ); + lm.getEvent().getResultRegister(), + lm.getValue(), + lm.getEvent().getExpr()); } else if (e instanceof AssertModel am) { tag = String.format("Assertion(%s)", am.getResult()); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Constraint.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Constraint.java index 780ee102ad..ca5a3b8fc3 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Constraint.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Constraint.java @@ -87,6 +87,8 @@ default T visitConstraint(Constraint constraint) { default T visitCoherence(Coherence co) { return visitDefinition(co); } default T visitSameLocation(SameLocation loc) { return visitDefinition(loc); } default T visitReadFrom(ReadFrom rf) { return visitDefinition(rf); } + default T visitAllocPtr(AllocPtr aPtr) { return visitDefinition(aPtr); } + default T visitAllocMem(AllocMem aMem) { return visitDefinition(aMem); } // --- Target-specific definitions default T visitCASDependency(CASDependency casDep) { return visitDefinition(casDep); } // IMM default T visitLinuxCriticalSections(LinuxCriticalSections rscs) { return visitDefinition(rscs); } // Linux diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/RelationNameRepository.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/RelationNameRepository.java index 73fd1571e7..27e0ba9db8 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/RelationNameRepository.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/RelationNameRepository.java @@ -21,6 +21,8 @@ public class RelationNameRepository { public static final String ADDR = "addr"; public static final String CTRL = "ctrl"; public static final String CASDEP = "casdep"; + public static final String ALLOCPTR = "allocptr"; + public static final String ALLOCMEM = "allocmem"; public static final String SI = "si"; public static final String SR = "sr"; public static final String SCTA = "scta"; // same-cta, the same as same_block_r in alloy diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java index be7b075120..8616777fd7 100755 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/Wmm.java @@ -205,16 +205,19 @@ private Relation makePredefinedRelation(String name) { case CTRLDIRECT -> new DirectControlDependency(r); case EMPTY -> new Empty(r); case IDDTRANS -> new TransitiveClosure(r, getOrCreatePredefinedRelation(IDD)); - case DATA -> intersection(r, - getOrCreatePredefinedRelation(IDDTRANS), - addDefinition(product(newRelation(), Tag.MEMORY, Tag.MEMORY)) - ); + case DATA -> intersection(r, getOrCreatePredefinedRelation(IDDTRANS), + addDefinition(new CartesianProduct(newRelation(), + Filter.union(Filter.byTag(Tag.MEMORY), Filter.byTag(Tag.ALLOC)), + Filter.byTag(Tag.MEMORY)))); case ADDR -> { Relation addrdirect = getOrCreatePredefinedRelation(ADDRDIRECT); Relation comp = addDefinition(composition(newRelation(), getOrCreatePredefinedRelation(IDDTRANS), addrdirect)); Relation union = addDefinition(union(newRelation(), addrdirect, comp)); Relation mm = addDefinition(product(newRelation(), Tag.MEMORY, Tag.MEMORY)); - yield intersection(r, union, mm); + Relation mf = addDefinition(product(newRelation(), Tag.MEMORY, Tag.FREE)); + Relation af = addDefinition(product(newRelation(), Tag.ALLOC, Tag.FREE)); + Relation productUnion = addDefinition(union(newRelation(), mm, mf, af)); + yield intersection(r, union, productUnion); } case CTRL -> { Relation comp = addDefinition(composition(newRelation(), getOrCreatePredefinedRelation(IDDTRANS), @@ -222,6 +225,8 @@ private Relation makePredefinedRelation(String name) { Relation mv = addDefinition(product(newRelation(), Tag.MEMORY, Tag.VISIBLE)); yield intersection(r, comp, mv); } + case ALLOCPTR -> new AllocPtr(r); + case ALLOCMEM -> new AllocMem(r); case SR -> new SameScope(r); case SCTA -> new SameScope(r, Tag.PTX.CTA); case SSG -> new SameScope(r, Tag.Vulkan.SUB_GROUP); @@ -238,8 +243,8 @@ private Relation makePredefinedRelation(String name) { return addDefinition(def); } - private Definition union(Relation r0, Relation r1, Relation r2) { - return new Union(r0, r1, r2); + private Definition union(Relation r0, Relation... others) { + return new Union(r0, others); } private Definition intersection(Relation r0, Relation r1, Relation r2) { diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java index 6a43920cc8..d2426f51b9 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/LazyRelationAnalysis.java @@ -34,8 +34,7 @@ import java.util.stream.Collectors; import static com.dat3m.dartagnan.program.Register.UsageType.*; -import static com.dat3m.dartagnan.program.event.Tag.FENCE; -import static com.dat3m.dartagnan.program.event.Tag.VISIBLE; +import static com.dat3m.dartagnan.program.event.Tag.*; import static java.util.stream.Collectors.toSet; public class LazyRelationAnalysis extends NativeRelationAnalysis { @@ -287,6 +286,29 @@ public RelationAnalysis.Knowledge visitCASDependency(CASDependency definition) { return new RelationAnalysis.Knowledge(must, must); } + @Override + public RelationAnalysis.Knowledge visitAllocPtr(AllocPtr definition) { + long start = System.currentTimeMillis(); + RelationAnalysis.Knowledge base = nativeInitializer.visitAllocPtr(definition); + EventGraph may = ImmutableMapEventGraph.from(base.getMaySet()); + EventGraph must = ImmutableMapEventGraph.from(base.getMustSet()); + time(definition, start, System.currentTimeMillis()); + return new RelationAnalysis.Knowledge(may, must); + } + + @Override + public RelationAnalysis.Knowledge visitAllocMem(AllocMem definition) { + long start = System.currentTimeMillis(); + Set allocs = new HashSet<>(program.getThreadEventsWithAllTags(ALLOC)); + Set memoryEvents = new HashSet<>(program.getThreadEventsWithAllTags(MEMORY)); + EventGraph may = new LazyEventGraph(allocs, memoryEvents, (e1, e2) -> + alias.mayObjectAlias((MemoryCoreEvent) e1, (MemoryCoreEvent) e2)); + EventGraph must = new LazyEventGraph(allocs, memoryEvents, (e1, e2) -> + alias.mustObjectAlias((MemoryCoreEvent) e1, (MemoryCoreEvent) e2)); + time(definition, start, System.currentTimeMillis()); + return new RelationAnalysis.Knowledge(may, must); + } + @Override public RelationAnalysis.Knowledge visitLinuxCriticalSections(LinuxCriticalSections definition) { long start = System.currentTimeMillis(); @@ -340,26 +362,13 @@ public RelationAnalysis.Knowledge visitReadFrom(ReadFrom definition) { @Override public RelationAnalysis.Knowledge visitSameLocation(SameLocation definition) { long start = System.currentTimeMillis(); - List memoryEvents = program.getThreadEvents(MemoryCoreEvent.class); - Map> mayData = new HashMap<>(); - Map> mustData = new HashMap<>(); - for (int i = 0; i < memoryEvents.size(); i++) { - MemoryCoreEvent e1 = memoryEvents.get(i); - for (int j = i; j < memoryEvents.size(); j++) { - MemoryCoreEvent e2 = memoryEvents.get(j); - if (!exec.areMutuallyExclusive(e1, e2) && alias.mayAlias(e1, e2)) { - mayData.computeIfAbsent(e1, x -> new HashSet<>()).add(e2); - mayData.computeIfAbsent(e2, x -> new HashSet<>()).add(e1); - if (alias.mustAlias(e1, e2)) { - mustData.computeIfAbsent(e1, x -> new HashSet<>()).add(e2); - mustData.computeIfAbsent(e2, x -> new HashSet<>()).add(e1); - } - } - } - } - // Cannot be a LazyEventGraph because AliasAnalysis is not thread safe - EventGraph may = new ImmutableMapEventGraph(mayData); - EventGraph must = new ImmutableMapEventGraph(mustData); + Set memoryEvents = new HashSet<>(program.getThreadEvents(MemoryCoreEvent.class)); + EventGraph may = new LazyEventGraph(memoryEvents, memoryEvents, (e1, e2) -> + !exec.areMutuallyExclusive(e1, e2) && + alias.mayAlias((MemoryCoreEvent) e1, (MemoryCoreEvent) e2)); + EventGraph must = new LazyEventGraph(memoryEvents, memoryEvents, (e1, e2) -> + !exec.areMutuallyExclusive(e1, e2) && + alias.mustAlias((MemoryCoreEvent) e1, (MemoryCoreEvent) e2)); time(definition, start, System.currentTimeMillis()); return new RelationAnalysis.Knowledge(may, must); } diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java index 10eb3e811d..17449e02fe 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/analysis/NativeRelationAnalysis.java @@ -856,6 +856,50 @@ public MutableKnowledge visitCoherence(Coherence co) { return new MutableKnowledge(may, must); } + @Override + public MutableKnowledge visitAllocPtr(AllocPtr allocPtr) { + MutableEventGraph may = new MapEventGraph(); + MutableEventGraph must = new MapEventGraph(); + List allocs = program.getThreadEventsWithAllTags(ALLOC).stream() + .map(e -> (MemAlloc) e).collect(Collectors.toList()); + List frees = program.getThreadEvents(MemFree.class); + List allocAndFrees = Stream.concat(allocs.stream(), frees.stream()).toList(); + for (MemoryCoreEvent e1 : allocAndFrees) { + for (MemFree e2 : frees) { + if (alias.mayAlias(e1, e2)) { + may.add(e1, e2); + if (alias.mustAlias(e1, e2)) { + must.add(e1, e2); + } + } + } + } + return new MutableKnowledge(may, must); + } + + @Override + public MutableKnowledge visitAllocMem(AllocMem allocMem) { + MutableEventGraph may = new MapEventGraph(); + MutableEventGraph must = new MapEventGraph(); + List memEvents = program.getThreadEvents(MemoryCoreEvent.class).stream() + .filter(e -> !(e instanceof MemAlloc) && !(e instanceof MemFree)) + .collect(Collectors.toList()); + List allocs = program.getThreadEventsWithAllTags(ALLOC).stream() + .map(e -> (MemAlloc) e).collect(Collectors.toList()); + for (MemAlloc e1 : allocs) { + for (MemoryCoreEvent e2 : memEvents) { + if (e2 instanceof Init) { continue; } + if (alias.mayObjectAlias(e1, e2)) { + may.add(e1, e2); + if (alias.mustObjectAlias(e1, e2)) { + must.add(e1, e2); + } + } + } + } + return new MutableKnowledge(may, must); + } + @Override public MutableKnowledge visitReadFrom(ReadFrom rf) { logger.trace("Computing knowledge about read-from"); diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocMem.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocMem.java new file mode 100644 index 0000000000..46c8fe60dc --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocMem.java @@ -0,0 +1,17 @@ +package com.dat3m.dartagnan.wmm.definition; + +import com.dat3m.dartagnan.wmm.Definition; +import com.dat3m.dartagnan.wmm.Relation; + +import static com.dat3m.dartagnan.wmm.RelationNameRepository.ALLOCMEM; + +public class AllocMem extends Definition { + public AllocMem(Relation r) { + super(r, ALLOCMEM); + } + + @Override + public T accept(Visitor v) { + return v.visitAllocMem(this); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocPtr.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocPtr.java new file mode 100644 index 0000000000..5af69c9570 --- /dev/null +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/definition/AllocPtr.java @@ -0,0 +1,18 @@ +package com.dat3m.dartagnan.wmm.definition; + +import com.dat3m.dartagnan.wmm.Definition; +import com.dat3m.dartagnan.wmm.Relation; + +import static com.dat3m.dartagnan.wmm.RelationNameRepository.ALLOCPTR; + +public class AllocPtr extends Definition { + + public AllocPtr(Relation r) { + super(r, ALLOCPTR); + } + + @Override + public T accept(Visitor v) { + return v.visitAllocPtr(this); + } +} diff --git a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/utils/ConstraintCopier.java b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/utils/ConstraintCopier.java index f1f218815b..570c1af1d9 100644 --- a/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/utils/ConstraintCopier.java +++ b/dartagnan/src/main/java/com/dat3m/dartagnan/wmm/utils/ConstraintCopier.java @@ -196,6 +196,16 @@ public CASDependency visitCASDependency(CASDependency casDep) { return new CASDependency(translate(casDep.getDefinedRelation())); } + @Override + public AllocPtr visitAllocPtr(AllocPtr aPtr) { + return new AllocPtr(translate(aPtr.getDefinedRelation())); + } + + @Override + public AllocMem visitAllocMem(AllocMem aMem) { + return new AllocMem(translate(aMem.getDefinedRelation())); + } + @Override public LinuxCriticalSections visitLinuxCriticalSections(LinuxCriticalSections rscs) { return new LinuxCriticalSections(translate(rscs.getDefinedRelation())); diff --git a/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java b/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java new file mode 100644 index 0000000000..e6b594520f --- /dev/null +++ b/dartagnan/src/test/java/com/dat3m/dartagnan/llvm/AllocFreeTest.java @@ -0,0 +1,121 @@ +package com.dat3m.dartagnan.llvm; + +import com.dat3m.dartagnan.configuration.Alias; +import com.dat3m.dartagnan.configuration.Arch; +import com.dat3m.dartagnan.configuration.OptionNames; +import com.dat3m.dartagnan.encoding.ProverWithTracker; +import com.dat3m.dartagnan.parsers.cat.ParserCat; +import com.dat3m.dartagnan.parsers.program.ProgramParser; +import com.dat3m.dartagnan.program.Program; +import com.dat3m.dartagnan.utils.Result; +import com.dat3m.dartagnan.verification.VerificationTask; +import com.dat3m.dartagnan.verification.solving.AssumeSolver; +import com.dat3m.dartagnan.verification.solving.RefinementSolver; +import com.dat3m.dartagnan.wmm.Wmm; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.sosy_lab.common.ShutdownManager; +import org.sosy_lab.common.configuration.Configuration; +import org.sosy_lab.common.configuration.InvalidConfigurationException; +import org.sosy_lab.common.log.BasicLogManager; +import org.sosy_lab.java_smt.SolverContextFactory; +import org.sosy_lab.java_smt.api.SolverContext; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; + +import static com.dat3m.dartagnan.configuration.Alias.*; +import static com.dat3m.dartagnan.configuration.Arch.C11; +import static com.dat3m.dartagnan.configuration.Property.CAT_SPEC; +import static com.dat3m.dartagnan.utils.ResourceHelper.getRootPath; +import static com.dat3m.dartagnan.utils.ResourceHelper.getTestResourcePath; +import static com.dat3m.dartagnan.utils.Result.FAIL; +import static com.dat3m.dartagnan.utils.Result.PASS; +import static org.junit.Assert.assertEquals; + +@RunWith(Parameterized.class) +public class AllocFreeTest { + + private final String name; + private final Arch target; + private final Result expected; + + public AllocFreeTest(String name, Arch target, Result expected) { + this.name = name; + this.target = target; + this.expected = expected; + } + + @Parameterized.Parameters(name = "{index}: {0}, target={1}") + public static Iterable data() throws IOException { + return Arrays.asList(new Object[][]{ + {"test_ok_1", C11, PASS}, + {"test_ok_2", C11, PASS}, + {"test_err_address", C11, FAIL}, + {"test_err_race", C11, FAIL}, + {"test_err_double_free_1", C11, FAIL}, + {"test_err_double_free_2", C11, FAIL}, + {"test_err_no_free", C11, FAIL}, + {"test_err_no_alloc_1", C11, FAIL}, + {"test_err_no_alloc_2", C11, FAIL}, + {"test_err_use_before_alloc", C11, FAIL}, + {"test_err_use_after_free", C11, FAIL}, + }); + } + + @Test + public void testAssume() throws Exception { + for (String mmPath : List.of("cat/rc11.cat", "cat/c11.cat")) { + for (Alias aliasMethod : List.of(FIELD_INSENSITIVE , FIELD_SENSITIVE, FULL)) { + Configuration cfg = mkConfiguration(aliasMethod); + SolverContext ctx = mkCtx(cfg); + AssumeSolver s = AssumeSolver.run(ctx, mkProver(ctx), mkTask(cfg, mmPath)); + assertEquals(expected, s.getResult()); + } + } + } + + @Test + public void testRefinement() throws Exception { + for (String mmPath : List.of("cat/rc11.cat", "cat/c11.cat")) { + for (Alias aliasMethod : List.of(FIELD_INSENSITIVE , FIELD_SENSITIVE, FULL)) { + Configuration cfg = mkConfiguration(aliasMethod); + SolverContext ctx = mkCtx(cfg); + RefinementSolver s = RefinementSolver.run(ctx, mkProver(ctx), mkTask(cfg, mmPath)); + assertEquals(expected, s.getResult()); + } + } + } + + private SolverContext mkCtx(Configuration cfg) throws InvalidConfigurationException { + return SolverContextFactory.createSolverContext( + cfg, + BasicLogManager.create(cfg), + ShutdownManager.create().getNotifier(), + SolverContextFactory.Solvers.Z3); + } + + private ProverWithTracker mkProver(SolverContext ctx) { + return new ProverWithTracker(ctx, "", SolverContext.ProverOptions.GENERATE_MODELS); + } + + private VerificationTask mkTask(Configuration configuration, String mmPath) throws Exception { + VerificationTask.VerificationTaskBuilder builder = VerificationTask.builder() + .withConfig(configuration) + .withTarget(target); + Program program = new ProgramParser().parse(new File(getTestResourcePath("alloc/" + name + ".ll"))); + Wmm mcm = new ParserCat().parse(new File(getRootPath(mmPath))); + return builder.build(program, mcm, EnumSet.of(CAT_SPEC)); + } + + private Configuration mkConfiguration(Alias aliasMethod) throws InvalidConfigurationException { + return Configuration.builder() + .setOption(OptionNames.USE_INTEGERS, "true") + .setOption(OptionNames.ALIAS_METHOD, aliasMethod.asStringOption()) + .build(); + } +} \ No newline at end of file diff --git a/dartagnan/src/test/java/com/dat3m/dartagnan/others/miscellaneous/AnalysisTest.java b/dartagnan/src/test/java/com/dat3m/dartagnan/others/miscellaneous/AnalysisTest.java index 28c654bd66..d801128c02 100644 --- a/dartagnan/src/test/java/com/dat3m/dartagnan/others/miscellaneous/AnalysisTest.java +++ b/dartagnan/src/test/java/com/dat3m/dartagnan/others/miscellaneous/AnalysisTest.java @@ -624,6 +624,363 @@ public void fullPropagation1() throws InvalidConfigurationException { assertAlias(MAY, a, me3, me4); } + @Test + public void fieldsensitive6() throws InvalidConfigurationException { + program6(FIELD_SENSITIVE, MUST, NONE, MUST, MUST); + } + + @Test + public void fieldinsensitive6() throws InvalidConfigurationException { + program6(FIELD_INSENSITIVE, MUST, NONE, MAY, MUST); + } + + @Test + public void full6() throws InvalidConfigurationException { + program6(FULL, MUST, NONE, MUST, MUST); + } + + private void program6(Alias method, Result... expect) throws InvalidConfigurationException { + ProgramBuilder b = ProgramBuilder.forLanguage(SourceLanguage.LITMUS); + + MemoryObject x = b.newMemoryObject("x", 1); + + b.newThread(0); + Register r0 = b.getOrNewRegister(0, "r0"); + MemAlloc a = newHeapAlloc(r0, 2); // r0 = malloc(2) + b.addChild(0, a); + Store e0 = newStore(r0, value(2)); // *r0 = 2 + b.addChild(0, e0); + Register r1 = b.getOrNewRegister(0, "r1"); + Load e1 = newLoad(r1, x); // r1 = x + b.addChild(0, e1); + Store e2 = newStore(plus(r0, 1), r1); // *(r0 + 1) = r1 + b.addChild(0, e2); + MemFree f = newFree(r0); // free(r0) + b.addChild(0, f); + + Program program = b.build(); + AliasAnalysis aa = analyze(program, method); + MemAlloc al = (MemAlloc) findMatchingEventAfterProcessing(program, a); + MemoryCoreEvent me0 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e0); + MemoryCoreEvent me1 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e1); + MemoryCoreEvent me2 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e2); + MemFree fr = (MemFree) findMatchingEventAfterProcessing(program, f); + + assertObjectAlias(expect[0], aa, al, me0); + assertObjectAlias(expect[1], aa, al, me1); + assertObjectAlias(expect[2], aa, al, me2); + assertAlias(expect[3], aa, al, fr); + } + + @Test + public void fieldsensitive7() throws InvalidConfigurationException { + program7(FIELD_SENSITIVE, MUST, NONE, MUST, NONE, MAY, NONE, MUST, NONE, MUST, MAY, MUST, NONE, NONE, MUST, NONE); + } + + @Test + public void fieldinsensitive7() throws InvalidConfigurationException { + program7(FIELD_INSENSITIVE, MUST, NONE, MAY, MAY, MAY, NONE, MUST, MAY, MAY, MAY, MUST, NONE, NONE, MUST, NONE); + } + + @Test + public void full7() throws InvalidConfigurationException { + program7(FULL, MUST, NONE, MUST, NONE, NONE, NONE, MUST, NONE, MUST, MUST, MUST, NONE, NONE, MUST, NONE); + } + + private void program7(Alias method, Result... expect) throws InvalidConfigurationException{ + ProgramBuilder b = ProgramBuilder.forLanguage(SourceLanguage.LITMUS); + + b.newThread(0); + Register r0 = b.getOrNewRegister(0, "r0"); + MemAlloc a0 = newHeapAlloc(r0, 3); // r0 = malloc(3) + b.addChild(0, a0); + Register r1 = b.getOrNewRegister(0, "r1"); + MemAlloc a1 = newHeapAlloc(r1, 4); // r1 = malloc(4) + b.addChild(0, a1); + Store e0 = newStore(r0, r1); // *r0 = r1 + b.addChild(0, e0); + Store e1 = newStore(r1, r0); // *r1 = r0 + b.addChild(0, e1); + Register r2 = b.getOrNewRegister(0, "r2"); + b.addChild(0, newLocal(r2, r0)); // r2 = r0 + Store e2 = newStore(plus(r2, 2), value(1)); // *(r2 + 2) = 1 + b.addChild(0, e2); + Register r3 = b.getOrNewRegister(0, "r3"); + b.addChild(0, newLocal(r3, r1)); // r3 = r1 + Store e3 = newStore(plus(r3, 3), value(1)); // *(r3 + 3) = 1 + b.addChild(0, e3); + Register r4 = b.getOrNewRegister(0, "r4"); + b.addChild(0, newLocal(r4, r0)); // r4 = r0 + b.addChild(0, newLocal(r4, r1)); // r4 = r1 + Store e4 = newStore(r4, value(1)); // *r4 = 1 + b.addChild(0, e4); + MemFree f0 = newFree(r0); // free(r0) + b.addChild(0, f0); + MemFree f1 = newFree(r1); // free(r1) + b.addChild(0, f1); + + Program program = b.build(); + AliasAnalysis aa = analyze(program, method); + MemAlloc al0 = (MemAlloc) findMatchingEventAfterProcessing(program, a0); + MemAlloc al1 = (MemAlloc) findMatchingEventAfterProcessing(program, a1); + MemoryCoreEvent me0 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e0); + MemoryCoreEvent me1 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e1); + MemoryCoreEvent me2 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e2); + MemoryCoreEvent me3 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e3); + MemoryCoreEvent me4 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e4); + MemFree fr0 = (MemFree) findMatchingEventAfterProcessing(program, f0); + MemFree fr1 = (MemFree) findMatchingEventAfterProcessing(program, f1); + + assertObjectAlias(expect[0], aa, al0, me0); + assertObjectAlias(expect[1], aa, al0, me1); + assertObjectAlias(expect[2], aa, al0, me2); + assertObjectAlias(expect[3], aa, al0, me3); + assertObjectAlias(expect[4], aa, al0, me4); + assertObjectAlias(expect[5], aa, al1, me0); + assertObjectAlias(expect[6], aa, al1, me1); + assertObjectAlias(expect[7], aa, al1, me2); + assertObjectAlias(expect[8], aa, al1, me3); + assertObjectAlias(expect[9], aa, al1, me4); + assertAlias(expect[10], aa, al0, fr0); + assertAlias(expect[11], aa, al0, fr1); + assertAlias(expect[12], aa, al1, fr0); + assertAlias(expect[13], aa, al1, fr1); + assertAlias(expect[14], aa, fr0, fr1); + } + + @Test + public void fieldsensitive8() throws InvalidConfigurationException { + program8(FIELD_SENSITIVE, MUST, MUST, MUST, MUST, MUST, NONE, MUST); + } + + @Test + public void fieldinsensitive8() throws InvalidConfigurationException { + program8(FIELD_INSENSITIVE, MUST, MAY, MAY, MUST, MAY, NONE, MUST); + } + + @Test + public void full8() throws InvalidConfigurationException { + program8(FULL, MUST, MUST, MUST, MUST, MUST, NONE, MUST); + } + + private void program8(Alias method, Result... expect) throws InvalidConfigurationException { + ProgramBuilder b = ProgramBuilder.forLanguage(SourceLanguage.LITMUS); + + MemoryObject x = b.newMemoryObject("x", 1); + + b.newThread(0); + Register r0 = b.getOrNewRegister(0, "r0"); + MemAlloc a0 = newHeapAlloc(r0, 4); // r0 = malloc(4) + b.addChild(0, a0); + Store e0 = newStore(r0, value(1)); // *r0 = 1 + b.addChild(0, e0); + Register r1 = b.getOrNewRegister(0, "r1"); + b.addChild(0, newLocal(r1, plus(r0, 2))); // r1 = r0 + 2 + Store e1 = newStore(r1, value(1)); // *r1 = 1 + b.addChild(0, e1); + Register r2 = b.getOrNewRegister(0, "r2"); + b.addChild(0, newLocal(r2, plus(r0, 3))); // r2 = r0 + 3 + Store e2 = newStore(r2, value(1)); // *r2 = 1 + b.addChild(0, e2); + Register r3 = b.getOrNewRegister(0, "r3"); + b.addChild(0, newLocal(r3, r0)); // r3 = r0 + Store e3 = newStore(r3, value(1)); // *r3 = 1 + b.addChild(0, e3); + Register r4 = b.getOrNewRegister(0, "r4"); + b.addChild(0, newLocal(r4, r1)); // r4 = r1 + Store e4 = newStore(r4, value(1)); // *r4 = 1 + b.addChild(0, e4); + Store e5 = newStore(x, value(1)); // x = 1 + b.addChild(0, e5); + MemFree f0 = newFree(r3); // free(r3) + b.addChild(0, f0); + + Program program = b.build(); + AliasAnalysis aa = analyze(program, method); + MemAlloc al0 = (MemAlloc) findMatchingEventAfterProcessing(program, a0); + MemoryCoreEvent me0 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e0); + MemoryCoreEvent me1 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e1); + MemoryCoreEvent me2 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e2); + MemoryCoreEvent me3 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e3); + MemoryCoreEvent me4 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e4); + MemoryCoreEvent me5 = (MemoryCoreEvent) findMatchingEventAfterProcessing(program, e5); + MemFree fr0 = (MemFree) findMatchingEventAfterProcessing(program, f0); + + assertObjectAlias(expect[0], aa, al0, me0); + assertObjectAlias(expect[1], aa, al0, me1); + assertObjectAlias(expect[2], aa, al0, me2); + assertObjectAlias(expect[3], aa, al0, me3); + assertObjectAlias(expect[4], aa, al0, me4); + assertObjectAlias(expect[5], aa, al0, me5); + assertAlias(expect[6], aa, al0, fr0); + } + + @Test + public void fieldsensitive9() throws InvalidConfigurationException { + program9(FIELD_SENSITIVE, MUST, NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, + NONE, NONE, NONE, + NONE, NONE, + NONE); + } + + @Test + public void fieldinsensitive9() throws InvalidConfigurationException { + program9(FIELD_INSENSITIVE, MUST, NONE, MUST, NONE, MAY, NONE, MAY, MAY, MAY, + NONE, MUST, NONE, NONE, MAY, NONE, MAY, MAY, MAY, + NONE, MUST, NONE, MAY, NONE, MAY, MAY, MAY, + NONE, NONE, MAY, NONE, MAY, MAY, MAY, + NONE, MAY, NONE, MAY, MAY, MAY, + MAY, MUST, MAY, MAY, MAY, + MAY, MAY, MAY, MAY, + MAY, MAY, MAY, + MAY, MAY, + MAY); + } + + @Test + public void full9() throws InvalidConfigurationException { + program9(FULL, MUST, NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, + NONE, MUST, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, + NONE, NONE, NONE, + NONE, NONE, + NONE); + } + + // This program is wrong because it frees the same memory multiple times. + // But it is suitable to test the alias analysis. + private void program9(Alias method, Result... expect) throws InvalidConfigurationException { + ProgramBuilder b = ProgramBuilder.forLanguage(SourceLanguage.LITMUS); + + MemoryObject x = b.newMemoryObject("x", 2); + x.setInitialValue(0, x); + MemoryObject y = b.newMemoryObject("y", 2); + + b.newThread(0); + Register r0 = b.getOrNewRegister(0, "r0"); + MemAlloc a0 = newHeapAlloc(r0, 2); // r0 = malloc(2) + b.addChild(0, a0); + Register r1 = b.getOrNewRegister(0, "r1"); + MemAlloc a1 = newHeapAlloc(r1, 3); // r1 = malloc(3) + b.addChild(0, a1); + Register r2 = b.getOrNewRegister(0, "r2"); + b.addChild(0, newLocal(r2, r0)); // r2 = r0 + Register r3 = b.getOrNewRegister(0, "r3"); + b.addChild(0, newLoad(r3, x)); // r3 = x + Register r4 = b.getOrNewRegister(0, "r4"); + b.addChild(0, newLocal(r4, plus(r3, 1))); // r4 = r3 + 1 + MemFree f0 = newFree(r0); // free(r0) + b.addChild(0, f0); + MemFree f1 = newFree(r1); // free(r1) + b.addChild(0, f1); + MemFree f2 = newFree(r2); // free(r2) + b.addChild(0, f2); + MemFree f3 = newFree(r3); // free(r3) + b.addChild(0, f3); + MemFree f4 = newFree(r4); // free(r4) + b.addChild(0, f4); + MemFree f5 = newFree(x); // free(x) + b.addChild(0, f5); + Register r5 = b.getOrNewRegister(0, "r5"); + b.addChild(0, newLocal(r5, plus(r0, 1))); // r5 = r0 + 1 + MemFree f6 = newFree(r5); // free(r5) + b.addChild(0, f6); + MemFree f7 = newFree(plus(r1, 2)); // free(r1 + 2) + b.addChild(0, f7); + Register r6 = b.getOrNewRegister(0, "r6"); + b.addChild(0, newLoad(r6, y)); // r6 = y + MemFree f8 = newFree(r6); // free(r6) + b.addChild(0, f8); + + Program program = b.build(); + AliasAnalysis aa = analyze(program, method); + MemAlloc al0 = (MemAlloc) findMatchingEventAfterProcessing(program, a0); + MemAlloc al1 = (MemAlloc) findMatchingEventAfterProcessing(program, a1); + MemFree fr0 = (MemFree) findMatchingEventAfterProcessing(program, f0); + MemFree fr1 = (MemFree) findMatchingEventAfterProcessing(program, f1); + MemFree fr2 = (MemFree) findMatchingEventAfterProcessing(program, f2); + MemFree fr3 = (MemFree) findMatchingEventAfterProcessing(program, f3); + MemFree fr4 = (MemFree) findMatchingEventAfterProcessing(program, f4); + MemFree fr5 = (MemFree) findMatchingEventAfterProcessing(program, f5); + MemFree fr6 = (MemFree) findMatchingEventAfterProcessing(program, f6); + MemFree fr7 = (MemFree) findMatchingEventAfterProcessing(program, f7); + MemFree fr8 = (MemFree) findMatchingEventAfterProcessing(program, f8); + + assertAlias(expect[0], aa, al0, fr0); + assertAlias(expect[1], aa, al0, fr1); + assertAlias(expect[2], aa, al0, fr2); + assertAlias(expect[3], aa, al0, fr3); + assertAlias(expect[4], aa, al0, fr4); + assertAlias(expect[5], aa, al0, fr5); + assertAlias(expect[6], aa, al0, fr6); + assertAlias(expect[7], aa, al0, fr7); + assertAlias(expect[8], aa, al0, fr8); + + assertAlias(expect[9], aa, al1, fr0); + assertAlias(expect[10], aa, al1, fr1); + assertAlias(expect[11], aa, al1, fr2); + assertAlias(expect[12], aa, al1, fr3); + assertAlias(expect[13], aa, al1, fr4); + assertAlias(expect[14], aa, al1, fr5); + assertAlias(expect[15], aa, al1, fr6); + assertAlias(expect[16], aa, al1, fr7); + assertAlias(expect[17], aa, al1, fr8); + + assertAlias(expect[18], aa, fr0, fr1); + assertAlias(expect[19], aa, fr0, fr2); + assertAlias(expect[20], aa, fr0, fr3); + assertAlias(expect[21], aa, fr0, fr4); + assertAlias(expect[22], aa, fr0, fr5); + assertAlias(expect[23], aa, fr0, fr6); + assertAlias(expect[24], aa, fr0, fr7); + assertAlias(expect[25], aa, fr0, fr8); + + assertAlias(expect[26], aa, fr1, fr2); + assertAlias(expect[27], aa, fr1, fr3); + assertAlias(expect[28], aa, fr1, fr4); + assertAlias(expect[29], aa, fr1, fr5); + assertAlias(expect[30], aa, fr1, fr6); + assertAlias(expect[31], aa, fr1, fr7); + assertAlias(expect[32], aa, fr1, fr8); + + assertAlias(expect[33], aa, fr2, fr3); + assertAlias(expect[34], aa, fr2, fr4); + assertAlias(expect[35], aa, fr2, fr5); + assertAlias(expect[36], aa, fr2, fr6); + assertAlias(expect[37], aa, fr2, fr7); + assertAlias(expect[38], aa, fr2, fr8); + + assertAlias(expect[39], aa, fr3, fr4); + assertAlias(expect[40], aa, fr3, fr5); + assertAlias(expect[41], aa, fr3, fr6); + assertAlias(expect[42], aa, fr3, fr7); + assertAlias(expect[43], aa, fr3, fr8); + + assertAlias(expect[44], aa, fr4, fr5); + assertAlias(expect[45], aa, fr4, fr6); + assertAlias(expect[46], aa, fr4, fr7); + assertAlias(expect[47], aa, fr4, fr8); + + assertAlias(expect[48], aa, fr5, fr6); + assertAlias(expect[49], aa, fr5, fr7); + assertAlias(expect[50], aa, fr5, fr8); + + assertAlias(expect[51], aa, fr6, fr7); + assertAlias(expect[52], aa, fr6, fr8); + + assertAlias(expect[53], aa, fr7, fr8); + } + private Load newLoad(Register value, Expression address) { return EventFactory.newLoad(value, address); } @@ -636,6 +993,10 @@ private Store newStore(Expression address, Expression value) { return EventFactory.newStore(address, value); } + private MemAlloc newHeapAlloc(Register resultReg, int size) { + return EventFactory.newAlloc(resultReg, types.getByteType(), value(size), true, true); + } + private Expression value(long v) { return expressions.makeValue(v, types.getArchType()); } @@ -677,6 +1038,23 @@ private void assertAlias(Result expect, AliasAnalysis a, MemoryCoreEvent x, Memo } } + private void assertObjectAlias(Result expect, AliasAnalysis a, MemoryCoreEvent x, MemoryCoreEvent y) { + switch (expect) { + case NONE: + assertFalse(a.mayObjectAlias(x, y)); + assertFalse(a.mustObjectAlias(x, y)); + break; + case MAY: + assertTrue(a.mayObjectAlias(x, y)); + assertFalse(a.mustObjectAlias(x, y)); + break; + case MUST: + assertTrue(a.mayObjectAlias(x, y)); + assertTrue(a.mustObjectAlias(x, y)); + break; + } + } + /* * This test may fail to show the presence of an error immediately. * When it fails during a merge, consider repeating it on the head of the target branch. diff --git a/dartagnan/src/test/resources/alloc/test_err_address.ll b/dartagnan/src/test/resources/alloc/test_err_address.ll new file mode 100644 index 0000000000..472487495c --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_err_address.ll @@ -0,0 +1,123 @@ +; ModuleID = 'benchmarks/alloc/test1_err_address.c' +source_filename = "benchmarks/alloc/test1_err_address.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !31 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i64, i64* %2, align 8, !dbg !44 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !45 + %10 = load i32*, i32** %3, align 8, !dbg !46 + %11 = getelementptr inbounds i32, i32* %10, i64 4, !dbg !47 + %12 = bitcast i32* %11 to i8*, !dbg !46 + call void @free(i8* noundef %12) #4, !dbg !48 + ret i32 0, !dbg !49 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_address.c", directory: "", checksumkind: CSK_MD5, checksum: "10f0e4c5d76d57d15b440887b3a1fd9f") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 18, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 23, column: 10, scope: !31) +!47 = !DILocation(line: 23, column: 14, scope: !31) +!48 = !DILocation(line: 23, column: 5, scope: !31) +!49 = !DILocation(line: 25, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test_err_double_free_1.ll b/dartagnan/src/test/resources/alloc/test_err_double_free_1.ll new file mode 100644 index 0000000000..2d8bc4b507 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_err_double_free_1.ll @@ -0,0 +1,126 @@ +; ModuleID = 'benchmarks/alloc/test1_err_double_free_1.c' +source_filename = "benchmarks/alloc/test1_err_double_free_1.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !31 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i64, i64* %2, align 8, !dbg !44 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !45 + %10 = load i32*, i32** %3, align 8, !dbg !46 + %11 = bitcast i32* %10 to i8*, !dbg !46 + call void @free(i8* noundef %11) #4, !dbg !47 + %12 = load i32*, i32** %3, align 8, !dbg !48 + %13 = bitcast i32* %12 to i8*, !dbg !48 + call void @free(i8* noundef %13) #4, !dbg !49 + ret i32 0, !dbg !50 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_double_free_1.c", directory: "", checksumkind: CSK_MD5, checksum: "000dddf7e9b0673f5f3e4f8212feb516") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 18, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 23, column: 10, scope: !31) +!47 = !DILocation(line: 23, column: 5, scope: !31) +!48 = !DILocation(line: 24, column: 10, scope: !31) +!49 = !DILocation(line: 24, column: 5, scope: !31) +!50 = !DILocation(line: 26, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test_err_double_free_2.ll b/dartagnan/src/test/resources/alloc/test_err_double_free_2.ll new file mode 100644 index 0000000000..b2c310951f --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_err_double_free_2.ll @@ -0,0 +1,126 @@ +; ModuleID = 'benchmarks/alloc/test1_err_double_free_2.c' +source_filename = "benchmarks/alloc/test1_err_double_free_2.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + %11 = load i32*, i32** %3, align 8, !dbg !30 + %12 = bitcast i32* %11 to i8*, !dbg !30 + call void @free(i8* noundef %12) #4, !dbg !31 + ret i8* null, !dbg !32 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !33 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !36, metadata !DIExpression()), !dbg !40 + call void @llvm.dbg.declare(metadata i32** %3, metadata !41, metadata !DIExpression()), !dbg !42 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !43 + %5 = bitcast i8* %4 to i32*, !dbg !43 + store i32* %5, i32** %3, align 8, !dbg !42 + %6 = bitcast i32** %3 to i8*, !dbg !44 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !45 + %8 = load i64, i64* %2, align 8, !dbg !46 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !47 + %10 = load i32*, i32** %3, align 8, !dbg !48 + %11 = bitcast i32* %10 to i8*, !dbg !48 + call void @free(i8* noundef %11) #4, !dbg !49 + ret i32 0, !dbg !50 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_double_free_2.c", directory: "", checksumkind: CSK_MD5, checksum: "45c24eb667d393b0b91a33073899f35b") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 10, scope: !15) +!31 = !DILocation(line: 12, column: 5, scope: !15) +!32 = !DILocation(line: 14, column: 2, scope: !15) +!33 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !34, scopeLine: 18, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!34 = !DISubroutineType(types: !35) +!35 = !{!5} +!36 = !DILocalVariable(name: "t1", scope: !33, file: !1, line: 19, type: !37) +!37 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !38, line: 27, baseType: !39) +!38 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!39 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!40 = !DILocation(line: 19, column: 15, scope: !33) +!41 = !DILocalVariable(name: "arr", scope: !33, file: !1, line: 20, type: !4) +!42 = !DILocation(line: 20, column: 10, scope: !33) +!43 = !DILocation(line: 20, column: 16, scope: !33) +!44 = !DILocation(line: 22, column: 41, scope: !33) +!45 = !DILocation(line: 22, column: 5, scope: !33) +!46 = !DILocation(line: 23, column: 18, scope: !33) +!47 = !DILocation(line: 23, column: 5, scope: !33) +!48 = !DILocation(line: 25, column: 10, scope: !33) +!49 = !DILocation(line: 25, column: 5, scope: !33) +!50 = !DILocation(line: 27, column: 2, scope: !33) diff --git a/dartagnan/src/test/resources/alloc/test_err_no_alloc_1.ll b/dartagnan/src/test/resources/alloc/test_err_no_alloc_1.ll new file mode 100644 index 0000000000..1831e5eb48 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_err_no_alloc_1.ll @@ -0,0 +1,104 @@ +; ModuleID = 'benchmarks/alloc/test1_err_no_alloc_1.c' +source_filename = "benchmarks/alloc/test1_err_no_alloc_1.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = bitcast i32* %7 to i8*, !dbg !26 + call void @free(i8* noundef %8) #4, !dbg !27 + ret i8* null, !dbg !28 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !29 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = bitcast i32** %3 to i8*, !dbg !39 + %5 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %4) #4, !dbg !40 + %6 = load i64, i64* %2, align 8, !dbg !41 + %7 = call i32 @pthread_join(i64 noundef %6, i8** noundef null), !dbg !42 + ret i32 0, !dbg !43 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_alloc_1.c", directory: "", checksumkind: CSK_MD5, checksum: "14a6148e31a552c09a9972943a522fc6") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 10, scope: !15) +!27 = !DILocation(line: 9, column: 5, scope: !15) +!28 = !DILocation(line: 11, column: 2, scope: !15) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !30, scopeLine: 15, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!30 = !DISubroutineType(types: !31) +!31 = !{!5} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 16, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 16, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 17, type: !4) +!38 = !DILocation(line: 17, column: 10, scope: !29) +!39 = !DILocation(line: 19, column: 41, scope: !29) +!40 = !DILocation(line: 19, column: 5, scope: !29) +!41 = !DILocation(line: 20, column: 18, scope: !29) +!42 = !DILocation(line: 20, column: 5, scope: !29) +!43 = !DILocation(line: 22, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test_err_no_alloc_2.ll b/dartagnan/src/test/resources/alloc/test_err_no_alloc_2.ll new file mode 100644 index 0000000000..3d123e6cfd --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_err_no_alloc_2.ll @@ -0,0 +1,114 @@ +; ModuleID = 'benchmarks/alloc/test1_err_no_alloc_2.c' +source_filename = "benchmarks/alloc/test1_err_no_alloc_2.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !31 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = bitcast i32** %3 to i8*, !dbg !41 + %5 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %4) #4, !dbg !42 + %6 = load i64, i64* %2, align 8, !dbg !43 + %7 = call i32 @pthread_join(i64 noundef %6, i8** noundef null), !dbg !44 + %8 = load i32*, i32** %3, align 8, !dbg !45 + %9 = bitcast i32* %8 to i8*, !dbg !45 + call void @free(i8* noundef %9) #4, !dbg !46 + ret i32 0, !dbg !47 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_alloc_2.c", directory: "", checksumkind: CSK_MD5, checksum: "b2bf37e36390289c32a839b496955f74") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 20, column: 41, scope: !31) +!42 = !DILocation(line: 20, column: 5, scope: !31) +!43 = !DILocation(line: 21, column: 18, scope: !31) +!44 = !DILocation(line: 21, column: 5, scope: !31) +!45 = !DILocation(line: 23, column: 10, scope: !31) +!46 = !DILocation(line: 23, column: 5, scope: !31) +!47 = !DILocation(line: 25, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test_err_no_free.ll b/dartagnan/src/test/resources/alloc/test_err_no_free.ll new file mode 100644 index 0000000000..3dbe6fb7e3 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_err_no_free.ll @@ -0,0 +1,113 @@ +; ModuleID = 'benchmarks/alloc/test1_err_no_free.c' +source_filename = "benchmarks/alloc/test1_err_no_free.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !31 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i64, i64* %2, align 8, !dbg !44 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !45 + ret i32 0, !dbg !46 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_no_free.c", directory: "", checksumkind: CSK_MD5, checksum: "e081113a88e49dfdea0e036a989897e2") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 18, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 23, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test_err_race.ll b/dartagnan/src/test/resources/alloc/test_err_race.ll new file mode 100644 index 0000000000..b0e1c08a51 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_err_race.ll @@ -0,0 +1,117 @@ +; ModuleID = 'benchmarks/alloc/test1_err_race.c' +source_filename = "benchmarks/alloc/test1_err_race.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = bitcast i32* %7 to i8*, !dbg !26 + call void @free(i8* noundef %8) #4, !dbg !27 + ret i8* null, !dbg !28 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !29 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !32, metadata !DIExpression()), !dbg !36 + call void @llvm.dbg.declare(metadata i32** %3, metadata !37, metadata !DIExpression()), !dbg !38 + %4 = bitcast i32** %3 to i8*, !dbg !39 + %5 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %4) #4, !dbg !40 + %6 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %7 = bitcast i8* %6 to i32*, !dbg !41 + store i32* %7, i32** %3, align 8, !dbg !42 + %8 = load i64, i64* %2, align 8, !dbg !43 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !44 + %10 = load i32*, i32** %3, align 8, !dbg !45 + %11 = bitcast i32* %10 to i8*, !dbg !45 + call void @free(i8* noundef %11) #4, !dbg !46 + ret i32 0, !dbg !47 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_race.c", directory: "", checksumkind: CSK_MD5, checksum: "5b343c7c5b5f3d29b761dd3f4bb442b1") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 10, scope: !15) +!27 = !DILocation(line: 9, column: 5, scope: !15) +!28 = !DILocation(line: 11, column: 2, scope: !15) +!29 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !30, scopeLine: 15, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!30 = !DISubroutineType(types: !31) +!31 = !{!5} +!32 = !DILocalVariable(name: "t1", scope: !29, file: !1, line: 16, type: !33) +!33 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !34, line: 27, baseType: !35) +!34 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!35 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!36 = !DILocation(line: 16, column: 15, scope: !29) +!37 = !DILocalVariable(name: "arr", scope: !29, file: !1, line: 17, type: !4) +!38 = !DILocation(line: 17, column: 10, scope: !29) +!39 = !DILocation(line: 19, column: 41, scope: !29) +!40 = !DILocation(line: 19, column: 5, scope: !29) +!41 = !DILocation(line: 20, column: 11, scope: !29) +!42 = !DILocation(line: 20, column: 9, scope: !29) +!43 = !DILocation(line: 21, column: 18, scope: !29) +!44 = !DILocation(line: 21, column: 5, scope: !29) +!45 = !DILocation(line: 23, column: 10, scope: !29) +!46 = !DILocation(line: 23, column: 5, scope: !29) +!47 = !DILocation(line: 25, column: 2, scope: !29) diff --git a/dartagnan/src/test/resources/alloc/test_err_use_after_free.ll b/dartagnan/src/test/resources/alloc/test_err_use_after_free.ll new file mode 100644 index 0000000000..341923add3 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_err_use_after_free.ll @@ -0,0 +1,121 @@ +; ModuleID = 'benchmarks/alloc/test1_err_use_after_free.c' +source_filename = "benchmarks/alloc/test1_err_use_after_free.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !31 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i32*, i32** %3, align 8, !dbg !44 + %9 = bitcast i32* %8 to i8*, !dbg !44 + call void @free(i8* noundef %9) #4, !dbg !45 + %10 = load i64, i64* %2, align 8, !dbg !46 + %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !47 + ret i32 0, !dbg !48 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_use_after_free.c", directory: "", checksumkind: CSK_MD5, checksum: "b7f8e5ba08709850a328a9a7557694f9") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 10, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 22, column: 18, scope: !31) +!47 = !DILocation(line: 22, column: 5, scope: !31) +!48 = !DILocation(line: 24, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test_err_use_before_alloc.ll b/dartagnan/src/test/resources/alloc/test_err_use_before_alloc.ll new file mode 100644 index 0000000000..d3023a7635 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_err_use_before_alloc.ll @@ -0,0 +1,122 @@ +; ModuleID = 'benchmarks/alloc/test1_err_use_before_alloc.c' +source_filename = "benchmarks/alloc/test1_err_use_before_alloc.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !31 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = bitcast i32** %3 to i8*, !dbg !41 + %5 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %4) #4, !dbg !42 + %6 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !43 + %7 = bitcast i8* %6 to i32*, !dbg !43 + store i32* %7, i32** %3, align 8, !dbg !44 + %8 = load i64, i64* %2, align 8, !dbg !45 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !46 + %10 = load i32*, i32** %3, align 8, !dbg !47 + %11 = bitcast i32* %10 to i8*, !dbg !47 + call void @free(i8* noundef %11) #4, !dbg !48 + ret i32 0, !dbg !49 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_err_use_before_alloc.c", directory: "", checksumkind: CSK_MD5, checksum: "38394d88843694d48c1b381d56bd1b78") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 20, column: 41, scope: !31) +!42 = !DILocation(line: 20, column: 5, scope: !31) +!43 = !DILocation(line: 21, column: 11, scope: !31) +!44 = !DILocation(line: 21, column: 9, scope: !31) +!45 = !DILocation(line: 22, column: 18, scope: !31) +!46 = !DILocation(line: 22, column: 5, scope: !31) +!47 = !DILocation(line: 24, column: 10, scope: !31) +!48 = !DILocation(line: 24, column: 5, scope: !31) +!49 = !DILocation(line: 26, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test_ok_1.ll b/dartagnan/src/test/resources/alloc/test_ok_1.ll new file mode 100644 index 0000000000..070835dcba --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_ok_1.ll @@ -0,0 +1,121 @@ +; ModuleID = 'benchmarks/alloc/test1_ok_1.c' +source_filename = "benchmarks/alloc/test1_ok_1.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + ret i8* null, !dbg !30 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !31 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !34, metadata !DIExpression()), !dbg !38 + call void @llvm.dbg.declare(metadata i32** %3, metadata !39, metadata !DIExpression()), !dbg !40 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !41 + %5 = bitcast i8* %4 to i32*, !dbg !41 + store i32* %5, i32** %3, align 8, !dbg !40 + %6 = bitcast i32** %3 to i8*, !dbg !42 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !43 + %8 = load i64, i64* %2, align 8, !dbg !44 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !45 + %10 = load i32*, i32** %3, align 8, !dbg !46 + %11 = bitcast i32* %10 to i8*, !dbg !46 + call void @free(i8* noundef %11) #4, !dbg !47 + ret i32 0, !dbg !48 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_ok_1.c", directory: "", checksumkind: CSK_MD5, checksum: "2e590941d7651d3df54b809725038357") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 2, scope: !15) +!31 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 15, type: !32, scopeLine: 16, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!32 = !DISubroutineType(types: !33) +!33 = !{!5} +!34 = !DILocalVariable(name: "t1", scope: !31, file: !1, line: 17, type: !35) +!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !36, line: 27, baseType: !37) +!36 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!37 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!38 = !DILocation(line: 17, column: 15, scope: !31) +!39 = !DILocalVariable(name: "arr", scope: !31, file: !1, line: 18, type: !4) +!40 = !DILocation(line: 18, column: 10, scope: !31) +!41 = !DILocation(line: 18, column: 16, scope: !31) +!42 = !DILocation(line: 20, column: 41, scope: !31) +!43 = !DILocation(line: 20, column: 5, scope: !31) +!44 = !DILocation(line: 21, column: 18, scope: !31) +!45 = !DILocation(line: 21, column: 5, scope: !31) +!46 = !DILocation(line: 23, column: 10, scope: !31) +!47 = !DILocation(line: 23, column: 5, scope: !31) +!48 = !DILocation(line: 25, column: 2, scope: !31) diff --git a/dartagnan/src/test/resources/alloc/test_ok_2.ll b/dartagnan/src/test/resources/alloc/test_ok_2.ll new file mode 100644 index 0000000000..3a010d9984 --- /dev/null +++ b/dartagnan/src/test/resources/alloc/test_ok_2.ll @@ -0,0 +1,121 @@ +; ModuleID = 'benchmarks/alloc/test1_ok_2.c' +source_filename = "benchmarks/alloc/test1_ok_2.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_attr_t = type { i64, [48 x i8] } + +; Function Attrs: noinline nounwind uwtable +define dso_local i8* @thread_1(i8* noundef %0) #0 !dbg !15 { + %2 = alloca i8*, align 8 + %3 = alloca i32*, align 8 + store i8* %0, i8** %2, align 8 + call void @llvm.dbg.declare(metadata i8** %2, metadata !19, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.declare(metadata i32** %3, metadata !21, metadata !DIExpression()), !dbg !22 + %4 = load i8*, i8** %2, align 8, !dbg !23 + %5 = bitcast i8* %4 to i32**, !dbg !24 + %6 = load i32*, i32** %5, align 8, !dbg !25 + store i32* %6, i32** %3, align 8, !dbg !22 + %7 = load i32*, i32** %3, align 8, !dbg !26 + %8 = getelementptr inbounds i32, i32* %7, i64 0, !dbg !26 + store i32 0, i32* %8, align 4, !dbg !27 + %9 = load i32*, i32** %3, align 8, !dbg !28 + %10 = getelementptr inbounds i32, i32* %9, i64 1, !dbg !28 + store i32 1, i32* %10, align 4, !dbg !29 + %11 = load i32*, i32** %3, align 8, !dbg !30 + %12 = bitcast i32* %11 to i8*, !dbg !30 + call void @free(i8* noundef %12) #4, !dbg !31 + ret i8* null, !dbg !32 +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: nounwind +declare void @free(i8* noundef) #2 + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !33 { + %1 = alloca i32, align 4 + %2 = alloca i64, align 8 + %3 = alloca i32*, align 8 + store i32 0, i32* %1, align 4 + call void @llvm.dbg.declare(metadata i64* %2, metadata !36, metadata !DIExpression()), !dbg !40 + call void @llvm.dbg.declare(metadata i32** %3, metadata !41, metadata !DIExpression()), !dbg !42 + %4 = call noalias i8* @malloc(i64 noundef 8) #4, !dbg !43 + %5 = bitcast i8* %4 to i32*, !dbg !43 + store i32* %5, i32** %3, align 8, !dbg !42 + %6 = bitcast i32** %3 to i8*, !dbg !44 + %7 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_1, i8* noundef %6) #4, !dbg !45 + %8 = load i64, i64* %2, align 8, !dbg !46 + %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !47 + ret i32 0, !dbg !48 +} + +; Function Attrs: nounwind +declare noalias i8* @malloc(i64 noundef) #2 + +; Function Attrs: nounwind +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "benchmarks/alloc/test1_ok_2.c", directory: "", checksumkind: CSK_MD5, checksum: "e91d7edb143929cccd1bbe8f9e07c187") +!2 = !{!3, !6} +!3 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 7, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 1} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!15 = distinct !DISubprogram(name: "thread_1", scope: !1, file: !1, line: 6, type: !16, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!16 = !DISubroutineType(types: !17) +!17 = !{!6, !6} +!18 = !{} +!19 = !DILocalVariable(name: "arg", arg: 1, scope: !15, file: !1, line: 6, type: !6) +!20 = !DILocation(line: 6, column: 22, scope: !15) +!21 = !DILocalVariable(name: "arr", scope: !15, file: !1, line: 8, type: !4) +!22 = !DILocation(line: 8, column: 10, scope: !15) +!23 = !DILocation(line: 8, column: 25, scope: !15) +!24 = !DILocation(line: 8, column: 18, scope: !15) +!25 = !DILocation(line: 8, column: 16, scope: !15) +!26 = !DILocation(line: 9, column: 5, scope: !15) +!27 = !DILocation(line: 9, column: 12, scope: !15) +!28 = !DILocation(line: 10, column: 5, scope: !15) +!29 = !DILocation(line: 10, column: 12, scope: !15) +!30 = !DILocation(line: 12, column: 10, scope: !15) +!31 = !DILocation(line: 12, column: 5, scope: !15) +!32 = !DILocation(line: 14, column: 2, scope: !15) +!33 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !34, scopeLine: 18, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!34 = !DISubroutineType(types: !35) +!35 = !{!5} +!36 = !DILocalVariable(name: "t1", scope: !33, file: !1, line: 19, type: !37) +!37 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !38, line: 27, baseType: !39) +!38 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") +!39 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!40 = !DILocation(line: 19, column: 15, scope: !33) +!41 = !DILocalVariable(name: "arr", scope: !33, file: !1, line: 20, type: !4) +!42 = !DILocation(line: 20, column: 10, scope: !33) +!43 = !DILocation(line: 20, column: 16, scope: !33) +!44 = !DILocation(line: 22, column: 41, scope: !33) +!45 = !DILocation(line: 22, column: 5, scope: !33) +!46 = !DILocation(line: 23, column: 18, scope: !33) +!47 = !DILocation(line: 23, column: 5, scope: !33) +!48 = !DILocation(line: 25, column: 2, scope: !33) diff --git a/dartagnan/src/test/resources/lfds/dglm-CAS-relaxed.ll b/dartagnan/src/test/resources/lfds/dglm-CAS-relaxed.ll index a152d7d2c5..b7f339f04e 100644 --- a/dartagnan/src/test/resources/lfds/dglm-CAS-relaxed.ll +++ b/dartagnan/src/test/resources/lfds/dglm-CAS-relaxed.ll @@ -1,51 +1,47 @@ -; ModuleID = 'dglm.c' -source_filename = "dglm.c" +; ModuleID = 'benchmarks/lfds/dglm.c' +source_filename = "benchmarks/lfds/dglm.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" %struct.Node = type { i32, %struct.Node* } %union.pthread_attr_t = type { i64, [48 x i8] } -@Head = dso_local global %struct.Node* null, align 8, !dbg !0 -@Tail = dso_local global %struct.Node* null, align 8, !dbg !13 +@Head = dso_local global %struct.Node* null, align 8 +@Tail = dso_local global %struct.Node* null, align 8 @.str = private unnamed_addr constant [13 x i8] c"tail != NULL\00", align 1 -@.str.1 = private unnamed_addr constant [9 x i8] c"./dglm.h\00", align 1 +@.str.1 = private unnamed_addr constant [23 x i8] c"benchmarks/lfds/dglm.h\00", align 1 @__PRETTY_FUNCTION__.enqueue = private unnamed_addr constant [18 x i8] c"void enqueue(int)\00", align 1 @.str.2 = private unnamed_addr constant [13 x i8] c"head != NULL\00", align 1 @__PRETTY_FUNCTION__.dequeue = private unnamed_addr constant [14 x i8] c"int dequeue()\00", align 1 @.str.3 = private unnamed_addr constant [11 x i8] c"r != EMPTY\00", align 1 -@.str.4 = private unnamed_addr constant [7 x i8] c"dglm.c\00", align 1 +@.str.4 = private unnamed_addr constant [23 x i8] c"benchmarks/lfds/dglm.c\00", align 1 @__PRETTY_FUNCTION__.worker = private unnamed_addr constant [21 x i8] c"void *worker(void *)\00", align 1 -@data = dso_local global [3 x i32] zeroinitializer, align 4, !dbg !26 +@data = dso_local global [3 x i32] zeroinitializer, align 4 @.str.5 = private unnamed_addr constant [11 x i8] c"r == EMPTY\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 @.str.6 = private unnamed_addr constant [13 x i8] c"data[i] == 1\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @init() #0 !dbg !39 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @init() #0 { %1 = alloca %struct.Node*, align 8 - call void @llvm.dbg.declare(metadata %struct.Node** %1, metadata !43, metadata !DIExpression()), !dbg !44 - %2 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !45 - %3 = bitcast i8* %2 to %struct.Node*, !dbg !45 - store %struct.Node* %3, %struct.Node** %1, align 8, !dbg !44 - %4 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !46 - %5 = getelementptr inbounds %struct.Node, %struct.Node* %4, i32 0, i32 1, !dbg !47 - store %struct.Node* null, %struct.Node** %5, align 8, !dbg !48 - %6 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !49 - store %struct.Node* %6, %struct.Node** @Head, align 8, !dbg !50 - %7 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !51 - store %struct.Node* %7, %struct.Node** @Tail, align 8, !dbg !52 - ret void, !dbg !53 + %2 = call noalias i8* @malloc(i64 noundef 16) #4 + %3 = bitcast i8* %2 to %struct.Node* + store %struct.Node* %3, %struct.Node** %1, align 8 + %4 = load %struct.Node*, %struct.Node** %1, align 8 + %5 = getelementptr inbounds %struct.Node, %struct.Node* %4, i32 0, i32 1 + store %struct.Node* null, %struct.Node** %5, align 8 + %6 = load %struct.Node*, %struct.Node** %1, align 8 + store %struct.Node* %6, %struct.Node** @Head, align 8 + %7 = load %struct.Node*, %struct.Node** %1, align 8 + store %struct.Node* %7, %struct.Node** @Tail, align 8 + ret void } -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 +declare noalias i8* @malloc(i64 noundef) #1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @enqueue(i32 noundef %0) #0 !dbg !54 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @enqueue(i32 noundef %0) #0 { %2 = alloca i32, align 4 %3 = alloca %struct.Node*, align 8 %4 = alloca %struct.Node*, align 8 @@ -60,154 +56,150 @@ define dso_local void @enqueue(i32 noundef %0) #0 !dbg !54 { %13 = alloca %struct.Node*, align 8 %14 = alloca i8, align 1 store i32 %0, i32* %2, align 4 - call void @llvm.dbg.declare(metadata i32* %2, metadata !57, metadata !DIExpression()), !dbg !58 - call void @llvm.dbg.declare(metadata %struct.Node** %3, metadata !59, metadata !DIExpression()), !dbg !60 - call void @llvm.dbg.declare(metadata %struct.Node** %4, metadata !61, metadata !DIExpression()), !dbg !62 - call void @llvm.dbg.declare(metadata %struct.Node** %5, metadata !63, metadata !DIExpression()), !dbg !64 - %15 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !65 - %16 = bitcast i8* %15 to %struct.Node*, !dbg !65 - store %struct.Node* %16, %struct.Node** %5, align 8, !dbg !66 - %17 = load i32, i32* %2, align 4, !dbg !67 - %18 = load %struct.Node*, %struct.Node** %5, align 8, !dbg !68 - %19 = getelementptr inbounds %struct.Node, %struct.Node* %18, i32 0, i32 0, !dbg !69 - store i32 %17, i32* %19, align 8, !dbg !70 - %20 = load %struct.Node*, %struct.Node** %5, align 8, !dbg !71 - %21 = getelementptr inbounds %struct.Node, %struct.Node* %20, i32 0, i32 1, !dbg !72 - store %struct.Node* null, %struct.Node** %21, align 8, !dbg !73 - br label %22, !dbg !74 + %15 = call noalias i8* @malloc(i64 noundef 16) #4 + %16 = bitcast i8* %15 to %struct.Node* + store %struct.Node* %16, %struct.Node** %5, align 8 + %17 = load i32, i32* %2, align 4 + %18 = load %struct.Node*, %struct.Node** %5, align 8 + %19 = getelementptr inbounds %struct.Node, %struct.Node* %18, i32 0, i32 0 + store i32 %17, i32* %19, align 8 + %20 = load %struct.Node*, %struct.Node** %5, align 8 + %21 = getelementptr inbounds %struct.Node, %struct.Node* %20, i32 0, i32 1 + store %struct.Node* null, %struct.Node** %21, align 8 + br label %22 22: ; preds = %1, %95 - %23 = bitcast %struct.Node** %6 to i64*, !dbg !75 - %24 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !75 - store i64 %24, i64* %23, align 8, !dbg !75 - %25 = bitcast i64* %23 to %struct.Node**, !dbg !75 - %26 = load %struct.Node*, %struct.Node** %25, align 8, !dbg !75 - store %struct.Node* %26, %struct.Node** %3, align 8, !dbg !77 - %27 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !78 - %28 = icmp ne %struct.Node* %27, null, !dbg !78 - br i1 %28, label %29, label %30, !dbg !81 + %23 = bitcast %struct.Node** %6 to i64* + %24 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %24, i64* %23, align 8 + %25 = bitcast i64* %23 to %struct.Node** + %26 = load %struct.Node*, %struct.Node** %25, align 8 + store %struct.Node* %26, %struct.Node** %3, align 8 + %27 = load %struct.Node*, %struct.Node** %3, align 8 + %28 = icmp ne %struct.Node* %27, null + br i1 %28, label %29, label %30 29: ; preds = %22 - br label %31, !dbg !81 + br label %31 30: ; preds = %22 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @__PRETTY_FUNCTION__.enqueue, i64 0, i64 0)) #6, !dbg !78 - unreachable, !dbg !78 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @__PRETTY_FUNCTION__.enqueue, i64 0, i64 0)) #5 + unreachable 31: ; preds = %29 - %32 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !82 - %33 = getelementptr inbounds %struct.Node, %struct.Node* %32, i32 0, i32 1, !dbg !83 - %34 = bitcast %struct.Node** %33 to i64*, !dbg !84 - %35 = bitcast %struct.Node** %7 to i64*, !dbg !84 - %36 = load atomic i64, i64* %34 acquire, align 8, !dbg !84 - store i64 %36, i64* %35, align 8, !dbg !84 - %37 = bitcast i64* %35 to %struct.Node**, !dbg !84 - %38 = load %struct.Node*, %struct.Node** %37, align 8, !dbg !84 - store %struct.Node* %38, %struct.Node** %4, align 8, !dbg !85 - %39 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !86 - %40 = bitcast %struct.Node** %8 to i64*, !dbg !88 - %41 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !88 - store i64 %41, i64* %40, align 8, !dbg !88 - %42 = bitcast i64* %40 to %struct.Node**, !dbg !88 - %43 = load %struct.Node*, %struct.Node** %42, align 8, !dbg !88 - %44 = icmp eq %struct.Node* %39, %43, !dbg !89 - br i1 %44, label %45, label %95, !dbg !90 + %32 = load %struct.Node*, %struct.Node** %3, align 8 + %33 = getelementptr inbounds %struct.Node, %struct.Node* %32, i32 0, i32 1 + %34 = bitcast %struct.Node** %33 to i64* + %35 = bitcast %struct.Node** %7 to i64* + %36 = load atomic i64, i64* %34 acquire, align 8 + store i64 %36, i64* %35, align 8 + %37 = bitcast i64* %35 to %struct.Node** + %38 = load %struct.Node*, %struct.Node** %37, align 8 + store %struct.Node* %38, %struct.Node** %4, align 8 + %39 = load %struct.Node*, %struct.Node** %3, align 8 + %40 = bitcast %struct.Node** %8 to i64* + %41 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %41, i64* %40, align 8 + %42 = bitcast i64* %40 to %struct.Node** + %43 = load %struct.Node*, %struct.Node** %42, align 8 + %44 = icmp eq %struct.Node* %39, %43 + br i1 %44, label %45, label %95 45: ; preds = %31 - %46 = load %struct.Node*, %struct.Node** %4, align 8, !dbg !91 - %47 = icmp eq %struct.Node* %46, null, !dbg !94 - br i1 %47, label %48, label %80, !dbg !95 + %46 = load %struct.Node*, %struct.Node** %4, align 8 + %47 = icmp eq %struct.Node* %46, null + br i1 %47, label %48, label %80 48: ; preds = %45 - %49 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !96 - %50 = getelementptr inbounds %struct.Node, %struct.Node* %49, i32 0, i32 1, !dbg !96 - %51 = load %struct.Node*, %struct.Node** %5, align 8, !dbg !96 - store %struct.Node* %51, %struct.Node** %9, align 8, !dbg !96 - %52 = bitcast %struct.Node** %50 to i64*, !dbg !96 - %53 = bitcast %struct.Node** %4 to i64*, !dbg !96 - %54 = bitcast %struct.Node** %9 to i64*, !dbg !96 - %55 = load i64, i64* %53, align 8, !dbg !96 - %56 = load i64, i64* %54, align 8, !dbg !96 - %57 = cmpxchg i64* %52, i64 %55, i64 %56 monotonic monotonic, align 8, !dbg !96 - %58 = extractvalue { i64, i1 } %57, 0, !dbg !96 - %59 = extractvalue { i64, i1 } %57, 1, !dbg !96 - br i1 %59, label %61, label %60, !dbg !96 + %49 = load %struct.Node*, %struct.Node** %3, align 8 + %50 = getelementptr inbounds %struct.Node, %struct.Node* %49, i32 0, i32 1 + %51 = load %struct.Node*, %struct.Node** %5, align 8 + store %struct.Node* %51, %struct.Node** %9, align 8 + %52 = bitcast %struct.Node** %50 to i64* + %53 = bitcast %struct.Node** %4 to i64* + %54 = bitcast %struct.Node** %9 to i64* + %55 = load i64, i64* %53, align 8 + %56 = load i64, i64* %54, align 8 + %57 = cmpxchg i64* %52, i64 %55, i64 %56 monotonic monotonic, align 8 + %58 = extractvalue { i64, i1 } %57, 0 + %59 = extractvalue { i64, i1 } %57, 1 + br i1 %59, label %61, label %60 60: ; preds = %48 - store i64 %58, i64* %53, align 8, !dbg !96 - br label %61, !dbg !96 + store i64 %58, i64* %53, align 8 + br label %61 61: ; preds = %60, %48 - %62 = zext i1 %59 to i8, !dbg !96 - store i8 %62, i8* %10, align 1, !dbg !96 - %63 = load i8, i8* %10, align 1, !dbg !96 - %64 = trunc i8 %63 to i1, !dbg !96 - br i1 %64, label %65, label %79, !dbg !99 + %62 = zext i1 %59 to i8 + store i8 %62, i8* %10, align 1 + %63 = load i8, i8* %10, align 1 + %64 = trunc i8 %63 to i1 + br i1 %64, label %65, label %79 65: ; preds = %61 - %66 = load %struct.Node*, %struct.Node** %5, align 8, !dbg !100 - store %struct.Node* %66, %struct.Node** %11, align 8, !dbg !100 - %67 = bitcast %struct.Node** %3 to i64*, !dbg !100 - %68 = bitcast %struct.Node** %11 to i64*, !dbg !100 - %69 = load i64, i64* %67, align 8, !dbg !100 - %70 = load i64, i64* %68, align 8, !dbg !100 - %71 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %69, i64 %70 monotonic monotonic, align 8, !dbg !100 - %72 = extractvalue { i64, i1 } %71, 0, !dbg !100 - %73 = extractvalue { i64, i1 } %71, 1, !dbg !100 - br i1 %73, label %75, label %74, !dbg !100 + %66 = load %struct.Node*, %struct.Node** %5, align 8 + store %struct.Node* %66, %struct.Node** %11, align 8 + %67 = bitcast %struct.Node** %3 to i64* + %68 = bitcast %struct.Node** %11 to i64* + %69 = load i64, i64* %67, align 8 + %70 = load i64, i64* %68, align 8 + %71 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %69, i64 %70 monotonic monotonic, align 8 + %72 = extractvalue { i64, i1 } %71, 0 + %73 = extractvalue { i64, i1 } %71, 1 + br i1 %73, label %75, label %74 74: ; preds = %65 - store i64 %72, i64* %67, align 8, !dbg !100 - br label %75, !dbg !100 + store i64 %72, i64* %67, align 8 + br label %75 75: ; preds = %74, %65 - %76 = zext i1 %73 to i8, !dbg !100 - store i8 %76, i8* %12, align 1, !dbg !100 - %77 = load i8, i8* %12, align 1, !dbg !100 - %78 = trunc i8 %77 to i1, !dbg !100 - br label %96, !dbg !102 + %76 = zext i1 %73 to i8 + store i8 %76, i8* %12, align 1 + %77 = load i8, i8* %12, align 1 + %78 = trunc i8 %77 to i1 + br label %96 79: ; preds = %61 - br label %94, !dbg !103 + br label %94 80: ; preds = %45 - %81 = load %struct.Node*, %struct.Node** %4, align 8, !dbg !104 - store %struct.Node* %81, %struct.Node** %13, align 8, !dbg !104 - %82 = bitcast %struct.Node** %3 to i64*, !dbg !104 - %83 = bitcast %struct.Node** %13 to i64*, !dbg !104 - %84 = load i64, i64* %82, align 8, !dbg !104 - %85 = load i64, i64* %83, align 8, !dbg !104 - %86 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %84, i64 %85 monotonic monotonic, align 8, !dbg !104 - %87 = extractvalue { i64, i1 } %86, 0, !dbg !104 - %88 = extractvalue { i64, i1 } %86, 1, !dbg !104 - br i1 %88, label %90, label %89, !dbg !104 + %81 = load %struct.Node*, %struct.Node** %4, align 8 + store %struct.Node* %81, %struct.Node** %13, align 8 + %82 = bitcast %struct.Node** %3 to i64* + %83 = bitcast %struct.Node** %13 to i64* + %84 = load i64, i64* %82, align 8 + %85 = load i64, i64* %83, align 8 + %86 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %84, i64 %85 monotonic monotonic, align 8 + %87 = extractvalue { i64, i1 } %86, 0 + %88 = extractvalue { i64, i1 } %86, 1 + br i1 %88, label %90, label %89 89: ; preds = %80 - store i64 %87, i64* %82, align 8, !dbg !104 - br label %90, !dbg !104 + store i64 %87, i64* %82, align 8 + br label %90 90: ; preds = %89, %80 - %91 = zext i1 %88 to i8, !dbg !104 - store i8 %91, i8* %14, align 1, !dbg !104 - %92 = load i8, i8* %14, align 1, !dbg !104 - %93 = trunc i8 %92 to i1, !dbg !104 + %91 = zext i1 %88 to i8 + store i8 %91, i8* %14, align 1 + %92 = load i8, i8* %14, align 1 + %93 = trunc i8 %92 to i1 br label %94 94: ; preds = %90, %79 - br label %95, !dbg !106 + br label %95 95: ; preds = %94, %31 - br label %22, !dbg !74, !llvm.loop !107 + br label %22 96: ; preds = %75 - ret void, !dbg !109 + ret void } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #2 -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @dequeue() #0 !dbg !110 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @dequeue() #0 { %1 = alloca %struct.Node*, align 8 %2 = alloca %struct.Node*, align 8 %3 = alloca %struct.Node*, align 8 @@ -220,193 +212,186 @@ define dso_local i32 @dequeue() #0 !dbg !110 { %10 = alloca %struct.Node*, align 8 %11 = alloca %struct.Node*, align 8 %12 = alloca i8, align 1 - call void @llvm.dbg.declare(metadata %struct.Node** %1, metadata !113, metadata !DIExpression()), !dbg !114 - call void @llvm.dbg.declare(metadata %struct.Node** %2, metadata !115, metadata !DIExpression()), !dbg !116 - call void @llvm.dbg.declare(metadata %struct.Node** %3, metadata !117, metadata !DIExpression()), !dbg !118 - call void @llvm.dbg.declare(metadata i32* %4, metadata !119, metadata !DIExpression()), !dbg !120 - br label %13, !dbg !121 + br label %13 13: ; preds = %0, %89 - %14 = bitcast %struct.Node** %5 to i64*, !dbg !122 - %15 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8, !dbg !122 - store i64 %15, i64* %14, align 8, !dbg !122 - %16 = bitcast i64* %14 to %struct.Node**, !dbg !122 - %17 = load %struct.Node*, %struct.Node** %16, align 8, !dbg !122 - store %struct.Node* %17, %struct.Node** %1, align 8, !dbg !124 - %18 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !125 - %19 = icmp ne %struct.Node* %18, null, !dbg !125 - br i1 %19, label %20, label %21, !dbg !128 + %14 = bitcast %struct.Node** %5 to i64* + %15 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8 + store i64 %15, i64* %14, align 8 + %16 = bitcast i64* %14 to %struct.Node** + %17 = load %struct.Node*, %struct.Node** %16, align 8 + store %struct.Node* %17, %struct.Node** %1, align 8 + %18 = load %struct.Node*, %struct.Node** %1, align 8 + %19 = icmp ne %struct.Node* %18, null + br i1 %19, label %20, label %21 20: ; preds = %13 - br label %22, !dbg !128 + br label %22 21: ; preds = %13 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), i32 noundef 61, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #6, !dbg !125 - unreachable, !dbg !125 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0), i32 noundef 61, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #5 + unreachable 22: ; preds = %20 - %23 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !129 - %24 = getelementptr inbounds %struct.Node, %struct.Node* %23, i32 0, i32 1, !dbg !130 - %25 = bitcast %struct.Node** %24 to i64*, !dbg !131 - %26 = bitcast %struct.Node** %6 to i64*, !dbg !131 - %27 = load atomic i64, i64* %25 acquire, align 8, !dbg !131 - store i64 %27, i64* %26, align 8, !dbg !131 - %28 = bitcast i64* %26 to %struct.Node**, !dbg !131 - %29 = load %struct.Node*, %struct.Node** %28, align 8, !dbg !131 - store %struct.Node* %29, %struct.Node** %2, align 8, !dbg !132 - %30 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !133 - %31 = bitcast %struct.Node** %7 to i64*, !dbg !135 - %32 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8, !dbg !135 - store i64 %32, i64* %31, align 8, !dbg !135 - %33 = bitcast i64* %31 to %struct.Node**, !dbg !135 - %34 = load %struct.Node*, %struct.Node** %33, align 8, !dbg !135 - %35 = icmp eq %struct.Node* %30, %34, !dbg !136 - br i1 %35, label %36, label %89, !dbg !137 + %23 = load %struct.Node*, %struct.Node** %1, align 8 + %24 = getelementptr inbounds %struct.Node, %struct.Node* %23, i32 0, i32 1 + %25 = bitcast %struct.Node** %24 to i64* + %26 = bitcast %struct.Node** %6 to i64* + %27 = load atomic i64, i64* %25 acquire, align 8 + store i64 %27, i64* %26, align 8 + %28 = bitcast i64* %26 to %struct.Node** + %29 = load %struct.Node*, %struct.Node** %28, align 8 + store %struct.Node* %29, %struct.Node** %2, align 8 + %30 = load %struct.Node*, %struct.Node** %1, align 8 + %31 = bitcast %struct.Node** %7 to i64* + %32 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8 + store i64 %32, i64* %31, align 8 + %33 = bitcast i64* %31 to %struct.Node** + %34 = load %struct.Node*, %struct.Node** %33, align 8 + %35 = icmp eq %struct.Node* %30, %34 + br i1 %35, label %36, label %89 36: ; preds = %22 - %37 = load %struct.Node*, %struct.Node** %2, align 8, !dbg !138 - %38 = icmp eq %struct.Node* %37, null, !dbg !141 - br i1 %38, label %39, label %40, !dbg !142 + %37 = load %struct.Node*, %struct.Node** %2, align 8 + %38 = icmp eq %struct.Node* %37, null + br i1 %38, label %39, label %40 39: ; preds = %36 - store i32 -1, i32* %4, align 4, !dbg !143 - br label %90, !dbg !145 + store i32 -1, i32* %4, align 4 + br label %90 40: ; preds = %36 - %41 = load %struct.Node*, %struct.Node** %2, align 8, !dbg !146 - %42 = getelementptr inbounds %struct.Node, %struct.Node* %41, i32 0, i32 0, !dbg !148 - %43 = load i32, i32* %42, align 8, !dbg !148 - store i32 %43, i32* %4, align 4, !dbg !149 - %44 = load %struct.Node*, %struct.Node** %2, align 8, !dbg !150 - store %struct.Node* %44, %struct.Node** %8, align 8, !dbg !150 - %45 = bitcast %struct.Node** %1 to i64*, !dbg !150 - %46 = bitcast %struct.Node** %8 to i64*, !dbg !150 - %47 = load i64, i64* %45, align 8, !dbg !150 - %48 = load i64, i64* %46, align 8, !dbg !150 - %49 = cmpxchg i64* bitcast (%struct.Node** @Head to i64*), i64 %47, i64 %48 monotonic monotonic, align 8, !dbg !150 - %50 = extractvalue { i64, i1 } %49, 0, !dbg !150 - %51 = extractvalue { i64, i1 } %49, 1, !dbg !150 - br i1 %51, label %53, label %52, !dbg !150 + %41 = load %struct.Node*, %struct.Node** %2, align 8 + %42 = getelementptr inbounds %struct.Node, %struct.Node* %41, i32 0, i32 0 + %43 = load i32, i32* %42, align 8 + store i32 %43, i32* %4, align 4 + %44 = load %struct.Node*, %struct.Node** %2, align 8 + store %struct.Node* %44, %struct.Node** %8, align 8 + %45 = bitcast %struct.Node** %1 to i64* + %46 = bitcast %struct.Node** %8 to i64* + %47 = load i64, i64* %45, align 8 + %48 = load i64, i64* %46, align 8 + %49 = cmpxchg i64* bitcast (%struct.Node** @Head to i64*), i64 %47, i64 %48 monotonic monotonic, align 8 + %50 = extractvalue { i64, i1 } %49, 0 + %51 = extractvalue { i64, i1 } %49, 1 + br i1 %51, label %53, label %52 52: ; preds = %40 - store i64 %50, i64* %45, align 8, !dbg !150 - br label %53, !dbg !150 + store i64 %50, i64* %45, align 8 + br label %53 53: ; preds = %52, %40 - %54 = zext i1 %51 to i8, !dbg !150 - store i8 %54, i8* %9, align 1, !dbg !150 - %55 = load i8, i8* %9, align 1, !dbg !150 - %56 = trunc i8 %55 to i1, !dbg !150 - br i1 %56, label %57, label %87, !dbg !152 + %54 = zext i1 %51 to i8 + store i8 %54, i8* %9, align 1 + %55 = load i8, i8* %9, align 1 + %56 = trunc i8 %55 to i1 + br i1 %56, label %57, label %87 57: ; preds = %53 - %58 = bitcast %struct.Node** %10 to i64*, !dbg !153 - %59 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !153 - store i64 %59, i64* %58, align 8, !dbg !153 - %60 = bitcast i64* %58 to %struct.Node**, !dbg !153 - %61 = load %struct.Node*, %struct.Node** %60, align 8, !dbg !153 - store %struct.Node* %61, %struct.Node** %3, align 8, !dbg !155 - %62 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !156 - %63 = icmp ne %struct.Node* %62, null, !dbg !156 - br i1 %63, label %64, label %65, !dbg !159 + %58 = bitcast %struct.Node** %10 to i64* + %59 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %59, i64* %58, align 8 + %60 = bitcast i64* %58 to %struct.Node** + %61 = load %struct.Node*, %struct.Node** %60, align 8 + store %struct.Node* %61, %struct.Node** %3, align 8 + %62 = load %struct.Node*, %struct.Node** %3, align 8 + %63 = icmp ne %struct.Node* %62, null + br i1 %63, label %64, label %65 64: ; preds = %57 - br label %66, !dbg !159 + br label %66 65: ; preds = %57 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), i32 noundef 73, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #6, !dbg !156 - unreachable, !dbg !156 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0), i32 noundef 73, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #5 + unreachable 66: ; preds = %64 - %67 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !160 - %68 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !162 - %69 = icmp eq %struct.Node* %67, %68, !dbg !163 - br i1 %69, label %70, label %84, !dbg !164 + %67 = load %struct.Node*, %struct.Node** %1, align 8 + %68 = load %struct.Node*, %struct.Node** %3, align 8 + %69 = icmp eq %struct.Node* %67, %68 + br i1 %69, label %70, label %84 70: ; preds = %66 - %71 = load %struct.Node*, %struct.Node** %2, align 8, !dbg !165 - store %struct.Node* %71, %struct.Node** %11, align 8, !dbg !165 - %72 = bitcast %struct.Node** %3 to i64*, !dbg !165 - %73 = bitcast %struct.Node** %11 to i64*, !dbg !165 - %74 = load i64, i64* %72, align 8, !dbg !165 - %75 = load i64, i64* %73, align 8, !dbg !165 - %76 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %74, i64 %75 monotonic monotonic, align 8, !dbg !165 - %77 = extractvalue { i64, i1 } %76, 0, !dbg !165 - %78 = extractvalue { i64, i1 } %76, 1, !dbg !165 - br i1 %78, label %80, label %79, !dbg !165 + %71 = load %struct.Node*, %struct.Node** %2, align 8 + store %struct.Node* %71, %struct.Node** %11, align 8 + %72 = bitcast %struct.Node** %3 to i64* + %73 = bitcast %struct.Node** %11 to i64* + %74 = load i64, i64* %72, align 8 + %75 = load i64, i64* %73, align 8 + %76 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %74, i64 %75 monotonic monotonic, align 8 + %77 = extractvalue { i64, i1 } %76, 0 + %78 = extractvalue { i64, i1 } %76, 1 + br i1 %78, label %80, label %79 79: ; preds = %70 - store i64 %77, i64* %72, align 8, !dbg !165 - br label %80, !dbg !165 + store i64 %77, i64* %72, align 8 + br label %80 80: ; preds = %79, %70 - %81 = zext i1 %78 to i8, !dbg !165 - store i8 %81, i8* %12, align 1, !dbg !165 - %82 = load i8, i8* %12, align 1, !dbg !165 - %83 = trunc i8 %82 to i1, !dbg !165 - br label %84, !dbg !167 + %81 = zext i1 %78 to i8 + store i8 %81, i8* %12, align 1 + %82 = load i8, i8* %12, align 1 + %83 = trunc i8 %82 to i1 + br label %84 84: ; preds = %80, %66 - %85 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !168 - %86 = bitcast %struct.Node* %85 to i8*, !dbg !168 - call void @free(i8* noundef %86) #5, !dbg !169 - br label %90, !dbg !170 + %85 = load %struct.Node*, %struct.Node** %1, align 8 + %86 = bitcast %struct.Node* %85 to i8* + call void @free(i8* noundef %86) #4 + br label %90 87: ; preds = %53 br label %88 88: ; preds = %87 - br label %89, !dbg !171 + br label %89 89: ; preds = %88, %22 - br label %13, !dbg !121, !llvm.loop !172 + br label %13 90: ; preds = %84, %39 - %91 = load i32, i32* %4, align 4, !dbg !174 - ret i32 %91, !dbg !175 + %91 = load i32, i32* %4, align 4 + ret i32 %91 } ; Function Attrs: nounwind -declare void @free(i8* noundef) #2 +declare void @free(i8* noundef) #1 -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @worker(i8* noundef %0) #0 !dbg !176 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @worker(i8* noundef %0) #0 { %2 = alloca i8*, align 8 %3 = alloca i64, align 8 %4 = alloca i32, align 4 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !179, metadata !DIExpression()), !dbg !180 - call void @llvm.dbg.declare(metadata i64* %3, metadata !181, metadata !DIExpression()), !dbg !182 - %5 = load i8*, i8** %2, align 8, !dbg !183 - %6 = ptrtoint i8* %5 to i64, !dbg !184 - store i64 %6, i64* %3, align 8, !dbg !182 - %7 = load i64, i64* %3, align 8, !dbg !185 - %8 = trunc i64 %7 to i32, !dbg !185 - call void @enqueue(i32 noundef %8), !dbg !186 - call void @llvm.dbg.declare(metadata i32* %4, metadata !187, metadata !DIExpression()), !dbg !188 - %9 = call i32 @dequeue(), !dbg !189 - store i32 %9, i32* %4, align 4, !dbg !188 - %10 = load i32, i32* %4, align 4, !dbg !190 - %11 = icmp ne i32 %10, -1, !dbg !190 - br i1 %11, label %12, label %13, !dbg !193 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + call void @enqueue(i32 noundef %8) + %9 = call i32 @dequeue() + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = icmp ne i32 %10, -1 + br i1 %11, label %12, label %13 12: ; preds = %1 - br label %14, !dbg !193 + br label %14 13: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* noundef getelementptr inbounds ([7 x i8], [7 x i8]* @.str.4, i64 0, i64 0), i32 noundef 18, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #6, !dbg !190 - unreachable, !dbg !190 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.4, i64 0, i64 0), i32 noundef 18, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #5 + unreachable 14: ; preds = %12 - %15 = load i32, i32* %4, align 4, !dbg !194 - %16 = sext i32 %15 to i64, !dbg !195 - %17 = getelementptr inbounds [3 x i32], [3 x i32]* @data, i64 0, i64 %16, !dbg !195 - store i32 1, i32* %17, align 4, !dbg !196 - ret i8* null, !dbg !197 + %15 = load i32, i32* %4, align 4 + %16 = sext i32 %15 to i64 + %17 = getelementptr inbounds [3 x i32], [3 x i32]* @data, i64 0, i64 %16 + store i32 1, i32* %17, align 4 + ret i8* null } -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !198 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca [3 x i64], align 16 %3 = alloca i32, align 4 @@ -414,394 +399,131 @@ define dso_local i32 @main() #0 !dbg !198 { %5 = alloca i32, align 4 %6 = alloca i32, align 4 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata [3 x i64]* %2, metadata !199, metadata !DIExpression()), !dbg !203 - call void @init(), !dbg !204 - call void @llvm.dbg.declare(metadata i32* %3, metadata !205, metadata !DIExpression()), !dbg !207 - store i32 0, i32* %3, align 4, !dbg !207 - br label %7, !dbg !208 + call void @init() + store i32 0, i32* %3, align 4 + br label %7 7: ; preds = %18, %0 - %8 = load i32, i32* %3, align 4, !dbg !209 - %9 = icmp slt i32 %8, 3, !dbg !211 - br i1 %9, label %10, label %21, !dbg !212 + %8 = load i32, i32* %3, align 4 + %9 = icmp slt i32 %8, 3 + br i1 %9, label %10, label %21 10: ; preds = %7 - %11 = load i32, i32* %3, align 4, !dbg !213 - %12 = sext i32 %11 to i64, !dbg !214 - %13 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %12, !dbg !214 - %14 = load i32, i32* %3, align 4, !dbg !215 - %15 = sext i32 %14 to i64, !dbg !216 - %16 = inttoptr i64 %15 to i8*, !dbg !217 - %17 = call i32 @pthread_create(i64* noundef %13, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef %16) #5, !dbg !218 - br label %18, !dbg !218 + %11 = load i32, i32* %3, align 4 + %12 = sext i32 %11 to i64 + %13 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %12 + %14 = load i32, i32* %3, align 4 + %15 = sext i32 %14 to i64 + %16 = inttoptr i64 %15 to i8* + %17 = call i32 @pthread_create(i64* noundef %13, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef %16) #4 + br label %18 18: ; preds = %10 - %19 = load i32, i32* %3, align 4, !dbg !219 - %20 = add nsw i32 %19, 1, !dbg !219 - store i32 %20, i32* %3, align 4, !dbg !219 - br label %7, !dbg !220, !llvm.loop !221 + %19 = load i32, i32* %3, align 4 + %20 = add nsw i32 %19, 1 + store i32 %20, i32* %3, align 4 + br label %7, !llvm.loop !6 21: ; preds = %7 - call void @llvm.dbg.declare(metadata i32* %4, metadata !224, metadata !DIExpression()), !dbg !226 - store i32 0, i32* %4, align 4, !dbg !226 - br label %22, !dbg !227 + store i32 0, i32* %4, align 4 + br label %22 22: ; preds = %31, %21 - %23 = load i32, i32* %4, align 4, !dbg !228 - %24 = icmp slt i32 %23, 3, !dbg !230 - br i1 %24, label %25, label %34, !dbg !231 + %23 = load i32, i32* %4, align 4 + %24 = icmp slt i32 %23, 3 + br i1 %24, label %25, label %34 25: ; preds = %22 - %26 = load i32, i32* %4, align 4, !dbg !232 - %27 = sext i32 %26 to i64, !dbg !233 - %28 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %27, !dbg !233 - %29 = load i64, i64* %28, align 8, !dbg !233 - %30 = call i32 @pthread_join(i64 noundef %29, i8** noundef null), !dbg !234 - br label %31, !dbg !234 + %26 = load i32, i32* %4, align 4 + %27 = sext i32 %26 to i64 + %28 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %27 + %29 = load i64, i64* %28, align 8 + %30 = call i32 @pthread_join(i64 noundef %29, i8** noundef null) + br label %31 31: ; preds = %25 - %32 = load i32, i32* %4, align 4, !dbg !235 - %33 = add nsw i32 %32, 1, !dbg !235 - store i32 %33, i32* %4, align 4, !dbg !235 - br label %22, !dbg !236, !llvm.loop !237 + %32 = load i32, i32* %4, align 4 + %33 = add nsw i32 %32, 1 + store i32 %33, i32* %4, align 4 + br label %22, !llvm.loop !8 34: ; preds = %22 - call void @llvm.dbg.declare(metadata i32* %5, metadata !239, metadata !DIExpression()), !dbg !240 - %35 = call i32 @dequeue(), !dbg !241 - store i32 %35, i32* %5, align 4, !dbg !240 - %36 = load i32, i32* %5, align 4, !dbg !242 - %37 = icmp eq i32 %36, -1, !dbg !242 - br i1 %37, label %38, label %39, !dbg !245 + %35 = call i32 @dequeue() + store i32 %35, i32* %5, align 4 + %36 = load i32, i32* %5, align 4 + %37 = icmp eq i32 %36, -1 + br i1 %37, label %38, label %39 38: ; preds = %34 - br label %40, !dbg !245 + br label %40 39: ; preds = %34 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* noundef getelementptr inbounds ([7 x i8], [7 x i8]* @.str.4, i64 0, i64 0), i32 noundef 37, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !242 - unreachable, !dbg !242 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.4, i64 0, i64 0), i32 noundef 37, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable 40: ; preds = %38 - %41 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) seq_cst, align 8, !dbg !246 - %42 = inttoptr i64 %41 to %struct.Node*, !dbg !246 - %43 = bitcast %struct.Node* %42 to i8*, !dbg !246 - call void @free(i8* noundef %43) #5, !dbg !247 - call void @llvm.dbg.declare(metadata i32* %6, metadata !248, metadata !DIExpression()), !dbg !250 - store i32 0, i32* %6, align 4, !dbg !250 - br label %44, !dbg !251 + %41 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) seq_cst, align 8 + %42 = inttoptr i64 %41 to %struct.Node* + %43 = bitcast %struct.Node* %42 to i8* + call void @free(i8* noundef %43) #4 + store i32 0, i32* %6, align 4 + br label %44 44: ; preds = %56, %40 - %45 = load i32, i32* %6, align 4, !dbg !252 - %46 = icmp slt i32 %45, 3, !dbg !254 - br i1 %46, label %47, label %59, !dbg !255 + %45 = load i32, i32* %6, align 4 + %46 = icmp slt i32 %45, 3 + br i1 %46, label %47, label %59 47: ; preds = %44 - %48 = load i32, i32* %6, align 4, !dbg !256 - %49 = sext i32 %48 to i64, !dbg !256 - %50 = getelementptr inbounds [3 x i32], [3 x i32]* @data, i64 0, i64 %49, !dbg !256 - %51 = load i32, i32* %50, align 4, !dbg !256 - %52 = icmp eq i32 %51, 1, !dbg !256 - br i1 %52, label %53, label %54, !dbg !259 + %48 = load i32, i32* %6, align 4 + %49 = sext i32 %48 to i64 + %50 = getelementptr inbounds [3 x i32], [3 x i32]* @data, i64 0, i64 %49 + %51 = load i32, i32* %50, align 4 + %52 = icmp eq i32 %51, 1 + br i1 %52, label %53, label %54 53: ; preds = %47 - br label %55, !dbg !259 + br label %55 54: ; preds = %47 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.6, i64 0, i64 0), i8* noundef getelementptr inbounds ([7 x i8], [7 x i8]* @.str.4, i64 0, i64 0), i32 noundef 41, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !256 - unreachable, !dbg !256 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.6, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.4, i64 0, i64 0), i32 noundef 41, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable 55: ; preds = %53 - br label %56, !dbg !260 + br label %56 56: ; preds = %55 - %57 = load i32, i32* %6, align 4, !dbg !261 - %58 = add nsw i32 %57, 1, !dbg !261 - store i32 %58, i32* %6, align 4, !dbg !261 - br label %44, !dbg !262, !llvm.loop !263 + %57 = load i32, i32* %6, align 4 + %58 = add nsw i32 %57, 1 + store i32 %58, i32* %6, align 4 + br label %44, !llvm.loop !9 59: ; preds = %44 - ret i32 0, !dbg !265 + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 - -declare i32 @pthread_join(i64 noundef, i8** noundef) #4 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!31, !32, !33, !34, !35, !36, !37} -!llvm.ident = !{!38} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "Head", scope: !2, file: !15, line: 19, type: !16, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !4, globals: !12, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "dglm.c", directory: "/home/ubuntu/Desktop/code/tianrui/Dat3M/benchmarks/lfds", checksumkind: CSK_MD5, checksum: "4ae6501ab5c2c592a30d5a52caaa9b80") -!4 = !{!5, !6, !9} -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !7, line: 87, baseType: !8) -!7 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "a48e64edacc5b19f56c99745232c963c") -!8 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !10, line: 46, baseType: !11) -!10 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.0/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!11 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!12 = !{!13, !0, !26} -!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression()) -!14 = distinct !DIGlobalVariable(name: "Tail", scope: !2, file: !15, line: 18, type: !16, isLocal: false, isDefinition: true) -!15 = !DIFile(filename: "./dglm.h", directory: "/home/ubuntu/Desktop/code/tianrui/Dat3M/benchmarks/lfds", checksumkind: CSK_MD5, checksum: "c81f98eeee5e13a9ab95151e3734648b") -!16 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !17) -!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) -!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "Node", file: !15, line: 16, baseType: !19) -!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Node", file: !15, line: 13, size: 128, elements: !20) -!20 = !{!21, !23} -!21 = !DIDerivedType(tag: DW_TAG_member, name: "val", scope: !19, file: !15, line: 14, baseType: !22, size: 32) -!22 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!23 = !DIDerivedType(tag: DW_TAG_member, name: "next", scope: !19, file: !15, line: 15, baseType: !24, size: 64, offset: 64) -!24 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !25) -!25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -!26 = !DIGlobalVariableExpression(var: !27, expr: !DIExpression()) -!27 = distinct !DIGlobalVariable(name: "data", scope: !2, file: !3, line: 8, type: !28, isLocal: false, isDefinition: true) -!28 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 96, elements: !29) -!29 = !{!30} -!30 = !DISubrange(count: 3) -!31 = !{i32 7, !"Dwarf Version", i32 5} -!32 = !{i32 2, !"Debug Info Version", i32 3} -!33 = !{i32 1, !"wchar_size", i32 4} -!34 = !{i32 7, !"PIC Level", i32 2} -!35 = !{i32 7, !"PIE Level", i32 2} -!36 = !{i32 7, !"uwtable", i32 1} -!37 = !{i32 7, !"frame-pointer", i32 2} -!38 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!39 = distinct !DISubprogram(name: "init", scope: !15, file: !15, line: 22, type: !40, scopeLine: 22, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!40 = !DISubroutineType(types: !41) -!41 = !{null} -!42 = !{} -!43 = !DILocalVariable(name: "node", scope: !39, file: !15, line: 23, type: !17) -!44 = !DILocation(line: 23, column: 8, scope: !39) -!45 = !DILocation(line: 23, column: 15, scope: !39) -!46 = !DILocation(line: 24, column: 15, scope: !39) -!47 = !DILocation(line: 24, column: 21, scope: !39) -!48 = !DILocation(line: 24, column: 2, scope: !39) -!49 = !DILocation(line: 25, column: 21, scope: !39) -!50 = !DILocation(line: 25, column: 2, scope: !39) -!51 = !DILocation(line: 26, column: 21, scope: !39) -!52 = !DILocation(line: 26, column: 2, scope: !39) -!53 = !DILocation(line: 27, column: 1, scope: !39) -!54 = distinct !DISubprogram(name: "enqueue", scope: !15, file: !15, line: 29, type: !55, scopeLine: 29, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!55 = !DISubroutineType(types: !56) -!56 = !{null, !22} -!57 = !DILocalVariable(name: "value", arg: 1, scope: !54, file: !15, line: 29, type: !22) -!58 = !DILocation(line: 29, column: 18, scope: !54) -!59 = !DILocalVariable(name: "tail", scope: !54, file: !15, line: 30, type: !17) -!60 = !DILocation(line: 30, column: 8, scope: !54) -!61 = !DILocalVariable(name: "next", scope: !54, file: !15, line: 30, type: !17) -!62 = !DILocation(line: 30, column: 15, scope: !54) -!63 = !DILocalVariable(name: "node", scope: !54, file: !15, line: 30, type: !17) -!64 = !DILocation(line: 30, column: 22, scope: !54) -!65 = !DILocation(line: 32, column: 12, scope: !54) -!66 = !DILocation(line: 32, column: 10, scope: !54) -!67 = !DILocation(line: 33, column: 14, scope: !54) -!68 = !DILocation(line: 33, column: 2, scope: !54) -!69 = !DILocation(line: 33, column: 8, scope: !54) -!70 = !DILocation(line: 33, column: 12, scope: !54) -!71 = !DILocation(line: 34, column: 15, scope: !54) -!72 = !DILocation(line: 34, column: 21, scope: !54) -!73 = !DILocation(line: 34, column: 2, scope: !54) -!74 = !DILocation(line: 36, column: 2, scope: !54) -!75 = !DILocation(line: 37, column: 10, scope: !76) -!76 = distinct !DILexicalBlock(scope: !54, file: !15, line: 36, column: 12) -!77 = !DILocation(line: 37, column: 8, scope: !76) -!78 = !DILocation(line: 38, column: 9, scope: !79) -!79 = distinct !DILexicalBlock(scope: !80, file: !15, line: 38, column: 9) -!80 = distinct !DILexicalBlock(scope: !76, file: !15, line: 38, column: 9) -!81 = !DILocation(line: 38, column: 9, scope: !80) -!82 = !DILocation(line: 39, column: 32, scope: !76) -!83 = !DILocation(line: 39, column: 38, scope: !76) -!84 = !DILocation(line: 39, column: 10, scope: !76) -!85 = !DILocation(line: 39, column: 8, scope: !76) -!86 = !DILocation(line: 41, column: 13, scope: !87) -!87 = distinct !DILexicalBlock(scope: !76, file: !15, line: 41, column: 13) -!88 = !DILocation(line: 41, column: 21, scope: !87) -!89 = !DILocation(line: 41, column: 18, scope: !87) -!90 = !DILocation(line: 41, column: 13, scope: !76) -!91 = !DILocation(line: 42, column: 17, scope: !92) -!92 = distinct !DILexicalBlock(scope: !93, file: !15, line: 42, column: 17) -!93 = distinct !DILexicalBlock(scope: !87, file: !15, line: 41, column: 68) -!94 = !DILocation(line: 42, column: 22, scope: !92) -!95 = !DILocation(line: 42, column: 17, scope: !93) -!96 = !DILocation(line: 43, column: 9, scope: !97) -!97 = distinct !DILexicalBlock(scope: !98, file: !15, line: 43, column: 9) -!98 = distinct !DILexicalBlock(scope: !92, file: !15, line: 42, column: 31) -!99 = !DILocation(line: 43, column: 9, scope: !98) -!100 = !DILocation(line: 44, column: 9, scope: !101) -!101 = distinct !DILexicalBlock(scope: !97, file: !15, line: 43, column: 40) -!102 = !DILocation(line: 45, column: 6, scope: !101) -!103 = !DILocation(line: 47, column: 13, scope: !98) -!104 = !DILocation(line: 48, column: 5, scope: !105) -!105 = distinct !DILexicalBlock(scope: !92, file: !15, line: 47, column: 20) -!106 = !DILocation(line: 51, column: 9, scope: !93) -!107 = distinct !{!107, !74, !108} -!108 = !DILocation(line: 52, column: 2, scope: !54) -!109 = !DILocation(line: 53, column: 1, scope: !54) -!110 = distinct !DISubprogram(name: "dequeue", scope: !15, file: !15, line: 55, type: !111, scopeLine: 55, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!111 = !DISubroutineType(types: !112) -!112 = !{!22} -!113 = !DILocalVariable(name: "head", scope: !110, file: !15, line: 56, type: !17) -!114 = !DILocation(line: 56, column: 8, scope: !110) -!115 = !DILocalVariable(name: "next", scope: !110, file: !15, line: 56, type: !17) -!116 = !DILocation(line: 56, column: 15, scope: !110) -!117 = !DILocalVariable(name: "tail", scope: !110, file: !15, line: 56, type: !17) -!118 = !DILocation(line: 56, column: 22, scope: !110) -!119 = !DILocalVariable(name: "result", scope: !110, file: !15, line: 57, type: !22) -!120 = !DILocation(line: 57, column: 6, scope: !110) -!121 = !DILocation(line: 59, column: 2, scope: !110) -!122 = !DILocation(line: 60, column: 10, scope: !123) -!123 = distinct !DILexicalBlock(scope: !110, file: !15, line: 59, column: 12) -!124 = !DILocation(line: 60, column: 8, scope: !123) -!125 = !DILocation(line: 61, column: 9, scope: !126) -!126 = distinct !DILexicalBlock(scope: !127, file: !15, line: 61, column: 9) -!127 = distinct !DILexicalBlock(scope: !123, file: !15, line: 61, column: 9) -!128 = !DILocation(line: 61, column: 9, scope: !127) -!129 = !DILocation(line: 62, column: 32, scope: !123) -!130 = !DILocation(line: 62, column: 38, scope: !123) -!131 = !DILocation(line: 62, column: 10, scope: !123) -!132 = !DILocation(line: 62, column: 8, scope: !123) -!133 = !DILocation(line: 64, column: 7, scope: !134) -!134 = distinct !DILexicalBlock(scope: !123, file: !15, line: 64, column: 7) -!135 = !DILocation(line: 64, column: 15, scope: !134) -!136 = !DILocation(line: 64, column: 12, scope: !134) -!137 = !DILocation(line: 64, column: 7, scope: !123) -!138 = !DILocation(line: 65, column: 8, scope: !139) -!139 = distinct !DILexicalBlock(scope: !140, file: !15, line: 65, column: 8) -!140 = distinct !DILexicalBlock(scope: !134, file: !15, line: 64, column: 62) -!141 = !DILocation(line: 65, column: 13, scope: !139) -!142 = !DILocation(line: 65, column: 8, scope: !140) -!143 = !DILocation(line: 66, column: 12, scope: !144) -!144 = distinct !DILexicalBlock(scope: !139, file: !15, line: 65, column: 22) -!145 = !DILocation(line: 67, column: 5, scope: !144) -!146 = !DILocation(line: 70, column: 26, scope: !147) -!147 = distinct !DILexicalBlock(scope: !139, file: !15, line: 69, column: 11) -!148 = !DILocation(line: 70, column: 32, scope: !147) -!149 = !DILocation(line: 70, column: 24, scope: !147) -!150 = !DILocation(line: 71, column: 21, scope: !151) -!151 = distinct !DILexicalBlock(scope: !147, file: !15, line: 71, column: 21) -!152 = !DILocation(line: 71, column: 21, scope: !147) -!153 = !DILocation(line: 72, column: 28, scope: !154) -!154 = distinct !DILexicalBlock(scope: !151, file: !15, line: 71, column: 46) -!155 = !DILocation(line: 72, column: 26, scope: !154) -!156 = !DILocation(line: 73, column: 21, scope: !157) -!157 = distinct !DILexicalBlock(scope: !158, file: !15, line: 73, column: 21) -!158 = distinct !DILexicalBlock(scope: !154, file: !15, line: 73, column: 21) -!159 = !DILocation(line: 73, column: 21, scope: !158) -!160 = !DILocation(line: 74, column: 25, scope: !161) -!161 = distinct !DILexicalBlock(scope: !154, file: !15, line: 74, column: 25) -!162 = !DILocation(line: 74, column: 33, scope: !161) -!163 = !DILocation(line: 74, column: 30, scope: !161) -!164 = !DILocation(line: 74, column: 25, scope: !154) -!165 = !DILocation(line: 75, column: 25, scope: !166) -!166 = distinct !DILexicalBlock(scope: !161, file: !15, line: 74, column: 39) -!167 = !DILocation(line: 76, column: 21, scope: !166) -!168 = !DILocation(line: 77, column: 26, scope: !154) -!169 = !DILocation(line: 77, column: 21, scope: !154) -!170 = !DILocation(line: 78, column: 21, scope: !154) -!171 = !DILocation(line: 81, column: 3, scope: !140) -!172 = distinct !{!172, !121, !173} -!173 = !DILocation(line: 82, column: 2, scope: !110) -!174 = !DILocation(line: 84, column: 9, scope: !110) -!175 = !DILocation(line: 84, column: 2, scope: !110) -!176 = distinct !DISubprogram(name: "worker", scope: !3, file: !3, line: 10, type: !177, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!177 = !DISubroutineType(types: !178) -!178 = !{!5, !5} -!179 = !DILocalVariable(name: "arg", arg: 1, scope: !176, file: !3, line: 10, type: !5) -!180 = !DILocation(line: 10, column: 20, scope: !176) -!181 = !DILocalVariable(name: "index", scope: !176, file: !3, line: 13, type: !6) -!182 = !DILocation(line: 13, column: 14, scope: !176) -!183 = !DILocation(line: 13, column: 34, scope: !176) -!184 = !DILocation(line: 13, column: 23, scope: !176) -!185 = !DILocation(line: 15, column: 10, scope: !176) -!186 = !DILocation(line: 15, column: 2, scope: !176) -!187 = !DILocalVariable(name: "r", scope: !176, file: !3, line: 16, type: !22) -!188 = !DILocation(line: 16, column: 9, scope: !176) -!189 = !DILocation(line: 16, column: 13, scope: !176) -!190 = !DILocation(line: 18, column: 2, scope: !191) -!191 = distinct !DILexicalBlock(scope: !192, file: !3, line: 18, column: 2) -!192 = distinct !DILexicalBlock(scope: !176, file: !3, line: 18, column: 2) -!193 = !DILocation(line: 18, column: 2, scope: !192) -!194 = !DILocation(line: 19, column: 7, scope: !176) -!195 = !DILocation(line: 19, column: 2, scope: !176) -!196 = !DILocation(line: 19, column: 10, scope: !176) -!197 = !DILocation(line: 21, column: 2, scope: !176) -!198 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 24, type: !111, scopeLine: 25, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!199 = !DILocalVariable(name: "t", scope: !198, file: !3, line: 26, type: !200) -!200 = !DICompositeType(tag: DW_TAG_array_type, baseType: !201, size: 192, elements: !29) -!201 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !202, line: 27, baseType: !11) -!202 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!203 = !DILocation(line: 26, column: 15, scope: !198) -!204 = !DILocation(line: 28, column: 5, scope: !198) -!205 = !DILocalVariable(name: "i", scope: !206, file: !3, line: 30, type: !22) -!206 = distinct !DILexicalBlock(scope: !198, file: !3, line: 30, column: 5) -!207 = !DILocation(line: 30, column: 14, scope: !206) -!208 = !DILocation(line: 30, column: 10, scope: !206) -!209 = !DILocation(line: 30, column: 21, scope: !210) -!210 = distinct !DILexicalBlock(scope: !206, file: !3, line: 30, column: 5) -!211 = !DILocation(line: 30, column: 23, scope: !210) -!212 = !DILocation(line: 30, column: 5, scope: !206) -!213 = !DILocation(line: 31, column: 27, scope: !210) -!214 = !DILocation(line: 31, column: 25, scope: !210) -!215 = !DILocation(line: 31, column: 58, scope: !210) -!216 = !DILocation(line: 31, column: 50, scope: !210) -!217 = !DILocation(line: 31, column: 42, scope: !210) -!218 = !DILocation(line: 31, column: 9, scope: !210) -!219 = !DILocation(line: 30, column: 36, scope: !210) -!220 = !DILocation(line: 30, column: 5, scope: !210) -!221 = distinct !{!221, !212, !222, !223} -!222 = !DILocation(line: 31, column: 59, scope: !206) -!223 = !{!"llvm.loop.mustprogress"} -!224 = !DILocalVariable(name: "i", scope: !225, file: !3, line: 33, type: !22) -!225 = distinct !DILexicalBlock(scope: !198, file: !3, line: 33, column: 5) -!226 = !DILocation(line: 33, column: 14, scope: !225) -!227 = !DILocation(line: 33, column: 10, scope: !225) -!228 = !DILocation(line: 33, column: 21, scope: !229) -!229 = distinct !DILexicalBlock(scope: !225, file: !3, line: 33, column: 5) -!230 = !DILocation(line: 33, column: 23, scope: !229) -!231 = !DILocation(line: 33, column: 5, scope: !225) -!232 = !DILocation(line: 34, column: 24, scope: !229) -!233 = !DILocation(line: 34, column: 22, scope: !229) -!234 = !DILocation(line: 34, column: 9, scope: !229) -!235 = !DILocation(line: 33, column: 36, scope: !229) -!236 = !DILocation(line: 33, column: 5, scope: !229) -!237 = distinct !{!237, !231, !238, !223} -!238 = !DILocation(line: 34, column: 29, scope: !225) -!239 = !DILocalVariable(name: "r", scope: !198, file: !3, line: 36, type: !22) -!240 = !DILocation(line: 36, column: 9, scope: !198) -!241 = !DILocation(line: 36, column: 13, scope: !198) -!242 = !DILocation(line: 37, column: 5, scope: !243) -!243 = distinct !DILexicalBlock(scope: !244, file: !3, line: 37, column: 5) -!244 = distinct !DILexicalBlock(scope: !198, file: !3, line: 37, column: 5) -!245 = !DILocation(line: 37, column: 5, scope: !244) -!246 = !DILocation(line: 38, column: 10, scope: !198) -!247 = !DILocation(line: 38, column: 5, scope: !198) -!248 = !DILocalVariable(name: "i", scope: !249, file: !3, line: 40, type: !22) -!249 = distinct !DILexicalBlock(scope: !198, file: !3, line: 40, column: 5) -!250 = !DILocation(line: 40, column: 14, scope: !249) -!251 = !DILocation(line: 40, column: 10, scope: !249) -!252 = !DILocation(line: 40, column: 21, scope: !253) -!253 = distinct !DILexicalBlock(scope: !249, file: !3, line: 40, column: 5) -!254 = !DILocation(line: 40, column: 23, scope: !253) -!255 = !DILocation(line: 40, column: 5, scope: !249) -!256 = !DILocation(line: 41, column: 9, scope: !257) -!257 = distinct !DILexicalBlock(scope: !258, file: !3, line: 41, column: 9) -!258 = distinct !DILexicalBlock(scope: !253, file: !3, line: 41, column: 9) -!259 = !DILocation(line: 41, column: 9, scope: !258) -!260 = !DILocation(line: 41, column: 9, scope: !253) -!261 = !DILocation(line: 40, column: 36, scope: !253) -!262 = !DILocation(line: 40, column: 5, scope: !253) -!263 = distinct !{!263, !255, !264, !223} -!264 = !DILocation(line: 41, column: 9, scope: !249) -!265 = !DILocation(line: 43, column: 5, scope: !198) +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} +!9 = distinct !{!9, !7} diff --git a/dartagnan/src/test/resources/lfds/dglm.ll b/dartagnan/src/test/resources/lfds/dglm.ll index d110c57695..54c159320b 100644 --- a/dartagnan/src/test/resources/lfds/dglm.ll +++ b/dartagnan/src/test/resources/lfds/dglm.ll @@ -1,51 +1,47 @@ -; ModuleID = 'dglm.c' -source_filename = "dglm.c" +; ModuleID = 'benchmarks/lfds/dglm.c' +source_filename = "benchmarks/lfds/dglm.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" %struct.Node = type { i32, %struct.Node* } %union.pthread_attr_t = type { i64, [48 x i8] } -@Head = dso_local global %struct.Node* null, align 8, !dbg !0 -@Tail = dso_local global %struct.Node* null, align 8, !dbg !13 +@Head = dso_local global %struct.Node* null, align 8 +@Tail = dso_local global %struct.Node* null, align 8 @.str = private unnamed_addr constant [13 x i8] c"tail != NULL\00", align 1 -@.str.1 = private unnamed_addr constant [9 x i8] c"./dglm.h\00", align 1 +@.str.1 = private unnamed_addr constant [23 x i8] c"benchmarks/lfds/dglm.h\00", align 1 @__PRETTY_FUNCTION__.enqueue = private unnamed_addr constant [18 x i8] c"void enqueue(int)\00", align 1 @.str.2 = private unnamed_addr constant [13 x i8] c"head != NULL\00", align 1 @__PRETTY_FUNCTION__.dequeue = private unnamed_addr constant [14 x i8] c"int dequeue()\00", align 1 @.str.3 = private unnamed_addr constant [11 x i8] c"r != EMPTY\00", align 1 -@.str.4 = private unnamed_addr constant [7 x i8] c"dglm.c\00", align 1 +@.str.4 = private unnamed_addr constant [23 x i8] c"benchmarks/lfds/dglm.c\00", align 1 @__PRETTY_FUNCTION__.worker = private unnamed_addr constant [21 x i8] c"void *worker(void *)\00", align 1 -@data = dso_local global [3 x i32] zeroinitializer, align 4, !dbg !26 +@data = dso_local global [3 x i32] zeroinitializer, align 4 @.str.5 = private unnamed_addr constant [11 x i8] c"r == EMPTY\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 @.str.6 = private unnamed_addr constant [13 x i8] c"data[i] == 1\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @init() #0 !dbg !39 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @init() #0 { %1 = alloca %struct.Node*, align 8 - call void @llvm.dbg.declare(metadata %struct.Node** %1, metadata !43, metadata !DIExpression()), !dbg !44 - %2 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !45 - %3 = bitcast i8* %2 to %struct.Node*, !dbg !45 - store %struct.Node* %3, %struct.Node** %1, align 8, !dbg !44 - %4 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !46 - %5 = getelementptr inbounds %struct.Node, %struct.Node* %4, i32 0, i32 1, !dbg !47 - store %struct.Node* null, %struct.Node** %5, align 8, !dbg !48 - %6 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !49 - store %struct.Node* %6, %struct.Node** @Head, align 8, !dbg !50 - %7 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !51 - store %struct.Node* %7, %struct.Node** @Tail, align 8, !dbg !52 - ret void, !dbg !53 + %2 = call noalias i8* @malloc(i64 noundef 16) #4 + %3 = bitcast i8* %2 to %struct.Node* + store %struct.Node* %3, %struct.Node** %1, align 8 + %4 = load %struct.Node*, %struct.Node** %1, align 8 + %5 = getelementptr inbounds %struct.Node, %struct.Node* %4, i32 0, i32 1 + store %struct.Node* null, %struct.Node** %5, align 8 + %6 = load %struct.Node*, %struct.Node** %1, align 8 + store %struct.Node* %6, %struct.Node** @Head, align 8 + %7 = load %struct.Node*, %struct.Node** %1, align 8 + store %struct.Node* %7, %struct.Node** @Tail, align 8 + ret void } -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 +declare noalias i8* @malloc(i64 noundef) #1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @enqueue(i32 noundef %0) #0 !dbg !54 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @enqueue(i32 noundef %0) #0 { %2 = alloca i32, align 4 %3 = alloca %struct.Node*, align 8 %4 = alloca %struct.Node*, align 8 @@ -60,154 +56,150 @@ define dso_local void @enqueue(i32 noundef %0) #0 !dbg !54 { %13 = alloca %struct.Node*, align 8 %14 = alloca i8, align 1 store i32 %0, i32* %2, align 4 - call void @llvm.dbg.declare(metadata i32* %2, metadata !57, metadata !DIExpression()), !dbg !58 - call void @llvm.dbg.declare(metadata %struct.Node** %3, metadata !59, metadata !DIExpression()), !dbg !60 - call void @llvm.dbg.declare(metadata %struct.Node** %4, metadata !61, metadata !DIExpression()), !dbg !62 - call void @llvm.dbg.declare(metadata %struct.Node** %5, metadata !63, metadata !DIExpression()), !dbg !64 - %15 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !65 - %16 = bitcast i8* %15 to %struct.Node*, !dbg !65 - store %struct.Node* %16, %struct.Node** %5, align 8, !dbg !66 - %17 = load i32, i32* %2, align 4, !dbg !67 - %18 = load %struct.Node*, %struct.Node** %5, align 8, !dbg !68 - %19 = getelementptr inbounds %struct.Node, %struct.Node* %18, i32 0, i32 0, !dbg !69 - store i32 %17, i32* %19, align 8, !dbg !70 - %20 = load %struct.Node*, %struct.Node** %5, align 8, !dbg !71 - %21 = getelementptr inbounds %struct.Node, %struct.Node* %20, i32 0, i32 1, !dbg !72 - store %struct.Node* null, %struct.Node** %21, align 8, !dbg !73 - br label %22, !dbg !74 + %15 = call noalias i8* @malloc(i64 noundef 16) #4 + %16 = bitcast i8* %15 to %struct.Node* + store %struct.Node* %16, %struct.Node** %5, align 8 + %17 = load i32, i32* %2, align 4 + %18 = load %struct.Node*, %struct.Node** %5, align 8 + %19 = getelementptr inbounds %struct.Node, %struct.Node* %18, i32 0, i32 0 + store i32 %17, i32* %19, align 8 + %20 = load %struct.Node*, %struct.Node** %5, align 8 + %21 = getelementptr inbounds %struct.Node, %struct.Node* %20, i32 0, i32 1 + store %struct.Node* null, %struct.Node** %21, align 8 + br label %22 22: ; preds = %1, %95 - %23 = bitcast %struct.Node** %6 to i64*, !dbg !75 - %24 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !75 - store i64 %24, i64* %23, align 8, !dbg !75 - %25 = bitcast i64* %23 to %struct.Node**, !dbg !75 - %26 = load %struct.Node*, %struct.Node** %25, align 8, !dbg !75 - store %struct.Node* %26, %struct.Node** %3, align 8, !dbg !77 - %27 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !78 - %28 = icmp ne %struct.Node* %27, null, !dbg !78 - br i1 %28, label %29, label %30, !dbg !81 + %23 = bitcast %struct.Node** %6 to i64* + %24 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %24, i64* %23, align 8 + %25 = bitcast i64* %23 to %struct.Node** + %26 = load %struct.Node*, %struct.Node** %25, align 8 + store %struct.Node* %26, %struct.Node** %3, align 8 + %27 = load %struct.Node*, %struct.Node** %3, align 8 + %28 = icmp ne %struct.Node* %27, null + br i1 %28, label %29, label %30 29: ; preds = %22 - br label %31, !dbg !81 + br label %31 30: ; preds = %22 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @__PRETTY_FUNCTION__.enqueue, i64 0, i64 0)) #6, !dbg !78 - unreachable, !dbg !78 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @__PRETTY_FUNCTION__.enqueue, i64 0, i64 0)) #5 + unreachable 31: ; preds = %29 - %32 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !82 - %33 = getelementptr inbounds %struct.Node, %struct.Node* %32, i32 0, i32 1, !dbg !83 - %34 = bitcast %struct.Node** %33 to i64*, !dbg !84 - %35 = bitcast %struct.Node** %7 to i64*, !dbg !84 - %36 = load atomic i64, i64* %34 acquire, align 8, !dbg !84 - store i64 %36, i64* %35, align 8, !dbg !84 - %37 = bitcast i64* %35 to %struct.Node**, !dbg !84 - %38 = load %struct.Node*, %struct.Node** %37, align 8, !dbg !84 - store %struct.Node* %38, %struct.Node** %4, align 8, !dbg !85 - %39 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !86 - %40 = bitcast %struct.Node** %8 to i64*, !dbg !88 - %41 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !88 - store i64 %41, i64* %40, align 8, !dbg !88 - %42 = bitcast i64* %40 to %struct.Node**, !dbg !88 - %43 = load %struct.Node*, %struct.Node** %42, align 8, !dbg !88 - %44 = icmp eq %struct.Node* %39, %43, !dbg !89 - br i1 %44, label %45, label %95, !dbg !90 + %32 = load %struct.Node*, %struct.Node** %3, align 8 + %33 = getelementptr inbounds %struct.Node, %struct.Node* %32, i32 0, i32 1 + %34 = bitcast %struct.Node** %33 to i64* + %35 = bitcast %struct.Node** %7 to i64* + %36 = load atomic i64, i64* %34 acquire, align 8 + store i64 %36, i64* %35, align 8 + %37 = bitcast i64* %35 to %struct.Node** + %38 = load %struct.Node*, %struct.Node** %37, align 8 + store %struct.Node* %38, %struct.Node** %4, align 8 + %39 = load %struct.Node*, %struct.Node** %3, align 8 + %40 = bitcast %struct.Node** %8 to i64* + %41 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %41, i64* %40, align 8 + %42 = bitcast i64* %40 to %struct.Node** + %43 = load %struct.Node*, %struct.Node** %42, align 8 + %44 = icmp eq %struct.Node* %39, %43 + br i1 %44, label %45, label %95 45: ; preds = %31 - %46 = load %struct.Node*, %struct.Node** %4, align 8, !dbg !91 - %47 = icmp eq %struct.Node* %46, null, !dbg !94 - br i1 %47, label %48, label %80, !dbg !95 + %46 = load %struct.Node*, %struct.Node** %4, align 8 + %47 = icmp eq %struct.Node* %46, null + br i1 %47, label %48, label %80 48: ; preds = %45 - %49 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !96 - %50 = getelementptr inbounds %struct.Node, %struct.Node* %49, i32 0, i32 1, !dbg !96 - %51 = load %struct.Node*, %struct.Node** %5, align 8, !dbg !96 - store %struct.Node* %51, %struct.Node** %9, align 8, !dbg !96 - %52 = bitcast %struct.Node** %50 to i64*, !dbg !96 - %53 = bitcast %struct.Node** %4 to i64*, !dbg !96 - %54 = bitcast %struct.Node** %9 to i64*, !dbg !96 - %55 = load i64, i64* %53, align 8, !dbg !96 - %56 = load i64, i64* %54, align 8, !dbg !96 - %57 = cmpxchg i64* %52, i64 %55, i64 %56 acq_rel monotonic, align 8, !dbg !96 - %58 = extractvalue { i64, i1 } %57, 0, !dbg !96 - %59 = extractvalue { i64, i1 } %57, 1, !dbg !96 - br i1 %59, label %61, label %60, !dbg !96 + %49 = load %struct.Node*, %struct.Node** %3, align 8 + %50 = getelementptr inbounds %struct.Node, %struct.Node* %49, i32 0, i32 1 + %51 = load %struct.Node*, %struct.Node** %5, align 8 + store %struct.Node* %51, %struct.Node** %9, align 8 + %52 = bitcast %struct.Node** %50 to i64* + %53 = bitcast %struct.Node** %4 to i64* + %54 = bitcast %struct.Node** %9 to i64* + %55 = load i64, i64* %53, align 8 + %56 = load i64, i64* %54, align 8 + %57 = cmpxchg i64* %52, i64 %55, i64 %56 acq_rel monotonic, align 8 + %58 = extractvalue { i64, i1 } %57, 0 + %59 = extractvalue { i64, i1 } %57, 1 + br i1 %59, label %61, label %60 60: ; preds = %48 - store i64 %58, i64* %53, align 8, !dbg !96 - br label %61, !dbg !96 + store i64 %58, i64* %53, align 8 + br label %61 61: ; preds = %60, %48 - %62 = zext i1 %59 to i8, !dbg !96 - store i8 %62, i8* %10, align 1, !dbg !96 - %63 = load i8, i8* %10, align 1, !dbg !96 - %64 = trunc i8 %63 to i1, !dbg !96 - br i1 %64, label %65, label %79, !dbg !99 + %62 = zext i1 %59 to i8 + store i8 %62, i8* %10, align 1 + %63 = load i8, i8* %10, align 1 + %64 = trunc i8 %63 to i1 + br i1 %64, label %65, label %79 65: ; preds = %61 - %66 = load %struct.Node*, %struct.Node** %5, align 8, !dbg !100 - store %struct.Node* %66, %struct.Node** %11, align 8, !dbg !100 - %67 = bitcast %struct.Node** %3 to i64*, !dbg !100 - %68 = bitcast %struct.Node** %11 to i64*, !dbg !100 - %69 = load i64, i64* %67, align 8, !dbg !100 - %70 = load i64, i64* %68, align 8, !dbg !100 - %71 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %69, i64 %70 acq_rel monotonic, align 8, !dbg !100 - %72 = extractvalue { i64, i1 } %71, 0, !dbg !100 - %73 = extractvalue { i64, i1 } %71, 1, !dbg !100 - br i1 %73, label %75, label %74, !dbg !100 + %66 = load %struct.Node*, %struct.Node** %5, align 8 + store %struct.Node* %66, %struct.Node** %11, align 8 + %67 = bitcast %struct.Node** %3 to i64* + %68 = bitcast %struct.Node** %11 to i64* + %69 = load i64, i64* %67, align 8 + %70 = load i64, i64* %68, align 8 + %71 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %69, i64 %70 acq_rel monotonic, align 8 + %72 = extractvalue { i64, i1 } %71, 0 + %73 = extractvalue { i64, i1 } %71, 1 + br i1 %73, label %75, label %74 74: ; preds = %65 - store i64 %72, i64* %67, align 8, !dbg !100 - br label %75, !dbg !100 + store i64 %72, i64* %67, align 8 + br label %75 75: ; preds = %74, %65 - %76 = zext i1 %73 to i8, !dbg !100 - store i8 %76, i8* %12, align 1, !dbg !100 - %77 = load i8, i8* %12, align 1, !dbg !100 - %78 = trunc i8 %77 to i1, !dbg !100 - br label %96, !dbg !102 + %76 = zext i1 %73 to i8 + store i8 %76, i8* %12, align 1 + %77 = load i8, i8* %12, align 1 + %78 = trunc i8 %77 to i1 + br label %96 79: ; preds = %61 - br label %94, !dbg !103 + br label %94 80: ; preds = %45 - %81 = load %struct.Node*, %struct.Node** %4, align 8, !dbg !104 - store %struct.Node* %81, %struct.Node** %13, align 8, !dbg !104 - %82 = bitcast %struct.Node** %3 to i64*, !dbg !104 - %83 = bitcast %struct.Node** %13 to i64*, !dbg !104 - %84 = load i64, i64* %82, align 8, !dbg !104 - %85 = load i64, i64* %83, align 8, !dbg !104 - %86 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %84, i64 %85 acq_rel monotonic, align 8, !dbg !104 - %87 = extractvalue { i64, i1 } %86, 0, !dbg !104 - %88 = extractvalue { i64, i1 } %86, 1, !dbg !104 - br i1 %88, label %90, label %89, !dbg !104 + %81 = load %struct.Node*, %struct.Node** %4, align 8 + store %struct.Node* %81, %struct.Node** %13, align 8 + %82 = bitcast %struct.Node** %3 to i64* + %83 = bitcast %struct.Node** %13 to i64* + %84 = load i64, i64* %82, align 8 + %85 = load i64, i64* %83, align 8 + %86 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %84, i64 %85 acq_rel monotonic, align 8 + %87 = extractvalue { i64, i1 } %86, 0 + %88 = extractvalue { i64, i1 } %86, 1 + br i1 %88, label %90, label %89 89: ; preds = %80 - store i64 %87, i64* %82, align 8, !dbg !104 - br label %90, !dbg !104 + store i64 %87, i64* %82, align 8 + br label %90 90: ; preds = %89, %80 - %91 = zext i1 %88 to i8, !dbg !104 - store i8 %91, i8* %14, align 1, !dbg !104 - %92 = load i8, i8* %14, align 1, !dbg !104 - %93 = trunc i8 %92 to i1, !dbg !104 + %91 = zext i1 %88 to i8 + store i8 %91, i8* %14, align 1 + %92 = load i8, i8* %14, align 1 + %93 = trunc i8 %92 to i1 br label %94 94: ; preds = %90, %79 - br label %95, !dbg !106 + br label %95 95: ; preds = %94, %31 - br label %22, !dbg !74, !llvm.loop !107 + br label %22 96: ; preds = %75 - ret void, !dbg !109 + ret void } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #2 -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @dequeue() #0 !dbg !110 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @dequeue() #0 { %1 = alloca %struct.Node*, align 8 %2 = alloca %struct.Node*, align 8 %3 = alloca %struct.Node*, align 8 @@ -220,193 +212,186 @@ define dso_local i32 @dequeue() #0 !dbg !110 { %10 = alloca %struct.Node*, align 8 %11 = alloca %struct.Node*, align 8 %12 = alloca i8, align 1 - call void @llvm.dbg.declare(metadata %struct.Node** %1, metadata !113, metadata !DIExpression()), !dbg !114 - call void @llvm.dbg.declare(metadata %struct.Node** %2, metadata !115, metadata !DIExpression()), !dbg !116 - call void @llvm.dbg.declare(metadata %struct.Node** %3, metadata !117, metadata !DIExpression()), !dbg !118 - call void @llvm.dbg.declare(metadata i32* %4, metadata !119, metadata !DIExpression()), !dbg !120 - br label %13, !dbg !121 + br label %13 13: ; preds = %0, %89 - %14 = bitcast %struct.Node** %5 to i64*, !dbg !122 - %15 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8, !dbg !122 - store i64 %15, i64* %14, align 8, !dbg !122 - %16 = bitcast i64* %14 to %struct.Node**, !dbg !122 - %17 = load %struct.Node*, %struct.Node** %16, align 8, !dbg !122 - store %struct.Node* %17, %struct.Node** %1, align 8, !dbg !124 - %18 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !125 - %19 = icmp ne %struct.Node* %18, null, !dbg !125 - br i1 %19, label %20, label %21, !dbg !128 + %14 = bitcast %struct.Node** %5 to i64* + %15 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8 + store i64 %15, i64* %14, align 8 + %16 = bitcast i64* %14 to %struct.Node** + %17 = load %struct.Node*, %struct.Node** %16, align 8 + store %struct.Node* %17, %struct.Node** %1, align 8 + %18 = load %struct.Node*, %struct.Node** %1, align 8 + %19 = icmp ne %struct.Node* %18, null + br i1 %19, label %20, label %21 20: ; preds = %13 - br label %22, !dbg !128 + br label %22 21: ; preds = %13 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), i32 noundef 61, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #6, !dbg !125 - unreachable, !dbg !125 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0), i32 noundef 61, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #5 + unreachable 22: ; preds = %20 - %23 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !129 - %24 = getelementptr inbounds %struct.Node, %struct.Node* %23, i32 0, i32 1, !dbg !130 - %25 = bitcast %struct.Node** %24 to i64*, !dbg !131 - %26 = bitcast %struct.Node** %6 to i64*, !dbg !131 - %27 = load atomic i64, i64* %25 acquire, align 8, !dbg !131 - store i64 %27, i64* %26, align 8, !dbg !131 - %28 = bitcast i64* %26 to %struct.Node**, !dbg !131 - %29 = load %struct.Node*, %struct.Node** %28, align 8, !dbg !131 - store %struct.Node* %29, %struct.Node** %2, align 8, !dbg !132 - %30 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !133 - %31 = bitcast %struct.Node** %7 to i64*, !dbg !135 - %32 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8, !dbg !135 - store i64 %32, i64* %31, align 8, !dbg !135 - %33 = bitcast i64* %31 to %struct.Node**, !dbg !135 - %34 = load %struct.Node*, %struct.Node** %33, align 8, !dbg !135 - %35 = icmp eq %struct.Node* %30, %34, !dbg !136 - br i1 %35, label %36, label %89, !dbg !137 + %23 = load %struct.Node*, %struct.Node** %1, align 8 + %24 = getelementptr inbounds %struct.Node, %struct.Node* %23, i32 0, i32 1 + %25 = bitcast %struct.Node** %24 to i64* + %26 = bitcast %struct.Node** %6 to i64* + %27 = load atomic i64, i64* %25 acquire, align 8 + store i64 %27, i64* %26, align 8 + %28 = bitcast i64* %26 to %struct.Node** + %29 = load %struct.Node*, %struct.Node** %28, align 8 + store %struct.Node* %29, %struct.Node** %2, align 8 + %30 = load %struct.Node*, %struct.Node** %1, align 8 + %31 = bitcast %struct.Node** %7 to i64* + %32 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8 + store i64 %32, i64* %31, align 8 + %33 = bitcast i64* %31 to %struct.Node** + %34 = load %struct.Node*, %struct.Node** %33, align 8 + %35 = icmp eq %struct.Node* %30, %34 + br i1 %35, label %36, label %89 36: ; preds = %22 - %37 = load %struct.Node*, %struct.Node** %2, align 8, !dbg !138 - %38 = icmp eq %struct.Node* %37, null, !dbg !141 - br i1 %38, label %39, label %40, !dbg !142 + %37 = load %struct.Node*, %struct.Node** %2, align 8 + %38 = icmp eq %struct.Node* %37, null + br i1 %38, label %39, label %40 39: ; preds = %36 - store i32 -1, i32* %4, align 4, !dbg !143 - br label %90, !dbg !145 + store i32 -1, i32* %4, align 4 + br label %90 40: ; preds = %36 - %41 = load %struct.Node*, %struct.Node** %2, align 8, !dbg !146 - %42 = getelementptr inbounds %struct.Node, %struct.Node* %41, i32 0, i32 0, !dbg !148 - %43 = load i32, i32* %42, align 8, !dbg !148 - store i32 %43, i32* %4, align 4, !dbg !149 - %44 = load %struct.Node*, %struct.Node** %2, align 8, !dbg !150 - store %struct.Node* %44, %struct.Node** %8, align 8, !dbg !150 - %45 = bitcast %struct.Node** %1 to i64*, !dbg !150 - %46 = bitcast %struct.Node** %8 to i64*, !dbg !150 - %47 = load i64, i64* %45, align 8, !dbg !150 - %48 = load i64, i64* %46, align 8, !dbg !150 - %49 = cmpxchg i64* bitcast (%struct.Node** @Head to i64*), i64 %47, i64 %48 acq_rel monotonic, align 8, !dbg !150 - %50 = extractvalue { i64, i1 } %49, 0, !dbg !150 - %51 = extractvalue { i64, i1 } %49, 1, !dbg !150 - br i1 %51, label %53, label %52, !dbg !150 + %41 = load %struct.Node*, %struct.Node** %2, align 8 + %42 = getelementptr inbounds %struct.Node, %struct.Node* %41, i32 0, i32 0 + %43 = load i32, i32* %42, align 8 + store i32 %43, i32* %4, align 4 + %44 = load %struct.Node*, %struct.Node** %2, align 8 + store %struct.Node* %44, %struct.Node** %8, align 8 + %45 = bitcast %struct.Node** %1 to i64* + %46 = bitcast %struct.Node** %8 to i64* + %47 = load i64, i64* %45, align 8 + %48 = load i64, i64* %46, align 8 + %49 = cmpxchg i64* bitcast (%struct.Node** @Head to i64*), i64 %47, i64 %48 acq_rel monotonic, align 8 + %50 = extractvalue { i64, i1 } %49, 0 + %51 = extractvalue { i64, i1 } %49, 1 + br i1 %51, label %53, label %52 52: ; preds = %40 - store i64 %50, i64* %45, align 8, !dbg !150 - br label %53, !dbg !150 + store i64 %50, i64* %45, align 8 + br label %53 53: ; preds = %52, %40 - %54 = zext i1 %51 to i8, !dbg !150 - store i8 %54, i8* %9, align 1, !dbg !150 - %55 = load i8, i8* %9, align 1, !dbg !150 - %56 = trunc i8 %55 to i1, !dbg !150 - br i1 %56, label %57, label %87, !dbg !152 + %54 = zext i1 %51 to i8 + store i8 %54, i8* %9, align 1 + %55 = load i8, i8* %9, align 1 + %56 = trunc i8 %55 to i1 + br i1 %56, label %57, label %87 57: ; preds = %53 - %58 = bitcast %struct.Node** %10 to i64*, !dbg !153 - %59 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !153 - store i64 %59, i64* %58, align 8, !dbg !153 - %60 = bitcast i64* %58 to %struct.Node**, !dbg !153 - %61 = load %struct.Node*, %struct.Node** %60, align 8, !dbg !153 - store %struct.Node* %61, %struct.Node** %3, align 8, !dbg !155 - %62 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !156 - %63 = icmp ne %struct.Node* %62, null, !dbg !156 - br i1 %63, label %64, label %65, !dbg !159 + %58 = bitcast %struct.Node** %10 to i64* + %59 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %59, i64* %58, align 8 + %60 = bitcast i64* %58 to %struct.Node** + %61 = load %struct.Node*, %struct.Node** %60, align 8 + store %struct.Node* %61, %struct.Node** %3, align 8 + %62 = load %struct.Node*, %struct.Node** %3, align 8 + %63 = icmp ne %struct.Node* %62, null + br i1 %63, label %64, label %65 64: ; preds = %57 - br label %66, !dbg !159 + br label %66 65: ; preds = %57 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), i32 noundef 73, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #6, !dbg !156 - unreachable, !dbg !156 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0), i32 noundef 73, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #5 + unreachable 66: ; preds = %64 - %67 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !160 - %68 = load %struct.Node*, %struct.Node** %3, align 8, !dbg !162 - %69 = icmp eq %struct.Node* %67, %68, !dbg !163 - br i1 %69, label %70, label %84, !dbg !164 + %67 = load %struct.Node*, %struct.Node** %1, align 8 + %68 = load %struct.Node*, %struct.Node** %3, align 8 + %69 = icmp eq %struct.Node* %67, %68 + br i1 %69, label %70, label %84 70: ; preds = %66 - %71 = load %struct.Node*, %struct.Node** %2, align 8, !dbg !165 - store %struct.Node* %71, %struct.Node** %11, align 8, !dbg !165 - %72 = bitcast %struct.Node** %3 to i64*, !dbg !165 - %73 = bitcast %struct.Node** %11 to i64*, !dbg !165 - %74 = load i64, i64* %72, align 8, !dbg !165 - %75 = load i64, i64* %73, align 8, !dbg !165 - %76 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %74, i64 %75 acq_rel monotonic, align 8, !dbg !165 - %77 = extractvalue { i64, i1 } %76, 0, !dbg !165 - %78 = extractvalue { i64, i1 } %76, 1, !dbg !165 - br i1 %78, label %80, label %79, !dbg !165 + %71 = load %struct.Node*, %struct.Node** %2, align 8 + store %struct.Node* %71, %struct.Node** %11, align 8 + %72 = bitcast %struct.Node** %3 to i64* + %73 = bitcast %struct.Node** %11 to i64* + %74 = load i64, i64* %72, align 8 + %75 = load i64, i64* %73, align 8 + %76 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %74, i64 %75 acq_rel monotonic, align 8 + %77 = extractvalue { i64, i1 } %76, 0 + %78 = extractvalue { i64, i1 } %76, 1 + br i1 %78, label %80, label %79 79: ; preds = %70 - store i64 %77, i64* %72, align 8, !dbg !165 - br label %80, !dbg !165 + store i64 %77, i64* %72, align 8 + br label %80 80: ; preds = %79, %70 - %81 = zext i1 %78 to i8, !dbg !165 - store i8 %81, i8* %12, align 1, !dbg !165 - %82 = load i8, i8* %12, align 1, !dbg !165 - %83 = trunc i8 %82 to i1, !dbg !165 - br label %84, !dbg !167 + %81 = zext i1 %78 to i8 + store i8 %81, i8* %12, align 1 + %82 = load i8, i8* %12, align 1 + %83 = trunc i8 %82 to i1 + br label %84 84: ; preds = %80, %66 - %85 = load %struct.Node*, %struct.Node** %1, align 8, !dbg !168 - %86 = bitcast %struct.Node* %85 to i8*, !dbg !168 - call void @free(i8* noundef %86) #5, !dbg !169 - br label %90, !dbg !170 + %85 = load %struct.Node*, %struct.Node** %1, align 8 + %86 = bitcast %struct.Node* %85 to i8* + call void @free(i8* noundef %86) #4 + br label %90 87: ; preds = %53 br label %88 88: ; preds = %87 - br label %89, !dbg !171 + br label %89 89: ; preds = %88, %22 - br label %13, !dbg !121, !llvm.loop !172 + br label %13 90: ; preds = %84, %39 - %91 = load i32, i32* %4, align 4, !dbg !174 - ret i32 %91, !dbg !175 + %91 = load i32, i32* %4, align 4 + ret i32 %91 } ; Function Attrs: nounwind -declare void @free(i8* noundef) #2 +declare void @free(i8* noundef) #1 -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @worker(i8* noundef %0) #0 !dbg !176 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @worker(i8* noundef %0) #0 { %2 = alloca i8*, align 8 %3 = alloca i64, align 8 %4 = alloca i32, align 4 store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !179, metadata !DIExpression()), !dbg !180 - call void @llvm.dbg.declare(metadata i64* %3, metadata !181, metadata !DIExpression()), !dbg !182 - %5 = load i8*, i8** %2, align 8, !dbg !183 - %6 = ptrtoint i8* %5 to i64, !dbg !184 - store i64 %6, i64* %3, align 8, !dbg !182 - %7 = load i64, i64* %3, align 8, !dbg !185 - %8 = trunc i64 %7 to i32, !dbg !185 - call void @enqueue(i32 noundef %8), !dbg !186 - call void @llvm.dbg.declare(metadata i32* %4, metadata !187, metadata !DIExpression()), !dbg !188 - %9 = call i32 @dequeue(), !dbg !189 - store i32 %9, i32* %4, align 4, !dbg !188 - %10 = load i32, i32* %4, align 4, !dbg !190 - %11 = icmp ne i32 %10, -1, !dbg !190 - br i1 %11, label %12, label %13, !dbg !193 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + call void @enqueue(i32 noundef %8) + %9 = call i32 @dequeue() + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = icmp ne i32 %10, -1 + br i1 %11, label %12, label %13 12: ; preds = %1 - br label %14, !dbg !193 + br label %14 13: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* noundef getelementptr inbounds ([7 x i8], [7 x i8]* @.str.4, i64 0, i64 0), i32 noundef 18, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #6, !dbg !190 - unreachable, !dbg !190 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.4, i64 0, i64 0), i32 noundef 18, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #5 + unreachable 14: ; preds = %12 - %15 = load i32, i32* %4, align 4, !dbg !194 - %16 = sext i32 %15 to i64, !dbg !195 - %17 = getelementptr inbounds [3 x i32], [3 x i32]* @data, i64 0, i64 %16, !dbg !195 - store i32 1, i32* %17, align 4, !dbg !196 - ret i8* null, !dbg !197 + %15 = load i32, i32* %4, align 4 + %16 = sext i32 %15 to i64 + %17 = getelementptr inbounds [3 x i32], [3 x i32]* @data, i64 0, i64 %16 + store i32 1, i32* %17, align 4 + ret i8* null } -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !198 { +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca [3 x i64], align 16 %3 = alloca i32, align 4 @@ -414,394 +399,131 @@ define dso_local i32 @main() #0 !dbg !198 { %5 = alloca i32, align 4 %6 = alloca i32, align 4 store i32 0, i32* %1, align 4 - call void @llvm.dbg.declare(metadata [3 x i64]* %2, metadata !199, metadata !DIExpression()), !dbg !203 - call void @init(), !dbg !204 - call void @llvm.dbg.declare(metadata i32* %3, metadata !205, metadata !DIExpression()), !dbg !207 - store i32 0, i32* %3, align 4, !dbg !207 - br label %7, !dbg !208 + call void @init() + store i32 0, i32* %3, align 4 + br label %7 7: ; preds = %18, %0 - %8 = load i32, i32* %3, align 4, !dbg !209 - %9 = icmp slt i32 %8, 3, !dbg !211 - br i1 %9, label %10, label %21, !dbg !212 + %8 = load i32, i32* %3, align 4 + %9 = icmp slt i32 %8, 3 + br i1 %9, label %10, label %21 10: ; preds = %7 - %11 = load i32, i32* %3, align 4, !dbg !213 - %12 = sext i32 %11 to i64, !dbg !214 - %13 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %12, !dbg !214 - %14 = load i32, i32* %3, align 4, !dbg !215 - %15 = sext i32 %14 to i64, !dbg !216 - %16 = inttoptr i64 %15 to i8*, !dbg !217 - %17 = call i32 @pthread_create(i64* noundef %13, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef %16) #5, !dbg !218 - br label %18, !dbg !218 + %11 = load i32, i32* %3, align 4 + %12 = sext i32 %11 to i64 + %13 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %12 + %14 = load i32, i32* %3, align 4 + %15 = sext i32 %14 to i64 + %16 = inttoptr i64 %15 to i8* + %17 = call i32 @pthread_create(i64* noundef %13, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef %16) #4 + br label %18 18: ; preds = %10 - %19 = load i32, i32* %3, align 4, !dbg !219 - %20 = add nsw i32 %19, 1, !dbg !219 - store i32 %20, i32* %3, align 4, !dbg !219 - br label %7, !dbg !220, !llvm.loop !221 + %19 = load i32, i32* %3, align 4 + %20 = add nsw i32 %19, 1 + store i32 %20, i32* %3, align 4 + br label %7, !llvm.loop !6 21: ; preds = %7 - call void @llvm.dbg.declare(metadata i32* %4, metadata !224, metadata !DIExpression()), !dbg !226 - store i32 0, i32* %4, align 4, !dbg !226 - br label %22, !dbg !227 + store i32 0, i32* %4, align 4 + br label %22 22: ; preds = %31, %21 - %23 = load i32, i32* %4, align 4, !dbg !228 - %24 = icmp slt i32 %23, 3, !dbg !230 - br i1 %24, label %25, label %34, !dbg !231 + %23 = load i32, i32* %4, align 4 + %24 = icmp slt i32 %23, 3 + br i1 %24, label %25, label %34 25: ; preds = %22 - %26 = load i32, i32* %4, align 4, !dbg !232 - %27 = sext i32 %26 to i64, !dbg !233 - %28 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %27, !dbg !233 - %29 = load i64, i64* %28, align 8, !dbg !233 - %30 = call i32 @pthread_join(i64 noundef %29, i8** noundef null), !dbg !234 - br label %31, !dbg !234 + %26 = load i32, i32* %4, align 4 + %27 = sext i32 %26 to i64 + %28 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %27 + %29 = load i64, i64* %28, align 8 + %30 = call i32 @pthread_join(i64 noundef %29, i8** noundef null) + br label %31 31: ; preds = %25 - %32 = load i32, i32* %4, align 4, !dbg !235 - %33 = add nsw i32 %32, 1, !dbg !235 - store i32 %33, i32* %4, align 4, !dbg !235 - br label %22, !dbg !236, !llvm.loop !237 + %32 = load i32, i32* %4, align 4 + %33 = add nsw i32 %32, 1 + store i32 %33, i32* %4, align 4 + br label %22, !llvm.loop !8 34: ; preds = %22 - call void @llvm.dbg.declare(metadata i32* %5, metadata !239, metadata !DIExpression()), !dbg !240 - %35 = call i32 @dequeue(), !dbg !241 - store i32 %35, i32* %5, align 4, !dbg !240 - %36 = load i32, i32* %5, align 4, !dbg !242 - %37 = icmp eq i32 %36, -1, !dbg !242 - br i1 %37, label %38, label %39, !dbg !245 + %35 = call i32 @dequeue() + store i32 %35, i32* %5, align 4 + %36 = load i32, i32* %5, align 4 + %37 = icmp eq i32 %36, -1 + br i1 %37, label %38, label %39 38: ; preds = %34 - br label %40, !dbg !245 + br label %40 39: ; preds = %34 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* noundef getelementptr inbounds ([7 x i8], [7 x i8]* @.str.4, i64 0, i64 0), i32 noundef 37, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !242 - unreachable, !dbg !242 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.4, i64 0, i64 0), i32 noundef 37, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable 40: ; preds = %38 - %41 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) seq_cst, align 8, !dbg !246 - %42 = inttoptr i64 %41 to %struct.Node*, !dbg !246 - %43 = bitcast %struct.Node* %42 to i8*, !dbg !246 - call void @free(i8* noundef %43) #5, !dbg !247 - call void @llvm.dbg.declare(metadata i32* %6, metadata !248, metadata !DIExpression()), !dbg !250 - store i32 0, i32* %6, align 4, !dbg !250 - br label %44, !dbg !251 + %41 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) seq_cst, align 8 + %42 = inttoptr i64 %41 to %struct.Node* + %43 = bitcast %struct.Node* %42 to i8* + call void @free(i8* noundef %43) #4 + store i32 0, i32* %6, align 4 + br label %44 44: ; preds = %56, %40 - %45 = load i32, i32* %6, align 4, !dbg !252 - %46 = icmp slt i32 %45, 3, !dbg !254 - br i1 %46, label %47, label %59, !dbg !255 + %45 = load i32, i32* %6, align 4 + %46 = icmp slt i32 %45, 3 + br i1 %46, label %47, label %59 47: ; preds = %44 - %48 = load i32, i32* %6, align 4, !dbg !256 - %49 = sext i32 %48 to i64, !dbg !256 - %50 = getelementptr inbounds [3 x i32], [3 x i32]* @data, i64 0, i64 %49, !dbg !256 - %51 = load i32, i32* %50, align 4, !dbg !256 - %52 = icmp eq i32 %51, 1, !dbg !256 - br i1 %52, label %53, label %54, !dbg !259 + %48 = load i32, i32* %6, align 4 + %49 = sext i32 %48 to i64 + %50 = getelementptr inbounds [3 x i32], [3 x i32]* @data, i64 0, i64 %49 + %51 = load i32, i32* %50, align 4 + %52 = icmp eq i32 %51, 1 + br i1 %52, label %53, label %54 53: ; preds = %47 - br label %55, !dbg !259 + br label %55 54: ; preds = %47 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.6, i64 0, i64 0), i8* noundef getelementptr inbounds ([7 x i8], [7 x i8]* @.str.4, i64 0, i64 0), i32 noundef 41, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !256 - unreachable, !dbg !256 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.6, i64 0, i64 0), i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @.str.4, i64 0, i64 0), i32 noundef 41, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable 55: ; preds = %53 - br label %56, !dbg !260 + br label %56 56: ; preds = %55 - %57 = load i32, i32* %6, align 4, !dbg !261 - %58 = add nsw i32 %57, 1, !dbg !261 - store i32 %58, i32* %6, align 4, !dbg !261 - br label %44, !dbg !262, !llvm.loop !263 + %57 = load i32, i32* %6, align 4 + %58 = add nsw i32 %57, 1 + store i32 %58, i32* %6, align 4 + br label %44, !llvm.loop !9 59: ; preds = %44 - ret i32 0, !dbg !265 + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 - -declare i32 @pthread_join(i64 noundef, i8** noundef) #4 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!31, !32, !33, !34, !35, !36, !37} -!llvm.ident = !{!38} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "Head", scope: !2, file: !15, line: 19, type: !16, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !4, globals: !12, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "dglm.c", directory: "/home/ubuntu/Desktop/code/tianrui/Dat3M/benchmarks/lfds", checksumkind: CSK_MD5, checksum: "4ae6501ab5c2c592a30d5a52caaa9b80") -!4 = !{!5, !6, !9} -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !7, line: 87, baseType: !8) -!7 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "a48e64edacc5b19f56c99745232c963c") -!8 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !10, line: 46, baseType: !11) -!10 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.0/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!11 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!12 = !{!13, !0, !26} -!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression()) -!14 = distinct !DIGlobalVariable(name: "Tail", scope: !2, file: !15, line: 18, type: !16, isLocal: false, isDefinition: true) -!15 = !DIFile(filename: "./dglm.h", directory: "/home/ubuntu/Desktop/code/tianrui/Dat3M/benchmarks/lfds", checksumkind: CSK_MD5, checksum: "c81f98eeee5e13a9ab95151e3734648b") -!16 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !17) -!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) -!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "Node", file: !15, line: 16, baseType: !19) -!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Node", file: !15, line: 13, size: 128, elements: !20) -!20 = !{!21, !23} -!21 = !DIDerivedType(tag: DW_TAG_member, name: "val", scope: !19, file: !15, line: 14, baseType: !22, size: 32) -!22 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!23 = !DIDerivedType(tag: DW_TAG_member, name: "next", scope: !19, file: !15, line: 15, baseType: !24, size: 64, offset: 64) -!24 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !25) -!25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -!26 = !DIGlobalVariableExpression(var: !27, expr: !DIExpression()) -!27 = distinct !DIGlobalVariable(name: "data", scope: !2, file: !3, line: 8, type: !28, isLocal: false, isDefinition: true) -!28 = !DICompositeType(tag: DW_TAG_array_type, baseType: !22, size: 96, elements: !29) -!29 = !{!30} -!30 = !DISubrange(count: 3) -!31 = !{i32 7, !"Dwarf Version", i32 5} -!32 = !{i32 2, !"Debug Info Version", i32 3} -!33 = !{i32 1, !"wchar_size", i32 4} -!34 = !{i32 7, !"PIC Level", i32 2} -!35 = !{i32 7, !"PIE Level", i32 2} -!36 = !{i32 7, !"uwtable", i32 1} -!37 = !{i32 7, !"frame-pointer", i32 2} -!38 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} -!39 = distinct !DISubprogram(name: "init", scope: !15, file: !15, line: 22, type: !40, scopeLine: 22, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!40 = !DISubroutineType(types: !41) -!41 = !{null} -!42 = !{} -!43 = !DILocalVariable(name: "node", scope: !39, file: !15, line: 23, type: !17) -!44 = !DILocation(line: 23, column: 8, scope: !39) -!45 = !DILocation(line: 23, column: 15, scope: !39) -!46 = !DILocation(line: 24, column: 15, scope: !39) -!47 = !DILocation(line: 24, column: 21, scope: !39) -!48 = !DILocation(line: 24, column: 2, scope: !39) -!49 = !DILocation(line: 25, column: 21, scope: !39) -!50 = !DILocation(line: 25, column: 2, scope: !39) -!51 = !DILocation(line: 26, column: 21, scope: !39) -!52 = !DILocation(line: 26, column: 2, scope: !39) -!53 = !DILocation(line: 27, column: 1, scope: !39) -!54 = distinct !DISubprogram(name: "enqueue", scope: !15, file: !15, line: 29, type: !55, scopeLine: 29, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!55 = !DISubroutineType(types: !56) -!56 = !{null, !22} -!57 = !DILocalVariable(name: "value", arg: 1, scope: !54, file: !15, line: 29, type: !22) -!58 = !DILocation(line: 29, column: 18, scope: !54) -!59 = !DILocalVariable(name: "tail", scope: !54, file: !15, line: 30, type: !17) -!60 = !DILocation(line: 30, column: 8, scope: !54) -!61 = !DILocalVariable(name: "next", scope: !54, file: !15, line: 30, type: !17) -!62 = !DILocation(line: 30, column: 15, scope: !54) -!63 = !DILocalVariable(name: "node", scope: !54, file: !15, line: 30, type: !17) -!64 = !DILocation(line: 30, column: 22, scope: !54) -!65 = !DILocation(line: 32, column: 12, scope: !54) -!66 = !DILocation(line: 32, column: 10, scope: !54) -!67 = !DILocation(line: 33, column: 14, scope: !54) -!68 = !DILocation(line: 33, column: 2, scope: !54) -!69 = !DILocation(line: 33, column: 8, scope: !54) -!70 = !DILocation(line: 33, column: 12, scope: !54) -!71 = !DILocation(line: 34, column: 15, scope: !54) -!72 = !DILocation(line: 34, column: 21, scope: !54) -!73 = !DILocation(line: 34, column: 2, scope: !54) -!74 = !DILocation(line: 36, column: 2, scope: !54) -!75 = !DILocation(line: 37, column: 10, scope: !76) -!76 = distinct !DILexicalBlock(scope: !54, file: !15, line: 36, column: 12) -!77 = !DILocation(line: 37, column: 8, scope: !76) -!78 = !DILocation(line: 38, column: 9, scope: !79) -!79 = distinct !DILexicalBlock(scope: !80, file: !15, line: 38, column: 9) -!80 = distinct !DILexicalBlock(scope: !76, file: !15, line: 38, column: 9) -!81 = !DILocation(line: 38, column: 9, scope: !80) -!82 = !DILocation(line: 39, column: 32, scope: !76) -!83 = !DILocation(line: 39, column: 38, scope: !76) -!84 = !DILocation(line: 39, column: 10, scope: !76) -!85 = !DILocation(line: 39, column: 8, scope: !76) -!86 = !DILocation(line: 41, column: 13, scope: !87) -!87 = distinct !DILexicalBlock(scope: !76, file: !15, line: 41, column: 13) -!88 = !DILocation(line: 41, column: 21, scope: !87) -!89 = !DILocation(line: 41, column: 18, scope: !87) -!90 = !DILocation(line: 41, column: 13, scope: !76) -!91 = !DILocation(line: 42, column: 17, scope: !92) -!92 = distinct !DILexicalBlock(scope: !93, file: !15, line: 42, column: 17) -!93 = distinct !DILexicalBlock(scope: !87, file: !15, line: 41, column: 68) -!94 = !DILocation(line: 42, column: 22, scope: !92) -!95 = !DILocation(line: 42, column: 17, scope: !93) -!96 = !DILocation(line: 43, column: 9, scope: !97) -!97 = distinct !DILexicalBlock(scope: !98, file: !15, line: 43, column: 9) -!98 = distinct !DILexicalBlock(scope: !92, file: !15, line: 42, column: 31) -!99 = !DILocation(line: 43, column: 9, scope: !98) -!100 = !DILocation(line: 44, column: 9, scope: !101) -!101 = distinct !DILexicalBlock(scope: !97, file: !15, line: 43, column: 40) -!102 = !DILocation(line: 45, column: 6, scope: !101) -!103 = !DILocation(line: 47, column: 13, scope: !98) -!104 = !DILocation(line: 48, column: 5, scope: !105) -!105 = distinct !DILexicalBlock(scope: !92, file: !15, line: 47, column: 20) -!106 = !DILocation(line: 51, column: 9, scope: !93) -!107 = distinct !{!107, !74, !108} -!108 = !DILocation(line: 52, column: 2, scope: !54) -!109 = !DILocation(line: 53, column: 1, scope: !54) -!110 = distinct !DISubprogram(name: "dequeue", scope: !15, file: !15, line: 55, type: !111, scopeLine: 55, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!111 = !DISubroutineType(types: !112) -!112 = !{!22} -!113 = !DILocalVariable(name: "head", scope: !110, file: !15, line: 56, type: !17) -!114 = !DILocation(line: 56, column: 8, scope: !110) -!115 = !DILocalVariable(name: "next", scope: !110, file: !15, line: 56, type: !17) -!116 = !DILocation(line: 56, column: 15, scope: !110) -!117 = !DILocalVariable(name: "tail", scope: !110, file: !15, line: 56, type: !17) -!118 = !DILocation(line: 56, column: 22, scope: !110) -!119 = !DILocalVariable(name: "result", scope: !110, file: !15, line: 57, type: !22) -!120 = !DILocation(line: 57, column: 6, scope: !110) -!121 = !DILocation(line: 59, column: 2, scope: !110) -!122 = !DILocation(line: 60, column: 10, scope: !123) -!123 = distinct !DILexicalBlock(scope: !110, file: !15, line: 59, column: 12) -!124 = !DILocation(line: 60, column: 8, scope: !123) -!125 = !DILocation(line: 61, column: 9, scope: !126) -!126 = distinct !DILexicalBlock(scope: !127, file: !15, line: 61, column: 9) -!127 = distinct !DILexicalBlock(scope: !123, file: !15, line: 61, column: 9) -!128 = !DILocation(line: 61, column: 9, scope: !127) -!129 = !DILocation(line: 62, column: 32, scope: !123) -!130 = !DILocation(line: 62, column: 38, scope: !123) -!131 = !DILocation(line: 62, column: 10, scope: !123) -!132 = !DILocation(line: 62, column: 8, scope: !123) -!133 = !DILocation(line: 64, column: 7, scope: !134) -!134 = distinct !DILexicalBlock(scope: !123, file: !15, line: 64, column: 7) -!135 = !DILocation(line: 64, column: 15, scope: !134) -!136 = !DILocation(line: 64, column: 12, scope: !134) -!137 = !DILocation(line: 64, column: 7, scope: !123) -!138 = !DILocation(line: 65, column: 8, scope: !139) -!139 = distinct !DILexicalBlock(scope: !140, file: !15, line: 65, column: 8) -!140 = distinct !DILexicalBlock(scope: !134, file: !15, line: 64, column: 62) -!141 = !DILocation(line: 65, column: 13, scope: !139) -!142 = !DILocation(line: 65, column: 8, scope: !140) -!143 = !DILocation(line: 66, column: 12, scope: !144) -!144 = distinct !DILexicalBlock(scope: !139, file: !15, line: 65, column: 22) -!145 = !DILocation(line: 67, column: 5, scope: !144) -!146 = !DILocation(line: 70, column: 26, scope: !147) -!147 = distinct !DILexicalBlock(scope: !139, file: !15, line: 69, column: 11) -!148 = !DILocation(line: 70, column: 32, scope: !147) -!149 = !DILocation(line: 70, column: 24, scope: !147) -!150 = !DILocation(line: 71, column: 21, scope: !151) -!151 = distinct !DILexicalBlock(scope: !147, file: !15, line: 71, column: 21) -!152 = !DILocation(line: 71, column: 21, scope: !147) -!153 = !DILocation(line: 72, column: 28, scope: !154) -!154 = distinct !DILexicalBlock(scope: !151, file: !15, line: 71, column: 46) -!155 = !DILocation(line: 72, column: 26, scope: !154) -!156 = !DILocation(line: 73, column: 21, scope: !157) -!157 = distinct !DILexicalBlock(scope: !158, file: !15, line: 73, column: 21) -!158 = distinct !DILexicalBlock(scope: !154, file: !15, line: 73, column: 21) -!159 = !DILocation(line: 73, column: 21, scope: !158) -!160 = !DILocation(line: 74, column: 25, scope: !161) -!161 = distinct !DILexicalBlock(scope: !154, file: !15, line: 74, column: 25) -!162 = !DILocation(line: 74, column: 33, scope: !161) -!163 = !DILocation(line: 74, column: 30, scope: !161) -!164 = !DILocation(line: 74, column: 25, scope: !154) -!165 = !DILocation(line: 75, column: 25, scope: !166) -!166 = distinct !DILexicalBlock(scope: !161, file: !15, line: 74, column: 39) -!167 = !DILocation(line: 76, column: 21, scope: !166) -!168 = !DILocation(line: 77, column: 26, scope: !154) -!169 = !DILocation(line: 77, column: 21, scope: !154) -!170 = !DILocation(line: 78, column: 21, scope: !154) -!171 = !DILocation(line: 81, column: 3, scope: !140) -!172 = distinct !{!172, !121, !173} -!173 = !DILocation(line: 82, column: 2, scope: !110) -!174 = !DILocation(line: 84, column: 9, scope: !110) -!175 = !DILocation(line: 84, column: 2, scope: !110) -!176 = distinct !DISubprogram(name: "worker", scope: !3, file: !3, line: 10, type: !177, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!177 = !DISubroutineType(types: !178) -!178 = !{!5, !5} -!179 = !DILocalVariable(name: "arg", arg: 1, scope: !176, file: !3, line: 10, type: !5) -!180 = !DILocation(line: 10, column: 20, scope: !176) -!181 = !DILocalVariable(name: "index", scope: !176, file: !3, line: 13, type: !6) -!182 = !DILocation(line: 13, column: 14, scope: !176) -!183 = !DILocation(line: 13, column: 34, scope: !176) -!184 = !DILocation(line: 13, column: 23, scope: !176) -!185 = !DILocation(line: 15, column: 10, scope: !176) -!186 = !DILocation(line: 15, column: 2, scope: !176) -!187 = !DILocalVariable(name: "r", scope: !176, file: !3, line: 16, type: !22) -!188 = !DILocation(line: 16, column: 9, scope: !176) -!189 = !DILocation(line: 16, column: 13, scope: !176) -!190 = !DILocation(line: 18, column: 2, scope: !191) -!191 = distinct !DILexicalBlock(scope: !192, file: !3, line: 18, column: 2) -!192 = distinct !DILexicalBlock(scope: !176, file: !3, line: 18, column: 2) -!193 = !DILocation(line: 18, column: 2, scope: !192) -!194 = !DILocation(line: 19, column: 7, scope: !176) -!195 = !DILocation(line: 19, column: 2, scope: !176) -!196 = !DILocation(line: 19, column: 10, scope: !176) -!197 = !DILocation(line: 21, column: 2, scope: !176) -!198 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 24, type: !111, scopeLine: 25, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !42) -!199 = !DILocalVariable(name: "t", scope: !198, file: !3, line: 26, type: !200) -!200 = !DICompositeType(tag: DW_TAG_array_type, baseType: !201, size: 192, elements: !29) -!201 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !202, line: 27, baseType: !11) -!202 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "735e3bf264ff9d8f5d95898b1692fbdb") -!203 = !DILocation(line: 26, column: 15, scope: !198) -!204 = !DILocation(line: 28, column: 5, scope: !198) -!205 = !DILocalVariable(name: "i", scope: !206, file: !3, line: 30, type: !22) -!206 = distinct !DILexicalBlock(scope: !198, file: !3, line: 30, column: 5) -!207 = !DILocation(line: 30, column: 14, scope: !206) -!208 = !DILocation(line: 30, column: 10, scope: !206) -!209 = !DILocation(line: 30, column: 21, scope: !210) -!210 = distinct !DILexicalBlock(scope: !206, file: !3, line: 30, column: 5) -!211 = !DILocation(line: 30, column: 23, scope: !210) -!212 = !DILocation(line: 30, column: 5, scope: !206) -!213 = !DILocation(line: 31, column: 27, scope: !210) -!214 = !DILocation(line: 31, column: 25, scope: !210) -!215 = !DILocation(line: 31, column: 58, scope: !210) -!216 = !DILocation(line: 31, column: 50, scope: !210) -!217 = !DILocation(line: 31, column: 42, scope: !210) -!218 = !DILocation(line: 31, column: 9, scope: !210) -!219 = !DILocation(line: 30, column: 36, scope: !210) -!220 = !DILocation(line: 30, column: 5, scope: !210) -!221 = distinct !{!221, !212, !222, !223} -!222 = !DILocation(line: 31, column: 59, scope: !206) -!223 = !{!"llvm.loop.mustprogress"} -!224 = !DILocalVariable(name: "i", scope: !225, file: !3, line: 33, type: !22) -!225 = distinct !DILexicalBlock(scope: !198, file: !3, line: 33, column: 5) -!226 = !DILocation(line: 33, column: 14, scope: !225) -!227 = !DILocation(line: 33, column: 10, scope: !225) -!228 = !DILocation(line: 33, column: 21, scope: !229) -!229 = distinct !DILexicalBlock(scope: !225, file: !3, line: 33, column: 5) -!230 = !DILocation(line: 33, column: 23, scope: !229) -!231 = !DILocation(line: 33, column: 5, scope: !225) -!232 = !DILocation(line: 34, column: 24, scope: !229) -!233 = !DILocation(line: 34, column: 22, scope: !229) -!234 = !DILocation(line: 34, column: 9, scope: !229) -!235 = !DILocation(line: 33, column: 36, scope: !229) -!236 = !DILocation(line: 33, column: 5, scope: !229) -!237 = distinct !{!237, !231, !238, !223} -!238 = !DILocation(line: 34, column: 29, scope: !225) -!239 = !DILocalVariable(name: "r", scope: !198, file: !3, line: 36, type: !22) -!240 = !DILocation(line: 36, column: 9, scope: !198) -!241 = !DILocation(line: 36, column: 13, scope: !198) -!242 = !DILocation(line: 37, column: 5, scope: !243) -!243 = distinct !DILexicalBlock(scope: !244, file: !3, line: 37, column: 5) -!244 = distinct !DILexicalBlock(scope: !198, file: !3, line: 37, column: 5) -!245 = !DILocation(line: 37, column: 5, scope: !244) -!246 = !DILocation(line: 38, column: 10, scope: !198) -!247 = !DILocation(line: 38, column: 5, scope: !198) -!248 = !DILocalVariable(name: "i", scope: !249, file: !3, line: 40, type: !22) -!249 = distinct !DILexicalBlock(scope: !198, file: !3, line: 40, column: 5) -!250 = !DILocation(line: 40, column: 14, scope: !249) -!251 = !DILocation(line: 40, column: 10, scope: !249) -!252 = !DILocation(line: 40, column: 21, scope: !253) -!253 = distinct !DILexicalBlock(scope: !249, file: !3, line: 40, column: 5) -!254 = !DILocation(line: 40, column: 23, scope: !253) -!255 = !DILocation(line: 40, column: 5, scope: !249) -!256 = !DILocation(line: 41, column: 9, scope: !257) -!257 = distinct !DILexicalBlock(scope: !258, file: !3, line: 41, column: 9) -!258 = distinct !DILexicalBlock(scope: !253, file: !3, line: 41, column: 9) -!259 = !DILocation(line: 41, column: 9, scope: !258) -!260 = !DILocation(line: 41, column: 9, scope: !253) -!261 = !DILocation(line: 40, column: 36, scope: !253) -!262 = !DILocation(line: 40, column: 5, scope: !253) -!263 = distinct !{!263, !255, !264, !223} -!264 = !DILocation(line: 41, column: 9, scope: !249) -!265 = !DILocation(line: 43, column: 5, scope: !198) +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} +!9 = distinct !{!9, !7} diff --git a/dartagnan/src/test/resources/lfds/ms-CAS-relaxed.ll b/dartagnan/src/test/resources/lfds/ms-CAS-relaxed.ll index be6b1e675a..f72e0b4607 100644 --- a/dartagnan/src/test/resources/lfds/ms-CAS-relaxed.ll +++ b/dartagnan/src/test/resources/lfds/ms-CAS-relaxed.ll @@ -1,443 +1,487 @@ -; ModuleID = '/home/ponce/git/Dat3M/output/ms.ll' -source_filename = "/home/ponce/git/Dat3M/benchmarks/lfds/ms.c" +; ModuleID = 'benchmarks/lfds/ms.c' +source_filename = "benchmarks/lfds/ms.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" %struct.Node = type { i32, %struct.Node* } %union.pthread_attr_t = type { i64, [48 x i8] } -@Head = dso_local global %struct.Node* null, align 8, !dbg !0 -@Tail = dso_local global %struct.Node* null, align 8, !dbg !13 +@Head = dso_local global %struct.Node* null, align 8 +@Tail = dso_local global %struct.Node* null, align 8 @.str = private unnamed_addr constant [13 x i8] c"tail != NULL\00", align 1 -@.str.1 = private unnamed_addr constant [43 x i8] c"/home/ponce/git/Dat3M/benchmarks/lfds/ms.h\00", align 1 +@.str.1 = private unnamed_addr constant [21 x i8] c"benchmarks/lfds/ms.h\00", align 1 @__PRETTY_FUNCTION__.enqueue = private unnamed_addr constant [18 x i8] c"void enqueue(int)\00", align 1 @.str.2 = private unnamed_addr constant [13 x i8] c"head != NULL\00", align 1 @__PRETTY_FUNCTION__.dequeue = private unnamed_addr constant [14 x i8] c"int dequeue()\00", align 1 @.str.3 = private unnamed_addr constant [11 x i8] c"r != EMPTY\00", align 1 -@.str.4 = private unnamed_addr constant [43 x i8] c"/home/ponce/git/Dat3M/benchmarks/lfds/ms.c\00", align 1 +@.str.4 = private unnamed_addr constant [21 x i8] c"benchmarks/lfds/ms.c\00", align 1 @__PRETTY_FUNCTION__.worker = private unnamed_addr constant [21 x i8] c"void *worker(void *)\00", align 1 @.str.5 = private unnamed_addr constant [11 x i8] c"r == EMPTY\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @init() #0 !dbg !34 { - %1 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !38 - %2 = bitcast i8* %1 to %struct.Node*, !dbg !38 - call void @llvm.dbg.value(metadata %struct.Node* %2, metadata !39, metadata !DIExpression()), !dbg !40 - %3 = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 0, i32 1, !dbg !41 - store %struct.Node* null, %struct.Node** %3, align 8, !dbg !42 - store %struct.Node* %2, %struct.Node** @Head, align 8, !dbg !43 - store %struct.Node* %2, %struct.Node** @Tail, align 8, !dbg !44 - ret void, !dbg !45 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @init() #0 { + %1 = alloca %struct.Node*, align 8 + %2 = call noalias i8* @malloc(i64 noundef 16) #4 + %3 = bitcast i8* %2 to %struct.Node* + store %struct.Node* %3, %struct.Node** %1, align 8 + %4 = load %struct.Node*, %struct.Node** %1, align 8 + %5 = getelementptr inbounds %struct.Node, %struct.Node* %4, i32 0, i32 1 + store %struct.Node* null, %struct.Node** %5, align 8 + %6 = load %struct.Node*, %struct.Node** %1, align 8 + store %struct.Node* %6, %struct.Node** @Head, align 8 + %7 = load %struct.Node*, %struct.Node** %1, align 8 + store %struct.Node* %7, %struct.Node** @Tail, align 8 + ret void } -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 - -; Function Attrs: noinline nounwind uwtable -define dso_local void @enqueue(i32 noundef %0) #0 !dbg !46 { - call void @llvm.dbg.value(metadata i32 %0, metadata !49, metadata !DIExpression()), !dbg !50 - %2 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !51 - %3 = bitcast i8* %2 to %struct.Node*, !dbg !51 - call void @llvm.dbg.value(metadata %struct.Node* %3, metadata !52, metadata !DIExpression()), !dbg !50 - %4 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 0, !dbg !53 - store i32 %0, i32* %4, align 8, !dbg !54 - %5 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 1, !dbg !55 - store %struct.Node* null, %struct.Node** %5, align 8, !dbg !56 - br label %6, !dbg !57 - -6: ; preds = %37, %1 - %7 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !58 - %8 = inttoptr i64 %7 to %struct.Node*, !dbg !58 - call void @llvm.dbg.value(metadata %struct.Node* %8, metadata !60, metadata !DIExpression()), !dbg !50 - %9 = icmp ne %struct.Node* %8, null, !dbg !61 - br i1 %9, label %11, label %10, !dbg !64 - -10: ; preds = %6 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @__PRETTY_FUNCTION__.enqueue, i64 0, i64 0)) #6, !dbg !61 - unreachable, !dbg !61 - -11: ; preds = %6 - %12 = getelementptr inbounds %struct.Node, %struct.Node* %8, i32 0, i32 1, !dbg !65 - %13 = bitcast %struct.Node** %12 to i64*, !dbg !66 - %14 = load atomic i64, i64* %13 acquire, align 8, !dbg !66 - %15 = inttoptr i64 %14 to %struct.Node*, !dbg !66 - call void @llvm.dbg.value(metadata %struct.Node* %15, metadata !67, metadata !DIExpression()), !dbg !50 - %16 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !68 - %17 = inttoptr i64 %16 to %struct.Node*, !dbg !68 - %18 = icmp eq %struct.Node* %8, %17, !dbg !70 - br i1 %18, label %19, label %37, !dbg !71 - -19: ; preds = %11 - %20 = icmp ne %struct.Node* %15, null, !dbg !72 - br i1 %20, label %21, label %26, !dbg !75 - -21: ; preds = %19 - %22 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %7, i64 %14 monotonic monotonic, align 8, !dbg !76 - %23 = extractvalue { i64, i1 } %22, 0, !dbg !76 - %24 = extractvalue { i64, i1 } %22, 1, !dbg !76 - %25 = zext i1 %24 to i8, !dbg !76 - br label %37, !dbg !78 - -26: ; preds = %19 - %27 = ptrtoint %struct.Node* %3 to i64, !dbg !79 - %28 = cmpxchg i64* %13, i64 %14, i64 %27 monotonic monotonic, align 8, !dbg !79 - %29 = extractvalue { i64, i1 } %28, 0, !dbg !79 - %30 = extractvalue { i64, i1 } %28, 1, !dbg !79 - %31 = zext i1 %30 to i8, !dbg !79 - br i1 %30, label %32, label %37, !dbg !82 - -32: ; preds = %26 - %33 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %7, i64 %27 monotonic monotonic, align 8, !dbg !83 - %34 = extractvalue { i64, i1 } %33, 0, !dbg !83 - %35 = extractvalue { i64, i1 } %33, 1, !dbg !83 - %36 = zext i1 %35 to i8, !dbg !83 - ret void, !dbg !85 - -37: ; preds = %21, %26, %11 - br label %6, !dbg !57, !llvm.loop !86 +declare noalias i8* @malloc(i64 noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @enqueue(i32 noundef %0) #0 { + %2 = alloca i32, align 4 + %3 = alloca %struct.Node*, align 8 + %4 = alloca %struct.Node*, align 8 + %5 = alloca %struct.Node*, align 8 + %6 = alloca %struct.Node*, align 8 + %7 = alloca %struct.Node*, align 8 + %8 = alloca %struct.Node*, align 8 + %9 = alloca %struct.Node*, align 8 + %10 = alloca i8, align 1 + %11 = alloca %struct.Node*, align 8 + %12 = alloca i8, align 1 + %13 = alloca %struct.Node*, align 8 + %14 = alloca i8, align 1 + store i32 %0, i32* %2, align 4 + %15 = call noalias i8* @malloc(i64 noundef 16) #4 + %16 = bitcast i8* %15 to %struct.Node* + store %struct.Node* %16, %struct.Node** %5, align 8 + %17 = load i32, i32* %2, align 4 + %18 = load %struct.Node*, %struct.Node** %5, align 8 + %19 = getelementptr inbounds %struct.Node, %struct.Node* %18, i32 0, i32 0 + store i32 %17, i32* %19, align 8 + %20 = load %struct.Node*, %struct.Node** %5, align 8 + %21 = getelementptr inbounds %struct.Node, %struct.Node* %20, i32 0, i32 1 + store %struct.Node* null, %struct.Node** %21, align 8 + br label %22 + +22: ; preds = %1, %95 + %23 = bitcast %struct.Node** %6 to i64* + %24 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %24, i64* %23, align 8 + %25 = bitcast i64* %23 to %struct.Node** + %26 = load %struct.Node*, %struct.Node** %25, align 8 + store %struct.Node* %26, %struct.Node** %3, align 8 + %27 = load %struct.Node*, %struct.Node** %3, align 8 + %28 = icmp ne %struct.Node* %27, null + br i1 %28, label %29, label %30 + +29: ; preds = %22 + br label %31 + +30: ; preds = %22 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @__PRETTY_FUNCTION__.enqueue, i64 0, i64 0)) #5 + unreachable + +31: ; preds = %29 + %32 = load %struct.Node*, %struct.Node** %3, align 8 + %33 = getelementptr inbounds %struct.Node, %struct.Node* %32, i32 0, i32 1 + %34 = bitcast %struct.Node** %33 to i64* + %35 = bitcast %struct.Node** %7 to i64* + %36 = load atomic i64, i64* %34 acquire, align 8 + store i64 %36, i64* %35, align 8 + %37 = bitcast i64* %35 to %struct.Node** + %38 = load %struct.Node*, %struct.Node** %37, align 8 + store %struct.Node* %38, %struct.Node** %4, align 8 + %39 = load %struct.Node*, %struct.Node** %3, align 8 + %40 = bitcast %struct.Node** %8 to i64* + %41 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %41, i64* %40, align 8 + %42 = bitcast i64* %40 to %struct.Node** + %43 = load %struct.Node*, %struct.Node** %42, align 8 + %44 = icmp eq %struct.Node* %39, %43 + br i1 %44, label %45, label %95 + +45: ; preds = %31 + %46 = load %struct.Node*, %struct.Node** %4, align 8 + %47 = icmp ne %struct.Node* %46, null + br i1 %47, label %48, label %62 + +48: ; preds = %45 + %49 = load %struct.Node*, %struct.Node** %4, align 8 + store %struct.Node* %49, %struct.Node** %9, align 8 + %50 = bitcast %struct.Node** %3 to i64* + %51 = bitcast %struct.Node** %9 to i64* + %52 = load i64, i64* %50, align 8 + %53 = load i64, i64* %51, align 8 + %54 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %52, i64 %53 monotonic monotonic, align 8 + %55 = extractvalue { i64, i1 } %54, 0 + %56 = extractvalue { i64, i1 } %54, 1 + br i1 %56, label %58, label %57 + +57: ; preds = %48 + store i64 %55, i64* %50, align 8 + br label %58 + +58: ; preds = %57, %48 + %59 = zext i1 %56 to i8 + store i8 %59, i8* %10, align 1 + %60 = load i8, i8* %10, align 1 + %61 = trunc i8 %60 to i1 + br label %94 + +62: ; preds = %45 + %63 = load %struct.Node*, %struct.Node** %3, align 8 + %64 = getelementptr inbounds %struct.Node, %struct.Node* %63, i32 0, i32 1 + %65 = load %struct.Node*, %struct.Node** %5, align 8 + store %struct.Node* %65, %struct.Node** %11, align 8 + %66 = bitcast %struct.Node** %64 to i64* + %67 = bitcast %struct.Node** %4 to i64* + %68 = bitcast %struct.Node** %11 to i64* + %69 = load i64, i64* %67, align 8 + %70 = load i64, i64* %68, align 8 + %71 = cmpxchg i64* %66, i64 %69, i64 %70 monotonic monotonic, align 8 + %72 = extractvalue { i64, i1 } %71, 0 + %73 = extractvalue { i64, i1 } %71, 1 + br i1 %73, label %75, label %74 + +74: ; preds = %62 + store i64 %72, i64* %67, align 8 + br label %75 + +75: ; preds = %74, %62 + %76 = zext i1 %73 to i8 + store i8 %76, i8* %12, align 1 + %77 = load i8, i8* %12, align 1 + %78 = trunc i8 %77 to i1 + br i1 %78, label %79, label %93 + +79: ; preds = %75 + %80 = load %struct.Node*, %struct.Node** %5, align 8 + store %struct.Node* %80, %struct.Node** %13, align 8 + %81 = bitcast %struct.Node** %3 to i64* + %82 = bitcast %struct.Node** %13 to i64* + %83 = load i64, i64* %81, align 8 + %84 = load i64, i64* %82, align 8 + %85 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %83, i64 %84 monotonic monotonic, align 8 + %86 = extractvalue { i64, i1 } %85, 0 + %87 = extractvalue { i64, i1 } %85, 1 + br i1 %87, label %89, label %88 + +88: ; preds = %79 + store i64 %86, i64* %81, align 8 + br label %89 + +89: ; preds = %88, %79 + %90 = zext i1 %87 to i8 + store i8 %90, i8* %14, align 1 + %91 = load i8, i8* %14, align 1 + %92 = trunc i8 %91 to i1 + br label %96 + +93: ; preds = %75 + br label %94 + +94: ; preds = %93, %58 + br label %95 + +95: ; preds = %94, %31 + br label %22 + +96: ; preds = %89 + ret void } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @dequeue() #0 !dbg !88 { - br label %1, !dbg !91 - -1: ; preds = %35, %0 - %2 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8, !dbg !92 - %3 = inttoptr i64 %2 to %struct.Node*, !dbg !92 - call void @llvm.dbg.value(metadata %struct.Node* %3, metadata !94, metadata !DIExpression()), !dbg !95 - %4 = icmp ne %struct.Node* %3, null, !dbg !96 - br i1 %4, label %6, label %5, !dbg !99 - -5: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.1, i64 0, i64 0), i32 noundef 60, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #6, !dbg !96 - unreachable, !dbg !96 - -6: ; preds = %1 - %7 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !100 - %8 = inttoptr i64 %7 to %struct.Node*, !dbg !100 - call void @llvm.dbg.value(metadata %struct.Node* %8, metadata !101, metadata !DIExpression()), !dbg !95 - %9 = icmp ne %struct.Node* %8, null, !dbg !102 - br i1 %9, label %11, label %10, !dbg !105 - -10: ; preds = %6 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.1, i64 0, i64 0), i32 noundef 62, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #6, !dbg !102 - unreachable, !dbg !102 - -11: ; preds = %6 - %12 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 1, !dbg !106 - %13 = bitcast %struct.Node** %12 to i64*, !dbg !107 - %14 = load atomic i64, i64* %13 acquire, align 8, !dbg !107 - %15 = inttoptr i64 %14 to %struct.Node*, !dbg !107 - call void @llvm.dbg.value(metadata %struct.Node* %15, metadata !108, metadata !DIExpression()), !dbg !95 - %16 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8, !dbg !109 - %17 = inttoptr i64 %16 to %struct.Node*, !dbg !109 - %18 = icmp eq %struct.Node* %3, %17, !dbg !111 - br i1 %18, label %19, label %35, !dbg !112 - -19: ; preds = %11 - %20 = icmp eq %struct.Node* %15, null, !dbg !113 - br i1 %20, label %36, label %21, !dbg !116 - -21: ; preds = %19 - %22 = icmp eq %struct.Node* %3, %8, !dbg !117 - br i1 %22, label %23, label %28, !dbg !120 - -23: ; preds = %21 - %24 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %7, i64 %14 monotonic monotonic, align 8, !dbg !121 - %25 = extractvalue { i64, i1 } %24, 0, !dbg !121 - %26 = extractvalue { i64, i1 } %24, 1, !dbg !121 - %27 = zext i1 %26 to i8, !dbg !121 - br label %35, !dbg !123 - -28: ; preds = %21 - %29 = getelementptr inbounds %struct.Node, %struct.Node* %15, i32 0, i32 0, !dbg !124 - %30 = load i32, i32* %29, align 8, !dbg !124 - call void @llvm.dbg.value(metadata i32 %30, metadata !126, metadata !DIExpression()), !dbg !95 - %31 = cmpxchg i64* bitcast (%struct.Node** @Head to i64*), i64 %2, i64 %14 monotonic monotonic, align 8, !dbg !127 - %32 = extractvalue { i64, i1 } %31, 0, !dbg !127 - %33 = extractvalue { i64, i1 } %31, 1, !dbg !127 - %34 = zext i1 %33 to i8, !dbg !127 - br i1 %33, label %36, label %35, !dbg !129 - -35: ; preds = %28, %23, %11 - br label %1, !dbg !91, !llvm.loop !130 - -36: ; preds = %28, %19 - %.0 = phi i32 [ -1, %19 ], [ %30, %28 ], !dbg !132 - call void @llvm.dbg.value(metadata i32 %.0, metadata !126, metadata !DIExpression()), !dbg !95 - ret i32 %.0, !dbg !133 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @dequeue() #0 { + %1 = alloca %struct.Node*, align 8 + %2 = alloca %struct.Node*, align 8 + %3 = alloca %struct.Node*, align 8 + %4 = alloca i32, align 4 + %5 = alloca %struct.Node*, align 8 + %6 = alloca %struct.Node*, align 8 + %7 = alloca %struct.Node*, align 8 + %8 = alloca %struct.Node*, align 8 + %9 = alloca %struct.Node*, align 8 + %10 = alloca i8, align 1 + %11 = alloca %struct.Node*, align 8 + %12 = alloca i8, align 1 + br label %13 + +13: ; preds = %0, %90 + %14 = bitcast %struct.Node** %5 to i64* + %15 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8 + store i64 %15, i64* %14, align 8 + %16 = bitcast i64* %14 to %struct.Node** + %17 = load %struct.Node*, %struct.Node** %16, align 8 + store %struct.Node* %17, %struct.Node** %1, align 8 + %18 = load %struct.Node*, %struct.Node** %1, align 8 + %19 = icmp ne %struct.Node* %18, null + br i1 %19, label %20, label %21 + +20: ; preds = %13 + br label %22 + +21: ; preds = %13 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), i32 noundef 60, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #5 + unreachable + +22: ; preds = %20 + %23 = bitcast %struct.Node** %6 to i64* + %24 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %24, i64* %23, align 8 + %25 = bitcast i64* %23 to %struct.Node** + %26 = load %struct.Node*, %struct.Node** %25, align 8 + store %struct.Node* %26, %struct.Node** %3, align 8 + %27 = load %struct.Node*, %struct.Node** %3, align 8 + %28 = icmp ne %struct.Node* %27, null + br i1 %28, label %29, label %30 + +29: ; preds = %22 + br label %31 + +30: ; preds = %22 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), i32 noundef 62, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #5 + unreachable + +31: ; preds = %29 + %32 = load %struct.Node*, %struct.Node** %1, align 8 + %33 = getelementptr inbounds %struct.Node, %struct.Node* %32, i32 0, i32 1 + %34 = bitcast %struct.Node** %33 to i64* + %35 = bitcast %struct.Node** %7 to i64* + %36 = load atomic i64, i64* %34 acquire, align 8 + store i64 %36, i64* %35, align 8 + %37 = bitcast i64* %35 to %struct.Node** + %38 = load %struct.Node*, %struct.Node** %37, align 8 + store %struct.Node* %38, %struct.Node** %2, align 8 + %39 = load %struct.Node*, %struct.Node** %1, align 8 + %40 = bitcast %struct.Node** %8 to i64* + %41 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8 + store i64 %41, i64* %40, align 8 + %42 = bitcast i64* %40 to %struct.Node** + %43 = load %struct.Node*, %struct.Node** %42, align 8 + %44 = icmp eq %struct.Node* %39, %43 + br i1 %44, label %45, label %90 + +45: ; preds = %31 + %46 = load %struct.Node*, %struct.Node** %2, align 8 + %47 = icmp eq %struct.Node* %46, null + br i1 %47, label %48, label %49 + +48: ; preds = %45 + store i32 -1, i32* %4, align 4 + br label %91 + +49: ; preds = %45 + %50 = load %struct.Node*, %struct.Node** %1, align 8 + %51 = load %struct.Node*, %struct.Node** %3, align 8 + %52 = icmp eq %struct.Node* %50, %51 + br i1 %52, label %53, label %67 + +53: ; preds = %49 + %54 = load %struct.Node*, %struct.Node** %2, align 8 + store %struct.Node* %54, %struct.Node** %9, align 8 + %55 = bitcast %struct.Node** %3 to i64* + %56 = bitcast %struct.Node** %9 to i64* + %57 = load i64, i64* %55, align 8 + %58 = load i64, i64* %56, align 8 + %59 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %57, i64 %58 monotonic monotonic, align 8 + %60 = extractvalue { i64, i1 } %59, 0 + %61 = extractvalue { i64, i1 } %59, 1 + br i1 %61, label %63, label %62 + +62: ; preds = %53 + store i64 %60, i64* %55, align 8 + br label %63 + +63: ; preds = %62, %53 + %64 = zext i1 %61 to i8 + store i8 %64, i8* %10, align 1 + %65 = load i8, i8* %10, align 1 + %66 = trunc i8 %65 to i1 + br label %88 + +67: ; preds = %49 + %68 = load %struct.Node*, %struct.Node** %2, align 8 + %69 = getelementptr inbounds %struct.Node, %struct.Node* %68, i32 0, i32 0 + %70 = load i32, i32* %69, align 8 + store i32 %70, i32* %4, align 4 + %71 = load %struct.Node*, %struct.Node** %2, align 8 + store %struct.Node* %71, %struct.Node** %11, align 8 + %72 = bitcast %struct.Node** %1 to i64* + %73 = bitcast %struct.Node** %11 to i64* + %74 = load i64, i64* %72, align 8 + %75 = load i64, i64* %73, align 8 + %76 = cmpxchg i64* bitcast (%struct.Node** @Head to i64*), i64 %74, i64 %75 monotonic monotonic, align 8 + %77 = extractvalue { i64, i1 } %76, 0 + %78 = extractvalue { i64, i1 } %76, 1 + br i1 %78, label %80, label %79 + +79: ; preds = %67 + store i64 %77, i64* %72, align 8 + br label %80 + +80: ; preds = %79, %67 + %81 = zext i1 %78 to i8 + store i8 %81, i8* %12, align 1 + %82 = load i8, i8* %12, align 1 + %83 = trunc i8 %82 to i1 + br i1 %83, label %84, label %87 + +84: ; preds = %80 + %85 = load %struct.Node*, %struct.Node** %1, align 8 + %86 = bitcast %struct.Node* %85 to i8* + call void @free(i8* noundef %86) #4 + br label %91 + +87: ; preds = %80 + br label %88 + +88: ; preds = %87, %63 + br label %89 + +89: ; preds = %88 + br label %90 + +90: ; preds = %89, %31 + br label %13 + +91: ; preds = %84, %48 + %92 = load i32, i32* %4, align 4 + ret i32 %92 } -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @worker(i8* noundef %0) #0 !dbg !134 { - call void @llvm.dbg.value(metadata i8* %0, metadata !138, metadata !DIExpression()), !dbg !139 - %2 = ptrtoint i8* %0 to i64, !dbg !140 - call void @llvm.dbg.value(metadata i64 %2, metadata !141, metadata !DIExpression()), !dbg !139 - %3 = trunc i64 %2 to i32, !dbg !142 - call void @enqueue(i32 noundef %3), !dbg !143 - %4 = call i32 @dequeue(), !dbg !144 - call void @llvm.dbg.value(metadata i32 %4, metadata !145, metadata !DIExpression()), !dbg !139 - %5 = icmp ne i32 %4, -1, !dbg !146 - br i1 %5, label %7, label %6, !dbg !149 - -6: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.4, i64 0, i64 0), i32 noundef 16, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #6, !dbg !146 - unreachable, !dbg !146 - -7: ; preds = %1 - ret i8* null, !dbg !150 +; Function Attrs: nounwind +declare void @free(i8* noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @worker(i8* noundef %0) #0 { + %2 = alloca i8*, align 8 + %3 = alloca i64, align 8 + %4 = alloca i32, align 4 + store i8* %0, i8** %2, align 8 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + call void @enqueue(i32 noundef %8) + %9 = call i32 @dequeue() + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = icmp ne i32 %10, -1 + br i1 %11, label %12, label %13 + +12: ; preds = %1 + br label %14 + +13: ; preds = %1 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i32 noundef 16, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #5 + unreachable + +14: ; preds = %12 + ret i8* null } -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !151 { - %1 = alloca [3 x i64], align 16 - call void @llvm.dbg.declare(metadata [3 x i64]* %1, metadata !152, metadata !DIExpression()), !dbg !158 - call void @init(), !dbg !159 - call void @llvm.dbg.value(metadata i32 0, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i64 0, metadata !160, metadata !DIExpression()), !dbg !162 - %2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0, !dbg !163 - %3 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef null) #5, !dbg !165 - call void @llvm.dbg.value(metadata i64 1, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i64 1, metadata !160, metadata !DIExpression()), !dbg !162 - %4 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1, !dbg !163 - %5 = call i32 @pthread_create(i64* noundef %4, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef inttoptr (i64 1 to i8*)) #5, !dbg !165 - call void @llvm.dbg.value(metadata i64 2, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i64 2, metadata !160, metadata !DIExpression()), !dbg !162 - %6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2, !dbg !163 - %7 = call i32 @pthread_create(i64* noundef %6, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef inttoptr (i64 2 to i8*)) #5, !dbg !165 - call void @llvm.dbg.value(metadata i64 3, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i64 3, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i32 0, metadata !166, metadata !DIExpression()), !dbg !168 - call void @llvm.dbg.value(metadata i64 0, metadata !166, metadata !DIExpression()), !dbg !168 - %8 = load i64, i64* %2, align 8, !dbg !169 - %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !171 - call void @llvm.dbg.value(metadata i64 1, metadata !166, metadata !DIExpression()), !dbg !168 - call void @llvm.dbg.value(metadata i64 1, metadata !166, metadata !DIExpression()), !dbg !168 - %10 = load i64, i64* %4, align 8, !dbg !169 - %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !171 - call void @llvm.dbg.value(metadata i64 2, metadata !166, metadata !DIExpression()), !dbg !168 - call void @llvm.dbg.value(metadata i64 2, metadata !166, metadata !DIExpression()), !dbg !168 - %12 = load i64, i64* %6, align 8, !dbg !169 - %13 = call i32 @pthread_join(i64 noundef %12, i8** noundef null), !dbg !171 - call void @llvm.dbg.value(metadata i64 3, metadata !166, metadata !DIExpression()), !dbg !168 - call void @llvm.dbg.value(metadata i64 3, metadata !166, metadata !DIExpression()), !dbg !168 - %14 = call i32 @dequeue(), !dbg !172 - call void @llvm.dbg.value(metadata i32 %14, metadata !173, metadata !DIExpression()), !dbg !174 - %15 = icmp eq i32 %14, -1, !dbg !175 - br i1 %15, label %17, label %16, !dbg !178 - -16: ; preds = %0 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.4, i64 0, i64 0), i32 noundef 34, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !175 - unreachable, !dbg !175 - -17: ; preds = %0 - ret i32 0, !dbg !179 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca [3 x i64], align 16 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + call void @init() + store i32 0, i32* %3, align 4 + br label %6 + +6: ; preds = %17, %0 + %7 = load i32, i32* %3, align 4 + %8 = icmp slt i32 %7, 3 + br i1 %8, label %9, label %20 + +9: ; preds = %6 + %10 = load i32, i32* %3, align 4 + %11 = sext i32 %10 to i64 + %12 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %11 + %13 = load i32, i32* %3, align 4 + %14 = sext i32 %13 to i64 + %15 = inttoptr i64 %14 to i8* + %16 = call i32 @pthread_create(i64* noundef %12, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef %15) #4 + br label %17 + +17: ; preds = %9 + %18 = load i32, i32* %3, align 4 + %19 = add nsw i32 %18, 1 + store i32 %19, i32* %3, align 4 + br label %6, !llvm.loop !6 + +20: ; preds = %6 + store i32 0, i32* %4, align 4 + br label %21 + +21: ; preds = %30, %20 + %22 = load i32, i32* %4, align 4 + %23 = icmp slt i32 %22, 3 + br i1 %23, label %24, label %33 + +24: ; preds = %21 + %25 = load i32, i32* %4, align 4 + %26 = sext i32 %25 to i64 + %27 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %26 + %28 = load i64, i64* %27, align 8 + %29 = call i32 @pthread_join(i64 noundef %28, i8** noundef null) + br label %30 + +30: ; preds = %24 + %31 = load i32, i32* %4, align 4 + %32 = add nsw i32 %31, 1 + store i32 %32, i32* %4, align 4 + br label %21, !llvm.loop !8 + +33: ; preds = %21 + %34 = call i32 @dequeue() + store i32 %34, i32* %5, align 4 + %35 = load i32, i32* %5, align 4 + %36 = icmp eq i32 %35, -1 + br i1 %36, label %37, label %38 + +37: ; preds = %33 + br label %39 + +38: ; preds = %33 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i32 noundef 34, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable + +39: ; preds = %37 + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 - -declare i32 @pthread_join(i64 noundef, i8** noundef) #4 - -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.value(metadata, metadata, metadata) #1 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!26, !27, !28, !29, !30, !31, !32} -!llvm.ident = !{!33} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "Head", scope: !2, file: !15, line: 19, type: !16, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.6", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !4, globals: !12, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "/home/ponce/git/Dat3M/benchmarks/lfds/ms.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "7e6a31b1f215ca043da6dae63284f84e") -!4 = !{!5, !6, !9} -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !7, line: 87, baseType: !8) -!7 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "24103e292ae21916e87130b926c8d2f8") -!8 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !10, line: 46, baseType: !11) -!10 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!11 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!12 = !{!13, !0} -!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression()) -!14 = distinct !DIGlobalVariable(name: "Tail", scope: !2, file: !15, line: 18, type: !16, isLocal: false, isDefinition: true) -!15 = !DIFile(filename: "benchmarks/lfds/ms.h", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "65dcb47a3cacb398e048973e28881a59") -!16 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !17) -!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) -!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "Node", file: !15, line: 16, baseType: !19) -!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Node", file: !15, line: 13, size: 128, elements: !20) -!20 = !{!21, !23} -!21 = !DIDerivedType(tag: DW_TAG_member, name: "val", scope: !19, file: !15, line: 14, baseType: !22, size: 32) -!22 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!23 = !DIDerivedType(tag: DW_TAG_member, name: "next", scope: !19, file: !15, line: 15, baseType: !24, size: 64, offset: 64) -!24 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !25) -!25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -!26 = !{i32 7, !"Dwarf Version", i32 5} -!27 = !{i32 2, !"Debug Info Version", i32 3} -!28 = !{i32 1, !"wchar_size", i32 4} -!29 = !{i32 7, !"PIC Level", i32 2} -!30 = !{i32 7, !"PIE Level", i32 2} -!31 = !{i32 7, !"uwtable", i32 1} -!32 = !{i32 7, !"frame-pointer", i32 2} -!33 = !{!"Ubuntu clang version 14.0.6"} -!34 = distinct !DISubprogram(name: "init", scope: !15, file: !15, line: 22, type: !35, scopeLine: 22, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!35 = !DISubroutineType(types: !36) -!36 = !{null} -!37 = !{} -!38 = !DILocation(line: 23, column: 15, scope: !34) -!39 = !DILocalVariable(name: "node", scope: !34, file: !15, line: 23, type: !17) -!40 = !DILocation(line: 0, scope: !34) -!41 = !DILocation(line: 24, column: 21, scope: !34) -!42 = !DILocation(line: 24, column: 2, scope: !34) -!43 = !DILocation(line: 25, column: 2, scope: !34) -!44 = !DILocation(line: 26, column: 2, scope: !34) -!45 = !DILocation(line: 27, column: 1, scope: !34) -!46 = distinct !DISubprogram(name: "enqueue", scope: !15, file: !15, line: 29, type: !47, scopeLine: 29, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!47 = !DISubroutineType(types: !48) -!48 = !{null, !22} -!49 = !DILocalVariable(name: "value", arg: 1, scope: !46, file: !15, line: 29, type: !22) -!50 = !DILocation(line: 0, scope: !46) -!51 = !DILocation(line: 32, column: 12, scope: !46) -!52 = !DILocalVariable(name: "node", scope: !46, file: !15, line: 30, type: !17) -!53 = !DILocation(line: 33, column: 8, scope: !46) -!54 = !DILocation(line: 33, column: 12, scope: !46) -!55 = !DILocation(line: 34, column: 21, scope: !46) -!56 = !DILocation(line: 34, column: 2, scope: !46) -!57 = !DILocation(line: 36, column: 2, scope: !46) -!58 = !DILocation(line: 37, column: 10, scope: !59) -!59 = distinct !DILexicalBlock(scope: !46, file: !15, line: 36, column: 12) -!60 = !DILocalVariable(name: "tail", scope: !46, file: !15, line: 30, type: !17) -!61 = !DILocation(line: 38, column: 3, scope: !62) -!62 = distinct !DILexicalBlock(scope: !63, file: !15, line: 38, column: 3) -!63 = distinct !DILexicalBlock(scope: !59, file: !15, line: 38, column: 3) -!64 = !DILocation(line: 38, column: 3, scope: !63) -!65 = !DILocation(line: 39, column: 38, scope: !59) -!66 = !DILocation(line: 39, column: 10, scope: !59) -!67 = !DILocalVariable(name: "next", scope: !46, file: !15, line: 30, type: !17) -!68 = !DILocation(line: 41, column: 15, scope: !69) -!69 = distinct !DILexicalBlock(scope: !59, file: !15, line: 41, column: 7) -!70 = !DILocation(line: 41, column: 12, scope: !69) -!71 = !DILocation(line: 41, column: 7, scope: !59) -!72 = !DILocation(line: 42, column: 13, scope: !73) -!73 = distinct !DILexicalBlock(scope: !74, file: !15, line: 42, column: 8) -!74 = distinct !DILexicalBlock(scope: !69, file: !15, line: 41, column: 62) -!75 = !DILocation(line: 42, column: 8, scope: !74) -!76 = !DILocation(line: 43, column: 5, scope: !77) -!77 = distinct !DILexicalBlock(scope: !73, file: !15, line: 42, column: 22) -!78 = !DILocation(line: 44, column: 4, scope: !77) -!79 = !DILocation(line: 45, column: 9, scope: !80) -!80 = distinct !DILexicalBlock(scope: !81, file: !15, line: 45, column: 9) -!81 = distinct !DILexicalBlock(scope: !73, file: !15, line: 44, column: 11) -!82 = !DILocation(line: 45, column: 9, scope: !81) -!83 = !DILocation(line: 46, column: 9, scope: !84) -!84 = distinct !DILexicalBlock(scope: !80, file: !15, line: 45, column: 40) -!85 = !DILocation(line: 52, column: 1, scope: !46) -!86 = distinct !{!86, !57, !87} -!87 = !DILocation(line: 51, column: 2, scope: !46) -!88 = distinct !DISubprogram(name: "dequeue", scope: !15, file: !15, line: 54, type: !89, scopeLine: 54, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!89 = !DISubroutineType(types: !90) -!90 = !{!22} -!91 = !DILocation(line: 58, column: 2, scope: !88) -!92 = !DILocation(line: 59, column: 10, scope: !93) -!93 = distinct !DILexicalBlock(scope: !88, file: !15, line: 58, column: 12) -!94 = !DILocalVariable(name: "head", scope: !88, file: !15, line: 55, type: !17) -!95 = !DILocation(line: 0, scope: !88) -!96 = !DILocation(line: 60, column: 3, scope: !97) -!97 = distinct !DILexicalBlock(scope: !98, file: !15, line: 60, column: 3) -!98 = distinct !DILexicalBlock(scope: !93, file: !15, line: 60, column: 3) -!99 = !DILocation(line: 60, column: 3, scope: !98) -!100 = !DILocation(line: 61, column: 10, scope: !93) -!101 = !DILocalVariable(name: "tail", scope: !88, file: !15, line: 55, type: !17) -!102 = !DILocation(line: 62, column: 3, scope: !103) -!103 = distinct !DILexicalBlock(scope: !104, file: !15, line: 62, column: 3) -!104 = distinct !DILexicalBlock(scope: !93, file: !15, line: 62, column: 3) -!105 = !DILocation(line: 62, column: 3, scope: !104) -!106 = !DILocation(line: 63, column: 38, scope: !93) -!107 = !DILocation(line: 63, column: 10, scope: !93) -!108 = !DILocalVariable(name: "next", scope: !88, file: !15, line: 55, type: !17) -!109 = !DILocation(line: 65, column: 15, scope: !110) -!110 = distinct !DILexicalBlock(scope: !93, file: !15, line: 65, column: 7) -!111 = !DILocation(line: 65, column: 12, scope: !110) -!112 = !DILocation(line: 65, column: 7, scope: !93) -!113 = !DILocation(line: 66, column: 13, scope: !114) -!114 = distinct !DILexicalBlock(scope: !115, file: !15, line: 66, column: 8) -!115 = distinct !DILexicalBlock(scope: !110, file: !15, line: 65, column: 62) -!116 = !DILocation(line: 66, column: 8, scope: !115) -!117 = !DILocation(line: 70, column: 14, scope: !118) -!118 = distinct !DILexicalBlock(scope: !119, file: !15, line: 70, column: 9) -!119 = distinct !DILexicalBlock(scope: !114, file: !15, line: 69, column: 11) -!120 = !DILocation(line: 70, column: 9, scope: !119) -!121 = !DILocation(line: 71, column: 6, scope: !122) -!122 = distinct !DILexicalBlock(scope: !118, file: !15, line: 70, column: 23) -!123 = !DILocation(line: 72, column: 5, scope: !122) -!124 = !DILocation(line: 73, column: 21, scope: !125) -!125 = distinct !DILexicalBlock(scope: !118, file: !15, line: 72, column: 12) -!126 = !DILocalVariable(name: "result", scope: !88, file: !15, line: 56, type: !22) -!127 = !DILocation(line: 74, column: 10, scope: !128) -!128 = distinct !DILexicalBlock(scope: !125, file: !15, line: 74, column: 10) -!129 = !DILocation(line: 74, column: 10, scope: !125) -!130 = distinct !{!130, !91, !131} -!131 = !DILocation(line: 81, column: 2, scope: !88) -!132 = !DILocation(line: 0, scope: !114) -!133 = !DILocation(line: 83, column: 2, scope: !88) -!134 = distinct !DISubprogram(name: "worker", scope: !135, file: !135, line: 8, type: !136, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!135 = !DIFile(filename: "benchmarks/lfds/ms.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "7e6a31b1f215ca043da6dae63284f84e") -!136 = !DISubroutineType(types: !137) -!137 = !{!5, !5} -!138 = !DILocalVariable(name: "arg", arg: 1, scope: !134, file: !135, line: 8, type: !5) -!139 = !DILocation(line: 0, scope: !134) -!140 = !DILocation(line: 11, column: 23, scope: !134) -!141 = !DILocalVariable(name: "index", scope: !134, file: !135, line: 11, type: !6) -!142 = !DILocation(line: 13, column: 10, scope: !134) -!143 = !DILocation(line: 13, column: 2, scope: !134) -!144 = !DILocation(line: 14, column: 13, scope: !134) -!145 = !DILocalVariable(name: "r", scope: !134, file: !135, line: 14, type: !22) -!146 = !DILocation(line: 16, column: 2, scope: !147) -!147 = distinct !DILexicalBlock(scope: !148, file: !135, line: 16, column: 2) -!148 = distinct !DILexicalBlock(scope: !134, file: !135, line: 16, column: 2) -!149 = !DILocation(line: 16, column: 2, scope: !148) -!150 = !DILocation(line: 18, column: 2, scope: !134) -!151 = distinct !DISubprogram(name: "main", scope: !135, file: !135, line: 21, type: !89, scopeLine: 22, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!152 = !DILocalVariable(name: "t", scope: !151, file: !135, line: 23, type: !153) -!153 = !DICompositeType(tag: DW_TAG_array_type, baseType: !154, size: 192, elements: !156) -!154 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !155, line: 27, baseType: !11) -!155 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "2d764266ce95ab26d4a4767c2ec78176") -!156 = !{!157} -!157 = !DISubrange(count: 3) -!158 = !DILocation(line: 23, column: 15, scope: !151) -!159 = !DILocation(line: 25, column: 5, scope: !151) -!160 = !DILocalVariable(name: "i", scope: !161, file: !135, line: 27, type: !22) -!161 = distinct !DILexicalBlock(scope: !151, file: !135, line: 27, column: 5) -!162 = !DILocation(line: 0, scope: !161) -!163 = !DILocation(line: 28, column: 25, scope: !164) -!164 = distinct !DILexicalBlock(scope: !161, file: !135, line: 27, column: 5) -!165 = !DILocation(line: 28, column: 9, scope: !164) -!166 = !DILocalVariable(name: "i", scope: !167, file: !135, line: 30, type: !22) -!167 = distinct !DILexicalBlock(scope: !151, file: !135, line: 30, column: 5) -!168 = !DILocation(line: 0, scope: !167) -!169 = !DILocation(line: 31, column: 22, scope: !170) -!170 = distinct !DILexicalBlock(scope: !167, file: !135, line: 30, column: 5) -!171 = !DILocation(line: 31, column: 9, scope: !170) -!172 = !DILocation(line: 33, column: 13, scope: !151) -!173 = !DILocalVariable(name: "r", scope: !151, file: !135, line: 33, type: !22) -!174 = !DILocation(line: 0, scope: !151) -!175 = !DILocation(line: 34, column: 5, scope: !176) -!176 = distinct !DILexicalBlock(scope: !177, file: !135, line: 34, column: 5) -!177 = distinct !DILexicalBlock(scope: !151, file: !135, line: 34, column: 5) -!178 = !DILocation(line: 34, column: 5, scope: !177) -!179 = !DILocation(line: 36, column: 5, scope: !151) +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} diff --git a/dartagnan/src/test/resources/lfds/ms.ll b/dartagnan/src/test/resources/lfds/ms.ll index e704f050cc..5cc2230776 100644 --- a/dartagnan/src/test/resources/lfds/ms.ll +++ b/dartagnan/src/test/resources/lfds/ms.ll @@ -1,443 +1,487 @@ -; ModuleID = '/home/ponce/git/Dat3M/output/ms.ll' -source_filename = "/home/ponce/git/Dat3M/benchmarks/lfds/ms.c" +; ModuleID = 'benchmarks/lfds/ms.c' +source_filename = "benchmarks/lfds/ms.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" %struct.Node = type { i32, %struct.Node* } %union.pthread_attr_t = type { i64, [48 x i8] } -@Head = dso_local global %struct.Node* null, align 8, !dbg !0 -@Tail = dso_local global %struct.Node* null, align 8, !dbg !13 +@Head = dso_local global %struct.Node* null, align 8 +@Tail = dso_local global %struct.Node* null, align 8 @.str = private unnamed_addr constant [13 x i8] c"tail != NULL\00", align 1 -@.str.1 = private unnamed_addr constant [43 x i8] c"/home/ponce/git/Dat3M/benchmarks/lfds/ms.h\00", align 1 +@.str.1 = private unnamed_addr constant [21 x i8] c"benchmarks/lfds/ms.h\00", align 1 @__PRETTY_FUNCTION__.enqueue = private unnamed_addr constant [18 x i8] c"void enqueue(int)\00", align 1 @.str.2 = private unnamed_addr constant [13 x i8] c"head != NULL\00", align 1 @__PRETTY_FUNCTION__.dequeue = private unnamed_addr constant [14 x i8] c"int dequeue()\00", align 1 @.str.3 = private unnamed_addr constant [11 x i8] c"r != EMPTY\00", align 1 -@.str.4 = private unnamed_addr constant [43 x i8] c"/home/ponce/git/Dat3M/benchmarks/lfds/ms.c\00", align 1 +@.str.4 = private unnamed_addr constant [21 x i8] c"benchmarks/lfds/ms.c\00", align 1 @__PRETTY_FUNCTION__.worker = private unnamed_addr constant [21 x i8] c"void *worker(void *)\00", align 1 @.str.5 = private unnamed_addr constant [11 x i8] c"r == EMPTY\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @init() #0 !dbg !34 { - %1 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !38 - %2 = bitcast i8* %1 to %struct.Node*, !dbg !38 - call void @llvm.dbg.value(metadata %struct.Node* %2, metadata !39, metadata !DIExpression()), !dbg !40 - %3 = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 0, i32 1, !dbg !41 - store %struct.Node* null, %struct.Node** %3, align 8, !dbg !42 - store %struct.Node* %2, %struct.Node** @Head, align 8, !dbg !43 - store %struct.Node* %2, %struct.Node** @Tail, align 8, !dbg !44 - ret void, !dbg !45 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @init() #0 { + %1 = alloca %struct.Node*, align 8 + %2 = call noalias i8* @malloc(i64 noundef 16) #4 + %3 = bitcast i8* %2 to %struct.Node* + store %struct.Node* %3, %struct.Node** %1, align 8 + %4 = load %struct.Node*, %struct.Node** %1, align 8 + %5 = getelementptr inbounds %struct.Node, %struct.Node* %4, i32 0, i32 1 + store %struct.Node* null, %struct.Node** %5, align 8 + %6 = load %struct.Node*, %struct.Node** %1, align 8 + store %struct.Node* %6, %struct.Node** @Head, align 8 + %7 = load %struct.Node*, %struct.Node** %1, align 8 + store %struct.Node* %7, %struct.Node** @Tail, align 8 + ret void } -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 - -; Function Attrs: noinline nounwind uwtable -define dso_local void @enqueue(i32 noundef %0) #0 !dbg !46 { - call void @llvm.dbg.value(metadata i32 %0, metadata !49, metadata !DIExpression()), !dbg !50 - %2 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !51 - %3 = bitcast i8* %2 to %struct.Node*, !dbg !51 - call void @llvm.dbg.value(metadata %struct.Node* %3, metadata !52, metadata !DIExpression()), !dbg !50 - %4 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 0, !dbg !53 - store i32 %0, i32* %4, align 8, !dbg !54 - %5 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 1, !dbg !55 - store %struct.Node* null, %struct.Node** %5, align 8, !dbg !56 - br label %6, !dbg !57 - -6: ; preds = %37, %1 - %7 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !58 - %8 = inttoptr i64 %7 to %struct.Node*, !dbg !58 - call void @llvm.dbg.value(metadata %struct.Node* %8, metadata !60, metadata !DIExpression()), !dbg !50 - %9 = icmp ne %struct.Node* %8, null, !dbg !61 - br i1 %9, label %11, label %10, !dbg !64 - -10: ; preds = %6 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @__PRETTY_FUNCTION__.enqueue, i64 0, i64 0)) #6, !dbg !61 - unreachable, !dbg !61 - -11: ; preds = %6 - %12 = getelementptr inbounds %struct.Node, %struct.Node* %8, i32 0, i32 1, !dbg !65 - %13 = bitcast %struct.Node** %12 to i64*, !dbg !66 - %14 = load atomic i64, i64* %13 acquire, align 8, !dbg !66 - %15 = inttoptr i64 %14 to %struct.Node*, !dbg !66 - call void @llvm.dbg.value(metadata %struct.Node* %15, metadata !67, metadata !DIExpression()), !dbg !50 - %16 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !68 - %17 = inttoptr i64 %16 to %struct.Node*, !dbg !68 - %18 = icmp eq %struct.Node* %8, %17, !dbg !70 - br i1 %18, label %19, label %37, !dbg !71 - -19: ; preds = %11 - %20 = icmp ne %struct.Node* %15, null, !dbg !72 - br i1 %20, label %21, label %26, !dbg !75 - -21: ; preds = %19 - %22 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %7, i64 %14 acq_rel monotonic, align 8, !dbg !76 - %23 = extractvalue { i64, i1 } %22, 0, !dbg !76 - %24 = extractvalue { i64, i1 } %22, 1, !dbg !76 - %25 = zext i1 %24 to i8, !dbg !76 - br label %37, !dbg !78 - -26: ; preds = %19 - %27 = ptrtoint %struct.Node* %3 to i64, !dbg !79 - %28 = cmpxchg i64* %13, i64 %14, i64 %27 acq_rel monotonic, align 8, !dbg !79 - %29 = extractvalue { i64, i1 } %28, 0, !dbg !79 - %30 = extractvalue { i64, i1 } %28, 1, !dbg !79 - %31 = zext i1 %30 to i8, !dbg !79 - br i1 %30, label %32, label %37, !dbg !82 - -32: ; preds = %26 - %33 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %7, i64 %27 acq_rel monotonic, align 8, !dbg !83 - %34 = extractvalue { i64, i1 } %33, 0, !dbg !83 - %35 = extractvalue { i64, i1 } %33, 1, !dbg !83 - %36 = zext i1 %35 to i8, !dbg !83 - ret void, !dbg !85 - -37: ; preds = %21, %26, %11 - br label %6, !dbg !57, !llvm.loop !86 +declare noalias i8* @malloc(i64 noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @enqueue(i32 noundef %0) #0 { + %2 = alloca i32, align 4 + %3 = alloca %struct.Node*, align 8 + %4 = alloca %struct.Node*, align 8 + %5 = alloca %struct.Node*, align 8 + %6 = alloca %struct.Node*, align 8 + %7 = alloca %struct.Node*, align 8 + %8 = alloca %struct.Node*, align 8 + %9 = alloca %struct.Node*, align 8 + %10 = alloca i8, align 1 + %11 = alloca %struct.Node*, align 8 + %12 = alloca i8, align 1 + %13 = alloca %struct.Node*, align 8 + %14 = alloca i8, align 1 + store i32 %0, i32* %2, align 4 + %15 = call noalias i8* @malloc(i64 noundef 16) #4 + %16 = bitcast i8* %15 to %struct.Node* + store %struct.Node* %16, %struct.Node** %5, align 8 + %17 = load i32, i32* %2, align 4 + %18 = load %struct.Node*, %struct.Node** %5, align 8 + %19 = getelementptr inbounds %struct.Node, %struct.Node* %18, i32 0, i32 0 + store i32 %17, i32* %19, align 8 + %20 = load %struct.Node*, %struct.Node** %5, align 8 + %21 = getelementptr inbounds %struct.Node, %struct.Node* %20, i32 0, i32 1 + store %struct.Node* null, %struct.Node** %21, align 8 + br label %22 + +22: ; preds = %1, %95 + %23 = bitcast %struct.Node** %6 to i64* + %24 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %24, i64* %23, align 8 + %25 = bitcast i64* %23 to %struct.Node** + %26 = load %struct.Node*, %struct.Node** %25, align 8 + store %struct.Node* %26, %struct.Node** %3, align 8 + %27 = load %struct.Node*, %struct.Node** %3, align 8 + %28 = icmp ne %struct.Node* %27, null + br i1 %28, label %29, label %30 + +29: ; preds = %22 + br label %31 + +30: ; preds = %22 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @__PRETTY_FUNCTION__.enqueue, i64 0, i64 0)) #5 + unreachable + +31: ; preds = %29 + %32 = load %struct.Node*, %struct.Node** %3, align 8 + %33 = getelementptr inbounds %struct.Node, %struct.Node* %32, i32 0, i32 1 + %34 = bitcast %struct.Node** %33 to i64* + %35 = bitcast %struct.Node** %7 to i64* + %36 = load atomic i64, i64* %34 acquire, align 8 + store i64 %36, i64* %35, align 8 + %37 = bitcast i64* %35 to %struct.Node** + %38 = load %struct.Node*, %struct.Node** %37, align 8 + store %struct.Node* %38, %struct.Node** %4, align 8 + %39 = load %struct.Node*, %struct.Node** %3, align 8 + %40 = bitcast %struct.Node** %8 to i64* + %41 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %41, i64* %40, align 8 + %42 = bitcast i64* %40 to %struct.Node** + %43 = load %struct.Node*, %struct.Node** %42, align 8 + %44 = icmp eq %struct.Node* %39, %43 + br i1 %44, label %45, label %95 + +45: ; preds = %31 + %46 = load %struct.Node*, %struct.Node** %4, align 8 + %47 = icmp ne %struct.Node* %46, null + br i1 %47, label %48, label %62 + +48: ; preds = %45 + %49 = load %struct.Node*, %struct.Node** %4, align 8 + store %struct.Node* %49, %struct.Node** %9, align 8 + %50 = bitcast %struct.Node** %3 to i64* + %51 = bitcast %struct.Node** %9 to i64* + %52 = load i64, i64* %50, align 8 + %53 = load i64, i64* %51, align 8 + %54 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %52, i64 %53 acq_rel monotonic, align 8 + %55 = extractvalue { i64, i1 } %54, 0 + %56 = extractvalue { i64, i1 } %54, 1 + br i1 %56, label %58, label %57 + +57: ; preds = %48 + store i64 %55, i64* %50, align 8 + br label %58 + +58: ; preds = %57, %48 + %59 = zext i1 %56 to i8 + store i8 %59, i8* %10, align 1 + %60 = load i8, i8* %10, align 1 + %61 = trunc i8 %60 to i1 + br label %94 + +62: ; preds = %45 + %63 = load %struct.Node*, %struct.Node** %3, align 8 + %64 = getelementptr inbounds %struct.Node, %struct.Node* %63, i32 0, i32 1 + %65 = load %struct.Node*, %struct.Node** %5, align 8 + store %struct.Node* %65, %struct.Node** %11, align 8 + %66 = bitcast %struct.Node** %64 to i64* + %67 = bitcast %struct.Node** %4 to i64* + %68 = bitcast %struct.Node** %11 to i64* + %69 = load i64, i64* %67, align 8 + %70 = load i64, i64* %68, align 8 + %71 = cmpxchg i64* %66, i64 %69, i64 %70 acq_rel monotonic, align 8 + %72 = extractvalue { i64, i1 } %71, 0 + %73 = extractvalue { i64, i1 } %71, 1 + br i1 %73, label %75, label %74 + +74: ; preds = %62 + store i64 %72, i64* %67, align 8 + br label %75 + +75: ; preds = %74, %62 + %76 = zext i1 %73 to i8 + store i8 %76, i8* %12, align 1 + %77 = load i8, i8* %12, align 1 + %78 = trunc i8 %77 to i1 + br i1 %78, label %79, label %93 + +79: ; preds = %75 + %80 = load %struct.Node*, %struct.Node** %5, align 8 + store %struct.Node* %80, %struct.Node** %13, align 8 + %81 = bitcast %struct.Node** %3 to i64* + %82 = bitcast %struct.Node** %13 to i64* + %83 = load i64, i64* %81, align 8 + %84 = load i64, i64* %82, align 8 + %85 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %83, i64 %84 acq_rel monotonic, align 8 + %86 = extractvalue { i64, i1 } %85, 0 + %87 = extractvalue { i64, i1 } %85, 1 + br i1 %87, label %89, label %88 + +88: ; preds = %79 + store i64 %86, i64* %81, align 8 + br label %89 + +89: ; preds = %88, %79 + %90 = zext i1 %87 to i8 + store i8 %90, i8* %14, align 1 + %91 = load i8, i8* %14, align 1 + %92 = trunc i8 %91 to i1 + br label %96 + +93: ; preds = %75 + br label %94 + +94: ; preds = %93, %58 + br label %95 + +95: ; preds = %94, %31 + br label %22 + +96: ; preds = %89 + ret void } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @dequeue() #0 !dbg !88 { - br label %1, !dbg !91 - -1: ; preds = %35, %0 - %2 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8, !dbg !92 - %3 = inttoptr i64 %2 to %struct.Node*, !dbg !92 - call void @llvm.dbg.value(metadata %struct.Node* %3, metadata !94, metadata !DIExpression()), !dbg !95 - %4 = icmp ne %struct.Node* %3, null, !dbg !96 - br i1 %4, label %6, label %5, !dbg !99 - -5: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.1, i64 0, i64 0), i32 noundef 60, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #6, !dbg !96 - unreachable, !dbg !96 - -6: ; preds = %1 - %7 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8, !dbg !100 - %8 = inttoptr i64 %7 to %struct.Node*, !dbg !100 - call void @llvm.dbg.value(metadata %struct.Node* %8, metadata !101, metadata !DIExpression()), !dbg !95 - %9 = icmp ne %struct.Node* %8, null, !dbg !102 - br i1 %9, label %11, label %10, !dbg !105 - -10: ; preds = %6 - call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.1, i64 0, i64 0), i32 noundef 62, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #6, !dbg !102 - unreachable, !dbg !102 - -11: ; preds = %6 - %12 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 1, !dbg !106 - %13 = bitcast %struct.Node** %12 to i64*, !dbg !107 - %14 = load atomic i64, i64* %13 acquire, align 8, !dbg !107 - %15 = inttoptr i64 %14 to %struct.Node*, !dbg !107 - call void @llvm.dbg.value(metadata %struct.Node* %15, metadata !108, metadata !DIExpression()), !dbg !95 - %16 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8, !dbg !109 - %17 = inttoptr i64 %16 to %struct.Node*, !dbg !109 - %18 = icmp eq %struct.Node* %3, %17, !dbg !111 - br i1 %18, label %19, label %35, !dbg !112 - -19: ; preds = %11 - %20 = icmp eq %struct.Node* %15, null, !dbg !113 - br i1 %20, label %36, label %21, !dbg !116 - -21: ; preds = %19 - %22 = icmp eq %struct.Node* %3, %8, !dbg !117 - br i1 %22, label %23, label %28, !dbg !120 - -23: ; preds = %21 - %24 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %7, i64 %14 acq_rel monotonic, align 8, !dbg !121 - %25 = extractvalue { i64, i1 } %24, 0, !dbg !121 - %26 = extractvalue { i64, i1 } %24, 1, !dbg !121 - %27 = zext i1 %26 to i8, !dbg !121 - br label %35, !dbg !123 - -28: ; preds = %21 - %29 = getelementptr inbounds %struct.Node, %struct.Node* %15, i32 0, i32 0, !dbg !124 - %30 = load i32, i32* %29, align 8, !dbg !124 - call void @llvm.dbg.value(metadata i32 %30, metadata !126, metadata !DIExpression()), !dbg !95 - %31 = cmpxchg i64* bitcast (%struct.Node** @Head to i64*), i64 %2, i64 %14 acq_rel monotonic, align 8, !dbg !127 - %32 = extractvalue { i64, i1 } %31, 0, !dbg !127 - %33 = extractvalue { i64, i1 } %31, 1, !dbg !127 - %34 = zext i1 %33 to i8, !dbg !127 - br i1 %33, label %36, label %35, !dbg !129 - -35: ; preds = %28, %23, %11 - br label %1, !dbg !91, !llvm.loop !130 - -36: ; preds = %28, %19 - %.0 = phi i32 [ -1, %19 ], [ %30, %28 ], !dbg !132 - call void @llvm.dbg.value(metadata i32 %.0, metadata !126, metadata !DIExpression()), !dbg !95 - ret i32 %.0, !dbg !133 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @dequeue() #0 { + %1 = alloca %struct.Node*, align 8 + %2 = alloca %struct.Node*, align 8 + %3 = alloca %struct.Node*, align 8 + %4 = alloca i32, align 4 + %5 = alloca %struct.Node*, align 8 + %6 = alloca %struct.Node*, align 8 + %7 = alloca %struct.Node*, align 8 + %8 = alloca %struct.Node*, align 8 + %9 = alloca %struct.Node*, align 8 + %10 = alloca i8, align 1 + %11 = alloca %struct.Node*, align 8 + %12 = alloca i8, align 1 + br label %13 + +13: ; preds = %0, %90 + %14 = bitcast %struct.Node** %5 to i64* + %15 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8 + store i64 %15, i64* %14, align 8 + %16 = bitcast i64* %14 to %struct.Node** + %17 = load %struct.Node*, %struct.Node** %16, align 8 + store %struct.Node* %17, %struct.Node** %1, align 8 + %18 = load %struct.Node*, %struct.Node** %1, align 8 + %19 = icmp ne %struct.Node* %18, null + br i1 %19, label %20, label %21 + +20: ; preds = %13 + br label %22 + +21: ; preds = %13 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), i32 noundef 60, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #5 + unreachable + +22: ; preds = %20 + %23 = bitcast %struct.Node** %6 to i64* + %24 = load atomic i64, i64* bitcast (%struct.Node** @Tail to i64*) acquire, align 8 + store i64 %24, i64* %23, align 8 + %25 = bitcast i64* %23 to %struct.Node** + %26 = load %struct.Node*, %struct.Node** %25, align 8 + store %struct.Node* %26, %struct.Node** %3, align 8 + %27 = load %struct.Node*, %struct.Node** %3, align 8 + %28 = icmp ne %struct.Node* %27, null + br i1 %28, label %29, label %30 + +29: ; preds = %22 + br label %31 + +30: ; preds = %22 + call void @__assert_fail(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i64 0, i64 0), i32 noundef 62, i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__PRETTY_FUNCTION__.dequeue, i64 0, i64 0)) #5 + unreachable + +31: ; preds = %29 + %32 = load %struct.Node*, %struct.Node** %1, align 8 + %33 = getelementptr inbounds %struct.Node, %struct.Node* %32, i32 0, i32 1 + %34 = bitcast %struct.Node** %33 to i64* + %35 = bitcast %struct.Node** %7 to i64* + %36 = load atomic i64, i64* %34 acquire, align 8 + store i64 %36, i64* %35, align 8 + %37 = bitcast i64* %35 to %struct.Node** + %38 = load %struct.Node*, %struct.Node** %37, align 8 + store %struct.Node* %38, %struct.Node** %2, align 8 + %39 = load %struct.Node*, %struct.Node** %1, align 8 + %40 = bitcast %struct.Node** %8 to i64* + %41 = load atomic i64, i64* bitcast (%struct.Node** @Head to i64*) acquire, align 8 + store i64 %41, i64* %40, align 8 + %42 = bitcast i64* %40 to %struct.Node** + %43 = load %struct.Node*, %struct.Node** %42, align 8 + %44 = icmp eq %struct.Node* %39, %43 + br i1 %44, label %45, label %90 + +45: ; preds = %31 + %46 = load %struct.Node*, %struct.Node** %2, align 8 + %47 = icmp eq %struct.Node* %46, null + br i1 %47, label %48, label %49 + +48: ; preds = %45 + store i32 -1, i32* %4, align 4 + br label %91 + +49: ; preds = %45 + %50 = load %struct.Node*, %struct.Node** %1, align 8 + %51 = load %struct.Node*, %struct.Node** %3, align 8 + %52 = icmp eq %struct.Node* %50, %51 + br i1 %52, label %53, label %67 + +53: ; preds = %49 + %54 = load %struct.Node*, %struct.Node** %2, align 8 + store %struct.Node* %54, %struct.Node** %9, align 8 + %55 = bitcast %struct.Node** %3 to i64* + %56 = bitcast %struct.Node** %9 to i64* + %57 = load i64, i64* %55, align 8 + %58 = load i64, i64* %56, align 8 + %59 = cmpxchg i64* bitcast (%struct.Node** @Tail to i64*), i64 %57, i64 %58 acq_rel monotonic, align 8 + %60 = extractvalue { i64, i1 } %59, 0 + %61 = extractvalue { i64, i1 } %59, 1 + br i1 %61, label %63, label %62 + +62: ; preds = %53 + store i64 %60, i64* %55, align 8 + br label %63 + +63: ; preds = %62, %53 + %64 = zext i1 %61 to i8 + store i8 %64, i8* %10, align 1 + %65 = load i8, i8* %10, align 1 + %66 = trunc i8 %65 to i1 + br label %88 + +67: ; preds = %49 + %68 = load %struct.Node*, %struct.Node** %2, align 8 + %69 = getelementptr inbounds %struct.Node, %struct.Node* %68, i32 0, i32 0 + %70 = load i32, i32* %69, align 8 + store i32 %70, i32* %4, align 4 + %71 = load %struct.Node*, %struct.Node** %2, align 8 + store %struct.Node* %71, %struct.Node** %11, align 8 + %72 = bitcast %struct.Node** %1 to i64* + %73 = bitcast %struct.Node** %11 to i64* + %74 = load i64, i64* %72, align 8 + %75 = load i64, i64* %73, align 8 + %76 = cmpxchg i64* bitcast (%struct.Node** @Head to i64*), i64 %74, i64 %75 acq_rel monotonic, align 8 + %77 = extractvalue { i64, i1 } %76, 0 + %78 = extractvalue { i64, i1 } %76, 1 + br i1 %78, label %80, label %79 + +79: ; preds = %67 + store i64 %77, i64* %72, align 8 + br label %80 + +80: ; preds = %79, %67 + %81 = zext i1 %78 to i8 + store i8 %81, i8* %12, align 1 + %82 = load i8, i8* %12, align 1 + %83 = trunc i8 %82 to i1 + br i1 %83, label %84, label %87 + +84: ; preds = %80 + %85 = load %struct.Node*, %struct.Node** %1, align 8 + %86 = bitcast %struct.Node* %85 to i8* + call void @free(i8* noundef %86) #4 + br label %91 + +87: ; preds = %80 + br label %88 + +88: ; preds = %87, %63 + br label %89 + +89: ; preds = %88 + br label %90 + +90: ; preds = %89, %31 + br label %13 + +91: ; preds = %84, %48 + %92 = load i32, i32* %4, align 4 + ret i32 %92 } -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @worker(i8* noundef %0) #0 !dbg !134 { - call void @llvm.dbg.value(metadata i8* %0, metadata !138, metadata !DIExpression()), !dbg !139 - %2 = ptrtoint i8* %0 to i64, !dbg !140 - call void @llvm.dbg.value(metadata i64 %2, metadata !141, metadata !DIExpression()), !dbg !139 - %3 = trunc i64 %2 to i32, !dbg !142 - call void @enqueue(i32 noundef %3), !dbg !143 - %4 = call i32 @dequeue(), !dbg !144 - call void @llvm.dbg.value(metadata i32 %4, metadata !145, metadata !DIExpression()), !dbg !139 - %5 = icmp ne i32 %4, -1, !dbg !146 - br i1 %5, label %7, label %6, !dbg !149 - -6: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.4, i64 0, i64 0), i32 noundef 16, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #6, !dbg !146 - unreachable, !dbg !146 - -7: ; preds = %1 - ret i8* null, !dbg !150 +; Function Attrs: nounwind +declare void @free(i8* noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @worker(i8* noundef %0) #0 { + %2 = alloca i8*, align 8 + %3 = alloca i64, align 8 + %4 = alloca i32, align 4 + store i8* %0, i8** %2, align 8 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + call void @enqueue(i32 noundef %8) + %9 = call i32 @dequeue() + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = icmp ne i32 %10, -1 + br i1 %11, label %12, label %13 + +12: ; preds = %1 + br label %14 + +13: ; preds = %1 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i32 noundef 16, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #5 + unreachable + +14: ; preds = %12 + ret i8* null } -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !151 { - %1 = alloca [3 x i64], align 16 - call void @llvm.dbg.declare(metadata [3 x i64]* %1, metadata !152, metadata !DIExpression()), !dbg !158 - call void @init(), !dbg !159 - call void @llvm.dbg.value(metadata i32 0, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i64 0, metadata !160, metadata !DIExpression()), !dbg !162 - %2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0, !dbg !163 - %3 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef null) #5, !dbg !165 - call void @llvm.dbg.value(metadata i64 1, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i64 1, metadata !160, metadata !DIExpression()), !dbg !162 - %4 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1, !dbg !163 - %5 = call i32 @pthread_create(i64* noundef %4, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef inttoptr (i64 1 to i8*)) #5, !dbg !165 - call void @llvm.dbg.value(metadata i64 2, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i64 2, metadata !160, metadata !DIExpression()), !dbg !162 - %6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2, !dbg !163 - %7 = call i32 @pthread_create(i64* noundef %6, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef inttoptr (i64 2 to i8*)) #5, !dbg !165 - call void @llvm.dbg.value(metadata i64 3, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i64 3, metadata !160, metadata !DIExpression()), !dbg !162 - call void @llvm.dbg.value(metadata i32 0, metadata !166, metadata !DIExpression()), !dbg !168 - call void @llvm.dbg.value(metadata i64 0, metadata !166, metadata !DIExpression()), !dbg !168 - %8 = load i64, i64* %2, align 8, !dbg !169 - %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !171 - call void @llvm.dbg.value(metadata i64 1, metadata !166, metadata !DIExpression()), !dbg !168 - call void @llvm.dbg.value(metadata i64 1, metadata !166, metadata !DIExpression()), !dbg !168 - %10 = load i64, i64* %4, align 8, !dbg !169 - %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !171 - call void @llvm.dbg.value(metadata i64 2, metadata !166, metadata !DIExpression()), !dbg !168 - call void @llvm.dbg.value(metadata i64 2, metadata !166, metadata !DIExpression()), !dbg !168 - %12 = load i64, i64* %6, align 8, !dbg !169 - %13 = call i32 @pthread_join(i64 noundef %12, i8** noundef null), !dbg !171 - call void @llvm.dbg.value(metadata i64 3, metadata !166, metadata !DIExpression()), !dbg !168 - call void @llvm.dbg.value(metadata i64 3, metadata !166, metadata !DIExpression()), !dbg !168 - %14 = call i32 @dequeue(), !dbg !172 - call void @llvm.dbg.value(metadata i32 %14, metadata !173, metadata !DIExpression()), !dbg !174 - %15 = icmp eq i32 %14, -1, !dbg !175 - br i1 %15, label %17, label %16, !dbg !178 - -16: ; preds = %0 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* noundef getelementptr inbounds ([43 x i8], [43 x i8]* @.str.4, i64 0, i64 0), i32 noundef 34, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !175 - unreachable, !dbg !175 - -17: ; preds = %0 - ret i32 0, !dbg !179 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca [3 x i64], align 16 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + call void @init() + store i32 0, i32* %3, align 4 + br label %6 + +6: ; preds = %17, %0 + %7 = load i32, i32* %3, align 4 + %8 = icmp slt i32 %7, 3 + br i1 %8, label %9, label %20 + +9: ; preds = %6 + %10 = load i32, i32* %3, align 4 + %11 = sext i32 %10 to i64 + %12 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %11 + %13 = load i32, i32* %3, align 4 + %14 = sext i32 %13 to i64 + %15 = inttoptr i64 %14 to i8* + %16 = call i32 @pthread_create(i64* noundef %12, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef %15) #4 + br label %17 + +17: ; preds = %9 + %18 = load i32, i32* %3, align 4 + %19 = add nsw i32 %18, 1 + store i32 %19, i32* %3, align 4 + br label %6, !llvm.loop !6 + +20: ; preds = %6 + store i32 0, i32* %4, align 4 + br label %21 + +21: ; preds = %30, %20 + %22 = load i32, i32* %4, align 4 + %23 = icmp slt i32 %22, 3 + br i1 %23, label %24, label %33 + +24: ; preds = %21 + %25 = load i32, i32* %4, align 4 + %26 = sext i32 %25 to i64 + %27 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %26 + %28 = load i64, i64* %27, align 8 + %29 = call i32 @pthread_join(i64 noundef %28, i8** noundef null) + br label %30 + +30: ; preds = %24 + %31 = load i32, i32* %4, align 4 + %32 = add nsw i32 %31, 1 + store i32 %32, i32* %4, align 4 + br label %21, !llvm.loop !8 + +33: ; preds = %21 + %34 = call i32 @dequeue() + store i32 %34, i32* %5, align 4 + %35 = load i32, i32* %5, align 4 + %36 = icmp eq i32 %35, -1 + br i1 %36, label %37, label %38 + +37: ; preds = %33 + br label %39 + +38: ; preds = %33 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i64 0, i64 0), i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i32 noundef 34, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable + +39: ; preds = %37 + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 - -declare i32 @pthread_join(i64 noundef, i8** noundef) #4 - -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.value(metadata, metadata, metadata) #1 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!26, !27, !28, !29, !30, !31, !32} -!llvm.ident = !{!33} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "Head", scope: !2, file: !15, line: 19, type: !16, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.6", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !4, globals: !12, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "/home/ponce/git/Dat3M/benchmarks/lfds/ms.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "7e6a31b1f215ca043da6dae63284f84e") -!4 = !{!5, !6, !9} -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !7, line: 87, baseType: !8) -!7 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "24103e292ae21916e87130b926c8d2f8") -!8 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !10, line: 46, baseType: !11) -!10 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!11 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!12 = !{!13, !0} -!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression()) -!14 = distinct !DIGlobalVariable(name: "Tail", scope: !2, file: !15, line: 18, type: !16, isLocal: false, isDefinition: true) -!15 = !DIFile(filename: "benchmarks/lfds/ms.h", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "65dcb47a3cacb398e048973e28881a59") -!16 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !17) -!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) -!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "Node", file: !15, line: 16, baseType: !19) -!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Node", file: !15, line: 13, size: 128, elements: !20) -!20 = !{!21, !23} -!21 = !DIDerivedType(tag: DW_TAG_member, name: "val", scope: !19, file: !15, line: 14, baseType: !22, size: 32) -!22 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!23 = !DIDerivedType(tag: DW_TAG_member, name: "next", scope: !19, file: !15, line: 15, baseType: !24, size: 64, offset: 64) -!24 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !25) -!25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -!26 = !{i32 7, !"Dwarf Version", i32 5} -!27 = !{i32 2, !"Debug Info Version", i32 3} -!28 = !{i32 1, !"wchar_size", i32 4} -!29 = !{i32 7, !"PIC Level", i32 2} -!30 = !{i32 7, !"PIE Level", i32 2} -!31 = !{i32 7, !"uwtable", i32 1} -!32 = !{i32 7, !"frame-pointer", i32 2} -!33 = !{!"Ubuntu clang version 14.0.6"} -!34 = distinct !DISubprogram(name: "init", scope: !15, file: !15, line: 22, type: !35, scopeLine: 22, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!35 = !DISubroutineType(types: !36) -!36 = !{null} -!37 = !{} -!38 = !DILocation(line: 23, column: 15, scope: !34) -!39 = !DILocalVariable(name: "node", scope: !34, file: !15, line: 23, type: !17) -!40 = !DILocation(line: 0, scope: !34) -!41 = !DILocation(line: 24, column: 21, scope: !34) -!42 = !DILocation(line: 24, column: 2, scope: !34) -!43 = !DILocation(line: 25, column: 2, scope: !34) -!44 = !DILocation(line: 26, column: 2, scope: !34) -!45 = !DILocation(line: 27, column: 1, scope: !34) -!46 = distinct !DISubprogram(name: "enqueue", scope: !15, file: !15, line: 29, type: !47, scopeLine: 29, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!47 = !DISubroutineType(types: !48) -!48 = !{null, !22} -!49 = !DILocalVariable(name: "value", arg: 1, scope: !46, file: !15, line: 29, type: !22) -!50 = !DILocation(line: 0, scope: !46) -!51 = !DILocation(line: 32, column: 12, scope: !46) -!52 = !DILocalVariable(name: "node", scope: !46, file: !15, line: 30, type: !17) -!53 = !DILocation(line: 33, column: 8, scope: !46) -!54 = !DILocation(line: 33, column: 12, scope: !46) -!55 = !DILocation(line: 34, column: 21, scope: !46) -!56 = !DILocation(line: 34, column: 2, scope: !46) -!57 = !DILocation(line: 36, column: 2, scope: !46) -!58 = !DILocation(line: 37, column: 10, scope: !59) -!59 = distinct !DILexicalBlock(scope: !46, file: !15, line: 36, column: 12) -!60 = !DILocalVariable(name: "tail", scope: !46, file: !15, line: 30, type: !17) -!61 = !DILocation(line: 38, column: 3, scope: !62) -!62 = distinct !DILexicalBlock(scope: !63, file: !15, line: 38, column: 3) -!63 = distinct !DILexicalBlock(scope: !59, file: !15, line: 38, column: 3) -!64 = !DILocation(line: 38, column: 3, scope: !63) -!65 = !DILocation(line: 39, column: 38, scope: !59) -!66 = !DILocation(line: 39, column: 10, scope: !59) -!67 = !DILocalVariable(name: "next", scope: !46, file: !15, line: 30, type: !17) -!68 = !DILocation(line: 41, column: 15, scope: !69) -!69 = distinct !DILexicalBlock(scope: !59, file: !15, line: 41, column: 7) -!70 = !DILocation(line: 41, column: 12, scope: !69) -!71 = !DILocation(line: 41, column: 7, scope: !59) -!72 = !DILocation(line: 42, column: 13, scope: !73) -!73 = distinct !DILexicalBlock(scope: !74, file: !15, line: 42, column: 8) -!74 = distinct !DILexicalBlock(scope: !69, file: !15, line: 41, column: 62) -!75 = !DILocation(line: 42, column: 8, scope: !74) -!76 = !DILocation(line: 43, column: 5, scope: !77) -!77 = distinct !DILexicalBlock(scope: !73, file: !15, line: 42, column: 22) -!78 = !DILocation(line: 44, column: 4, scope: !77) -!79 = !DILocation(line: 45, column: 9, scope: !80) -!80 = distinct !DILexicalBlock(scope: !81, file: !15, line: 45, column: 9) -!81 = distinct !DILexicalBlock(scope: !73, file: !15, line: 44, column: 11) -!82 = !DILocation(line: 45, column: 9, scope: !81) -!83 = !DILocation(line: 46, column: 9, scope: !84) -!84 = distinct !DILexicalBlock(scope: !80, file: !15, line: 45, column: 40) -!85 = !DILocation(line: 52, column: 1, scope: !46) -!86 = distinct !{!86, !57, !87} -!87 = !DILocation(line: 51, column: 2, scope: !46) -!88 = distinct !DISubprogram(name: "dequeue", scope: !15, file: !15, line: 54, type: !89, scopeLine: 54, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!89 = !DISubroutineType(types: !90) -!90 = !{!22} -!91 = !DILocation(line: 58, column: 2, scope: !88) -!92 = !DILocation(line: 59, column: 10, scope: !93) -!93 = distinct !DILexicalBlock(scope: !88, file: !15, line: 58, column: 12) -!94 = !DILocalVariable(name: "head", scope: !88, file: !15, line: 55, type: !17) -!95 = !DILocation(line: 0, scope: !88) -!96 = !DILocation(line: 60, column: 3, scope: !97) -!97 = distinct !DILexicalBlock(scope: !98, file: !15, line: 60, column: 3) -!98 = distinct !DILexicalBlock(scope: !93, file: !15, line: 60, column: 3) -!99 = !DILocation(line: 60, column: 3, scope: !98) -!100 = !DILocation(line: 61, column: 10, scope: !93) -!101 = !DILocalVariable(name: "tail", scope: !88, file: !15, line: 55, type: !17) -!102 = !DILocation(line: 62, column: 3, scope: !103) -!103 = distinct !DILexicalBlock(scope: !104, file: !15, line: 62, column: 3) -!104 = distinct !DILexicalBlock(scope: !93, file: !15, line: 62, column: 3) -!105 = !DILocation(line: 62, column: 3, scope: !104) -!106 = !DILocation(line: 63, column: 38, scope: !93) -!107 = !DILocation(line: 63, column: 10, scope: !93) -!108 = !DILocalVariable(name: "next", scope: !88, file: !15, line: 55, type: !17) -!109 = !DILocation(line: 65, column: 15, scope: !110) -!110 = distinct !DILexicalBlock(scope: !93, file: !15, line: 65, column: 7) -!111 = !DILocation(line: 65, column: 12, scope: !110) -!112 = !DILocation(line: 65, column: 7, scope: !93) -!113 = !DILocation(line: 66, column: 13, scope: !114) -!114 = distinct !DILexicalBlock(scope: !115, file: !15, line: 66, column: 8) -!115 = distinct !DILexicalBlock(scope: !110, file: !15, line: 65, column: 62) -!116 = !DILocation(line: 66, column: 8, scope: !115) -!117 = !DILocation(line: 70, column: 14, scope: !118) -!118 = distinct !DILexicalBlock(scope: !119, file: !15, line: 70, column: 9) -!119 = distinct !DILexicalBlock(scope: !114, file: !15, line: 69, column: 11) -!120 = !DILocation(line: 70, column: 9, scope: !119) -!121 = !DILocation(line: 71, column: 6, scope: !122) -!122 = distinct !DILexicalBlock(scope: !118, file: !15, line: 70, column: 23) -!123 = !DILocation(line: 72, column: 5, scope: !122) -!124 = !DILocation(line: 73, column: 21, scope: !125) -!125 = distinct !DILexicalBlock(scope: !118, file: !15, line: 72, column: 12) -!126 = !DILocalVariable(name: "result", scope: !88, file: !15, line: 56, type: !22) -!127 = !DILocation(line: 74, column: 10, scope: !128) -!128 = distinct !DILexicalBlock(scope: !125, file: !15, line: 74, column: 10) -!129 = !DILocation(line: 74, column: 10, scope: !125) -!130 = distinct !{!130, !91, !131} -!131 = !DILocation(line: 81, column: 2, scope: !88) -!132 = !DILocation(line: 0, scope: !114) -!133 = !DILocation(line: 83, column: 2, scope: !88) -!134 = distinct !DISubprogram(name: "worker", scope: !135, file: !135, line: 8, type: !136, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!135 = !DIFile(filename: "benchmarks/lfds/ms.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "7e6a31b1f215ca043da6dae63284f84e") -!136 = !DISubroutineType(types: !137) -!137 = !{!5, !5} -!138 = !DILocalVariable(name: "arg", arg: 1, scope: !134, file: !135, line: 8, type: !5) -!139 = !DILocation(line: 0, scope: !134) -!140 = !DILocation(line: 11, column: 23, scope: !134) -!141 = !DILocalVariable(name: "index", scope: !134, file: !135, line: 11, type: !6) -!142 = !DILocation(line: 13, column: 10, scope: !134) -!143 = !DILocation(line: 13, column: 2, scope: !134) -!144 = !DILocation(line: 14, column: 13, scope: !134) -!145 = !DILocalVariable(name: "r", scope: !134, file: !135, line: 14, type: !22) -!146 = !DILocation(line: 16, column: 2, scope: !147) -!147 = distinct !DILexicalBlock(scope: !148, file: !135, line: 16, column: 2) -!148 = distinct !DILexicalBlock(scope: !134, file: !135, line: 16, column: 2) -!149 = !DILocation(line: 16, column: 2, scope: !148) -!150 = !DILocation(line: 18, column: 2, scope: !134) -!151 = distinct !DISubprogram(name: "main", scope: !135, file: !135, line: 21, type: !89, scopeLine: 22, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !37) -!152 = !DILocalVariable(name: "t", scope: !151, file: !135, line: 23, type: !153) -!153 = !DICompositeType(tag: DW_TAG_array_type, baseType: !154, size: 192, elements: !156) -!154 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !155, line: 27, baseType: !11) -!155 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "2d764266ce95ab26d4a4767c2ec78176") -!156 = !{!157} -!157 = !DISubrange(count: 3) -!158 = !DILocation(line: 23, column: 15, scope: !151) -!159 = !DILocation(line: 25, column: 5, scope: !151) -!160 = !DILocalVariable(name: "i", scope: !161, file: !135, line: 27, type: !22) -!161 = distinct !DILexicalBlock(scope: !151, file: !135, line: 27, column: 5) -!162 = !DILocation(line: 0, scope: !161) -!163 = !DILocation(line: 28, column: 25, scope: !164) -!164 = distinct !DILexicalBlock(scope: !161, file: !135, line: 27, column: 5) -!165 = !DILocation(line: 28, column: 9, scope: !164) -!166 = !DILocalVariable(name: "i", scope: !167, file: !135, line: 30, type: !22) -!167 = distinct !DILexicalBlock(scope: !151, file: !135, line: 30, column: 5) -!168 = !DILocation(line: 0, scope: !167) -!169 = !DILocation(line: 31, column: 22, scope: !170) -!170 = distinct !DILexicalBlock(scope: !167, file: !135, line: 30, column: 5) -!171 = !DILocation(line: 31, column: 9, scope: !170) -!172 = !DILocation(line: 33, column: 13, scope: !151) -!173 = !DILocalVariable(name: "r", scope: !151, file: !135, line: 33, type: !22) -!174 = !DILocation(line: 0, scope: !151) -!175 = !DILocation(line: 34, column: 5, scope: !176) -!176 = distinct !DILexicalBlock(scope: !177, file: !135, line: 34, column: 5) -!177 = distinct !DILexicalBlock(scope: !151, file: !135, line: 34, column: 5) -!178 = !DILocation(line: 34, column: 5, scope: !177) -!179 = !DILocation(line: 36, column: 5, scope: !151) +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} diff --git a/dartagnan/src/test/resources/lfds/treiber-CAS-relaxed.ll b/dartagnan/src/test/resources/lfds/treiber-CAS-relaxed.ll index b314a841aa..54c174b2ca 100644 --- a/dartagnan/src/test/resources/lfds/treiber-CAS-relaxed.ll +++ b/dartagnan/src/test/resources/lfds/treiber-CAS-relaxed.ll @@ -1,5 +1,5 @@ -; ModuleID = '/home/ponce/git/Dat3M/output/treiber.ll' -source_filename = "/home/ponce/git/Dat3M/benchmarks/lfds/treiber.c" +; ModuleID = 'benchmarks/lfds/treiber.c' +source_filename = "benchmarks/lfds/treiber.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" @@ -7,306 +7,300 @@ target triple = "x86_64-pc-linux-gnu" %struct.Node = type { i32, %struct.Node* } %union.pthread_attr_t = type { i64, [48 x i8] } -@TOP = dso_local global %struct.anon zeroinitializer, align 8, !dbg !0 +@TOP = dso_local global %struct.anon zeroinitializer, align 8 @.str = private unnamed_addr constant [11 x i8] c"r != EMPTY\00", align 1 -@.str.1 = private unnamed_addr constant [48 x i8] c"/home/ponce/git/Dat3M/benchmarks/lfds/treiber.c\00", align 1 +@.str.1 = private unnamed_addr constant [26 x i8] c"benchmarks/lfds/treiber.c\00", align 1 @__PRETTY_FUNCTION__.worker = private unnamed_addr constant [21 x i8] c"void *worker(void *)\00", align 1 @.str.2 = private unnamed_addr constant [11 x i8] c"r == EMPTY\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @init() #0 !dbg !35 { - store %struct.Node* null, %struct.Node** getelementptr inbounds (%struct.anon, %struct.anon* @TOP, i32 0, i32 0), align 8, !dbg !39 - ret void, !dbg !40 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @init() #0 { + store %struct.Node* null, %struct.Node** getelementptr inbounds (%struct.anon, %struct.anon* @TOP, i32 0, i32 0), align 8 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local void @push(i32 noundef %0) #0 !dbg !41 { - call void @llvm.dbg.value(metadata i32 %0, metadata !44, metadata !DIExpression()), !dbg !45 - %2 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !46 - %3 = bitcast i8* %2 to %struct.Node*, !dbg !46 - call void @llvm.dbg.value(metadata %struct.Node* %3, metadata !47, metadata !DIExpression()), !dbg !45 - %4 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 0, !dbg !48 - store i32 %0, i32* %4, align 8, !dbg !49 - br label %5, !dbg !50 - -5: ; preds = %5, %1 - %6 = load atomic i64, i64* bitcast (%struct.anon* @TOP to i64*) acquire, align 8, !dbg !51 - %7 = inttoptr i64 %6 to %struct.Node*, !dbg !51 - call void @llvm.dbg.value(metadata %struct.Node* %7, metadata !53, metadata !DIExpression()), !dbg !45 - %8 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 1, !dbg !54 - %9 = bitcast %struct.Node** %8 to i64*, !dbg !55 - store atomic i64 %6, i64* %9 monotonic, align 8, !dbg !55 - %10 = ptrtoint %struct.Node* %3 to i64, !dbg !56 - %11 = cmpxchg i64* bitcast (%struct.anon* @TOP to i64*), i64 %6, i64 %10 monotonic monotonic, align 8, !dbg !56 - %12 = extractvalue { i64, i1 } %11, 0, !dbg !56 - %13 = extractvalue { i64, i1 } %11, 1, !dbg !56 - %14 = zext i1 %13 to i8, !dbg !56 - br i1 %13, label %15, label %5, !dbg !58, !llvm.loop !59 - -15: ; preds = %5 - ret void, !dbg !61 -} +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @push(i32 noundef %0) #0 { + %2 = alloca i32, align 4 + %3 = alloca %struct.Node*, align 8 + %4 = alloca %struct.Node*, align 8 + %5 = alloca %struct.Node*, align 8 + %6 = alloca %struct.Node*, align 8 + %7 = alloca %struct.Node*, align 8 + %8 = alloca i8, align 1 + store i32 %0, i32* %2, align 4 + %9 = call noalias i8* @malloc(i64 noundef 16) #4 + %10 = bitcast i8* %9 to %struct.Node* + store %struct.Node* %10, %struct.Node** %3, align 8 + %11 = load i32, i32* %2, align 4 + %12 = load %struct.Node*, %struct.Node** %3, align 8 + %13 = getelementptr inbounds %struct.Node, %struct.Node* %12, i32 0, i32 0 + store i32 %11, i32* %13, align 8 + br label %14 + +14: ; preds = %1, %39 + %15 = bitcast %struct.Node** %5 to i64* + %16 = load atomic i64, i64* bitcast (%struct.anon* @TOP to i64*) acquire, align 8 + store i64 %16, i64* %15, align 8 + %17 = bitcast i64* %15 to %struct.Node** + %18 = load %struct.Node*, %struct.Node** %17, align 8 + store %struct.Node* %18, %struct.Node** %4, align 8 + %19 = load %struct.Node*, %struct.Node** %3, align 8 + %20 = getelementptr inbounds %struct.Node, %struct.Node* %19, i32 0, i32 1 + %21 = load %struct.Node*, %struct.Node** %4, align 8 + store %struct.Node* %21, %struct.Node** %6, align 8 + %22 = bitcast %struct.Node** %20 to i64* + %23 = bitcast %struct.Node** %6 to i64* + %24 = load i64, i64* %23, align 8 + store atomic i64 %24, i64* %22 monotonic, align 8 + %25 = load %struct.Node*, %struct.Node** %3, align 8 + store %struct.Node* %25, %struct.Node** %7, align 8 + %26 = bitcast %struct.Node** %4 to i64* + %27 = bitcast %struct.Node** %7 to i64* + %28 = load i64, i64* %26, align 8 + %29 = load i64, i64* %27, align 8 + %30 = cmpxchg i64* bitcast (%struct.anon* @TOP to i64*), i64 %28, i64 %29 monotonic monotonic, align 8 + %31 = extractvalue { i64, i1 } %30, 0 + %32 = extractvalue { i64, i1 } %30, 1 + br i1 %32, label %34, label %33 + +33: ; preds = %14 + store i64 %31, i64* %26, align 8 + br label %34 + +34: ; preds = %33, %14 + %35 = zext i1 %32 to i8 + store i8 %35, i8* %8, align 1 + %36 = load i8, i8* %8, align 1 + %37 = trunc i8 %36 to i1 + br i1 %37, label %38, label %39 + +38: ; preds = %34 + br label %40 -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 +39: ; preds = %34 + br label %14 + +40: ; preds = %38 + ret void +} ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @pop() #0 !dbg !62 { - br label %1, !dbg !65 - -1: ; preds = %5, %0 - %2 = load atomic i64, i64* bitcast (%struct.anon* @TOP to i64*) acquire, align 8, !dbg !66 - %3 = inttoptr i64 %2 to %struct.Node*, !dbg !66 - call void @llvm.dbg.value(metadata %struct.Node* %3, metadata !68, metadata !DIExpression()), !dbg !69 - %4 = icmp eq %struct.Node* %3, null, !dbg !70 - br i1 %4, label %18, label %5, !dbg !72 - -5: ; preds = %1 - %6 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 1, !dbg !73 - %7 = bitcast %struct.Node** %6 to i64*, !dbg !75 - %8 = load atomic i64, i64* %7 acquire, align 8, !dbg !75 - %9 = inttoptr i64 %8 to %struct.Node*, !dbg !75 - call void @llvm.dbg.value(metadata %struct.Node* %9, metadata !76, metadata !DIExpression()), !dbg !69 - %10 = cmpxchg i64* bitcast (%struct.anon* @TOP to i64*), i64 %2, i64 %8 monotonic monotonic, align 8, !dbg !77 - %11 = extractvalue { i64, i1 } %10, 0, !dbg !77 - %12 = extractvalue { i64, i1 } %10, 1, !dbg !77 - %13 = inttoptr i64 %11 to %struct.Node*, !dbg !77 - %.06 = select i1 %12, %struct.Node* %3, %struct.Node* %13, !dbg !77 - call void @llvm.dbg.value(metadata %struct.Node* %.06, metadata !68, metadata !DIExpression()), !dbg !69 - %14 = zext i1 %12 to i8, !dbg !77 - br i1 %12, label %15, label %1, !dbg !79, !llvm.loop !80 - -15: ; preds = %5 - %16 = getelementptr inbounds %struct.Node, %struct.Node* %.06, i32 0, i32 0, !dbg !82 - %17 = load i32, i32* %16, align 8, !dbg !82 - br label %18, !dbg !83 - -18: ; preds = %1, %15 - %.0 = phi i32 [ %17, %15 ], [ -1, %1 ], !dbg !69 - ret i32 %.0, !dbg !84 +declare noalias i8* @malloc(i64 noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @pop() #0 { + %1 = alloca i32, align 4 + %2 = alloca %struct.Node*, align 8 + %3 = alloca %struct.Node*, align 8 + %4 = alloca %struct.Node*, align 8 + %5 = alloca %struct.Node*, align 8 + %6 = alloca %struct.Node*, align 8 + %7 = alloca i8, align 1 + br label %8 + +8: ; preds = %0, %41 + %9 = bitcast %struct.Node** %4 to i64* + %10 = load atomic i64, i64* bitcast (%struct.anon* @TOP to i64*) acquire, align 8 + store i64 %10, i64* %9, align 8 + %11 = bitcast i64* %9 to %struct.Node** + %12 = load %struct.Node*, %struct.Node** %11, align 8 + store %struct.Node* %12, %struct.Node** %2, align 8 + %13 = load %struct.Node*, %struct.Node** %2, align 8 + %14 = icmp eq %struct.Node* %13, null + br i1 %14, label %15, label %16 + +15: ; preds = %8 + store i32 -1, i32* %1, align 4 + br label %46 + +16: ; preds = %8 + %17 = load %struct.Node*, %struct.Node** %2, align 8 + %18 = getelementptr inbounds %struct.Node, %struct.Node* %17, i32 0, i32 1 + %19 = bitcast %struct.Node** %18 to i64* + %20 = bitcast %struct.Node** %5 to i64* + %21 = load atomic i64, i64* %19 acquire, align 8 + store i64 %21, i64* %20, align 8 + %22 = bitcast i64* %20 to %struct.Node** + %23 = load %struct.Node*, %struct.Node** %22, align 8 + store %struct.Node* %23, %struct.Node** %3, align 8 + %24 = load %struct.Node*, %struct.Node** %3, align 8 + store %struct.Node* %24, %struct.Node** %6, align 8 + %25 = bitcast %struct.Node** %2 to i64* + %26 = bitcast %struct.Node** %6 to i64* + %27 = load i64, i64* %25, align 8 + %28 = load i64, i64* %26, align 8 + %29 = cmpxchg i64* bitcast (%struct.anon* @TOP to i64*), i64 %27, i64 %28 monotonic monotonic, align 8 + %30 = extractvalue { i64, i1 } %29, 0 + %31 = extractvalue { i64, i1 } %29, 1 + br i1 %31, label %33, label %32 + +32: ; preds = %16 + store i64 %30, i64* %25, align 8 + br label %33 + +33: ; preds = %32, %16 + %34 = zext i1 %31 to i8 + store i8 %34, i8* %7, align 1 + %35 = load i8, i8* %7, align 1 + %36 = trunc i8 %35 to i1 + br i1 %36, label %37, label %40 + +37: ; preds = %33 + %38 = load %struct.Node*, %struct.Node** %2, align 8 + %39 = bitcast %struct.Node* %38 to i8* + call void @free(i8* noundef %39) #4 + br label %42 + +40: ; preds = %33 + br label %41 + +41: ; preds = %40 + br label %8 + +42: ; preds = %37 + %43 = load %struct.Node*, %struct.Node** %2, align 8 + %44 = getelementptr inbounds %struct.Node, %struct.Node* %43, i32 0, i32 0 + %45 = load i32, i32* %44, align 8 + store i32 %45, i32* %1, align 4 + br label %46 + +46: ; preds = %42, %15 + %47 = load i32, i32* %1, align 4 + ret i32 %47 } -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @worker(i8* noundef %0) #0 !dbg !85 { - call void @llvm.dbg.value(metadata i8* %0, metadata !89, metadata !DIExpression()), !dbg !90 - %2 = ptrtoint i8* %0 to i64, !dbg !91 - call void @llvm.dbg.value(metadata i64 %2, metadata !92, metadata !DIExpression()), !dbg !90 - %3 = trunc i64 %2 to i32, !dbg !93 - call void @push(i32 noundef %3), !dbg !94 - %4 = call i32 @pop(), !dbg !95 - call void @llvm.dbg.value(metadata i32 %4, metadata !96, metadata !DIExpression()), !dbg !90 - %5 = icmp ne i32 %4, -1, !dbg !97 - br i1 %5, label %7, label %6, !dbg !100 - -6: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([48 x i8], [48 x i8]* @.str.1, i64 0, i64 0), i32 noundef 17, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #6, !dbg !97 - unreachable, !dbg !97 - -7: ; preds = %1 - ret i8* null, !dbg !101 +; Function Attrs: nounwind +declare void @free(i8* noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @worker(i8* noundef %0) #0 { + %2 = alloca i8*, align 8 + %3 = alloca i64, align 8 + %4 = alloca i32, align 4 + store i8* %0, i8** %2, align 8 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + call void @push(i32 noundef %8) + %9 = call i32 @pop() + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = icmp ne i32 %10, -1 + br i1 %11, label %12, label %13 + +12: ; preds = %1 + br label %14 + +13: ; preds = %1 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 noundef 17, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #5 + unreachable + +14: ; preds = %12 + ret i8* null } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !102 { - %1 = alloca [3 x i64], align 16 - call void @llvm.dbg.declare(metadata [3 x i64]* %1, metadata !103, metadata !DIExpression()), !dbg !109 - call void @init(), !dbg !110 - call void @llvm.dbg.value(metadata i32 0, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i64 0, metadata !111, metadata !DIExpression()), !dbg !113 - %2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0, !dbg !114 - %3 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef null) #5, !dbg !116 - call void @llvm.dbg.value(metadata i64 1, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i64 1, metadata !111, metadata !DIExpression()), !dbg !113 - %4 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1, !dbg !114 - %5 = call i32 @pthread_create(i64* noundef %4, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef inttoptr (i64 1 to i8*)) #5, !dbg !116 - call void @llvm.dbg.value(metadata i64 2, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i64 2, metadata !111, metadata !DIExpression()), !dbg !113 - %6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2, !dbg !114 - %7 = call i32 @pthread_create(i64* noundef %6, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef inttoptr (i64 2 to i8*)) #5, !dbg !116 - call void @llvm.dbg.value(metadata i64 3, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i64 3, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i32 0, metadata !117, metadata !DIExpression()), !dbg !119 - call void @llvm.dbg.value(metadata i64 0, metadata !117, metadata !DIExpression()), !dbg !119 - %8 = load i64, i64* %2, align 8, !dbg !120 - %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !122 - call void @llvm.dbg.value(metadata i64 1, metadata !117, metadata !DIExpression()), !dbg !119 - call void @llvm.dbg.value(metadata i64 1, metadata !117, metadata !DIExpression()), !dbg !119 - %10 = load i64, i64* %4, align 8, !dbg !120 - %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !122 - call void @llvm.dbg.value(metadata i64 2, metadata !117, metadata !DIExpression()), !dbg !119 - call void @llvm.dbg.value(metadata i64 2, metadata !117, metadata !DIExpression()), !dbg !119 - %12 = load i64, i64* %6, align 8, !dbg !120 - %13 = call i32 @pthread_join(i64 noundef %12, i8** noundef null), !dbg !122 - call void @llvm.dbg.value(metadata i64 3, metadata !117, metadata !DIExpression()), !dbg !119 - call void @llvm.dbg.value(metadata i64 3, metadata !117, metadata !DIExpression()), !dbg !119 - %14 = call i32 @pop(), !dbg !123 - call void @llvm.dbg.value(metadata i32 %14, metadata !124, metadata !DIExpression()), !dbg !125 - %15 = icmp eq i32 %14, -1, !dbg !126 - br i1 %15, label %17, label %16, !dbg !129 - -16: ; preds = %0 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([48 x i8], [48 x i8]* @.str.1, i64 0, i64 0), i32 noundef 35, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !126 - unreachable, !dbg !126 - -17: ; preds = %0 - ret i32 0, !dbg !130 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca [3 x i64], align 16 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + call void @init() + store i32 0, i32* %3, align 4 + br label %6 + +6: ; preds = %17, %0 + %7 = load i32, i32* %3, align 4 + %8 = icmp slt i32 %7, 3 + br i1 %8, label %9, label %20 + +9: ; preds = %6 + %10 = load i32, i32* %3, align 4 + %11 = sext i32 %10 to i64 + %12 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %11 + %13 = load i32, i32* %3, align 4 + %14 = sext i32 %13 to i64 + %15 = inttoptr i64 %14 to i8* + %16 = call i32 @pthread_create(i64* noundef %12, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef %15) #4 + br label %17 + +17: ; preds = %9 + %18 = load i32, i32* %3, align 4 + %19 = add nsw i32 %18, 1 + store i32 %19, i32* %3, align 4 + br label %6, !llvm.loop !6 + +20: ; preds = %6 + store i32 0, i32* %4, align 4 + br label %21 + +21: ; preds = %30, %20 + %22 = load i32, i32* %4, align 4 + %23 = icmp slt i32 %22, 3 + br i1 %23, label %24, label %33 + +24: ; preds = %21 + %25 = load i32, i32* %4, align 4 + %26 = sext i32 %25 to i64 + %27 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %26 + %28 = load i64, i64* %27, align 8 + %29 = call i32 @pthread_join(i64 noundef %28, i8** noundef null) + br label %30 + +30: ; preds = %24 + %31 = load i32, i32* %4, align 4 + %32 = add nsw i32 %31, 1 + store i32 %32, i32* %4, align 4 + br label %21, !llvm.loop !8 + +33: ; preds = %21 + %34 = call i32 @pop() + store i32 %34, i32* %5, align 4 + %35 = load i32, i32* %5, align 4 + %36 = icmp eq i32 %35, -1 + br i1 %36, label %37, label %38 + +37: ; preds = %33 + br label %39 + +38: ; preds = %33 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 noundef 35, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable + +39: ; preds = %37 + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 - -declare i32 @pthread_join(i64 noundef, i8** noundef) #4 - -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.value(metadata, metadata, metadata) #1 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!27, !28, !29, !30, !31, !32, !33} -!llvm.ident = !{!34} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "TOP", scope: !2, file: !13, line: 19, type: !14, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.6", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !4, globals: !12, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "/home/ponce/git/Dat3M/benchmarks/lfds/treiber.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "6374e26f9e48e84c9da108eff1ccfc9b") -!4 = !{!5, !6, !9} -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !7, line: 87, baseType: !8) -!7 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "24103e292ae21916e87130b926c8d2f8") -!8 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !10, line: 46, baseType: !11) -!10 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!11 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!12 = !{!0} -!13 = !DIFile(filename: "benchmarks/lfds/treiber.h", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "a4031056245a21941de5af4b4e486aa2") -!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !13, line: 17, size: 64, elements: !15) -!15 = !{!16} -!16 = !DIDerivedType(tag: DW_TAG_member, name: "node", scope: !14, file: !13, line: 18, baseType: !17, size: 64) -!17 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !18) -!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "Node", file: !13, line: 15, baseType: !20) -!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Node", file: !13, line: 12, size: 128, elements: !21) -!21 = !{!22, !24} -!22 = !DIDerivedType(tag: DW_TAG_member, name: "val", scope: !20, file: !13, line: 13, baseType: !23, size: 32) -!23 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!24 = !DIDerivedType(tag: DW_TAG_member, name: "next", scope: !20, file: !13, line: 14, baseType: !25, size: 64, offset: 64) -!25 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !26) -!26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64) -!27 = !{i32 7, !"Dwarf Version", i32 5} -!28 = !{i32 2, !"Debug Info Version", i32 3} -!29 = !{i32 1, !"wchar_size", i32 4} -!30 = !{i32 7, !"PIC Level", i32 2} -!31 = !{i32 7, !"PIE Level", i32 2} -!32 = !{i32 7, !"uwtable", i32 1} -!33 = !{i32 7, !"frame-pointer", i32 2} -!34 = !{!"Ubuntu clang version 14.0.6"} -!35 = distinct !DISubprogram(name: "init", scope: !13, file: !13, line: 21, type: !36, scopeLine: 21, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!36 = !DISubroutineType(types: !37) -!37 = !{null} -!38 = !{} -!39 = !DILocation(line: 22, column: 5, scope: !35) -!40 = !DILocation(line: 23, column: 1, scope: !35) -!41 = distinct !DISubprogram(name: "push", scope: !13, file: !13, line: 25, type: !42, scopeLine: 25, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!42 = !DISubroutineType(types: !43) -!43 = !{null, !23} -!44 = !DILocalVariable(name: "e", arg: 1, scope: !41, file: !13, line: 25, type: !23) -!45 = !DILocation(line: 0, scope: !41) -!46 = !DILocation(line: 27, column: 9, scope: !41) -!47 = !DILocalVariable(name: "y", scope: !41, file: !13, line: 26, type: !18) -!48 = !DILocation(line: 28, column: 8, scope: !41) -!49 = !DILocation(line: 28, column: 12, scope: !41) -!50 = !DILocation(line: 30, column: 5, scope: !41) -!51 = !DILocation(line: 31, column: 13, scope: !52) -!52 = distinct !DILexicalBlock(scope: !41, file: !13, line: 30, column: 14) -!53 = !DILocalVariable(name: "n", scope: !41, file: !13, line: 26, type: !18) -!54 = !DILocation(line: 32, column: 35, scope: !52) -!55 = !DILocation(line: 32, column: 9, scope: !52) -!56 = !DILocation(line: 34, column: 13, scope: !57) -!57 = distinct !DILexicalBlock(scope: !52, file: !13, line: 34, column: 13) -!58 = !DILocation(line: 34, column: 13, scope: !52) -!59 = distinct !{!59, !50, !60} -!60 = !DILocation(line: 37, column: 5, scope: !41) -!61 = !DILocation(line: 38, column: 1, scope: !41) -!62 = distinct !DISubprogram(name: "pop", scope: !13, file: !13, line: 40, type: !63, scopeLine: 40, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!63 = !DISubroutineType(types: !64) -!64 = !{!23} -!65 = !DILocation(line: 43, column: 5, scope: !62) -!66 = !DILocation(line: 44, column: 13, scope: !67) -!67 = distinct !DILexicalBlock(scope: !62, file: !13, line: 43, column: 15) -!68 = !DILocalVariable(name: "y", scope: !62, file: !13, line: 41, type: !18) -!69 = !DILocation(line: 0, scope: !62) -!70 = !DILocation(line: 45, column: 15, scope: !71) -!71 = distinct !DILexicalBlock(scope: !67, file: !13, line: 45, column: 13) -!72 = !DILocation(line: 45, column: 13, scope: !67) -!73 = !DILocation(line: 48, column: 42, scope: !74) -!74 = distinct !DILexicalBlock(scope: !71, file: !13, line: 47, column: 16) -!75 = !DILocation(line: 48, column: 17, scope: !74) -!76 = !DILocalVariable(name: "z", scope: !62, file: !13, line: 41, type: !18) -!77 = !DILocation(line: 49, column: 17, scope: !78) -!78 = distinct !DILexicalBlock(scope: !74, file: !13, line: 49, column: 17) -!79 = !DILocation(line: 49, column: 17, scope: !74) -!80 = distinct !{!80, !65, !81} -!81 = !DILocation(line: 54, column: 5, scope: !62) -!82 = !DILocation(line: 55, column: 15, scope: !62) -!83 = !DILocation(line: 55, column: 5, scope: !62) -!84 = !DILocation(line: 56, column: 1, scope: !62) -!85 = distinct !DISubprogram(name: "worker", scope: !86, file: !86, line: 9, type: !87, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!86 = !DIFile(filename: "benchmarks/lfds/treiber.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "6374e26f9e48e84c9da108eff1ccfc9b") -!87 = !DISubroutineType(types: !88) -!88 = !{!5, !5} -!89 = !DILocalVariable(name: "arg", arg: 1, scope: !85, file: !86, line: 9, type: !5) -!90 = !DILocation(line: 0, scope: !85) -!91 = !DILocation(line: 12, column: 23, scope: !85) -!92 = !DILocalVariable(name: "index", scope: !85, file: !86, line: 12, type: !6) -!93 = !DILocation(line: 14, column: 7, scope: !85) -!94 = !DILocation(line: 14, column: 2, scope: !85) -!95 = !DILocation(line: 15, column: 13, scope: !85) -!96 = !DILocalVariable(name: "r", scope: !85, file: !86, line: 15, type: !23) -!97 = !DILocation(line: 17, column: 2, scope: !98) -!98 = distinct !DILexicalBlock(scope: !99, file: !86, line: 17, column: 2) -!99 = distinct !DILexicalBlock(scope: !85, file: !86, line: 17, column: 2) -!100 = !DILocation(line: 17, column: 2, scope: !99) -!101 = !DILocation(line: 19, column: 2, scope: !85) -!102 = distinct !DISubprogram(name: "main", scope: !86, file: !86, line: 22, type: !63, scopeLine: 23, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!103 = !DILocalVariable(name: "t", scope: !102, file: !86, line: 24, type: !104) -!104 = !DICompositeType(tag: DW_TAG_array_type, baseType: !105, size: 192, elements: !107) -!105 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !106, line: 27, baseType: !11) -!106 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "2d764266ce95ab26d4a4767c2ec78176") -!107 = !{!108} -!108 = !DISubrange(count: 3) -!109 = !DILocation(line: 24, column: 15, scope: !102) -!110 = !DILocation(line: 26, column: 5, scope: !102) -!111 = !DILocalVariable(name: "i", scope: !112, file: !86, line: 28, type: !23) -!112 = distinct !DILexicalBlock(scope: !102, file: !86, line: 28, column: 5) -!113 = !DILocation(line: 0, scope: !112) -!114 = !DILocation(line: 29, column: 25, scope: !115) -!115 = distinct !DILexicalBlock(scope: !112, file: !86, line: 28, column: 5) -!116 = !DILocation(line: 29, column: 9, scope: !115) -!117 = !DILocalVariable(name: "i", scope: !118, file: !86, line: 31, type: !23) -!118 = distinct !DILexicalBlock(scope: !102, file: !86, line: 31, column: 5) -!119 = !DILocation(line: 0, scope: !118) -!120 = !DILocation(line: 32, column: 22, scope: !121) -!121 = distinct !DILexicalBlock(scope: !118, file: !86, line: 31, column: 5) -!122 = !DILocation(line: 32, column: 9, scope: !121) -!123 = !DILocation(line: 34, column: 13, scope: !102) -!124 = !DILocalVariable(name: "r", scope: !102, file: !86, line: 34, type: !23) -!125 = !DILocation(line: 0, scope: !102) -!126 = !DILocation(line: 35, column: 5, scope: !127) -!127 = distinct !DILexicalBlock(scope: !128, file: !86, line: 35, column: 5) -!128 = distinct !DILexicalBlock(scope: !102, file: !86, line: 35, column: 5) -!129 = !DILocation(line: 35, column: 5, scope: !128) -!130 = !DILocation(line: 37, column: 5, scope: !102) +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} diff --git a/dartagnan/src/test/resources/lfds/treiber.ll b/dartagnan/src/test/resources/lfds/treiber.ll index edb45eea90..eb36e9ffd7 100644 --- a/dartagnan/src/test/resources/lfds/treiber.ll +++ b/dartagnan/src/test/resources/lfds/treiber.ll @@ -1,5 +1,5 @@ -; ModuleID = '/home/ponce/git/Dat3M/output/treiber.ll' -source_filename = "/home/ponce/git/Dat3M/benchmarks/lfds/treiber.c" +; ModuleID = 'benchmarks/lfds/treiber.c' +source_filename = "benchmarks/lfds/treiber.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" @@ -7,306 +7,300 @@ target triple = "x86_64-pc-linux-gnu" %struct.Node = type { i32, %struct.Node* } %union.pthread_attr_t = type { i64, [48 x i8] } -@TOP = dso_local global %struct.anon zeroinitializer, align 8, !dbg !0 +@TOP = dso_local global %struct.anon zeroinitializer, align 8 @.str = private unnamed_addr constant [11 x i8] c"r != EMPTY\00", align 1 -@.str.1 = private unnamed_addr constant [48 x i8] c"/home/ponce/git/Dat3M/benchmarks/lfds/treiber.c\00", align 1 +@.str.1 = private unnamed_addr constant [26 x i8] c"benchmarks/lfds/treiber.c\00", align 1 @__PRETTY_FUNCTION__.worker = private unnamed_addr constant [21 x i8] c"void *worker(void *)\00", align 1 @.str.2 = private unnamed_addr constant [11 x i8] c"r == EMPTY\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @init() #0 !dbg !35 { - store %struct.Node* null, %struct.Node** getelementptr inbounds (%struct.anon, %struct.anon* @TOP, i32 0, i32 0), align 8, !dbg !39 - ret void, !dbg !40 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @init() #0 { + store %struct.Node* null, %struct.Node** getelementptr inbounds (%struct.anon, %struct.anon* @TOP, i32 0, i32 0), align 8 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local void @push(i32 noundef %0) #0 !dbg !41 { - call void @llvm.dbg.value(metadata i32 %0, metadata !44, metadata !DIExpression()), !dbg !45 - %2 = call noalias i8* @malloc(i64 noundef 16) #5, !dbg !46 - %3 = bitcast i8* %2 to %struct.Node*, !dbg !46 - call void @llvm.dbg.value(metadata %struct.Node* %3, metadata !47, metadata !DIExpression()), !dbg !45 - %4 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 0, !dbg !48 - store i32 %0, i32* %4, align 8, !dbg !49 - br label %5, !dbg !50 - -5: ; preds = %5, %1 - %6 = load atomic i64, i64* bitcast (%struct.anon* @TOP to i64*) acquire, align 8, !dbg !51 - %7 = inttoptr i64 %6 to %struct.Node*, !dbg !51 - call void @llvm.dbg.value(metadata %struct.Node* %7, metadata !53, metadata !DIExpression()), !dbg !45 - %8 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 1, !dbg !54 - %9 = bitcast %struct.Node** %8 to i64*, !dbg !55 - store atomic i64 %6, i64* %9 monotonic, align 8, !dbg !55 - %10 = ptrtoint %struct.Node* %3 to i64, !dbg !56 - %11 = cmpxchg i64* bitcast (%struct.anon* @TOP to i64*), i64 %6, i64 %10 acq_rel monotonic, align 8, !dbg !56 - %12 = extractvalue { i64, i1 } %11, 0, !dbg !56 - %13 = extractvalue { i64, i1 } %11, 1, !dbg !56 - %14 = zext i1 %13 to i8, !dbg !56 - br i1 %13, label %15, label %5, !dbg !58, !llvm.loop !59 - -15: ; preds = %5 - ret void, !dbg !61 -} +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @push(i32 noundef %0) #0 { + %2 = alloca i32, align 4 + %3 = alloca %struct.Node*, align 8 + %4 = alloca %struct.Node*, align 8 + %5 = alloca %struct.Node*, align 8 + %6 = alloca %struct.Node*, align 8 + %7 = alloca %struct.Node*, align 8 + %8 = alloca i8, align 1 + store i32 %0, i32* %2, align 4 + %9 = call noalias i8* @malloc(i64 noundef 16) #4 + %10 = bitcast i8* %9 to %struct.Node* + store %struct.Node* %10, %struct.Node** %3, align 8 + %11 = load i32, i32* %2, align 4 + %12 = load %struct.Node*, %struct.Node** %3, align 8 + %13 = getelementptr inbounds %struct.Node, %struct.Node* %12, i32 0, i32 0 + store i32 %11, i32* %13, align 8 + br label %14 + +14: ; preds = %1, %39 + %15 = bitcast %struct.Node** %5 to i64* + %16 = load atomic i64, i64* bitcast (%struct.anon* @TOP to i64*) acquire, align 8 + store i64 %16, i64* %15, align 8 + %17 = bitcast i64* %15 to %struct.Node** + %18 = load %struct.Node*, %struct.Node** %17, align 8 + store %struct.Node* %18, %struct.Node** %4, align 8 + %19 = load %struct.Node*, %struct.Node** %3, align 8 + %20 = getelementptr inbounds %struct.Node, %struct.Node* %19, i32 0, i32 1 + %21 = load %struct.Node*, %struct.Node** %4, align 8 + store %struct.Node* %21, %struct.Node** %6, align 8 + %22 = bitcast %struct.Node** %20 to i64* + %23 = bitcast %struct.Node** %6 to i64* + %24 = load i64, i64* %23, align 8 + store atomic i64 %24, i64* %22 monotonic, align 8 + %25 = load %struct.Node*, %struct.Node** %3, align 8 + store %struct.Node* %25, %struct.Node** %7, align 8 + %26 = bitcast %struct.Node** %4 to i64* + %27 = bitcast %struct.Node** %7 to i64* + %28 = load i64, i64* %26, align 8 + %29 = load i64, i64* %27, align 8 + %30 = cmpxchg i64* bitcast (%struct.anon* @TOP to i64*), i64 %28, i64 %29 acq_rel monotonic, align 8 + %31 = extractvalue { i64, i1 } %30, 0 + %32 = extractvalue { i64, i1 } %30, 1 + br i1 %32, label %34, label %33 + +33: ; preds = %14 + store i64 %31, i64* %26, align 8 + br label %34 + +34: ; preds = %33, %14 + %35 = zext i1 %32 to i8 + store i8 %35, i8* %8, align 1 + %36 = load i8, i8* %8, align 1 + %37 = trunc i8 %36 to i1 + br i1 %37, label %38, label %39 + +38: ; preds = %34 + br label %40 -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 +39: ; preds = %34 + br label %14 + +40: ; preds = %38 + ret void +} ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @pop() #0 !dbg !62 { - br label %1, !dbg !65 - -1: ; preds = %5, %0 - %2 = load atomic i64, i64* bitcast (%struct.anon* @TOP to i64*) acquire, align 8, !dbg !66 - %3 = inttoptr i64 %2 to %struct.Node*, !dbg !66 - call void @llvm.dbg.value(metadata %struct.Node* %3, metadata !68, metadata !DIExpression()), !dbg !69 - %4 = icmp eq %struct.Node* %3, null, !dbg !70 - br i1 %4, label %18, label %5, !dbg !72 - -5: ; preds = %1 - %6 = getelementptr inbounds %struct.Node, %struct.Node* %3, i32 0, i32 1, !dbg !73 - %7 = bitcast %struct.Node** %6 to i64*, !dbg !75 - %8 = load atomic i64, i64* %7 acquire, align 8, !dbg !75 - %9 = inttoptr i64 %8 to %struct.Node*, !dbg !75 - call void @llvm.dbg.value(metadata %struct.Node* %9, metadata !76, metadata !DIExpression()), !dbg !69 - %10 = cmpxchg i64* bitcast (%struct.anon* @TOP to i64*), i64 %2, i64 %8 acq_rel monotonic, align 8, !dbg !77 - %11 = extractvalue { i64, i1 } %10, 0, !dbg !77 - %12 = extractvalue { i64, i1 } %10, 1, !dbg !77 - %13 = inttoptr i64 %11 to %struct.Node*, !dbg !77 - %.06 = select i1 %12, %struct.Node* %3, %struct.Node* %13, !dbg !77 - call void @llvm.dbg.value(metadata %struct.Node* %.06, metadata !68, metadata !DIExpression()), !dbg !69 - %14 = zext i1 %12 to i8, !dbg !77 - br i1 %12, label %15, label %1, !dbg !79, !llvm.loop !80 - -15: ; preds = %5 - %16 = getelementptr inbounds %struct.Node, %struct.Node* %.06, i32 0, i32 0, !dbg !82 - %17 = load i32, i32* %16, align 8, !dbg !82 - br label %18, !dbg !83 - -18: ; preds = %1, %15 - %.0 = phi i32 [ %17, %15 ], [ -1, %1 ], !dbg !69 - ret i32 %.0, !dbg !84 +declare noalias i8* @malloc(i64 noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @pop() #0 { + %1 = alloca i32, align 4 + %2 = alloca %struct.Node*, align 8 + %3 = alloca %struct.Node*, align 8 + %4 = alloca %struct.Node*, align 8 + %5 = alloca %struct.Node*, align 8 + %6 = alloca %struct.Node*, align 8 + %7 = alloca i8, align 1 + br label %8 + +8: ; preds = %0, %41 + %9 = bitcast %struct.Node** %4 to i64* + %10 = load atomic i64, i64* bitcast (%struct.anon* @TOP to i64*) acquire, align 8 + store i64 %10, i64* %9, align 8 + %11 = bitcast i64* %9 to %struct.Node** + %12 = load %struct.Node*, %struct.Node** %11, align 8 + store %struct.Node* %12, %struct.Node** %2, align 8 + %13 = load %struct.Node*, %struct.Node** %2, align 8 + %14 = icmp eq %struct.Node* %13, null + br i1 %14, label %15, label %16 + +15: ; preds = %8 + store i32 -1, i32* %1, align 4 + br label %46 + +16: ; preds = %8 + %17 = load %struct.Node*, %struct.Node** %2, align 8 + %18 = getelementptr inbounds %struct.Node, %struct.Node* %17, i32 0, i32 1 + %19 = bitcast %struct.Node** %18 to i64* + %20 = bitcast %struct.Node** %5 to i64* + %21 = load atomic i64, i64* %19 acquire, align 8 + store i64 %21, i64* %20, align 8 + %22 = bitcast i64* %20 to %struct.Node** + %23 = load %struct.Node*, %struct.Node** %22, align 8 + store %struct.Node* %23, %struct.Node** %3, align 8 + %24 = load %struct.Node*, %struct.Node** %3, align 8 + store %struct.Node* %24, %struct.Node** %6, align 8 + %25 = bitcast %struct.Node** %2 to i64* + %26 = bitcast %struct.Node** %6 to i64* + %27 = load i64, i64* %25, align 8 + %28 = load i64, i64* %26, align 8 + %29 = cmpxchg i64* bitcast (%struct.anon* @TOP to i64*), i64 %27, i64 %28 acq_rel monotonic, align 8 + %30 = extractvalue { i64, i1 } %29, 0 + %31 = extractvalue { i64, i1 } %29, 1 + br i1 %31, label %33, label %32 + +32: ; preds = %16 + store i64 %30, i64* %25, align 8 + br label %33 + +33: ; preds = %32, %16 + %34 = zext i1 %31 to i8 + store i8 %34, i8* %7, align 1 + %35 = load i8, i8* %7, align 1 + %36 = trunc i8 %35 to i1 + br i1 %36, label %37, label %40 + +37: ; preds = %33 + %38 = load %struct.Node*, %struct.Node** %2, align 8 + %39 = bitcast %struct.Node* %38 to i8* + call void @free(i8* noundef %39) #4 + br label %42 + +40: ; preds = %33 + br label %41 + +41: ; preds = %40 + br label %8 + +42: ; preds = %37 + %43 = load %struct.Node*, %struct.Node** %2, align 8 + %44 = getelementptr inbounds %struct.Node, %struct.Node* %43, i32 0, i32 0 + %45 = load i32, i32* %44, align 8 + store i32 %45, i32* %1, align 4 + br label %46 + +46: ; preds = %42, %15 + %47 = load i32, i32* %1, align 4 + ret i32 %47 } -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @worker(i8* noundef %0) #0 !dbg !85 { - call void @llvm.dbg.value(metadata i8* %0, metadata !89, metadata !DIExpression()), !dbg !90 - %2 = ptrtoint i8* %0 to i64, !dbg !91 - call void @llvm.dbg.value(metadata i64 %2, metadata !92, metadata !DIExpression()), !dbg !90 - %3 = trunc i64 %2 to i32, !dbg !93 - call void @push(i32 noundef %3), !dbg !94 - %4 = call i32 @pop(), !dbg !95 - call void @llvm.dbg.value(metadata i32 %4, metadata !96, metadata !DIExpression()), !dbg !90 - %5 = icmp ne i32 %4, -1, !dbg !97 - br i1 %5, label %7, label %6, !dbg !100 - -6: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([48 x i8], [48 x i8]* @.str.1, i64 0, i64 0), i32 noundef 17, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #6, !dbg !97 - unreachable, !dbg !97 - -7: ; preds = %1 - ret i8* null, !dbg !101 +; Function Attrs: nounwind +declare void @free(i8* noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @worker(i8* noundef %0) #0 { + %2 = alloca i8*, align 8 + %3 = alloca i64, align 8 + %4 = alloca i32, align 4 + store i8* %0, i8** %2, align 8 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + call void @push(i32 noundef %8) + %9 = call i32 @pop() + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = icmp ne i32 %10, -1 + br i1 %11, label %12, label %13 + +12: ; preds = %1 + br label %14 + +13: ; preds = %1 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 noundef 17, i8* noundef getelementptr inbounds ([21 x i8], [21 x i8]* @__PRETTY_FUNCTION__.worker, i64 0, i64 0)) #5 + unreachable + +14: ; preds = %12 + ret i8* null } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !102 { - %1 = alloca [3 x i64], align 16 - call void @llvm.dbg.declare(metadata [3 x i64]* %1, metadata !103, metadata !DIExpression()), !dbg !109 - call void @init(), !dbg !110 - call void @llvm.dbg.value(metadata i32 0, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i64 0, metadata !111, metadata !DIExpression()), !dbg !113 - %2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0, !dbg !114 - %3 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef null) #5, !dbg !116 - call void @llvm.dbg.value(metadata i64 1, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i64 1, metadata !111, metadata !DIExpression()), !dbg !113 - %4 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1, !dbg !114 - %5 = call i32 @pthread_create(i64* noundef %4, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef inttoptr (i64 1 to i8*)) #5, !dbg !116 - call void @llvm.dbg.value(metadata i64 2, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i64 2, metadata !111, metadata !DIExpression()), !dbg !113 - %6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2, !dbg !114 - %7 = call i32 @pthread_create(i64* noundef %6, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef inttoptr (i64 2 to i8*)) #5, !dbg !116 - call void @llvm.dbg.value(metadata i64 3, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i64 3, metadata !111, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.value(metadata i32 0, metadata !117, metadata !DIExpression()), !dbg !119 - call void @llvm.dbg.value(metadata i64 0, metadata !117, metadata !DIExpression()), !dbg !119 - %8 = load i64, i64* %2, align 8, !dbg !120 - %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !122 - call void @llvm.dbg.value(metadata i64 1, metadata !117, metadata !DIExpression()), !dbg !119 - call void @llvm.dbg.value(metadata i64 1, metadata !117, metadata !DIExpression()), !dbg !119 - %10 = load i64, i64* %4, align 8, !dbg !120 - %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !122 - call void @llvm.dbg.value(metadata i64 2, metadata !117, metadata !DIExpression()), !dbg !119 - call void @llvm.dbg.value(metadata i64 2, metadata !117, metadata !DIExpression()), !dbg !119 - %12 = load i64, i64* %6, align 8, !dbg !120 - %13 = call i32 @pthread_join(i64 noundef %12, i8** noundef null), !dbg !122 - call void @llvm.dbg.value(metadata i64 3, metadata !117, metadata !DIExpression()), !dbg !119 - call void @llvm.dbg.value(metadata i64 3, metadata !117, metadata !DIExpression()), !dbg !119 - %14 = call i32 @pop(), !dbg !123 - call void @llvm.dbg.value(metadata i32 %14, metadata !124, metadata !DIExpression()), !dbg !125 - %15 = icmp eq i32 %14, -1, !dbg !126 - br i1 %15, label %17, label %16, !dbg !129 - -16: ; preds = %0 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([48 x i8], [48 x i8]* @.str.1, i64 0, i64 0), i32 noundef 35, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !126 - unreachable, !dbg !126 - -17: ; preds = %0 - ret i32 0, !dbg !130 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca [3 x i64], align 16 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + call void @init() + store i32 0, i32* %3, align 4 + br label %6 + +6: ; preds = %17, %0 + %7 = load i32, i32* %3, align 4 + %8 = icmp slt i32 %7, 3 + br i1 %8, label %9, label %20 + +9: ; preds = %6 + %10 = load i32, i32* %3, align 4 + %11 = sext i32 %10 to i64 + %12 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %11 + %13 = load i32, i32* %3, align 4 + %14 = sext i32 %13 to i64 + %15 = inttoptr i64 %14 to i8* + %16 = call i32 @pthread_create(i64* noundef %12, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @worker, i8* noundef %15) #4 + br label %17 + +17: ; preds = %9 + %18 = load i32, i32* %3, align 4 + %19 = add nsw i32 %18, 1 + store i32 %19, i32* %3, align 4 + br label %6, !llvm.loop !6 + +20: ; preds = %6 + store i32 0, i32* %4, align 4 + br label %21 + +21: ; preds = %30, %20 + %22 = load i32, i32* %4, align 4 + %23 = icmp slt i32 %22, 3 + br i1 %23, label %24, label %33 + +24: ; preds = %21 + %25 = load i32, i32* %4, align 4 + %26 = sext i32 %25 to i64 + %27 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %26 + %28 = load i64, i64* %27, align 8 + %29 = call i32 @pthread_join(i64 noundef %28, i8** noundef null) + br label %30 + +30: ; preds = %24 + %31 = load i32, i32* %4, align 4 + %32 = add nsw i32 %31, 1 + store i32 %32, i32* %4, align 4 + br label %21, !llvm.loop !8 + +33: ; preds = %21 + %34 = call i32 @pop() + store i32 %34, i32* %5, align 4 + %35 = load i32, i32* %5, align 4 + %36 = icmp eq i32 %35, -1 + br i1 %36, label %37, label %38 + +37: ; preds = %33 + br label %39 + +38: ; preds = %33 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 noundef 35, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable + +39: ; preds = %37 + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 - -declare i32 @pthread_join(i64 noundef, i8** noundef) #4 - -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.value(metadata, metadata, metadata) #1 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!27, !28, !29, !30, !31, !32, !33} -!llvm.ident = !{!34} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "TOP", scope: !2, file: !13, line: 19, type: !14, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.6", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !4, globals: !12, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "/home/ponce/git/Dat3M/benchmarks/lfds/treiber.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "6374e26f9e48e84c9da108eff1ccfc9b") -!4 = !{!5, !6, !9} -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !7, line: 87, baseType: !8) -!7 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "24103e292ae21916e87130b926c8d2f8") -!8 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !10, line: 46, baseType: !11) -!10 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!11 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!12 = !{!0} -!13 = !DIFile(filename: "benchmarks/lfds/treiber.h", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "a4031056245a21941de5af4b4e486aa2") -!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !13, line: 17, size: 64, elements: !15) -!15 = !{!16} -!16 = !DIDerivedType(tag: DW_TAG_member, name: "node", scope: !14, file: !13, line: 18, baseType: !17, size: 64) -!17 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !18) -!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "Node", file: !13, line: 15, baseType: !20) -!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Node", file: !13, line: 12, size: 128, elements: !21) -!21 = !{!22, !24} -!22 = !DIDerivedType(tag: DW_TAG_member, name: "val", scope: !20, file: !13, line: 13, baseType: !23, size: 32) -!23 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!24 = !DIDerivedType(tag: DW_TAG_member, name: "next", scope: !20, file: !13, line: 14, baseType: !25, size: 64, offset: 64) -!25 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !26) -!26 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64) -!27 = !{i32 7, !"Dwarf Version", i32 5} -!28 = !{i32 2, !"Debug Info Version", i32 3} -!29 = !{i32 1, !"wchar_size", i32 4} -!30 = !{i32 7, !"PIC Level", i32 2} -!31 = !{i32 7, !"PIE Level", i32 2} -!32 = !{i32 7, !"uwtable", i32 1} -!33 = !{i32 7, !"frame-pointer", i32 2} -!34 = !{!"Ubuntu clang version 14.0.6"} -!35 = distinct !DISubprogram(name: "init", scope: !13, file: !13, line: 21, type: !36, scopeLine: 21, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!36 = !DISubroutineType(types: !37) -!37 = !{null} -!38 = !{} -!39 = !DILocation(line: 22, column: 5, scope: !35) -!40 = !DILocation(line: 23, column: 1, scope: !35) -!41 = distinct !DISubprogram(name: "push", scope: !13, file: !13, line: 25, type: !42, scopeLine: 25, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!42 = !DISubroutineType(types: !43) -!43 = !{null, !23} -!44 = !DILocalVariable(name: "e", arg: 1, scope: !41, file: !13, line: 25, type: !23) -!45 = !DILocation(line: 0, scope: !41) -!46 = !DILocation(line: 27, column: 9, scope: !41) -!47 = !DILocalVariable(name: "y", scope: !41, file: !13, line: 26, type: !18) -!48 = !DILocation(line: 28, column: 8, scope: !41) -!49 = !DILocation(line: 28, column: 12, scope: !41) -!50 = !DILocation(line: 30, column: 5, scope: !41) -!51 = !DILocation(line: 31, column: 13, scope: !52) -!52 = distinct !DILexicalBlock(scope: !41, file: !13, line: 30, column: 14) -!53 = !DILocalVariable(name: "n", scope: !41, file: !13, line: 26, type: !18) -!54 = !DILocation(line: 32, column: 35, scope: !52) -!55 = !DILocation(line: 32, column: 9, scope: !52) -!56 = !DILocation(line: 34, column: 13, scope: !57) -!57 = distinct !DILexicalBlock(scope: !52, file: !13, line: 34, column: 13) -!58 = !DILocation(line: 34, column: 13, scope: !52) -!59 = distinct !{!59, !50, !60} -!60 = !DILocation(line: 37, column: 5, scope: !41) -!61 = !DILocation(line: 38, column: 1, scope: !41) -!62 = distinct !DISubprogram(name: "pop", scope: !13, file: !13, line: 40, type: !63, scopeLine: 40, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!63 = !DISubroutineType(types: !64) -!64 = !{!23} -!65 = !DILocation(line: 43, column: 5, scope: !62) -!66 = !DILocation(line: 44, column: 13, scope: !67) -!67 = distinct !DILexicalBlock(scope: !62, file: !13, line: 43, column: 15) -!68 = !DILocalVariable(name: "y", scope: !62, file: !13, line: 41, type: !18) -!69 = !DILocation(line: 0, scope: !62) -!70 = !DILocation(line: 45, column: 15, scope: !71) -!71 = distinct !DILexicalBlock(scope: !67, file: !13, line: 45, column: 13) -!72 = !DILocation(line: 45, column: 13, scope: !67) -!73 = !DILocation(line: 48, column: 42, scope: !74) -!74 = distinct !DILexicalBlock(scope: !71, file: !13, line: 47, column: 16) -!75 = !DILocation(line: 48, column: 17, scope: !74) -!76 = !DILocalVariable(name: "z", scope: !62, file: !13, line: 41, type: !18) -!77 = !DILocation(line: 49, column: 17, scope: !78) -!78 = distinct !DILexicalBlock(scope: !74, file: !13, line: 49, column: 17) -!79 = !DILocation(line: 49, column: 17, scope: !74) -!80 = distinct !{!80, !65, !81} -!81 = !DILocation(line: 54, column: 5, scope: !62) -!82 = !DILocation(line: 55, column: 15, scope: !62) -!83 = !DILocation(line: 55, column: 5, scope: !62) -!84 = !DILocation(line: 56, column: 1, scope: !62) -!85 = distinct !DISubprogram(name: "worker", scope: !86, file: !86, line: 9, type: !87, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!86 = !DIFile(filename: "benchmarks/lfds/treiber.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "6374e26f9e48e84c9da108eff1ccfc9b") -!87 = !DISubroutineType(types: !88) -!88 = !{!5, !5} -!89 = !DILocalVariable(name: "arg", arg: 1, scope: !85, file: !86, line: 9, type: !5) -!90 = !DILocation(line: 0, scope: !85) -!91 = !DILocation(line: 12, column: 23, scope: !85) -!92 = !DILocalVariable(name: "index", scope: !85, file: !86, line: 12, type: !6) -!93 = !DILocation(line: 14, column: 7, scope: !85) -!94 = !DILocation(line: 14, column: 2, scope: !85) -!95 = !DILocation(line: 15, column: 13, scope: !85) -!96 = !DILocalVariable(name: "r", scope: !85, file: !86, line: 15, type: !23) -!97 = !DILocation(line: 17, column: 2, scope: !98) -!98 = distinct !DILexicalBlock(scope: !99, file: !86, line: 17, column: 2) -!99 = distinct !DILexicalBlock(scope: !85, file: !86, line: 17, column: 2) -!100 = !DILocation(line: 17, column: 2, scope: !99) -!101 = !DILocation(line: 19, column: 2, scope: !85) -!102 = distinct !DISubprogram(name: "main", scope: !86, file: !86, line: 22, type: !63, scopeLine: 23, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !38) -!103 = !DILocalVariable(name: "t", scope: !102, file: !86, line: 24, type: !104) -!104 = !DICompositeType(tag: DW_TAG_array_type, baseType: !105, size: 192, elements: !107) -!105 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !106, line: 27, baseType: !11) -!106 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "2d764266ce95ab26d4a4767c2ec78176") -!107 = !{!108} -!108 = !DISubrange(count: 3) -!109 = !DILocation(line: 24, column: 15, scope: !102) -!110 = !DILocation(line: 26, column: 5, scope: !102) -!111 = !DILocalVariable(name: "i", scope: !112, file: !86, line: 28, type: !23) -!112 = distinct !DILexicalBlock(scope: !102, file: !86, line: 28, column: 5) -!113 = !DILocation(line: 0, scope: !112) -!114 = !DILocation(line: 29, column: 25, scope: !115) -!115 = distinct !DILexicalBlock(scope: !112, file: !86, line: 28, column: 5) -!116 = !DILocation(line: 29, column: 9, scope: !115) -!117 = !DILocalVariable(name: "i", scope: !118, file: !86, line: 31, type: !23) -!118 = distinct !DILexicalBlock(scope: !102, file: !86, line: 31, column: 5) -!119 = !DILocation(line: 0, scope: !118) -!120 = !DILocation(line: 32, column: 22, scope: !121) -!121 = distinct !DILexicalBlock(scope: !118, file: !86, line: 31, column: 5) -!122 = !DILocation(line: 32, column: 9, scope: !121) -!123 = !DILocation(line: 34, column: 13, scope: !102) -!124 = !DILocalVariable(name: "r", scope: !102, file: !86, line: 34, type: !23) -!125 = !DILocation(line: 0, scope: !102) -!126 = !DILocation(line: 35, column: 5, scope: !127) -!127 = distinct !DILexicalBlock(scope: !128, file: !86, line: 35, column: 5) -!128 = distinct !DILexicalBlock(scope: !102, file: !86, line: 35, column: 5) -!129 = !DILocation(line: 35, column: 5, scope: !128) -!130 = !DILocation(line: 37, column: 5, scope: !102) +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} diff --git a/dartagnan/src/test/resources/locks/clh_mutex-acq2rx.ll b/dartagnan/src/test/resources/locks/clh_mutex-acq2rx.ll index b877475236..7150033a85 100644 --- a/dartagnan/src/test/resources/locks/clh_mutex-acq2rx.ll +++ b/dartagnan/src/test/resources/locks/clh_mutex-acq2rx.ll @@ -1,5 +1,5 @@ -; ModuleID = '/home/ponce/git/Dat3M/output/clh_mutex.ll' -source_filename = "/home/ponce/git/Dat3M/benchmarks/locks/clh_mutex.c" +; ModuleID = 'benchmarks/locks/clh_mutex.c' +source_filename = "benchmarks/locks/clh_mutex.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" @@ -7,370 +7,301 @@ target triple = "x86_64-pc-linux-gnu" %struct.clh_mutex_node_ = type { i32 } %union.pthread_attr_t = type { i64, [48 x i8] } -@sum = dso_local global i32 0, align 4, !dbg !0 -@lock = dso_local global %struct.clh_mutex_t zeroinitializer, align 8, !dbg !36 -@shared = dso_local global i32 0, align 4, !dbg !33 +@sum = dso_local global i32 0, align 4 +@lock = dso_local global %struct.clh_mutex_t zeroinitializer, align 8 +@shared = dso_local global i32 0, align 4 @.str = private unnamed_addr constant [11 x i8] c"r == index\00", align 1 -@.str.1 = private unnamed_addr constant [51 x i8] c"/home/ponce/git/Dat3M/benchmarks/locks/clh_mutex.c\00", align 1 +@.str.1 = private unnamed_addr constant [29 x i8] c"benchmarks/locks/clh_mutex.c\00", align 1 @__PRETTY_FUNCTION__.thread_n = private unnamed_addr constant [23 x i8] c"void *thread_n(void *)\00", align 1 @.str.2 = private unnamed_addr constant [16 x i8] c"sum == NTHREADS\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @clh_mutex_init(%struct.clh_mutex_t* noundef %0) #0 !dbg !56 { - call void @llvm.dbg.value(metadata %struct.clh_mutex_t* %0, metadata !61, metadata !DIExpression()), !dbg !62 - %2 = call %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef 0), !dbg !63 - call void @llvm.dbg.value(metadata %struct.clh_mutex_node_* %2, metadata !64, metadata !DIExpression()), !dbg !62 - %3 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 0, !dbg !65 - store %struct.clh_mutex_node_* %2, %struct.clh_mutex_node_** %3, align 8, !dbg !66 - %4 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 2, !dbg !67 - store %struct.clh_mutex_node_* %2, %struct.clh_mutex_node_** %4, align 8, !dbg !68 - ret void, !dbg !69 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @clh_mutex_init(%struct.clh_mutex_t* noundef %0) #0 { + %2 = alloca %struct.clh_mutex_t*, align 8 + %3 = alloca %struct.clh_mutex_node_*, align 8 + store %struct.clh_mutex_t* %0, %struct.clh_mutex_t** %2, align 8 + %4 = call %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef 0) + store %struct.clh_mutex_node_* %4, %struct.clh_mutex_node_** %3, align 8 + %5 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + %6 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %7 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %6, i32 0, i32 0 + store %struct.clh_mutex_node_* %5, %struct.clh_mutex_node_** %7, align 8 + %8 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %9 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %8, i32 0, i32 2 + %10 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + store %struct.clh_mutex_node_* %10, %struct.clh_mutex_node_** %9, align 8 + ret void } -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - -; Function Attrs: noinline nounwind uwtable -define internal %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef %0) #0 !dbg !70 { - call void @llvm.dbg.value(metadata i32 %0, metadata !73, metadata !DIExpression()), !dbg !74 - %2 = call noalias i8* @malloc(i64 noundef 4) #5, !dbg !75 - %3 = bitcast i8* %2 to %struct.clh_mutex_node_*, !dbg !76 - call void @llvm.dbg.value(metadata %struct.clh_mutex_node_* %3, metadata !77, metadata !DIExpression()), !dbg !74 - %4 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %3, i32 0, i32 0, !dbg !78 - store i32 %0, i32* %4, align 4, !dbg !79 - ret %struct.clh_mutex_node_* %3, !dbg !80 +; Function Attrs: noinline nounwind optnone uwtable +define internal %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef %0) #0 { + %2 = alloca i32, align 4 + %3 = alloca %struct.clh_mutex_node_*, align 8 + store i32 %0, i32* %2, align 4 + %4 = call noalias i8* @malloc(i64 noundef 4) #4 + %5 = bitcast i8* %4 to %struct.clh_mutex_node_* + store %struct.clh_mutex_node_* %5, %struct.clh_mutex_node_** %3, align 8 + %6 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + %7 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %6, i32 0, i32 0 + %8 = load i32, i32* %2, align 4 + store i32 %8, i32* %7, align 4 + %9 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + ret %struct.clh_mutex_node_* %9 } -; Function Attrs: noinline nounwind uwtable -define dso_local void @clh_mutex_destroy(%struct.clh_mutex_t* noundef %0) #0 !dbg !81 { - call void @llvm.dbg.value(metadata %struct.clh_mutex_t* %0, metadata !82, metadata !DIExpression()), !dbg !83 - %2 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 2, !dbg !84 - %3 = bitcast %struct.clh_mutex_node_** %2 to i64*, !dbg !84 - %4 = load atomic i64, i64* %3 seq_cst, align 8, !dbg !84 - %5 = inttoptr i64 %4 to %struct.clh_mutex_node_*, !dbg !84 - %6 = bitcast %struct.clh_mutex_node_* %5 to i8*, !dbg !84 - call void @free(i8* noundef %6) #5, !dbg !85 - ret void, !dbg !86 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @clh_mutex_destroy(%struct.clh_mutex_t* noundef %0) #0 { + %2 = alloca %struct.clh_mutex_t*, align 8 + %3 = alloca %struct.clh_mutex_node_*, align 8 + store %struct.clh_mutex_t* %0, %struct.clh_mutex_t** %2, align 8 + %4 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %5 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %4, i32 0, i32 2 + %6 = bitcast %struct.clh_mutex_node_** %5 to i64* + %7 = bitcast %struct.clh_mutex_node_** %3 to i64* + %8 = load atomic i64, i64* %6 seq_cst, align 8 + store i64 %8, i64* %7, align 8 + %9 = bitcast i64* %7 to %struct.clh_mutex_node_** + %10 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %9, align 8 + %11 = bitcast %struct.clh_mutex_node_* %10 to i8* + call void @free(i8* noundef %11) #4 + ret void } ; Function Attrs: nounwind -declare void @free(i8* noundef) #2 - -; Function Attrs: noinline nounwind uwtable -define dso_local void @clh_mutex_lock(%struct.clh_mutex_t* noundef %0) #0 !dbg !87 { - call void @llvm.dbg.value(metadata %struct.clh_mutex_t* %0, metadata !88, metadata !DIExpression()), !dbg !89 - %2 = call %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef 1), !dbg !90 - call void @llvm.dbg.value(metadata %struct.clh_mutex_node_* %2, metadata !91, metadata !DIExpression()), !dbg !89 - %3 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 2, !dbg !92 - %4 = bitcast %struct.clh_mutex_node_** %3 to i64*, !dbg !92 - %5 = ptrtoint %struct.clh_mutex_node_* %2 to i64, !dbg !92 - %6 = atomicrmw xchg i64* %4, i64 %5 seq_cst, align 8, !dbg !92 - %7 = inttoptr i64 %6 to %struct.clh_mutex_node_*, !dbg !92 - call void @llvm.dbg.value(metadata %struct.clh_mutex_node_* %7, metadata !93, metadata !DIExpression()), !dbg !89 - %8 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %7, i32 0, i32 0, !dbg !94 - %9 = load atomic i32, i32* %8 monotonic, align 4, !dbg !95 - call void @llvm.dbg.value(metadata i32 %9, metadata !96, metadata !DIExpression()), !dbg !89 - %10 = icmp ne i32 %9, 0, !dbg !97 - br i1 %10, label %11, label %15, !dbg !99 - -11: ; preds = %1, %13 - %.0 = phi i32 [ %14, %13 ], [ %9, %1 ], !dbg !89 - call void @llvm.dbg.value(metadata i32 %.0, metadata !96, metadata !DIExpression()), !dbg !89 - %12 = icmp ne i32 %.0, 0, !dbg !100 - br i1 %12, label %13, label %15, !dbg !100 - -13: ; preds = %11 - %14 = load atomic i32, i32* %8 acquire, align 4, !dbg !102 - call void @llvm.dbg.value(metadata i32 %14, metadata !96, metadata !DIExpression()), !dbg !89 - br label %11, !dbg !100, !llvm.loop !104 - -15: ; preds = %11, %1 - %16 = bitcast %struct.clh_mutex_node_* %7 to i8*, !dbg !107 - call void @free(i8* noundef %16) #5, !dbg !108 - %17 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 0, !dbg !109 - store %struct.clh_mutex_node_* %2, %struct.clh_mutex_node_** %17, align 8, !dbg !110 - ret void, !dbg !111 +declare void @free(i8* noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @clh_mutex_lock(%struct.clh_mutex_t* noundef %0) #0 { + %2 = alloca %struct.clh_mutex_t*, align 8 + %3 = alloca %struct.clh_mutex_node_*, align 8 + %4 = alloca %struct.clh_mutex_node_*, align 8 + %5 = alloca %struct.clh_mutex_node_*, align 8 + %6 = alloca %struct.clh_mutex_node_*, align 8 + %7 = alloca i32, align 4 + %8 = alloca i32, align 4 + %9 = alloca i32, align 4 + store %struct.clh_mutex_t* %0, %struct.clh_mutex_t** %2, align 8 + %10 = call %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef 1) + store %struct.clh_mutex_node_* %10, %struct.clh_mutex_node_** %3, align 8 + %11 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %12 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %11, i32 0, i32 2 + %13 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + store %struct.clh_mutex_node_* %13, %struct.clh_mutex_node_** %5, align 8 + %14 = bitcast %struct.clh_mutex_node_** %12 to i64* + %15 = bitcast %struct.clh_mutex_node_** %5 to i64* + %16 = bitcast %struct.clh_mutex_node_** %6 to i64* + %17 = load i64, i64* %15, align 8 + %18 = atomicrmw xchg i64* %14, i64 %17 seq_cst, align 8 + store i64 %18, i64* %16, align 8 + %19 = bitcast i64* %16 to %struct.clh_mutex_node_** + %20 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %19, align 8 + store %struct.clh_mutex_node_* %20, %struct.clh_mutex_node_** %4, align 8 + %21 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %4, align 8 + %22 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %21, i32 0, i32 0 + %23 = load atomic i32, i32* %22 monotonic, align 4 + store i32 %23, i32* %8, align 4 + %24 = load i32, i32* %8, align 4 + store i32 %24, i32* %7, align 4 + %25 = load i32, i32* %7, align 4 + %26 = icmp ne i32 %25, 0 + br i1 %26, label %27, label %37 + +27: ; preds = %1 + br label %28 + +28: ; preds = %31, %27 + %29 = load i32, i32* %7, align 4 + %30 = icmp ne i32 %29, 0 + br i1 %30, label %31, label %36 + +31: ; preds = %28 + %32 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %4, align 8 + %33 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %32, i32 0, i32 0 + %34 = load atomic i32, i32* %33 acquire, align 4 + store i32 %34, i32* %9, align 4 + %35 = load i32, i32* %9, align 4 + store i32 %35, i32* %7, align 4 + br label %28, !llvm.loop !6 + +36: ; preds = %28 + br label %37 + +37: ; preds = %36, %1 + %38 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %4, align 8 + %39 = bitcast %struct.clh_mutex_node_* %38 to i8* + call void @free(i8* noundef %39) #4 + %40 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + %41 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %42 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %41, i32 0, i32 0 + store %struct.clh_mutex_node_* %40, %struct.clh_mutex_node_** %42, align 8 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local void @clh_mutex_unlock(%struct.clh_mutex_t* noundef %0) #0 !dbg !112 { - call void @llvm.dbg.value(metadata %struct.clh_mutex_t* %0, metadata !113, metadata !DIExpression()), !dbg !114 - %2 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 0, !dbg !115 - %3 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %2, align 8, !dbg !115 - %4 = icmp eq %struct.clh_mutex_node_* %3, null, !dbg !117 - br i1 %4, label %7, label %5, !dbg !118 - -5: ; preds = %1 - %6 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %3, i32 0, i32 0, !dbg !119 - store atomic i32 0, i32* %6 release, align 4, !dbg !120 - br label %7, !dbg !121 - -7: ; preds = %1, %5 - ret void, !dbg !121 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @clh_mutex_unlock(%struct.clh_mutex_t* noundef %0) #0 { + %2 = alloca %struct.clh_mutex_t*, align 8 + %3 = alloca i32, align 4 + store %struct.clh_mutex_t* %0, %struct.clh_mutex_t** %2, align 8 + %4 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %5 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %4, i32 0, i32 0 + %6 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %5, align 8 + %7 = icmp eq %struct.clh_mutex_node_* %6, null + br i1 %7, label %8, label %9 + +8: ; preds = %1 + br label %15 + +9: ; preds = %1 + %10 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %11 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %10, i32 0, i32 0 + %12 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %11, align 8 + %13 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %12, i32 0, i32 0 + store i32 0, i32* %3, align 4 + %14 = load i32, i32* %3, align 4 + store atomic i32 %14, i32* %13 release, align 4 + br label %15 + +15: ; preds = %9, %8 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_n(i8* noundef %0) #0 !dbg !122 { - call void @llvm.dbg.value(metadata i8* %0, metadata !125, metadata !DIExpression()), !dbg !126 - %2 = ptrtoint i8* %0 to i64, !dbg !127 - call void @llvm.dbg.value(metadata i64 %2, metadata !128, metadata !DIExpression()), !dbg !126 - call void @clh_mutex_lock(%struct.clh_mutex_t* noundef @lock), !dbg !129 - %3 = trunc i64 %2 to i32, !dbg !130 - store i32 %3, i32* @shared, align 4, !dbg !131 - call void @llvm.dbg.value(metadata i32 %3, metadata !132, metadata !DIExpression()), !dbg !126 - %4 = sext i32 %3 to i64, !dbg !133 - %5 = icmp eq i64 %4, %2, !dbg !133 - br i1 %5, label %7, label %6, !dbg !136 - -6: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([51 x i8], [51 x i8]* @.str.1, i64 0, i64 0), i32 noundef 20, i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @__PRETTY_FUNCTION__.thread_n, i64 0, i64 0)) #6, !dbg !133 - unreachable, !dbg !133 - -7: ; preds = %1 - %8 = load i32, i32* @sum, align 4, !dbg !137 - %9 = add nsw i32 %8, 1, !dbg !137 - store i32 %9, i32* @sum, align 4, !dbg !137 - call void @clh_mutex_unlock(%struct.clh_mutex_t* noundef @lock), !dbg !138 - ret i8* null, !dbg !139 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @thread_n(i8* noundef %0) #0 { + %2 = alloca i8*, align 8 + %3 = alloca i64, align 8 + %4 = alloca i32, align 4 + store i8* %0, i8** %2, align 8 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + call void @clh_mutex_lock(%struct.clh_mutex_t* noundef @lock) + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + store i32 %8, i32* @shared, align 4 + %9 = load i32, i32* @shared, align 4 + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = sext i32 %10 to i64 + %12 = load i64, i64* %3, align 8 + %13 = icmp eq i64 %11, %12 + br i1 %13, label %14, label %15 + +14: ; preds = %1 + br label %16 + +15: ; preds = %1 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([29 x i8], [29 x i8]* @.str.1, i64 0, i64 0), i32 noundef 20, i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @__PRETTY_FUNCTION__.thread_n, i64 0, i64 0)) #5 + unreachable + +16: ; preds = %14 + %17 = load i32, i32* @sum, align 4 + %18 = add nsw i32 %17, 1 + store i32 %18, i32* @sum, align 4 + call void @clh_mutex_unlock(%struct.clh_mutex_t* noundef @lock) + ret i8* null } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !140 { - %1 = alloca [3 x i64], align 16 - call void @llvm.dbg.declare(metadata [3 x i64]* %1, metadata !143, metadata !DIExpression()), !dbg !149 - call void @clh_mutex_init(%struct.clh_mutex_t* noundef @lock), !dbg !150 - call void @llvm.dbg.value(metadata i32 0, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i64 0, metadata !151, metadata !DIExpression()), !dbg !153 - %2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0, !dbg !154 - %3 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef null) #5, !dbg !156 - call void @llvm.dbg.value(metadata i64 1, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i64 1, metadata !151, metadata !DIExpression()), !dbg !153 - %4 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1, !dbg !154 - %5 = call i32 @pthread_create(i64* noundef %4, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef inttoptr (i64 1 to i8*)) #5, !dbg !156 - call void @llvm.dbg.value(metadata i64 2, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i64 2, metadata !151, metadata !DIExpression()), !dbg !153 - %6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2, !dbg !154 - %7 = call i32 @pthread_create(i64* noundef %6, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef inttoptr (i64 2 to i8*)) #5, !dbg !156 - call void @llvm.dbg.value(metadata i64 3, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i64 3, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i32 0, metadata !157, metadata !DIExpression()), !dbg !159 - call void @llvm.dbg.value(metadata i64 0, metadata !157, metadata !DIExpression()), !dbg !159 - %8 = load i64, i64* %2, align 8, !dbg !160 - %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !162 - call void @llvm.dbg.value(metadata i64 1, metadata !157, metadata !DIExpression()), !dbg !159 - call void @llvm.dbg.value(metadata i64 1, metadata !157, metadata !DIExpression()), !dbg !159 - %10 = load i64, i64* %4, align 8, !dbg !160 - %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !162 - call void @llvm.dbg.value(metadata i64 2, metadata !157, metadata !DIExpression()), !dbg !159 - call void @llvm.dbg.value(metadata i64 2, metadata !157, metadata !DIExpression()), !dbg !159 - %12 = load i64, i64* %6, align 8, !dbg !160 - %13 = call i32 @pthread_join(i64 noundef %12, i8** noundef null), !dbg !162 - call void @llvm.dbg.value(metadata i64 3, metadata !157, metadata !DIExpression()), !dbg !159 - call void @llvm.dbg.value(metadata i64 3, metadata !157, metadata !DIExpression()), !dbg !159 - %14 = load i32, i32* @sum, align 4, !dbg !163 - %15 = icmp eq i32 %14, 3, !dbg !163 - br i1 %15, label %17, label %16, !dbg !166 - -16: ; preds = %0 - call void @__assert_fail(i8* noundef getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([51 x i8], [51 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !163 - unreachable, !dbg !163 - -17: ; preds = %0 - ret i32 0, !dbg !167 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca [3 x i64], align 16 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + call void @clh_mutex_init(%struct.clh_mutex_t* noundef @lock) + store i32 0, i32* %3, align 4 + br label %5 + +5: ; preds = %16, %0 + %6 = load i32, i32* %3, align 4 + %7 = icmp slt i32 %6, 3 + br i1 %7, label %8, label %19 + +8: ; preds = %5 + %9 = load i32, i32* %3, align 4 + %10 = sext i32 %9 to i64 + %11 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %10 + %12 = load i32, i32* %3, align 4 + %13 = sext i32 %12 to i64 + %14 = inttoptr i64 %13 to i8* + %15 = call i32 @pthread_create(i64* noundef %11, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef %14) #4 + br label %16 + +16: ; preds = %8 + %17 = load i32, i32* %3, align 4 + %18 = add nsw i32 %17, 1 + store i32 %18, i32* %3, align 4 + br label %5, !llvm.loop !8 + +19: ; preds = %5 + store i32 0, i32* %4, align 4 + br label %20 + +20: ; preds = %29, %19 + %21 = load i32, i32* %4, align 4 + %22 = icmp slt i32 %21, 3 + br i1 %22, label %23, label %32 + +23: ; preds = %20 + %24 = load i32, i32* %4, align 4 + %25 = sext i32 %24 to i64 + %26 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %25 + %27 = load i64, i64* %26, align 8 + %28 = call i32 @pthread_join(i64 noundef %27, i8** noundef null) + br label %29 + +29: ; preds = %23 + %30 = load i32, i32* %4, align 4 + %31 = add nsw i32 %30, 1 + store i32 %31, i32* %4, align 4 + br label %20, !llvm.loop !9 + +32: ; preds = %20 + %33 = load i32, i32* @sum, align 4 + %34 = icmp eq i32 %33, 3 + br i1 %34, label %35, label %36 + +35: ; preds = %32 + br label %37 + +36: ; preds = %32 + call void @__assert_fail(i8* noundef getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([29 x i8], [29 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable + +37: ; preds = %35 + call void @clh_mutex_destroy(%struct.clh_mutex_t* noundef @lock) + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 -declare i32 @pthread_join(i64 noundef, i8** noundef) #4 +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 - -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.value(metadata, metadata, metadata) #1 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!48, !49, !50, !51, !52, !53, !54} -!llvm.ident = !{!55} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "sum", scope: !2, file: !35, line: 11, type: !31, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.6", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !15, globals: !32, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "/home/ponce/git/Dat3M/benchmarks/locks/clh_mutex.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "3ad3285fca566d9de137b5cd10f9f38c") -!4 = !{!5} -!5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "memory_order", file: !6, line: 56, baseType: !7, size: 32, elements: !8) -!6 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stdatomic.h", directory: "", checksumkind: CSK_MD5, checksum: "de5d66a1ef2f5448cc1919ff39db92bc") -!7 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!8 = !{!9, !10, !11, !12, !13, !14} -!9 = !DIEnumerator(name: "memory_order_relaxed", value: 0) -!10 = !DIEnumerator(name: "memory_order_consume", value: 1) -!11 = !DIEnumerator(name: "memory_order_acquire", value: 2) -!12 = !DIEnumerator(name: "memory_order_release", value: 3) -!13 = !DIEnumerator(name: "memory_order_acq_rel", value: 4) -!14 = !DIEnumerator(name: "memory_order_seq_cst", value: 5) -!15 = !{!16, !17, !20, !23} -!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !18, line: 87, baseType: !19) -!18 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "24103e292ae21916e87130b926c8d2f8") -!19 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !21, line: 46, baseType: !22) -!21 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!22 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64) -!24 = !DIDerivedType(tag: DW_TAG_typedef, name: "clh_mutex_node_t", file: !25, line: 74, baseType: !26) -!25 = !DIFile(filename: "benchmarks/locks/clh_mutex.h", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "d88c40a0440b1421c9a593b20ac5ab10") -!26 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "clh_mutex_node_", file: !25, line: 76, size: 32, elements: !27) -!27 = !{!28} -!28 = !DIDerivedType(tag: DW_TAG_member, name: "succ_must_wait", scope: !26, file: !25, line: 78, baseType: !29, size: 32) -!29 = !DIDerivedType(tag: DW_TAG_typedef, name: "atomic_int", file: !6, line: 92, baseType: !30) -!30 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !31) -!31 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!32 = !{!0, !33, !36} -!33 = !DIGlobalVariableExpression(var: !34, expr: !DIExpression()) -!34 = distinct !DIGlobalVariable(name: "shared", scope: !2, file: !35, line: 9, type: !31, isLocal: false, isDefinition: true) -!35 = !DIFile(filename: "benchmarks/locks/clh_mutex.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "3ad3285fca566d9de137b5cd10f9f38c") -!36 = !DIGlobalVariableExpression(var: !37, expr: !DIExpression()) -!37 = distinct !DIGlobalVariable(name: "lock", scope: !2, file: !35, line: 10, type: !38, isLocal: false, isDefinition: true) -!38 = !DIDerivedType(tag: DW_TAG_typedef, name: "clh_mutex_t", file: !25, line: 86, baseType: !39) -!39 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !25, line: 81, size: 2176, elements: !40) -!40 = !{!41, !42, !46} -!41 = !DIDerivedType(tag: DW_TAG_member, name: "mynode", scope: !39, file: !25, line: 83, baseType: !23, size: 64) -!42 = !DIDerivedType(tag: DW_TAG_member, name: "padding", scope: !39, file: !25, line: 84, baseType: !43, size: 2048, offset: 64) -!43 = !DICompositeType(tag: DW_TAG_array_type, baseType: !31, size: 2048, elements: !44) -!44 = !{!45} -!45 = !DISubrange(count: 64) -!46 = !DIDerivedType(tag: DW_TAG_member, name: "tail", scope: !39, file: !25, line: 85, baseType: !47, size: 64, offset: 2112) -!47 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !23) -!48 = !{i32 7, !"Dwarf Version", i32 5} -!49 = !{i32 2, !"Debug Info Version", i32 3} -!50 = !{i32 1, !"wchar_size", i32 4} -!51 = !{i32 7, !"PIC Level", i32 2} -!52 = !{i32 7, !"PIE Level", i32 2} -!53 = !{i32 7, !"uwtable", i32 1} -!54 = !{i32 7, !"frame-pointer", i32 2} -!55 = !{!"Ubuntu clang version 14.0.6"} -!56 = distinct !DISubprogram(name: "clh_mutex_init", scope: !25, file: !25, line: 101, type: !57, scopeLine: 102, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!57 = !DISubroutineType(types: !58) -!58 = !{null, !59} -!59 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !38, size: 64) -!60 = !{} -!61 = !DILocalVariable(name: "self", arg: 1, scope: !56, file: !25, line: 101, type: !59) -!62 = !DILocation(line: 0, scope: !56) -!63 = !DILocation(line: 104, column: 31, scope: !56) -!64 = !DILocalVariable(name: "node", scope: !56, file: !25, line: 104, type: !23) -!65 = !DILocation(line: 105, column: 11, scope: !56) -!66 = !DILocation(line: 105, column: 18, scope: !56) -!67 = !DILocation(line: 106, column: 24, scope: !56) -!68 = !DILocation(line: 106, column: 5, scope: !56) -!69 = !DILocation(line: 107, column: 1, scope: !56) -!70 = distinct !DISubprogram(name: "clh_mutex_create_node", scope: !25, file: !25, line: 88, type: !71, scopeLine: 89, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !2, retainedNodes: !60) -!71 = !DISubroutineType(types: !72) -!72 = !{!23, !31} -!73 = !DILocalVariable(name: "islocked", arg: 1, scope: !70, file: !25, line: 88, type: !31) -!74 = !DILocation(line: 0, scope: !70) -!75 = !DILocation(line: 90, column: 55, scope: !70) -!76 = !DILocation(line: 90, column: 35, scope: !70) -!77 = !DILocalVariable(name: "new_node", scope: !70, file: !25, line: 90, type: !23) -!78 = !DILocation(line: 91, column: 28, scope: !70) -!79 = !DILocation(line: 91, column: 5, scope: !70) -!80 = !DILocation(line: 92, column: 5, scope: !70) -!81 = distinct !DISubprogram(name: "clh_mutex_destroy", scope: !25, file: !25, line: 117, type: !57, scopeLine: 118, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!82 = !DILocalVariable(name: "self", arg: 1, scope: !81, file: !25, line: 117, type: !59) -!83 = !DILocation(line: 0, scope: !81) -!84 = !DILocation(line: 119, column: 10, scope: !81) -!85 = !DILocation(line: 119, column: 5, scope: !81) -!86 = !DILocation(line: 120, column: 1, scope: !81) -!87 = distinct !DISubprogram(name: "clh_mutex_lock", scope: !25, file: !25, line: 129, type: !57, scopeLine: 130, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!88 = !DILocalVariable(name: "self", arg: 1, scope: !87, file: !25, line: 129, type: !59) -!89 = !DILocation(line: 0, scope: !87) -!90 = !DILocation(line: 132, column: 32, scope: !87) -!91 = !DILocalVariable(name: "mynode", scope: !87, file: !25, line: 132, type: !23) -!92 = !DILocation(line: 133, column: 30, scope: !87) -!93 = !DILocalVariable(name: "prev", scope: !87, file: !25, line: 133, type: !23) -!94 = !DILocation(line: 138, column: 53, scope: !87) -!95 = !DILocation(line: 138, column: 25, scope: !87) -!96 = !DILocalVariable(name: "prev_islocked", scope: !87, file: !25, line: 138, type: !31) -!97 = !DILocation(line: 142, column: 9, scope: !98) -!98 = distinct !DILexicalBlock(scope: !87, file: !25, line: 142, column: 9) -!99 = !DILocation(line: 142, column: 9, scope: !87) -!100 = !DILocation(line: 143, column: 9, scope: !101) -!101 = distinct !DILexicalBlock(scope: !98, file: !25, line: 142, column: 24) -!102 = !DILocation(line: 144, column: 29, scope: !103) -!103 = distinct !DILexicalBlock(scope: !101, file: !25, line: 143, column: 31) -!104 = distinct !{!104, !100, !105, !106} -!105 = !DILocation(line: 145, column: 9, scope: !101) -!106 = !{!"llvm.loop.mustprogress"} -!107 = !DILocation(line: 149, column: 10, scope: !87) -!108 = !DILocation(line: 149, column: 5, scope: !87) -!109 = !DILocation(line: 153, column: 11, scope: !87) -!110 = !DILocation(line: 153, column: 18, scope: !87) -!111 = !DILocation(line: 154, column: 1, scope: !87) -!112 = distinct !DISubprogram(name: "clh_mutex_unlock", scope: !25, file: !25, line: 163, type: !57, scopeLine: 164, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!113 = !DILocalVariable(name: "self", arg: 1, scope: !112, file: !25, line: 163, type: !59) -!114 = !DILocation(line: 0, scope: !112) -!115 = !DILocation(line: 168, column: 15, scope: !116) -!116 = distinct !DILexicalBlock(scope: !112, file: !25, line: 168, column: 9) -!117 = !DILocation(line: 168, column: 22, scope: !116) -!118 = !DILocation(line: 168, column: 9, scope: !112) -!119 = !DILocation(line: 172, column: 42, scope: !112) -!120 = !DILocation(line: 172, column: 5, scope: !112) -!121 = !DILocation(line: 173, column: 1, scope: !112) -!122 = distinct !DISubprogram(name: "thread_n", scope: !35, file: !35, line: 13, type: !123, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!123 = !DISubroutineType(types: !124) -!124 = !{!16, !16} -!125 = !DILocalVariable(name: "arg", arg: 1, scope: !122, file: !35, line: 13, type: !16) -!126 = !DILocation(line: 0, scope: !122) -!127 = !DILocation(line: 15, column: 23, scope: !122) -!128 = !DILocalVariable(name: "index", scope: !122, file: !35, line: 15, type: !17) -!129 = !DILocation(line: 17, column: 5, scope: !122) -!130 = !DILocation(line: 18, column: 14, scope: !122) -!131 = !DILocation(line: 18, column: 12, scope: !122) -!132 = !DILocalVariable(name: "r", scope: !122, file: !35, line: 19, type: !31) -!133 = !DILocation(line: 20, column: 5, scope: !134) -!134 = distinct !DILexicalBlock(scope: !135, file: !35, line: 20, column: 5) -!135 = distinct !DILexicalBlock(scope: !122, file: !35, line: 20, column: 5) -!136 = !DILocation(line: 20, column: 5, scope: !135) -!137 = !DILocation(line: 21, column: 8, scope: !122) -!138 = !DILocation(line: 22, column: 5, scope: !122) -!139 = !DILocation(line: 23, column: 5, scope: !122) -!140 = distinct !DISubprogram(name: "main", scope: !35, file: !35, line: 26, type: !141, scopeLine: 27, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!141 = !DISubroutineType(types: !142) -!142 = !{!31} -!143 = !DILocalVariable(name: "t", scope: !140, file: !35, line: 28, type: !144) -!144 = !DICompositeType(tag: DW_TAG_array_type, baseType: !145, size: 192, elements: !147) -!145 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !146, line: 27, baseType: !22) -!146 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "2d764266ce95ab26d4a4767c2ec78176") -!147 = !{!148} -!148 = !DISubrange(count: 3) -!149 = !DILocation(line: 28, column: 15, scope: !140) -!150 = !DILocation(line: 30, column: 5, scope: !140) -!151 = !DILocalVariable(name: "i", scope: !152, file: !35, line: 32, type: !31) -!152 = distinct !DILexicalBlock(scope: !140, file: !35, line: 32, column: 5) -!153 = !DILocation(line: 0, scope: !152) -!154 = !DILocation(line: 33, column: 25, scope: !155) -!155 = distinct !DILexicalBlock(scope: !152, file: !35, line: 32, column: 5) -!156 = !DILocation(line: 33, column: 9, scope: !155) -!157 = !DILocalVariable(name: "i", scope: !158, file: !35, line: 35, type: !31) -!158 = distinct !DILexicalBlock(scope: !140, file: !35, line: 35, column: 5) -!159 = !DILocation(line: 0, scope: !158) -!160 = !DILocation(line: 36, column: 22, scope: !161) -!161 = distinct !DILexicalBlock(scope: !158, file: !35, line: 35, column: 5) -!162 = !DILocation(line: 36, column: 9, scope: !161) -!163 = !DILocation(line: 38, column: 5, scope: !164) -!164 = distinct !DILexicalBlock(scope: !165, file: !35, line: 38, column: 5) -!165 = distinct !DILexicalBlock(scope: !140, file: !35, line: 38, column: 5) -!166 = !DILocation(line: 38, column: 5, scope: !165) -!167 = !DILocation(line: 40, column: 5, scope: !140) +declare noalias i8* @malloc(i64 noundef) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} +!9 = distinct !{!9, !7} diff --git a/dartagnan/src/test/resources/locks/clh_mutex.ll b/dartagnan/src/test/resources/locks/clh_mutex.ll index d9a81064dc..452cc53e4d 100644 --- a/dartagnan/src/test/resources/locks/clh_mutex.ll +++ b/dartagnan/src/test/resources/locks/clh_mutex.ll @@ -1,5 +1,5 @@ -; ModuleID = '/home/ponce/git/Dat3M/output/clh_mutex.ll' -source_filename = "/home/ponce/git/Dat3M/benchmarks/locks/clh_mutex.c" +; ModuleID = 'benchmarks/locks/clh_mutex.c' +source_filename = "benchmarks/locks/clh_mutex.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" @@ -7,370 +7,301 @@ target triple = "x86_64-pc-linux-gnu" %struct.clh_mutex_node_ = type { i32 } %union.pthread_attr_t = type { i64, [48 x i8] } -@sum = dso_local global i32 0, align 4, !dbg !0 -@lock = dso_local global %struct.clh_mutex_t zeroinitializer, align 8, !dbg !36 -@shared = dso_local global i32 0, align 4, !dbg !33 +@sum = dso_local global i32 0, align 4 +@lock = dso_local global %struct.clh_mutex_t zeroinitializer, align 8 +@shared = dso_local global i32 0, align 4 @.str = private unnamed_addr constant [11 x i8] c"r == index\00", align 1 -@.str.1 = private unnamed_addr constant [51 x i8] c"/home/ponce/git/Dat3M/benchmarks/locks/clh_mutex.c\00", align 1 +@.str.1 = private unnamed_addr constant [29 x i8] c"benchmarks/locks/clh_mutex.c\00", align 1 @__PRETTY_FUNCTION__.thread_n = private unnamed_addr constant [23 x i8] c"void *thread_n(void *)\00", align 1 @.str.2 = private unnamed_addr constant [16 x i8] c"sum == NTHREADS\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @clh_mutex_init(%struct.clh_mutex_t* noundef %0) #0 !dbg !56 { - call void @llvm.dbg.value(metadata %struct.clh_mutex_t* %0, metadata !61, metadata !DIExpression()), !dbg !62 - %2 = call %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef 0), !dbg !63 - call void @llvm.dbg.value(metadata %struct.clh_mutex_node_* %2, metadata !64, metadata !DIExpression()), !dbg !62 - %3 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 0, !dbg !65 - store %struct.clh_mutex_node_* %2, %struct.clh_mutex_node_** %3, align 8, !dbg !66 - %4 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 2, !dbg !67 - store %struct.clh_mutex_node_* %2, %struct.clh_mutex_node_** %4, align 8, !dbg !68 - ret void, !dbg !69 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @clh_mutex_init(%struct.clh_mutex_t* noundef %0) #0 { + %2 = alloca %struct.clh_mutex_t*, align 8 + %3 = alloca %struct.clh_mutex_node_*, align 8 + store %struct.clh_mutex_t* %0, %struct.clh_mutex_t** %2, align 8 + %4 = call %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef 0) + store %struct.clh_mutex_node_* %4, %struct.clh_mutex_node_** %3, align 8 + %5 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + %6 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %7 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %6, i32 0, i32 0 + store %struct.clh_mutex_node_* %5, %struct.clh_mutex_node_** %7, align 8 + %8 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %9 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %8, i32 0, i32 2 + %10 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + store %struct.clh_mutex_node_* %10, %struct.clh_mutex_node_** %9, align 8 + ret void } -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - -; Function Attrs: noinline nounwind uwtable -define internal %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef %0) #0 !dbg !70 { - call void @llvm.dbg.value(metadata i32 %0, metadata !73, metadata !DIExpression()), !dbg !74 - %2 = call noalias i8* @malloc(i64 noundef 4) #5, !dbg !75 - %3 = bitcast i8* %2 to %struct.clh_mutex_node_*, !dbg !76 - call void @llvm.dbg.value(metadata %struct.clh_mutex_node_* %3, metadata !77, metadata !DIExpression()), !dbg !74 - %4 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %3, i32 0, i32 0, !dbg !78 - store i32 %0, i32* %4, align 4, !dbg !79 - ret %struct.clh_mutex_node_* %3, !dbg !80 +; Function Attrs: noinline nounwind optnone uwtable +define internal %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef %0) #0 { + %2 = alloca i32, align 4 + %3 = alloca %struct.clh_mutex_node_*, align 8 + store i32 %0, i32* %2, align 4 + %4 = call noalias i8* @malloc(i64 noundef 4) #4 + %5 = bitcast i8* %4 to %struct.clh_mutex_node_* + store %struct.clh_mutex_node_* %5, %struct.clh_mutex_node_** %3, align 8 + %6 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + %7 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %6, i32 0, i32 0 + %8 = load i32, i32* %2, align 4 + store i32 %8, i32* %7, align 4 + %9 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + ret %struct.clh_mutex_node_* %9 } -; Function Attrs: noinline nounwind uwtable -define dso_local void @clh_mutex_destroy(%struct.clh_mutex_t* noundef %0) #0 !dbg !81 { - call void @llvm.dbg.value(metadata %struct.clh_mutex_t* %0, metadata !82, metadata !DIExpression()), !dbg !83 - %2 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 2, !dbg !84 - %3 = bitcast %struct.clh_mutex_node_** %2 to i64*, !dbg !84 - %4 = load atomic i64, i64* %3 seq_cst, align 8, !dbg !84 - %5 = inttoptr i64 %4 to %struct.clh_mutex_node_*, !dbg !84 - %6 = bitcast %struct.clh_mutex_node_* %5 to i8*, !dbg !84 - call void @free(i8* noundef %6) #5, !dbg !85 - ret void, !dbg !86 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @clh_mutex_destroy(%struct.clh_mutex_t* noundef %0) #0 { + %2 = alloca %struct.clh_mutex_t*, align 8 + %3 = alloca %struct.clh_mutex_node_*, align 8 + store %struct.clh_mutex_t* %0, %struct.clh_mutex_t** %2, align 8 + %4 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %5 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %4, i32 0, i32 2 + %6 = bitcast %struct.clh_mutex_node_** %5 to i64* + %7 = bitcast %struct.clh_mutex_node_** %3 to i64* + %8 = load atomic i64, i64* %6 seq_cst, align 8 + store i64 %8, i64* %7, align 8 + %9 = bitcast i64* %7 to %struct.clh_mutex_node_** + %10 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %9, align 8 + %11 = bitcast %struct.clh_mutex_node_* %10 to i8* + call void @free(i8* noundef %11) #4 + ret void } ; Function Attrs: nounwind -declare void @free(i8* noundef) #2 - -; Function Attrs: noinline nounwind uwtable -define dso_local void @clh_mutex_lock(%struct.clh_mutex_t* noundef %0) #0 !dbg !87 { - call void @llvm.dbg.value(metadata %struct.clh_mutex_t* %0, metadata !88, metadata !DIExpression()), !dbg !89 - %2 = call %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef 1), !dbg !90 - call void @llvm.dbg.value(metadata %struct.clh_mutex_node_* %2, metadata !91, metadata !DIExpression()), !dbg !89 - %3 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 2, !dbg !92 - %4 = bitcast %struct.clh_mutex_node_** %3 to i64*, !dbg !92 - %5 = ptrtoint %struct.clh_mutex_node_* %2 to i64, !dbg !92 - %6 = atomicrmw xchg i64* %4, i64 %5 seq_cst, align 8, !dbg !92 - %7 = inttoptr i64 %6 to %struct.clh_mutex_node_*, !dbg !92 - call void @llvm.dbg.value(metadata %struct.clh_mutex_node_* %7, metadata !93, metadata !DIExpression()), !dbg !89 - %8 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %7, i32 0, i32 0, !dbg !94 - %9 = load atomic i32, i32* %8 acquire, align 4, !dbg !95 - call void @llvm.dbg.value(metadata i32 %9, metadata !96, metadata !DIExpression()), !dbg !89 - %10 = icmp ne i32 %9, 0, !dbg !97 - br i1 %10, label %11, label %15, !dbg !99 - -11: ; preds = %1, %13 - %.0 = phi i32 [ %14, %13 ], [ %9, %1 ], !dbg !89 - call void @llvm.dbg.value(metadata i32 %.0, metadata !96, metadata !DIExpression()), !dbg !89 - %12 = icmp ne i32 %.0, 0, !dbg !100 - br i1 %12, label %13, label %15, !dbg !100 - -13: ; preds = %11 - %14 = load atomic i32, i32* %8 acquire, align 4, !dbg !102 - call void @llvm.dbg.value(metadata i32 %14, metadata !96, metadata !DIExpression()), !dbg !89 - br label %11, !dbg !100, !llvm.loop !104 - -15: ; preds = %11, %1 - %16 = bitcast %struct.clh_mutex_node_* %7 to i8*, !dbg !107 - call void @free(i8* noundef %16) #5, !dbg !108 - %17 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 0, !dbg !109 - store %struct.clh_mutex_node_* %2, %struct.clh_mutex_node_** %17, align 8, !dbg !110 - ret void, !dbg !111 +declare void @free(i8* noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @clh_mutex_lock(%struct.clh_mutex_t* noundef %0) #0 { + %2 = alloca %struct.clh_mutex_t*, align 8 + %3 = alloca %struct.clh_mutex_node_*, align 8 + %4 = alloca %struct.clh_mutex_node_*, align 8 + %5 = alloca %struct.clh_mutex_node_*, align 8 + %6 = alloca %struct.clh_mutex_node_*, align 8 + %7 = alloca i32, align 4 + %8 = alloca i32, align 4 + %9 = alloca i32, align 4 + store %struct.clh_mutex_t* %0, %struct.clh_mutex_t** %2, align 8 + %10 = call %struct.clh_mutex_node_* @clh_mutex_create_node(i32 noundef 1) + store %struct.clh_mutex_node_* %10, %struct.clh_mutex_node_** %3, align 8 + %11 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %12 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %11, i32 0, i32 2 + %13 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + store %struct.clh_mutex_node_* %13, %struct.clh_mutex_node_** %5, align 8 + %14 = bitcast %struct.clh_mutex_node_** %12 to i64* + %15 = bitcast %struct.clh_mutex_node_** %5 to i64* + %16 = bitcast %struct.clh_mutex_node_** %6 to i64* + %17 = load i64, i64* %15, align 8 + %18 = atomicrmw xchg i64* %14, i64 %17 seq_cst, align 8 + store i64 %18, i64* %16, align 8 + %19 = bitcast i64* %16 to %struct.clh_mutex_node_** + %20 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %19, align 8 + store %struct.clh_mutex_node_* %20, %struct.clh_mutex_node_** %4, align 8 + %21 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %4, align 8 + %22 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %21, i32 0, i32 0 + %23 = load atomic i32, i32* %22 acquire, align 4 + store i32 %23, i32* %8, align 4 + %24 = load i32, i32* %8, align 4 + store i32 %24, i32* %7, align 4 + %25 = load i32, i32* %7, align 4 + %26 = icmp ne i32 %25, 0 + br i1 %26, label %27, label %37 + +27: ; preds = %1 + br label %28 + +28: ; preds = %31, %27 + %29 = load i32, i32* %7, align 4 + %30 = icmp ne i32 %29, 0 + br i1 %30, label %31, label %36 + +31: ; preds = %28 + %32 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %4, align 8 + %33 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %32, i32 0, i32 0 + %34 = load atomic i32, i32* %33 acquire, align 4 + store i32 %34, i32* %9, align 4 + %35 = load i32, i32* %9, align 4 + store i32 %35, i32* %7, align 4 + br label %28, !llvm.loop !6 + +36: ; preds = %28 + br label %37 + +37: ; preds = %36, %1 + %38 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %4, align 8 + %39 = bitcast %struct.clh_mutex_node_* %38 to i8* + call void @free(i8* noundef %39) #4 + %40 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %3, align 8 + %41 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %42 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %41, i32 0, i32 0 + store %struct.clh_mutex_node_* %40, %struct.clh_mutex_node_** %42, align 8 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local void @clh_mutex_unlock(%struct.clh_mutex_t* noundef %0) #0 !dbg !112 { - call void @llvm.dbg.value(metadata %struct.clh_mutex_t* %0, metadata !113, metadata !DIExpression()), !dbg !114 - %2 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %0, i32 0, i32 0, !dbg !115 - %3 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %2, align 8, !dbg !115 - %4 = icmp eq %struct.clh_mutex_node_* %3, null, !dbg !117 - br i1 %4, label %7, label %5, !dbg !118 - -5: ; preds = %1 - %6 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %3, i32 0, i32 0, !dbg !119 - store atomic i32 0, i32* %6 release, align 4, !dbg !120 - br label %7, !dbg !121 - -7: ; preds = %1, %5 - ret void, !dbg !121 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @clh_mutex_unlock(%struct.clh_mutex_t* noundef %0) #0 { + %2 = alloca %struct.clh_mutex_t*, align 8 + %3 = alloca i32, align 4 + store %struct.clh_mutex_t* %0, %struct.clh_mutex_t** %2, align 8 + %4 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %5 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %4, i32 0, i32 0 + %6 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %5, align 8 + %7 = icmp eq %struct.clh_mutex_node_* %6, null + br i1 %7, label %8, label %9 + +8: ; preds = %1 + br label %15 + +9: ; preds = %1 + %10 = load %struct.clh_mutex_t*, %struct.clh_mutex_t** %2, align 8 + %11 = getelementptr inbounds %struct.clh_mutex_t, %struct.clh_mutex_t* %10, i32 0, i32 0 + %12 = load %struct.clh_mutex_node_*, %struct.clh_mutex_node_** %11, align 8 + %13 = getelementptr inbounds %struct.clh_mutex_node_, %struct.clh_mutex_node_* %12, i32 0, i32 0 + store i32 0, i32* %3, align 4 + %14 = load i32, i32* %3, align 4 + store atomic i32 %14, i32* %13 release, align 4 + br label %15 + +15: ; preds = %9, %8 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_n(i8* noundef %0) #0 !dbg !122 { - call void @llvm.dbg.value(metadata i8* %0, metadata !125, metadata !DIExpression()), !dbg !126 - %2 = ptrtoint i8* %0 to i64, !dbg !127 - call void @llvm.dbg.value(metadata i64 %2, metadata !128, metadata !DIExpression()), !dbg !126 - call void @clh_mutex_lock(%struct.clh_mutex_t* noundef @lock), !dbg !129 - %3 = trunc i64 %2 to i32, !dbg !130 - store i32 %3, i32* @shared, align 4, !dbg !131 - call void @llvm.dbg.value(metadata i32 %3, metadata !132, metadata !DIExpression()), !dbg !126 - %4 = sext i32 %3 to i64, !dbg !133 - %5 = icmp eq i64 %4, %2, !dbg !133 - br i1 %5, label %7, label %6, !dbg !136 - -6: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([51 x i8], [51 x i8]* @.str.1, i64 0, i64 0), i32 noundef 20, i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @__PRETTY_FUNCTION__.thread_n, i64 0, i64 0)) #6, !dbg !133 - unreachable, !dbg !133 - -7: ; preds = %1 - %8 = load i32, i32* @sum, align 4, !dbg !137 - %9 = add nsw i32 %8, 1, !dbg !137 - store i32 %9, i32* @sum, align 4, !dbg !137 - call void @clh_mutex_unlock(%struct.clh_mutex_t* noundef @lock), !dbg !138 - ret i8* null, !dbg !139 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @thread_n(i8* noundef %0) #0 { + %2 = alloca i8*, align 8 + %3 = alloca i64, align 8 + %4 = alloca i32, align 4 + store i8* %0, i8** %2, align 8 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + call void @clh_mutex_lock(%struct.clh_mutex_t* noundef @lock) + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + store i32 %8, i32* @shared, align 4 + %9 = load i32, i32* @shared, align 4 + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = sext i32 %10 to i64 + %12 = load i64, i64* %3, align 8 + %13 = icmp eq i64 %11, %12 + br i1 %13, label %14, label %15 + +14: ; preds = %1 + br label %16 + +15: ; preds = %1 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([29 x i8], [29 x i8]* @.str.1, i64 0, i64 0), i32 noundef 20, i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @__PRETTY_FUNCTION__.thread_n, i64 0, i64 0)) #5 + unreachable + +16: ; preds = %14 + %17 = load i32, i32* @sum, align 4 + %18 = add nsw i32 %17, 1 + store i32 %18, i32* @sum, align 4 + call void @clh_mutex_unlock(%struct.clh_mutex_t* noundef @lock) + ret i8* null } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !140 { - %1 = alloca [3 x i64], align 16 - call void @llvm.dbg.declare(metadata [3 x i64]* %1, metadata !143, metadata !DIExpression()), !dbg !149 - call void @clh_mutex_init(%struct.clh_mutex_t* noundef @lock), !dbg !150 - call void @llvm.dbg.value(metadata i32 0, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i64 0, metadata !151, metadata !DIExpression()), !dbg !153 - %2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0, !dbg !154 - %3 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef null) #5, !dbg !156 - call void @llvm.dbg.value(metadata i64 1, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i64 1, metadata !151, metadata !DIExpression()), !dbg !153 - %4 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1, !dbg !154 - %5 = call i32 @pthread_create(i64* noundef %4, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef inttoptr (i64 1 to i8*)) #5, !dbg !156 - call void @llvm.dbg.value(metadata i64 2, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i64 2, metadata !151, metadata !DIExpression()), !dbg !153 - %6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2, !dbg !154 - %7 = call i32 @pthread_create(i64* noundef %6, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef inttoptr (i64 2 to i8*)) #5, !dbg !156 - call void @llvm.dbg.value(metadata i64 3, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i64 3, metadata !151, metadata !DIExpression()), !dbg !153 - call void @llvm.dbg.value(metadata i32 0, metadata !157, metadata !DIExpression()), !dbg !159 - call void @llvm.dbg.value(metadata i64 0, metadata !157, metadata !DIExpression()), !dbg !159 - %8 = load i64, i64* %2, align 8, !dbg !160 - %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !162 - call void @llvm.dbg.value(metadata i64 1, metadata !157, metadata !DIExpression()), !dbg !159 - call void @llvm.dbg.value(metadata i64 1, metadata !157, metadata !DIExpression()), !dbg !159 - %10 = load i64, i64* %4, align 8, !dbg !160 - %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !162 - call void @llvm.dbg.value(metadata i64 2, metadata !157, metadata !DIExpression()), !dbg !159 - call void @llvm.dbg.value(metadata i64 2, metadata !157, metadata !DIExpression()), !dbg !159 - %12 = load i64, i64* %6, align 8, !dbg !160 - %13 = call i32 @pthread_join(i64 noundef %12, i8** noundef null), !dbg !162 - call void @llvm.dbg.value(metadata i64 3, metadata !157, metadata !DIExpression()), !dbg !159 - call void @llvm.dbg.value(metadata i64 3, metadata !157, metadata !DIExpression()), !dbg !159 - %14 = load i32, i32* @sum, align 4, !dbg !163 - %15 = icmp eq i32 %14, 3, !dbg !163 - br i1 %15, label %17, label %16, !dbg !166 - -16: ; preds = %0 - call void @__assert_fail(i8* noundef getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([51 x i8], [51 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !163 - unreachable, !dbg !163 - -17: ; preds = %0 - ret i32 0, !dbg !167 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca [3 x i64], align 16 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + call void @clh_mutex_init(%struct.clh_mutex_t* noundef @lock) + store i32 0, i32* %3, align 4 + br label %5 + +5: ; preds = %16, %0 + %6 = load i32, i32* %3, align 4 + %7 = icmp slt i32 %6, 3 + br i1 %7, label %8, label %19 + +8: ; preds = %5 + %9 = load i32, i32* %3, align 4 + %10 = sext i32 %9 to i64 + %11 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %10 + %12 = load i32, i32* %3, align 4 + %13 = sext i32 %12 to i64 + %14 = inttoptr i64 %13 to i8* + %15 = call i32 @pthread_create(i64* noundef %11, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef %14) #4 + br label %16 + +16: ; preds = %8 + %17 = load i32, i32* %3, align 4 + %18 = add nsw i32 %17, 1 + store i32 %18, i32* %3, align 4 + br label %5, !llvm.loop !8 + +19: ; preds = %5 + store i32 0, i32* %4, align 4 + br label %20 + +20: ; preds = %29, %19 + %21 = load i32, i32* %4, align 4 + %22 = icmp slt i32 %21, 3 + br i1 %22, label %23, label %32 + +23: ; preds = %20 + %24 = load i32, i32* %4, align 4 + %25 = sext i32 %24 to i64 + %26 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %25 + %27 = load i64, i64* %26, align 8 + %28 = call i32 @pthread_join(i64 noundef %27, i8** noundef null) + br label %29 + +29: ; preds = %23 + %30 = load i32, i32* %4, align 4 + %31 = add nsw i32 %30, 1 + store i32 %31, i32* %4, align 4 + br label %20, !llvm.loop !9 + +32: ; preds = %20 + %33 = load i32, i32* @sum, align 4 + %34 = icmp eq i32 %33, 3 + br i1 %34, label %35, label %36 + +35: ; preds = %32 + br label %37 + +36: ; preds = %32 + call void @__assert_fail(i8* noundef getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([29 x i8], [29 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable + +37: ; preds = %35 + call void @clh_mutex_destroy(%struct.clh_mutex_t* noundef @lock) + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 -declare i32 @pthread_join(i64 noundef, i8** noundef) #4 +declare i32 @pthread_join(i64 noundef, i8** noundef) #3 ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 - -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.value(metadata, metadata, metadata) #1 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!48, !49, !50, !51, !52, !53, !54} -!llvm.ident = !{!55} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "sum", scope: !2, file: !35, line: 11, type: !31, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.6", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !15, globals: !32, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "/home/ponce/git/Dat3M/benchmarks/locks/clh_mutex.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "3ad3285fca566d9de137b5cd10f9f38c") -!4 = !{!5} -!5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "memory_order", file: !6, line: 56, baseType: !7, size: 32, elements: !8) -!6 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stdatomic.h", directory: "", checksumkind: CSK_MD5, checksum: "de5d66a1ef2f5448cc1919ff39db92bc") -!7 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!8 = !{!9, !10, !11, !12, !13, !14} -!9 = !DIEnumerator(name: "memory_order_relaxed", value: 0) -!10 = !DIEnumerator(name: "memory_order_consume", value: 1) -!11 = !DIEnumerator(name: "memory_order_acquire", value: 2) -!12 = !DIEnumerator(name: "memory_order_release", value: 3) -!13 = !DIEnumerator(name: "memory_order_acq_rel", value: 4) -!14 = !DIEnumerator(name: "memory_order_seq_cst", value: 5) -!15 = !{!16, !17, !20, !23} -!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !18, line: 87, baseType: !19) -!18 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "24103e292ae21916e87130b926c8d2f8") -!19 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!20 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !21, line: 46, baseType: !22) -!21 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!22 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64) -!24 = !DIDerivedType(tag: DW_TAG_typedef, name: "clh_mutex_node_t", file: !25, line: 74, baseType: !26) -!25 = !DIFile(filename: "benchmarks/locks/clh_mutex.h", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "d88c40a0440b1421c9a593b20ac5ab10") -!26 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "clh_mutex_node_", file: !25, line: 76, size: 32, elements: !27) -!27 = !{!28} -!28 = !DIDerivedType(tag: DW_TAG_member, name: "succ_must_wait", scope: !26, file: !25, line: 78, baseType: !29, size: 32) -!29 = !DIDerivedType(tag: DW_TAG_typedef, name: "atomic_int", file: !6, line: 92, baseType: !30) -!30 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !31) -!31 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!32 = !{!0, !33, !36} -!33 = !DIGlobalVariableExpression(var: !34, expr: !DIExpression()) -!34 = distinct !DIGlobalVariable(name: "shared", scope: !2, file: !35, line: 9, type: !31, isLocal: false, isDefinition: true) -!35 = !DIFile(filename: "benchmarks/locks/clh_mutex.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "3ad3285fca566d9de137b5cd10f9f38c") -!36 = !DIGlobalVariableExpression(var: !37, expr: !DIExpression()) -!37 = distinct !DIGlobalVariable(name: "lock", scope: !2, file: !35, line: 10, type: !38, isLocal: false, isDefinition: true) -!38 = !DIDerivedType(tag: DW_TAG_typedef, name: "clh_mutex_t", file: !25, line: 86, baseType: !39) -!39 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !25, line: 81, size: 2176, elements: !40) -!40 = !{!41, !42, !46} -!41 = !DIDerivedType(tag: DW_TAG_member, name: "mynode", scope: !39, file: !25, line: 83, baseType: !23, size: 64) -!42 = !DIDerivedType(tag: DW_TAG_member, name: "padding", scope: !39, file: !25, line: 84, baseType: !43, size: 2048, offset: 64) -!43 = !DICompositeType(tag: DW_TAG_array_type, baseType: !31, size: 2048, elements: !44) -!44 = !{!45} -!45 = !DISubrange(count: 64) -!46 = !DIDerivedType(tag: DW_TAG_member, name: "tail", scope: !39, file: !25, line: 85, baseType: !47, size: 64, offset: 2112) -!47 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !23) -!48 = !{i32 7, !"Dwarf Version", i32 5} -!49 = !{i32 2, !"Debug Info Version", i32 3} -!50 = !{i32 1, !"wchar_size", i32 4} -!51 = !{i32 7, !"PIC Level", i32 2} -!52 = !{i32 7, !"PIE Level", i32 2} -!53 = !{i32 7, !"uwtable", i32 1} -!54 = !{i32 7, !"frame-pointer", i32 2} -!55 = !{!"Ubuntu clang version 14.0.6"} -!56 = distinct !DISubprogram(name: "clh_mutex_init", scope: !25, file: !25, line: 101, type: !57, scopeLine: 102, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!57 = !DISubroutineType(types: !58) -!58 = !{null, !59} -!59 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !38, size: 64) -!60 = !{} -!61 = !DILocalVariable(name: "self", arg: 1, scope: !56, file: !25, line: 101, type: !59) -!62 = !DILocation(line: 0, scope: !56) -!63 = !DILocation(line: 104, column: 31, scope: !56) -!64 = !DILocalVariable(name: "node", scope: !56, file: !25, line: 104, type: !23) -!65 = !DILocation(line: 105, column: 11, scope: !56) -!66 = !DILocation(line: 105, column: 18, scope: !56) -!67 = !DILocation(line: 106, column: 24, scope: !56) -!68 = !DILocation(line: 106, column: 5, scope: !56) -!69 = !DILocation(line: 107, column: 1, scope: !56) -!70 = distinct !DISubprogram(name: "clh_mutex_create_node", scope: !25, file: !25, line: 88, type: !71, scopeLine: 89, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !2, retainedNodes: !60) -!71 = !DISubroutineType(types: !72) -!72 = !{!23, !31} -!73 = !DILocalVariable(name: "islocked", arg: 1, scope: !70, file: !25, line: 88, type: !31) -!74 = !DILocation(line: 0, scope: !70) -!75 = !DILocation(line: 90, column: 55, scope: !70) -!76 = !DILocation(line: 90, column: 35, scope: !70) -!77 = !DILocalVariable(name: "new_node", scope: !70, file: !25, line: 90, type: !23) -!78 = !DILocation(line: 91, column: 28, scope: !70) -!79 = !DILocation(line: 91, column: 5, scope: !70) -!80 = !DILocation(line: 92, column: 5, scope: !70) -!81 = distinct !DISubprogram(name: "clh_mutex_destroy", scope: !25, file: !25, line: 117, type: !57, scopeLine: 118, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!82 = !DILocalVariable(name: "self", arg: 1, scope: !81, file: !25, line: 117, type: !59) -!83 = !DILocation(line: 0, scope: !81) -!84 = !DILocation(line: 119, column: 10, scope: !81) -!85 = !DILocation(line: 119, column: 5, scope: !81) -!86 = !DILocation(line: 120, column: 1, scope: !81) -!87 = distinct !DISubprogram(name: "clh_mutex_lock", scope: !25, file: !25, line: 129, type: !57, scopeLine: 130, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!88 = !DILocalVariable(name: "self", arg: 1, scope: !87, file: !25, line: 129, type: !59) -!89 = !DILocation(line: 0, scope: !87) -!90 = !DILocation(line: 132, column: 32, scope: !87) -!91 = !DILocalVariable(name: "mynode", scope: !87, file: !25, line: 132, type: !23) -!92 = !DILocation(line: 133, column: 30, scope: !87) -!93 = !DILocalVariable(name: "prev", scope: !87, file: !25, line: 133, type: !23) -!94 = !DILocation(line: 140, column: 53, scope: !87) -!95 = !DILocation(line: 140, column: 25, scope: !87) -!96 = !DILocalVariable(name: "prev_islocked", scope: !87, file: !25, line: 140, type: !31) -!97 = !DILocation(line: 142, column: 9, scope: !98) -!98 = distinct !DILexicalBlock(scope: !87, file: !25, line: 142, column: 9) -!99 = !DILocation(line: 142, column: 9, scope: !87) -!100 = !DILocation(line: 143, column: 9, scope: !101) -!101 = distinct !DILexicalBlock(scope: !98, file: !25, line: 142, column: 24) -!102 = !DILocation(line: 144, column: 29, scope: !103) -!103 = distinct !DILexicalBlock(scope: !101, file: !25, line: 143, column: 31) -!104 = distinct !{!104, !100, !105, !106} -!105 = !DILocation(line: 145, column: 9, scope: !101) -!106 = !{!"llvm.loop.mustprogress"} -!107 = !DILocation(line: 149, column: 10, scope: !87) -!108 = !DILocation(line: 149, column: 5, scope: !87) -!109 = !DILocation(line: 153, column: 11, scope: !87) -!110 = !DILocation(line: 153, column: 18, scope: !87) -!111 = !DILocation(line: 154, column: 1, scope: !87) -!112 = distinct !DISubprogram(name: "clh_mutex_unlock", scope: !25, file: !25, line: 163, type: !57, scopeLine: 164, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!113 = !DILocalVariable(name: "self", arg: 1, scope: !112, file: !25, line: 163, type: !59) -!114 = !DILocation(line: 0, scope: !112) -!115 = !DILocation(line: 168, column: 15, scope: !116) -!116 = distinct !DILexicalBlock(scope: !112, file: !25, line: 168, column: 9) -!117 = !DILocation(line: 168, column: 22, scope: !116) -!118 = !DILocation(line: 168, column: 9, scope: !112) -!119 = !DILocation(line: 172, column: 42, scope: !112) -!120 = !DILocation(line: 172, column: 5, scope: !112) -!121 = !DILocation(line: 173, column: 1, scope: !112) -!122 = distinct !DISubprogram(name: "thread_n", scope: !35, file: !35, line: 13, type: !123, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!123 = !DISubroutineType(types: !124) -!124 = !{!16, !16} -!125 = !DILocalVariable(name: "arg", arg: 1, scope: !122, file: !35, line: 13, type: !16) -!126 = !DILocation(line: 0, scope: !122) -!127 = !DILocation(line: 15, column: 23, scope: !122) -!128 = !DILocalVariable(name: "index", scope: !122, file: !35, line: 15, type: !17) -!129 = !DILocation(line: 17, column: 5, scope: !122) -!130 = !DILocation(line: 18, column: 14, scope: !122) -!131 = !DILocation(line: 18, column: 12, scope: !122) -!132 = !DILocalVariable(name: "r", scope: !122, file: !35, line: 19, type: !31) -!133 = !DILocation(line: 20, column: 5, scope: !134) -!134 = distinct !DILexicalBlock(scope: !135, file: !35, line: 20, column: 5) -!135 = distinct !DILexicalBlock(scope: !122, file: !35, line: 20, column: 5) -!136 = !DILocation(line: 20, column: 5, scope: !135) -!137 = !DILocation(line: 21, column: 8, scope: !122) -!138 = !DILocation(line: 22, column: 5, scope: !122) -!139 = !DILocation(line: 23, column: 5, scope: !122) -!140 = distinct !DISubprogram(name: "main", scope: !35, file: !35, line: 26, type: !141, scopeLine: 27, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !60) -!141 = !DISubroutineType(types: !142) -!142 = !{!31} -!143 = !DILocalVariable(name: "t", scope: !140, file: !35, line: 28, type: !144) -!144 = !DICompositeType(tag: DW_TAG_array_type, baseType: !145, size: 192, elements: !147) -!145 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !146, line: 27, baseType: !22) -!146 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "2d764266ce95ab26d4a4767c2ec78176") -!147 = !{!148} -!148 = !DISubrange(count: 3) -!149 = !DILocation(line: 28, column: 15, scope: !140) -!150 = !DILocation(line: 30, column: 5, scope: !140) -!151 = !DILocalVariable(name: "i", scope: !152, file: !35, line: 32, type: !31) -!152 = distinct !DILexicalBlock(scope: !140, file: !35, line: 32, column: 5) -!153 = !DILocation(line: 0, scope: !152) -!154 = !DILocation(line: 33, column: 25, scope: !155) -!155 = distinct !DILexicalBlock(scope: !152, file: !35, line: 32, column: 5) -!156 = !DILocation(line: 33, column: 9, scope: !155) -!157 = !DILocalVariable(name: "i", scope: !158, file: !35, line: 35, type: !31) -!158 = distinct !DILexicalBlock(scope: !140, file: !35, line: 35, column: 5) -!159 = !DILocation(line: 0, scope: !158) -!160 = !DILocation(line: 36, column: 22, scope: !161) -!161 = distinct !DILexicalBlock(scope: !158, file: !35, line: 35, column: 5) -!162 = !DILocation(line: 36, column: 9, scope: !161) -!163 = !DILocation(line: 38, column: 5, scope: !164) -!164 = distinct !DILexicalBlock(scope: !165, file: !35, line: 38, column: 5) -!165 = distinct !DILexicalBlock(scope: !140, file: !35, line: 38, column: 5) -!166 = !DILocation(line: 38, column: 5, scope: !165) -!167 = !DILocation(line: 40, column: 5, scope: !140) +declare noalias i8* @malloc(i64 noundef) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} +!9 = distinct !{!9, !7} diff --git a/dartagnan/src/test/resources/locks/ticket_awnsb_mutex-acq2rx.ll b/dartagnan/src/test/resources/locks/ticket_awnsb_mutex-acq2rx.ll index c5b24641f5..b69f5feb8e 100644 --- a/dartagnan/src/test/resources/locks/ticket_awnsb_mutex-acq2rx.ll +++ b/dartagnan/src/test/resources/locks/ticket_awnsb_mutex-acq2rx.ll @@ -1,5 +1,5 @@ -; ModuleID = '/home/ponce/git/Dat3M/output/ticket_awnsb_mutex.ll' -source_filename = "/home/ponce/git/Dat3M/benchmarks/locks/ticket_awnsb_mutex.c" +; ModuleID = 'benchmarks/locks/ticket_awnsb_mutex.c' +source_filename = "benchmarks/locks/ticket_awnsb_mutex.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" @@ -7,587 +7,579 @@ target triple = "x86_64-pc-linux-gnu" %struct.ticket_awnsb_mutex_t = type { i32, [8 x i8], i32, [8 x i8], i32, %struct.awnsb_node_t** } %union.pthread_attr_t = type { i64, [48 x i8] } -@tlNode = internal thread_local global %struct.awnsb_node_t zeroinitializer, align 4, !dbg !0 -@sum = dso_local global i32 0, align 4, !dbg !35 -@lock = dso_local global %struct.ticket_awnsb_mutex_t zeroinitializer, align 8, !dbg !40 -@shared = dso_local global i32 0, align 4, !dbg !38 +@tlNode = internal thread_local global %struct.awnsb_node_t zeroinitializer, align 4 +@sum = dso_local global i32 0, align 4 +@lock = dso_local global %struct.ticket_awnsb_mutex_t zeroinitializer, align 8 +@shared = dso_local global i32 0, align 4 @.str = private unnamed_addr constant [11 x i8] c"r == index\00", align 1 -@.str.1 = private unnamed_addr constant [60 x i8] c"/home/ponce/git/Dat3M/benchmarks/locks/ticket_awnsb_mutex.c\00", align 1 +@.str.1 = private unnamed_addr constant [38 x i8] c"benchmarks/locks/ticket_awnsb_mutex.c\00", align 1 @__PRETTY_FUNCTION__.thread_n = private unnamed_addr constant [23 x i8] c"void *thread_n(void *)\00", align 1 @.str.2 = private unnamed_addr constant [16 x i8] c"sum == NTHREADS\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @ticket_awnsb_mutex_init(%struct.ticket_awnsb_mutex_t* noundef %0, i32 noundef %1) #0 !dbg !63 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !68, metadata !DIExpression()), !dbg !69 - call void @llvm.dbg.value(metadata i32 %1, metadata !70, metadata !DIExpression()), !dbg !69 - %3 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 0, !dbg !71 - store i32 0, i32* %3, align 4, !dbg !72 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !73 - store i32 0, i32* %4, align 4, !dbg !74 - %5 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 4, !dbg !75 - store i32 %1, i32* %5, align 8, !dbg !76 - %6 = sext i32 %1 to i64, !dbg !77 - %7 = mul i64 %6, 8, !dbg !78 - %8 = call noalias i8* @malloc(i64 noundef %7) #5, !dbg !79 - %9 = bitcast i8* %8 to %struct.awnsb_node_t**, !dbg !80 - %10 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 5, !dbg !81 - store %struct.awnsb_node_t** %9, %struct.awnsb_node_t*** %10, align 8, !dbg !82 - call void @__VERIFIER_loop_bound(i32 noundef 4), !dbg !83 - call void @llvm.dbg.value(metadata i32 0, metadata !84, metadata !DIExpression()), !dbg !86 - br label %11, !dbg !87 - -11: ; preds = %15, %2 - %indvars.iv = phi i64 [ %indvars.iv.next, %15 ], [ 0, %2 ], !dbg !86 - call void @llvm.dbg.value(metadata i64 %indvars.iv, metadata !84, metadata !DIExpression()), !dbg !86 - %12 = load i32, i32* %5, align 8, !dbg !88 - %13 = sext i32 %12 to i64, !dbg !90 - %14 = icmp slt i64 %indvars.iv, %13, !dbg !90 - br i1 %14, label %15, label %18, !dbg !91 - -15: ; preds = %11 - %16 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %10, align 8, !dbg !92 - %17 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %16, i64 %indvars.iv, !dbg !93 - store %struct.awnsb_node_t* null, %struct.awnsb_node_t** %17, align 8, !dbg !94 - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1, !dbg !95 - call void @llvm.dbg.value(metadata i64 %indvars.iv.next, metadata !84, metadata !DIExpression()), !dbg !86 - br label %11, !dbg !96, !llvm.loop !97 - -18: ; preds = %11 - ret void, !dbg !100 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @ticket_awnsb_mutex_init(%struct.ticket_awnsb_mutex_t* noundef %0, i32 noundef %1) #0 { + %3 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %3, align 8 + store i32 %1, i32* %4, align 4 + %6 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %7 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %6, i32 0, i32 0 + store i32 0, i32* %7, align 4 + %8 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %9 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %8, i32 0, i32 2 + store i32 0, i32* %9, align 4 + %10 = load i32, i32* %4, align 4 + %11 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %12 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %11, i32 0, i32 4 + store i32 %10, i32* %12, align 8 + %13 = load i32, i32* %4, align 4 + %14 = sext i32 %13 to i64 + %15 = mul i64 %14, 8 + %16 = call noalias i8* @malloc(i64 noundef %15) #4 + %17 = bitcast i8* %16 to %struct.awnsb_node_t** + %18 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %19 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %18, i32 0, i32 5 + store %struct.awnsb_node_t** %17, %struct.awnsb_node_t*** %19, align 8 + call void @__VERIFIER_loop_bound(i32 noundef 4) + store i32 0, i32* %5, align 4 + br label %20 + +20: ; preds = %33, %2 + %21 = load i32, i32* %5, align 4 + %22 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %23 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %22, i32 0, i32 4 + %24 = load i32, i32* %23, align 8 + %25 = icmp slt i32 %21, %24 + br i1 %25, label %26, label %36 + +26: ; preds = %20 + %27 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %28 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %27, i32 0, i32 5 + %29 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %28, align 8 + %30 = load i32, i32* %5, align 4 + %31 = sext i32 %30 to i64 + %32 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %29, i64 %31 + store %struct.awnsb_node_t* null, %struct.awnsb_node_t** %32, align 8 + br label %33 + +33: ; preds = %26 + %34 = load i32, i32* %5, align 4 + %35 = add nsw i32 %34, 1 + store i32 %35, i32* %5, align 4 + br label %20, !llvm.loop !6 + +36: ; preds = %20 + ret void } -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 - -declare void @__VERIFIER_loop_bound(i32 noundef) #3 - -; Function Attrs: noinline nounwind uwtable -define dso_local void @ticket_awnsb_mutex_destroy(%struct.ticket_awnsb_mutex_t* noundef %0) #0 !dbg !101 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !104, metadata !DIExpression()), !dbg !105 - %2 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 0, !dbg !106 - store atomic i32 0, i32* %2 seq_cst, align 8, !dbg !106 - %3 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !107 - store atomic i32 0, i32* %3 seq_cst, align 4, !dbg !107 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 5, !dbg !108 - %5 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %4, align 8, !dbg !108 - %6 = bitcast %struct.awnsb_node_t** %5 to i8*, !dbg !109 - call void @free(i8* noundef %6) #5, !dbg !110 - ret void, !dbg !111 +declare noalias i8* @malloc(i64 noundef) #1 + +declare void @__VERIFIER_loop_bound(i32 noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @ticket_awnsb_mutex_destroy(%struct.ticket_awnsb_mutex_t* noundef %0) #0 { + %2 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %2, align 8 + %5 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %6 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %5, i32 0, i32 0 + store i32 0, i32* %3, align 4 + %7 = load i32, i32* %3, align 4 + store atomic i32 %7, i32* %6 seq_cst, align 8 + %8 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %9 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %8, i32 0, i32 2 + store i32 0, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + store atomic i32 %10, i32* %9 seq_cst, align 4 + %11 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %12 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %11, i32 0, i32 5 + %13 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %12, align 8 + %14 = bitcast %struct.awnsb_node_t** %13 to i8* + call void @free(i8* noundef %14) #4 + ret void } ; Function Attrs: nounwind -declare void @free(i8* noundef) #2 - -; Function Attrs: noinline nounwind uwtable -define dso_local void @ticket_awnsb_mutex_lock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 !dbg !112 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !113, metadata !DIExpression()), !dbg !114 - %2 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 0, !dbg !115 - %3 = atomicrmw add i32* %2, i32 1 monotonic, align 4, !dbg !116 - call void @llvm.dbg.value(metadata i32 %3, metadata !117, metadata !DIExpression()), !dbg !114 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !119 - %5 = load atomic i32, i32* %4 monotonic, align 4, !dbg !121 - %6 = icmp eq i32 %5, %3, !dbg !122 - br i1 %6, label %43, label %7, !dbg !123 - -7: ; preds = %1 - %8 = add i32 %3, -1, !dbg !124 - br label %9, !dbg !124 - -9: ; preds = %13, %7 - %10 = load atomic i32, i32* %4 monotonic, align 4, !dbg !125 - %11 = sub nsw i32 %3, 1, !dbg !126 - %12 = icmp sge i32 %10, %11, !dbg !127 - br i1 %12, label %13, label %._crit_edge, !dbg !124 - -._crit_edge: ; preds = %9 - %.phi.trans.insert = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 4 - %.pre = load i32, i32* %.phi.trans.insert, align 8, !dbg !128 - br label %16, !dbg !124 - -13: ; preds = %9 - %14 = load atomic i32, i32* %4 acquire, align 4, !dbg !129 - %15 = icmp eq i32 %14, %3, !dbg !132 - br i1 %15, label %43, label %9, !dbg !133, !llvm.loop !134 - -16: ; preds = %._crit_edge, %16 - %17 = load atomic i32, i32* %4 monotonic, align 4, !dbg !136 - %18 = sub nsw i32 %3, %17, !dbg !137 - %19 = sub nsw i32 %.pre, 1, !dbg !138 - %20 = icmp sge i32 %18, %19, !dbg !139 - br i1 %20, label %16, label %21, !dbg !140, !llvm.loop !141 - -21: ; preds = %16 - %scevgep = getelementptr %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i64 0, i32 4, !dbg !140 - call void @llvm.dbg.value(metadata %struct.awnsb_node_t* @tlNode, metadata !143, metadata !DIExpression()), !dbg !114 - store atomic i32 0, i32* getelementptr inbounds (%struct.awnsb_node_t, %struct.awnsb_node_t* @tlNode, i64 0, i32 0) monotonic, align 4, !dbg !144 - %22 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 5, !dbg !145 - %23 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %22, align 8, !dbg !145 - %24 = load i32, i32* %scevgep, align 8, !dbg !146 - %25 = srem i32 %3, %24, !dbg !147 - %26 = sext i32 %25 to i64, !dbg !148 - %27 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %23, i64 %26, !dbg !148 - %28 = bitcast %struct.awnsb_node_t** %27 to i64*, !dbg !149 - store atomic i64 ptrtoint (%struct.awnsb_node_t* @tlNode to i64), i64* %28 release, align 8, !dbg !149 - %29 = load atomic i32, i32* %4 monotonic, align 4, !dbg !150 - %30 = icmp slt i32 %29, %8, !dbg !152 - br i1 %30, label %31, label %36, !dbg !153 - -31: ; preds = %31, %21 - %32 = load atomic i32, i32* getelementptr inbounds (%struct.awnsb_node_t, %struct.awnsb_node_t* @tlNode, i64 0, i32 0) monotonic, align 4, !dbg !154 - %33 = icmp ne i32 %32, 0, !dbg !156 - %34 = xor i1 %33, true, !dbg !156 - br i1 %34, label %31, label %35, !dbg !157, !llvm.loop !158 - -35: ; preds = %31 - store atomic i32 %3, i32* %4 monotonic, align 4, !dbg !160 - br label %43, !dbg !161 - -36: ; preds = %39, %21 - %37 = load atomic i32, i32* %4 acquire, align 4, !dbg !162 - %38 = icmp ne i32 %37, %3, !dbg !164 - br i1 %38, label %39, label %43, !dbg !165 - -39: ; preds = %36 - %40 = load atomic i32, i32* getelementptr inbounds (%struct.awnsb_node_t, %struct.awnsb_node_t* @tlNode, i64 0, i32 0) acquire, align 4, !dbg !166 - %41 = icmp ne i32 %40, 0, !dbg !166 - br i1 %41, label %42, label %36, !dbg !169, !llvm.loop !170 - -42: ; preds = %39 - store atomic i32 %3, i32* %4 monotonic, align 4, !dbg !172 - br label %43, !dbg !174 - -43: ; preds = %36, %13, %1, %42, %35 - ret void, !dbg !175 +declare void @free(i8* noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @ticket_awnsb_mutex_lock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 { + %2 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + %7 = alloca i32, align 4 + %8 = alloca i32, align 4 + %9 = alloca i32, align 4 + %10 = alloca %struct.awnsb_node_t*, align 8 + %11 = alloca i32, align 4 + %12 = alloca %struct.awnsb_node_t*, align 8 + %13 = alloca i32, align 4 + %14 = alloca i32, align 4 + %15 = alloca i32, align 4 + %16 = alloca i32, align 4 + %17 = alloca i32, align 4 + %18 = alloca i32, align 4 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %2, align 8 + %19 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %20 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %19, i32 0, i32 0 + store i32 1, i32* %4, align 4 + %21 = load i32, i32* %4, align 4 + %22 = atomicrmw add i32* %20, i32 %21 monotonic, align 4 + store i32 %22, i32* %5, align 4 + %23 = load i32, i32* %5, align 4 + store i32 %23, i32* %3, align 4 + %24 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %25 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %24, i32 0, i32 2 + %26 = load atomic i32, i32* %25 monotonic, align 4 + store i32 %26, i32* %6, align 4 + %27 = load i32, i32* %6, align 4 + %28 = load i32, i32* %3, align 4 + %29 = icmp eq i32 %27, %28 + br i1 %29, label %30, label %31 + +30: ; preds = %1 + br label %123 + +31: ; preds = %1 + br label %32 + +32: ; preds = %48, %31 + %33 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %34 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %33, i32 0, i32 2 + %35 = load atomic i32, i32* %34 monotonic, align 4 + store i32 %35, i32* %7, align 4 + %36 = load i32, i32* %7, align 4 + %37 = load i32, i32* %3, align 4 + %38 = sub nsw i32 %37, 1 + %39 = icmp sge i32 %36, %38 + br i1 %39, label %40, label %49 + +40: ; preds = %32 + %41 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %42 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %41, i32 0, i32 2 + %43 = load atomic i32, i32* %42 acquire, align 4 + store i32 %43, i32* %8, align 4 + %44 = load i32, i32* %8, align 4 + %45 = load i32, i32* %3, align 4 + %46 = icmp eq i32 %44, %45 + br i1 %46, label %47, label %48 + +47: ; preds = %40 + br label %123 + +48: ; preds = %40 + br label %32, !llvm.loop !8 + +49: ; preds = %32 + br label %50 + +50: ; preds = %62, %49 + %51 = load i32, i32* %3, align 4 + %52 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %53 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %52, i32 0, i32 2 + %54 = load atomic i32, i32* %53 monotonic, align 4 + store i32 %54, i32* %9, align 4 + %55 = load i32, i32* %9, align 4 + %56 = sub nsw i32 %51, %55 + %57 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %58 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %57, i32 0, i32 4 + %59 = load i32, i32* %58, align 8 + %60 = sub nsw i32 %59, 1 + %61 = icmp sge i32 %56, %60 + br i1 %61, label %62, label %63 + +62: ; preds = %50 + br label %50, !llvm.loop !9 + +63: ; preds = %50 + store %struct.awnsb_node_t* @tlNode, %struct.awnsb_node_t** %10, align 8 + %64 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %10, align 8 + %65 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %64, i32 0, i32 0 + store i32 0, i32* %11, align 4 + %66 = load i32, i32* %11, align 4 + store atomic i32 %66, i32* %65 monotonic, align 4 + %67 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %68 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %67, i32 0, i32 5 + %69 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %68, align 8 + %70 = load i32, i32* %3, align 4 + %71 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %72 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %71, i32 0, i32 4 + %73 = load i32, i32* %72, align 8 + %74 = srem i32 %70, %73 + %75 = sext i32 %74 to i64 + %76 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %69, i64 %75 + %77 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %10, align 8 + store %struct.awnsb_node_t* %77, %struct.awnsb_node_t** %12, align 8 + %78 = bitcast %struct.awnsb_node_t** %76 to i64* + %79 = bitcast %struct.awnsb_node_t** %12 to i64* + %80 = load i64, i64* %79, align 8 + store atomic i64 %80, i64* %78 release, align 8 + %81 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %82 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %81, i32 0, i32 2 + %83 = load atomic i32, i32* %82 monotonic, align 4 + store i32 %83, i32* %13, align 4 + %84 = load i32, i32* %13, align 4 + %85 = load i32, i32* %3, align 4 + %86 = sub nsw i32 %85, 1 + %87 = icmp slt i32 %84, %86 + br i1 %87, label %88, label %102 + +88: ; preds = %63 + br label %89 + +89: ; preds = %96, %88 + %90 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %10, align 8 + %91 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %90, i32 0, i32 0 + %92 = load atomic i32, i32* %91 monotonic, align 4 + store i32 %92, i32* %14, align 4 + %93 = load i32, i32* %14, align 4 + %94 = icmp ne i32 %93, 0 + %95 = xor i1 %94, true + br i1 %95, label %96, label %97 + +96: ; preds = %89 + br label %89, !llvm.loop !10 + +97: ; preds = %89 + %98 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %99 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %98, i32 0, i32 2 + %100 = load i32, i32* %3, align 4 + store i32 %100, i32* %15, align 4 + %101 = load i32, i32* %15, align 4 + store atomic i32 %101, i32* %99 monotonic, align 4 + br label %123 + +102: ; preds = %63 + br label %103 + +103: ; preds = %121, %102 + %104 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %105 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %104, i32 0, i32 2 + %106 = load atomic i32, i32* %105 acquire, align 4 + store i32 %106, i32* %16, align 4 + %107 = load i32, i32* %16, align 4 + %108 = load i32, i32* %3, align 4 + %109 = icmp ne i32 %107, %108 + br i1 %109, label %110, label %122 + +110: ; preds = %103 + %111 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %10, align 8 + %112 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %111, i32 0, i32 0 + %113 = load atomic i32, i32* %112 acquire, align 4 + store i32 %113, i32* %17, align 4 + %114 = load i32, i32* %17, align 4 + %115 = icmp ne i32 %114, 0 + br i1 %115, label %116, label %121 + +116: ; preds = %110 + %117 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %118 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %117, i32 0, i32 2 + %119 = load i32, i32* %3, align 4 + store i32 %119, i32* %18, align 4 + %120 = load i32, i32* %18, align 4 + store atomic i32 %120, i32* %118 monotonic, align 4 + br label %123 + +121: ; preds = %110 + br label %103, !llvm.loop !11 + +122: ; preds = %103 + br label %123 + +123: ; preds = %30, %47, %116, %122, %97 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local void @ticket_awnsb_mutex_unlock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 !dbg !176 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !177, metadata !DIExpression()), !dbg !178 - %2 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !179 - %3 = load atomic i32, i32* %2 monotonic, align 4, !dbg !180 - call void @llvm.dbg.value(metadata i32 %3, metadata !181, metadata !DIExpression()), !dbg !178 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 5, !dbg !182 - %5 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %4, align 8, !dbg !182 - %6 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 4, !dbg !183 - %7 = load i32, i32* %6, align 8, !dbg !183 - %8 = srem i32 %3, %7, !dbg !184 - %9 = sext i32 %8 to i64, !dbg !185 - %10 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %5, i64 %9, !dbg !185 - %11 = bitcast %struct.awnsb_node_t** %10 to i64*, !dbg !186 - store atomic i64 0, i64* %11 monotonic, align 8, !dbg !186 - %12 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %4, align 8, !dbg !187 - %13 = add nsw i32 %3, 1, !dbg !188 - %14 = load i32, i32* %6, align 8, !dbg !189 - %15 = srem i32 %13, %14, !dbg !190 - %16 = sext i32 %15 to i64, !dbg !191 - %17 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %12, i64 %16, !dbg !191 - %18 = bitcast %struct.awnsb_node_t** %17 to i64*, !dbg !192 - %19 = load atomic i64, i64* %18 acquire, align 8, !dbg !192 - %20 = inttoptr i64 %19 to %struct.awnsb_node_t*, !dbg !192 - call void @llvm.dbg.value(metadata %struct.awnsb_node_t* %20, metadata !193, metadata !DIExpression()), !dbg !178 - %21 = icmp ne %struct.awnsb_node_t* %20, null, !dbg !194 - br i1 %21, label %22, label %24, !dbg !196 - -22: ; preds = %1 - %23 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %20, i32 0, i32 0, !dbg !197 - store atomic i32 1, i32* %23 release, align 4, !dbg !199 - br label %25, !dbg !200 - -24: ; preds = %1 - store atomic i32 %13, i32* %2 release, align 4, !dbg !201 - br label %25 - -25: ; preds = %24, %22 - ret void, !dbg !203 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @ticket_awnsb_mutex_unlock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 { + %2 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca %struct.awnsb_node_t*, align 8 + %6 = alloca %struct.awnsb_node_t*, align 8 + %7 = alloca %struct.awnsb_node_t*, align 8 + %8 = alloca i32, align 4 + %9 = alloca i32, align 4 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %2, align 8 + %10 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %11 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %10, i32 0, i32 2 + %12 = load atomic i32, i32* %11 monotonic, align 4 + store i32 %12, i32* %4, align 4 + %13 = load i32, i32* %4, align 4 + store i32 %13, i32* %3, align 4 + %14 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %15 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %14, i32 0, i32 5 + %16 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %15, align 8 + %17 = load i32, i32* %3, align 4 + %18 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %19 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %18, i32 0, i32 4 + %20 = load i32, i32* %19, align 8 + %21 = srem i32 %17, %20 + %22 = sext i32 %21 to i64 + %23 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %16, i64 %22 + store %struct.awnsb_node_t* null, %struct.awnsb_node_t** %5, align 8 + %24 = bitcast %struct.awnsb_node_t** %23 to i64* + %25 = bitcast %struct.awnsb_node_t** %5 to i64* + %26 = load i64, i64* %25, align 8 + store atomic i64 %26, i64* %24 monotonic, align 8 + %27 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %28 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %27, i32 0, i32 5 + %29 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %28, align 8 + %30 = load i32, i32* %3, align 4 + %31 = add nsw i32 %30, 1 + %32 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %33 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %32, i32 0, i32 4 + %34 = load i32, i32* %33, align 8 + %35 = srem i32 %31, %34 + %36 = sext i32 %35 to i64 + %37 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %29, i64 %36 + %38 = bitcast %struct.awnsb_node_t** %37 to i64* + %39 = bitcast %struct.awnsb_node_t** %7 to i64* + %40 = load atomic i64, i64* %38 acquire, align 8 + store i64 %40, i64* %39, align 8 + %41 = bitcast i64* %39 to %struct.awnsb_node_t** + %42 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %41, align 8 + store %struct.awnsb_node_t* %42, %struct.awnsb_node_t** %6, align 8 + %43 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %6, align 8 + %44 = icmp ne %struct.awnsb_node_t* %43, null + br i1 %44, label %45, label %49 + +45: ; preds = %1 + %46 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %6, align 8 + %47 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %46, i32 0, i32 0 + store i32 1, i32* %8, align 4 + %48 = load i32, i32* %8, align 4 + store atomic i32 %48, i32* %47 release, align 4 + br label %55 + +49: ; preds = %1 + %50 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %51 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %50, i32 0, i32 2 + %52 = load i32, i32* %3, align 4 + %53 = add nsw i32 %52, 1 + store i32 %53, i32* %9, align 4 + %54 = load i32, i32* %9, align 4 + store atomic i32 %54, i32* %51 release, align 4 + br label %55 + +55: ; preds = %49, %45 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @ticket_awnsb_mutex_trylock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 !dbg !204 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !207, metadata !DIExpression()), !dbg !208 - %2 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !209 - %3 = load atomic i32, i32* %2 seq_cst, align 4, !dbg !209 - call void @llvm.dbg.value(metadata i32 %3, metadata !210, metadata !DIExpression()), !dbg !208 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 0, !dbg !211 - %5 = load atomic i32, i32* %4 monotonic, align 8, !dbg !212 - call void @llvm.dbg.value(metadata i32 %5, metadata !213, metadata !DIExpression()), !dbg !208 - %6 = icmp ne i32 %3, %5, !dbg !214 - br i1 %6, label %13, label %7, !dbg !216 - -7: ; preds = %1 - %8 = load atomic i32, i32* %4 seq_cst, align 4, !dbg !217 - %9 = add nsw i32 %8, 1, !dbg !217 - %10 = cmpxchg i32* %4, i32 %3, i32 %9 seq_cst seq_cst, align 4, !dbg !217 - %11 = extractvalue { i32, i1 } %10, 1, !dbg !217 - %12 = zext i1 %11 to i8, !dbg !217 - %spec.select = select i1 %11, i32 0, i32 16, !dbg !219 - br label %13, !dbg !219 - -13: ; preds = %7, %1 - %.0 = phi i32 [ 16, %1 ], [ %spec.select, %7 ], !dbg !208 - ret i32 %.0, !dbg !220 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @ticket_awnsb_mutex_trylock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 { + %2 = alloca i32, align 4 + %3 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + %7 = alloca i32, align 4 + %8 = alloca i32, align 4 + %9 = alloca i8, align 1 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %3, align 8 + %10 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %11 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %10, i32 0, i32 2 + %12 = load atomic i32, i32* %11 seq_cst, align 4 + store i32 %12, i32* %5, align 4 + %13 = load i32, i32* %5, align 4 + store i32 %13, i32* %4, align 4 + %14 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %15 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %14, i32 0, i32 0 + %16 = load atomic i32, i32* %15 monotonic, align 8 + store i32 %16, i32* %7, align 4 + %17 = load i32, i32* %7, align 4 + store i32 %17, i32* %6, align 4 + %18 = load i32, i32* %4, align 4 + %19 = load i32, i32* %6, align 4 + %20 = icmp ne i32 %18, %19 + br i1 %20, label %21, label %22 + +21: ; preds = %1 + store i32 16, i32* %2, align 4 + br label %41 + +22: ; preds = %1 + %23 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %24 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %23, i32 0, i32 0 + %25 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %26 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %25, i32 0, i32 0 + %27 = load atomic i32, i32* %26 seq_cst, align 4 + %28 = add nsw i32 %27, 1 + store i32 %28, i32* %8, align 4 + %29 = load i32, i32* %6, align 4 + %30 = load i32, i32* %8, align 4 + %31 = cmpxchg i32* %24, i32 %29, i32 %30 seq_cst seq_cst, align 4 + %32 = extractvalue { i32, i1 } %31, 0 + %33 = extractvalue { i32, i1 } %31, 1 + br i1 %33, label %35, label %34 + +34: ; preds = %22 + store i32 %32, i32* %6, align 4 + br label %35 + +35: ; preds = %34, %22 + %36 = zext i1 %33 to i8 + store i8 %36, i8* %9, align 1 + %37 = load i8, i8* %9, align 1 + %38 = trunc i8 %37 to i1 + br i1 %38, label %40, label %39 + +39: ; preds = %35 + store i32 16, i32* %2, align 4 + br label %41 + +40: ; preds = %35 + store i32 0, i32* %2, align 4 + br label %41 + +41: ; preds = %40, %39, %21 + %42 = load i32, i32* %2, align 4 + ret i32 %42 } -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_n(i8* noundef %0) #0 !dbg !221 { - call void @llvm.dbg.value(metadata i8* %0, metadata !224, metadata !DIExpression()), !dbg !225 - %2 = ptrtoint i8* %0 to i64, !dbg !226 - call void @llvm.dbg.value(metadata i64 %2, metadata !227, metadata !DIExpression()), !dbg !225 - call void @ticket_awnsb_mutex_lock(%struct.ticket_awnsb_mutex_t* noundef @lock), !dbg !228 - %3 = trunc i64 %2 to i32, !dbg !229 - store i32 %3, i32* @shared, align 4, !dbg !230 - call void @llvm.dbg.value(metadata i32 %3, metadata !231, metadata !DIExpression()), !dbg !225 - %4 = sext i32 %3 to i64, !dbg !232 - %5 = icmp eq i64 %4, %2, !dbg !232 - br i1 %5, label %7, label %6, !dbg !235 - -6: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([60 x i8], [60 x i8]* @.str.1, i64 0, i64 0), i32 noundef 20, i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @__PRETTY_FUNCTION__.thread_n, i64 0, i64 0)) #6, !dbg !232 - unreachable, !dbg !232 - -7: ; preds = %1 - %8 = load i32, i32* @sum, align 4, !dbg !236 - %9 = add nsw i32 %8, 1, !dbg !236 - store i32 %9, i32* @sum, align 4, !dbg !236 - call void @ticket_awnsb_mutex_unlock(%struct.ticket_awnsb_mutex_t* noundef @lock), !dbg !237 - ret i8* null, !dbg !238 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @thread_n(i8* noundef %0) #0 { + %2 = alloca i8*, align 8 + %3 = alloca i64, align 8 + %4 = alloca i32, align 4 + store i8* %0, i8** %2, align 8 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + call void @ticket_awnsb_mutex_lock(%struct.ticket_awnsb_mutex_t* noundef @lock) + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + store i32 %8, i32* @shared, align 4 + %9 = load i32, i32* @shared, align 4 + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = sext i32 %10 to i64 + %12 = load i64, i64* %3, align 8 + %13 = icmp eq i64 %11, %12 + br i1 %13, label %14, label %15 + +14: ; preds = %1 + br label %16 + +15: ; preds = %1 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([38 x i8], [38 x i8]* @.str.1, i64 0, i64 0), i32 noundef 20, i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @__PRETTY_FUNCTION__.thread_n, i64 0, i64 0)) #5 + unreachable + +16: ; preds = %14 + %17 = load i32, i32* @sum, align 4 + %18 = add nsw i32 %17, 1 + store i32 %18, i32* @sum, align 4 + call void @ticket_awnsb_mutex_unlock(%struct.ticket_awnsb_mutex_t* noundef @lock) + ret i8* null } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #4 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !239 { - %1 = alloca [3 x i64], align 16 - call void @llvm.dbg.declare(metadata [3 x i64]* %1, metadata !242, metadata !DIExpression()), !dbg !248 - call void @ticket_awnsb_mutex_init(%struct.ticket_awnsb_mutex_t* noundef @lock, i32 noundef 3), !dbg !249 - call void @llvm.dbg.value(metadata i32 0, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i64 0, metadata !250, metadata !DIExpression()), !dbg !252 - %2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0, !dbg !253 - %3 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef null) #5, !dbg !255 - call void @llvm.dbg.value(metadata i64 1, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i64 1, metadata !250, metadata !DIExpression()), !dbg !252 - %4 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1, !dbg !253 - %5 = call i32 @pthread_create(i64* noundef %4, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef inttoptr (i64 1 to i8*)) #5, !dbg !255 - call void @llvm.dbg.value(metadata i64 2, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i64 2, metadata !250, metadata !DIExpression()), !dbg !252 - %6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2, !dbg !253 - %7 = call i32 @pthread_create(i64* noundef %6, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef inttoptr (i64 2 to i8*)) #5, !dbg !255 - call void @llvm.dbg.value(metadata i64 3, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i64 3, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i32 0, metadata !256, metadata !DIExpression()), !dbg !258 - call void @llvm.dbg.value(metadata i64 0, metadata !256, metadata !DIExpression()), !dbg !258 - %8 = load i64, i64* %2, align 8, !dbg !259 - %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !261 - call void @llvm.dbg.value(metadata i64 1, metadata !256, metadata !DIExpression()), !dbg !258 - call void @llvm.dbg.value(metadata i64 1, metadata !256, metadata !DIExpression()), !dbg !258 - %10 = load i64, i64* %4, align 8, !dbg !259 - %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !261 - call void @llvm.dbg.value(metadata i64 2, metadata !256, metadata !DIExpression()), !dbg !258 - call void @llvm.dbg.value(metadata i64 2, metadata !256, metadata !DIExpression()), !dbg !258 - %12 = load i64, i64* %6, align 8, !dbg !259 - %13 = call i32 @pthread_join(i64 noundef %12, i8** noundef null), !dbg !261 - call void @llvm.dbg.value(metadata i64 3, metadata !256, metadata !DIExpression()), !dbg !258 - call void @llvm.dbg.value(metadata i64 3, metadata !256, metadata !DIExpression()), !dbg !258 - %14 = load i32, i32* @sum, align 4, !dbg !262 - %15 = icmp eq i32 %14, 3, !dbg !262 - br i1 %15, label %17, label %16, !dbg !265 - -16: ; preds = %0 - call void @__assert_fail(i8* noundef getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([60 x i8], [60 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !262 - unreachable, !dbg !262 - -17: ; preds = %0 - ret i32 0, !dbg !266 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca [3 x i64], align 16 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + call void @ticket_awnsb_mutex_init(%struct.ticket_awnsb_mutex_t* noundef @lock, i32 noundef 3) + store i32 0, i32* %3, align 4 + br label %5 + +5: ; preds = %16, %0 + %6 = load i32, i32* %3, align 4 + %7 = icmp slt i32 %6, 3 + br i1 %7, label %8, label %19 + +8: ; preds = %5 + %9 = load i32, i32* %3, align 4 + %10 = sext i32 %9 to i64 + %11 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %10 + %12 = load i32, i32* %3, align 4 + %13 = sext i32 %12 to i64 + %14 = inttoptr i64 %13 to i8* + %15 = call i32 @pthread_create(i64* noundef %11, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef %14) #4 + br label %16 + +16: ; preds = %8 + %17 = load i32, i32* %3, align 4 + %18 = add nsw i32 %17, 1 + store i32 %18, i32* %3, align 4 + br label %5, !llvm.loop !12 + +19: ; preds = %5 + store i32 0, i32* %4, align 4 + br label %20 + +20: ; preds = %29, %19 + %21 = load i32, i32* %4, align 4 + %22 = icmp slt i32 %21, 3 + br i1 %22, label %23, label %32 + +23: ; preds = %20 + %24 = load i32, i32* %4, align 4 + %25 = sext i32 %24 to i64 + %26 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %25 + %27 = load i64, i64* %26, align 8 + %28 = call i32 @pthread_join(i64 noundef %27, i8** noundef null) + br label %29 + +29: ; preds = %23 + %30 = load i32, i32* %4, align 4 + %31 = add nsw i32 %30, 1 + store i32 %31, i32* %4, align 4 + br label %20, !llvm.loop !13 + +32: ; preds = %20 + %33 = load i32, i32* @sum, align 4 + %34 = icmp eq i32 %33, 3 + br i1 %34, label %35, label %36 + +35: ; preds = %32 + br label %37 + +36: ; preds = %32 + call void @__assert_fail(i8* noundef getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([38 x i8], [38 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable + +37: ; preds = %35 + call void @ticket_awnsb_mutex_destroy(%struct.ticket_awnsb_mutex_t* noundef @lock) + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 - -declare i32 @pthread_join(i64 noundef, i8** noundef) #3 - -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.value(metadata, metadata, metadata) #1 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!55, !56, !57, !58, !59, !60, !61} -!llvm.ident = !{!62} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "tlNode", scope: !2, file: !20, line: 143, type: !19, isLocal: true, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.6", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !15, globals: !34, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "/home/ponce/git/Dat3M/benchmarks/locks/ticket_awnsb_mutex.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "20563f8b3b1d8adf516623558b564708") -!4 = !{!5} -!5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "memory_order", file: !6, line: 56, baseType: !7, size: 32, elements: !8) -!6 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stdatomic.h", directory: "", checksumkind: CSK_MD5, checksum: "de5d66a1ef2f5448cc1919ff39db92bc") -!7 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!8 = !{!9, !10, !11, !12, !13, !14} -!9 = !DIEnumerator(name: "memory_order_relaxed", value: 0) -!10 = !DIEnumerator(name: "memory_order_consume", value: 1) -!11 = !DIEnumerator(name: "memory_order_acquire", value: 2) -!12 = !DIEnumerator(name: "memory_order_release", value: 3) -!13 = !DIEnumerator(name: "memory_order_acq_rel", value: 4) -!14 = !DIEnumerator(name: "memory_order_seq_cst", value: 5) -!15 = !{!16, !26, !27, !28, !31} -!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) -!17 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !18) -!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "awnsb_node_t", file: !20, line: 125, baseType: !21) -!20 = !DIFile(filename: "benchmarks/locks/ticket_awnsb_mutex.h", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "03045fdddbaf6ab40e7d6c6e55719514") -!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !20, line: 123, size: 32, elements: !22) -!22 = !{!23} -!23 = !DIDerivedType(tag: DW_TAG_member, name: "lockIsMine", scope: !21, file: !20, line: 124, baseType: !24, size: 32) -!24 = !DIDerivedType(tag: DW_TAG_typedef, name: "atomic_int", file: !6, line: 92, baseType: !25) -!25 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !26) -!26 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!28 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !29, line: 87, baseType: !30) -!29 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "24103e292ae21916e87130b926c8d2f8") -!30 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !32, line: 46, baseType: !33) -!32 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!33 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!34 = !{!35, !0, !38, !40} -!35 = !DIGlobalVariableExpression(var: !36, expr: !DIExpression()) -!36 = distinct !DIGlobalVariable(name: "sum", scope: !2, file: !37, line: 11, type: !26, isLocal: false, isDefinition: true) -!37 = !DIFile(filename: "benchmarks/locks/ticket_awnsb_mutex.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "20563f8b3b1d8adf516623558b564708") -!38 = !DIGlobalVariableExpression(var: !39, expr: !DIExpression()) -!39 = distinct !DIGlobalVariable(name: "shared", scope: !2, file: !37, line: 9, type: !26, isLocal: false, isDefinition: true) -!40 = !DIGlobalVariableExpression(var: !41, expr: !DIExpression()) -!41 = distinct !DIGlobalVariable(name: "lock", scope: !2, file: !37, line: 10, type: !42, isLocal: false, isDefinition: true) -!42 = !DIDerivedType(tag: DW_TAG_typedef, name: "ticket_awnsb_mutex_t", file: !20, line: 135, baseType: !43) -!43 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !20, line: 127, size: 320, elements: !44) -!44 = !{!45, !46, !51, !52, !53, !54} -!45 = !DIDerivedType(tag: DW_TAG_member, name: "ingress", scope: !43, file: !20, line: 129, baseType: !24, size: 32) -!46 = !DIDerivedType(tag: DW_TAG_member, name: "padding1", scope: !43, file: !20, line: 130, baseType: !47, size: 64, offset: 32) -!47 = !DICompositeType(tag: DW_TAG_array_type, baseType: !48, size: 64, elements: !49) -!48 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -!49 = !{!50} -!50 = !DISubrange(count: 8) -!51 = !DIDerivedType(tag: DW_TAG_member, name: "egress", scope: !43, file: !20, line: 131, baseType: !24, size: 32, offset: 96) -!52 = !DIDerivedType(tag: DW_TAG_member, name: "padding2", scope: !43, file: !20, line: 132, baseType: !47, size: 64, offset: 128) -!53 = !DIDerivedType(tag: DW_TAG_member, name: "maxArrayWaiters", scope: !43, file: !20, line: 133, baseType: !26, size: 32, offset: 192) -!54 = !DIDerivedType(tag: DW_TAG_member, name: "waitersArray", scope: !43, file: !20, line: 134, baseType: !16, size: 64, offset: 256) -!55 = !{i32 7, !"Dwarf Version", i32 5} -!56 = !{i32 2, !"Debug Info Version", i32 3} -!57 = !{i32 1, !"wchar_size", i32 4} -!58 = !{i32 7, !"PIC Level", i32 2} -!59 = !{i32 7, !"PIE Level", i32 2} -!60 = !{i32 7, !"uwtable", i32 1} -!61 = !{i32 7, !"frame-pointer", i32 2} -!62 = !{!"Ubuntu clang version 14.0.6"} -!63 = distinct !DISubprogram(name: "ticket_awnsb_mutex_init", scope: !20, file: !20, line: 153, type: !64, scopeLine: 154, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!64 = !DISubroutineType(types: !65) -!65 = !{null, !66, !26} -!66 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !42, size: 64) -!67 = !{} -!68 = !DILocalVariable(name: "self", arg: 1, scope: !63, file: !20, line: 153, type: !66) -!69 = !DILocation(line: 0, scope: !63) -!70 = !DILocalVariable(name: "maxArrayWaiters", arg: 2, scope: !63, file: !20, line: 153, type: !26) -!71 = !DILocation(line: 155, column: 24, scope: !63) -!72 = !DILocation(line: 155, column: 5, scope: !63) -!73 = !DILocation(line: 156, column: 24, scope: !63) -!74 = !DILocation(line: 156, column: 5, scope: !63) -!75 = !DILocation(line: 157, column: 11, scope: !63) -!76 = !DILocation(line: 157, column: 27, scope: !63) -!77 = !DILocation(line: 158, column: 59, scope: !63) -!78 = !DILocation(line: 158, column: 80, scope: !63) -!79 = !DILocation(line: 158, column: 52, scope: !63) -!80 = !DILocation(line: 158, column: 26, scope: !63) -!81 = !DILocation(line: 158, column: 11, scope: !63) -!82 = !DILocation(line: 158, column: 24, scope: !63) -!83 = !DILocation(line: 159, column: 5, scope: !63) -!84 = !DILocalVariable(name: "i", scope: !85, file: !20, line: 160, type: !26) -!85 = distinct !DILexicalBlock(scope: !63, file: !20, line: 160, column: 5) -!86 = !DILocation(line: 0, scope: !85) -!87 = !DILocation(line: 160, column: 10, scope: !85) -!88 = !DILocation(line: 160, column: 31, scope: !89) -!89 = distinct !DILexicalBlock(scope: !85, file: !20, line: 160, column: 5) -!90 = !DILocation(line: 160, column: 23, scope: !89) -!91 = !DILocation(line: 160, column: 5, scope: !85) -!92 = !DILocation(line: 160, column: 72, scope: !89) -!93 = !DILocation(line: 160, column: 66, scope: !89) -!94 = !DILocation(line: 160, column: 53, scope: !89) -!95 = !DILocation(line: 160, column: 49, scope: !89) -!96 = !DILocation(line: 160, column: 5, scope: !89) -!97 = distinct !{!97, !91, !98, !99} -!98 = !DILocation(line: 160, column: 93, scope: !85) -!99 = !{!"llvm.loop.mustprogress"} -!100 = !DILocation(line: 161, column: 1, scope: !63) -!101 = distinct !DISubprogram(name: "ticket_awnsb_mutex_destroy", scope: !20, file: !20, line: 164, type: !102, scopeLine: 165, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!102 = !DISubroutineType(types: !103) -!103 = !{null, !66} -!104 = !DILocalVariable(name: "self", arg: 1, scope: !101, file: !20, line: 164, type: !66) -!105 = !DILocation(line: 0, scope: !101) -!106 = !DILocation(line: 166, column: 5, scope: !101) -!107 = !DILocation(line: 167, column: 5, scope: !101) -!108 = !DILocation(line: 168, column: 16, scope: !101) -!109 = !DILocation(line: 168, column: 10, scope: !101) -!110 = !DILocation(line: 168, column: 5, scope: !101) -!111 = !DILocation(line: 169, column: 1, scope: !101) -!112 = distinct !DISubprogram(name: "ticket_awnsb_mutex_lock", scope: !20, file: !20, line: 179, type: !102, scopeLine: 180, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!113 = !DILocalVariable(name: "self", arg: 1, scope: !112, file: !20, line: 179, type: !66) -!114 = !DILocation(line: 0, scope: !112) -!115 = !DILocation(line: 181, column: 57, scope: !112) -!116 = !DILocation(line: 181, column: 24, scope: !112) -!117 = !DILocalVariable(name: "ticket", scope: !112, file: !20, line: 181, type: !118) -!118 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !26) -!119 = !DILocation(line: 183, column: 37, scope: !120) -!120 = distinct !DILexicalBlock(scope: !112, file: !20, line: 183, column: 9) -!121 = !DILocation(line: 183, column: 9, scope: !120) -!122 = !DILocation(line: 183, column: 67, scope: !120) -!123 = !DILocation(line: 183, column: 9, scope: !112) -!124 = !DILocation(line: 187, column: 5, scope: !112) -!125 = !DILocation(line: 187, column: 12, scope: !112) -!126 = !DILocation(line: 187, column: 79, scope: !112) -!127 = !DILocation(line: 187, column: 70, scope: !112) -!128 = !DILocation(line: 191, column: 87, scope: !112) -!129 = !DILocation(line: 188, column: 13, scope: !130) -!130 = distinct !DILexicalBlock(scope: !131, file: !20, line: 188, column: 13) -!131 = distinct !DILexicalBlock(scope: !112, file: !20, line: 187, column: 83) -!132 = !DILocation(line: 188, column: 71, scope: !130) -!133 = !DILocation(line: 188, column: 13, scope: !131) -!134 = distinct !{!134, !124, !135, !99} -!135 = !DILocation(line: 189, column: 5, scope: !112) -!136 = !DILocation(line: 191, column: 19, scope: !112) -!137 = !DILocation(line: 191, column: 18, scope: !112) -!138 = !DILocation(line: 191, column: 102, scope: !112) -!139 = !DILocation(line: 191, column: 77, scope: !112) -!140 = !DILocation(line: 191, column: 5, scope: !112) -!141 = distinct !{!141, !140, !142, !99} -!142 = !DILocation(line: 191, column: 106, scope: !112) -!143 = !DILocalVariable(name: "wnode", scope: !112, file: !20, line: 194, type: !18) -!144 = !DILocation(line: 196, column: 5, scope: !112) -!145 = !DILocation(line: 197, column: 34, scope: !112) -!146 = !DILocation(line: 197, column: 68, scope: !112) -!147 = !DILocation(line: 197, column: 60, scope: !112) -!148 = !DILocation(line: 197, column: 28, scope: !112) -!149 = !DILocation(line: 197, column: 5, scope: !112) -!150 = !DILocation(line: 199, column: 9, scope: !151) -!151 = distinct !DILexicalBlock(scope: !112, file: !20, line: 199, column: 9) -!152 = !DILocation(line: 199, column: 67, scope: !151) -!153 = !DILocation(line: 199, column: 9, scope: !112) -!154 = !DILocation(line: 201, column: 17, scope: !155) -!155 = distinct !DILexicalBlock(scope: !151, file: !20, line: 199, column: 79) -!156 = !DILocation(line: 201, column: 16, scope: !155) -!157 = !DILocation(line: 201, column: 9, scope: !155) -!158 = distinct !{!158, !157, !159, !99} -!159 = !DILocation(line: 201, column: 80, scope: !155) -!160 = !DILocation(line: 202, column: 9, scope: !155) -!161 = !DILocation(line: 203, column: 5, scope: !155) -!162 = !DILocation(line: 205, column: 16, scope: !163) -!163 = distinct !DILexicalBlock(scope: !151, file: !20, line: 203, column: 12) -!164 = !DILocation(line: 205, column: 74, scope: !163) -!165 = !DILocation(line: 205, column: 9, scope: !163) -!166 = !DILocation(line: 206, column: 17, scope: !167) -!167 = distinct !DILexicalBlock(scope: !168, file: !20, line: 206, column: 17) -!168 = distinct !DILexicalBlock(scope: !163, file: !20, line: 205, column: 85) -!169 = !DILocation(line: 206, column: 17, scope: !168) -!170 = distinct !{!170, !165, !171, !99} -!171 = !DILocation(line: 210, column: 9, scope: !163) -!172 = !DILocation(line: 207, column: 17, scope: !173) -!173 = distinct !DILexicalBlock(scope: !167, file: !20, line: 206, column: 81) -!174 = !DILocation(line: 208, column: 17, scope: !173) -!175 = !DILocation(line: 213, column: 1, scope: !112) -!176 = distinct !DISubprogram(name: "ticket_awnsb_mutex_unlock", scope: !20, file: !20, line: 222, type: !102, scopeLine: 223, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!177 = !DILocalVariable(name: "self", arg: 1, scope: !176, file: !20, line: 222, type: !66) -!178 = !DILocation(line: 0, scope: !176) -!179 = !DILocation(line: 224, column: 46, scope: !176) -!180 = !DILocation(line: 224, column: 18, scope: !176) -!181 = !DILocalVariable(name: "ticket", scope: !176, file: !20, line: 224, type: !26) -!182 = !DILocation(line: 226, column: 34, scope: !176) -!183 = !DILocation(line: 226, column: 68, scope: !176) -!184 = !DILocation(line: 226, column: 60, scope: !176) -!185 = !DILocation(line: 226, column: 28, scope: !176) -!186 = !DILocation(line: 226, column: 5, scope: !176) -!187 = !DILocation(line: 228, column: 56, scope: !176) -!188 = !DILocation(line: 228, column: 82, scope: !176) -!189 = !DILocation(line: 228, column: 94, scope: !176) -!190 = !DILocation(line: 228, column: 86, scope: !176) -!191 = !DILocation(line: 228, column: 50, scope: !176) -!192 = !DILocation(line: 228, column: 28, scope: !176) -!193 = !DILocalVariable(name: "wnode", scope: !176, file: !20, line: 228, type: !18) -!194 = !DILocation(line: 229, column: 15, scope: !195) -!195 = distinct !DILexicalBlock(scope: !176, file: !20, line: 229, column: 9) -!196 = !DILocation(line: 229, column: 9, scope: !176) -!197 = !DILocation(line: 231, column: 39, scope: !198) -!198 = distinct !DILexicalBlock(scope: !195, file: !20, line: 229, column: 24) -!199 = !DILocation(line: 231, column: 9, scope: !198) -!200 = !DILocation(line: 232, column: 5, scope: !198) -!201 = !DILocation(line: 233, column: 9, scope: !202) -!202 = distinct !DILexicalBlock(scope: !195, file: !20, line: 232, column: 12) -!203 = !DILocation(line: 235, column: 1, scope: !176) -!204 = distinct !DISubprogram(name: "ticket_awnsb_mutex_trylock", scope: !20, file: !20, line: 243, type: !205, scopeLine: 244, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!205 = !DISubroutineType(types: !206) -!206 = !{!26, !66} -!207 = !DILocalVariable(name: "self", arg: 1, scope: !204, file: !20, line: 243, type: !66) -!208 = !DILocation(line: 0, scope: !204) -!209 = !DILocation(line: 245, column: 18, scope: !204) -!210 = !DILocalVariable(name: "localE", scope: !204, file: !20, line: 245, type: !26) -!211 = !DILocation(line: 246, column: 46, scope: !204) -!212 = !DILocation(line: 246, column: 18, scope: !204) -!213 = !DILocalVariable(name: "localI", scope: !204, file: !20, line: 246, type: !26) -!214 = !DILocation(line: 247, column: 16, scope: !215) -!215 = distinct !DILexicalBlock(scope: !204, file: !20, line: 247, column: 9) -!216 = !DILocation(line: 247, column: 9, scope: !204) -!217 = !DILocation(line: 248, column: 10, scope: !218) -!218 = distinct !DILexicalBlock(scope: !204, file: !20, line: 248, column: 9) -!219 = !DILocation(line: 248, column: 9, scope: !204) -!220 = !DILocation(line: 251, column: 1, scope: !204) -!221 = distinct !DISubprogram(name: "thread_n", scope: !37, file: !37, line: 13, type: !222, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!222 = !DISubroutineType(types: !223) -!223 = !{!27, !27} -!224 = !DILocalVariable(name: "arg", arg: 1, scope: !221, file: !37, line: 13, type: !27) -!225 = !DILocation(line: 0, scope: !221) -!226 = !DILocation(line: 15, column: 23, scope: !221) -!227 = !DILocalVariable(name: "index", scope: !221, file: !37, line: 15, type: !28) -!228 = !DILocation(line: 17, column: 5, scope: !221) -!229 = !DILocation(line: 18, column: 14, scope: !221) -!230 = !DILocation(line: 18, column: 12, scope: !221) -!231 = !DILocalVariable(name: "r", scope: !221, file: !37, line: 19, type: !26) -!232 = !DILocation(line: 20, column: 5, scope: !233) -!233 = distinct !DILexicalBlock(scope: !234, file: !37, line: 20, column: 5) -!234 = distinct !DILexicalBlock(scope: !221, file: !37, line: 20, column: 5) -!235 = !DILocation(line: 20, column: 5, scope: !234) -!236 = !DILocation(line: 21, column: 8, scope: !221) -!237 = !DILocation(line: 22, column: 5, scope: !221) -!238 = !DILocation(line: 23, column: 5, scope: !221) -!239 = distinct !DISubprogram(name: "main", scope: !37, file: !37, line: 26, type: !240, scopeLine: 27, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!240 = !DISubroutineType(types: !241) -!241 = !{!26} -!242 = !DILocalVariable(name: "t", scope: !239, file: !37, line: 28, type: !243) -!243 = !DICompositeType(tag: DW_TAG_array_type, baseType: !244, size: 192, elements: !246) -!244 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !245, line: 27, baseType: !33) -!245 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "2d764266ce95ab26d4a4767c2ec78176") -!246 = !{!247} -!247 = !DISubrange(count: 3) -!248 = !DILocation(line: 28, column: 15, scope: !239) -!249 = !DILocation(line: 30, column: 5, scope: !239) -!250 = !DILocalVariable(name: "i", scope: !251, file: !37, line: 32, type: !26) -!251 = distinct !DILexicalBlock(scope: !239, file: !37, line: 32, column: 5) -!252 = !DILocation(line: 0, scope: !251) -!253 = !DILocation(line: 33, column: 25, scope: !254) -!254 = distinct !DILexicalBlock(scope: !251, file: !37, line: 32, column: 5) -!255 = !DILocation(line: 33, column: 9, scope: !254) -!256 = !DILocalVariable(name: "i", scope: !257, file: !37, line: 35, type: !26) -!257 = distinct !DILexicalBlock(scope: !239, file: !37, line: 35, column: 5) -!258 = !DILocation(line: 0, scope: !257) -!259 = !DILocation(line: 36, column: 22, scope: !260) -!260 = distinct !DILexicalBlock(scope: !257, file: !37, line: 35, column: 5) -!261 = !DILocation(line: 36, column: 9, scope: !260) -!262 = !DILocation(line: 38, column: 5, scope: !263) -!263 = distinct !DILexicalBlock(scope: !264, file: !37, line: 38, column: 5) -!264 = distinct !DILexicalBlock(scope: !239, file: !37, line: 38, column: 5) -!265 = !DILocation(line: 38, column: 5, scope: !264) -!266 = !DILocation(line: 40, column: 5, scope: !239) +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #2 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} +!9 = distinct !{!9, !7} +!10 = distinct !{!10, !7} +!11 = distinct !{!11, !7} +!12 = distinct !{!12, !7} +!13 = distinct !{!13, !7} diff --git a/dartagnan/src/test/resources/locks/ticket_awnsb_mutex.ll b/dartagnan/src/test/resources/locks/ticket_awnsb_mutex.ll index faf3c68dcc..6c3dd3d373 100644 --- a/dartagnan/src/test/resources/locks/ticket_awnsb_mutex.ll +++ b/dartagnan/src/test/resources/locks/ticket_awnsb_mutex.ll @@ -1,5 +1,5 @@ -; ModuleID = '/home/ponce/git/Dat3M/output/ticket_awnsb_mutex.ll' -source_filename = "/home/ponce/git/Dat3M/benchmarks/locks/ticket_awnsb_mutex.c" +; ModuleID = 'benchmarks/locks/ticket_awnsb_mutex.c' +source_filename = "benchmarks/locks/ticket_awnsb_mutex.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" @@ -7,587 +7,579 @@ target triple = "x86_64-pc-linux-gnu" %struct.ticket_awnsb_mutex_t = type { i32, [8 x i8], i32, [8 x i8], i32, %struct.awnsb_node_t** } %union.pthread_attr_t = type { i64, [48 x i8] } -@tlNode = internal thread_local global %struct.awnsb_node_t zeroinitializer, align 4, !dbg !0 -@sum = dso_local global i32 0, align 4, !dbg !35 -@lock = dso_local global %struct.ticket_awnsb_mutex_t zeroinitializer, align 8, !dbg !40 -@shared = dso_local global i32 0, align 4, !dbg !38 +@tlNode = internal thread_local global %struct.awnsb_node_t zeroinitializer, align 4 +@sum = dso_local global i32 0, align 4 +@lock = dso_local global %struct.ticket_awnsb_mutex_t zeroinitializer, align 8 +@shared = dso_local global i32 0, align 4 @.str = private unnamed_addr constant [11 x i8] c"r == index\00", align 1 -@.str.1 = private unnamed_addr constant [60 x i8] c"/home/ponce/git/Dat3M/benchmarks/locks/ticket_awnsb_mutex.c\00", align 1 +@.str.1 = private unnamed_addr constant [38 x i8] c"benchmarks/locks/ticket_awnsb_mutex.c\00", align 1 @__PRETTY_FUNCTION__.thread_n = private unnamed_addr constant [23 x i8] c"void *thread_n(void *)\00", align 1 @.str.2 = private unnamed_addr constant [16 x i8] c"sum == NTHREADS\00", align 1 @__PRETTY_FUNCTION__.main = private unnamed_addr constant [11 x i8] c"int main()\00", align 1 -; Function Attrs: noinline nounwind uwtable -define dso_local void @ticket_awnsb_mutex_init(%struct.ticket_awnsb_mutex_t* noundef %0, i32 noundef %1) #0 !dbg !63 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !68, metadata !DIExpression()), !dbg !69 - call void @llvm.dbg.value(metadata i32 %1, metadata !70, metadata !DIExpression()), !dbg !69 - %3 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 0, !dbg !71 - store i32 0, i32* %3, align 4, !dbg !72 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !73 - store i32 0, i32* %4, align 4, !dbg !74 - %5 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 4, !dbg !75 - store i32 %1, i32* %5, align 8, !dbg !76 - %6 = sext i32 %1 to i64, !dbg !77 - %7 = mul i64 %6, 8, !dbg !78 - %8 = call noalias i8* @malloc(i64 noundef %7) #5, !dbg !79 - %9 = bitcast i8* %8 to %struct.awnsb_node_t**, !dbg !80 - %10 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 5, !dbg !81 - store %struct.awnsb_node_t** %9, %struct.awnsb_node_t*** %10, align 8, !dbg !82 - call void @__VERIFIER_loop_bound(i32 noundef 4), !dbg !83 - call void @llvm.dbg.value(metadata i32 0, metadata !84, metadata !DIExpression()), !dbg !86 - br label %11, !dbg !87 - -11: ; preds = %15, %2 - %indvars.iv = phi i64 [ %indvars.iv.next, %15 ], [ 0, %2 ], !dbg !86 - call void @llvm.dbg.value(metadata i64 %indvars.iv, metadata !84, metadata !DIExpression()), !dbg !86 - %12 = load i32, i32* %5, align 8, !dbg !88 - %13 = sext i32 %12 to i64, !dbg !90 - %14 = icmp slt i64 %indvars.iv, %13, !dbg !90 - br i1 %14, label %15, label %18, !dbg !91 - -15: ; preds = %11 - %16 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %10, align 8, !dbg !92 - %17 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %16, i64 %indvars.iv, !dbg !93 - store %struct.awnsb_node_t* null, %struct.awnsb_node_t** %17, align 8, !dbg !94 - %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1, !dbg !95 - call void @llvm.dbg.value(metadata i64 %indvars.iv.next, metadata !84, metadata !DIExpression()), !dbg !86 - br label %11, !dbg !96, !llvm.loop !97 - -18: ; preds = %11 - ret void, !dbg !100 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @ticket_awnsb_mutex_init(%struct.ticket_awnsb_mutex_t* noundef %0, i32 noundef %1) #0 { + %3 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %3, align 8 + store i32 %1, i32* %4, align 4 + %6 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %7 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %6, i32 0, i32 0 + store i32 0, i32* %7, align 4 + %8 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %9 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %8, i32 0, i32 2 + store i32 0, i32* %9, align 4 + %10 = load i32, i32* %4, align 4 + %11 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %12 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %11, i32 0, i32 4 + store i32 %10, i32* %12, align 8 + %13 = load i32, i32* %4, align 4 + %14 = sext i32 %13 to i64 + %15 = mul i64 %14, 8 + %16 = call noalias i8* @malloc(i64 noundef %15) #4 + %17 = bitcast i8* %16 to %struct.awnsb_node_t** + %18 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %19 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %18, i32 0, i32 5 + store %struct.awnsb_node_t** %17, %struct.awnsb_node_t*** %19, align 8 + call void @__VERIFIER_loop_bound(i32 noundef 4) + store i32 0, i32* %5, align 4 + br label %20 + +20: ; preds = %33, %2 + %21 = load i32, i32* %5, align 4 + %22 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %23 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %22, i32 0, i32 4 + %24 = load i32, i32* %23, align 8 + %25 = icmp slt i32 %21, %24 + br i1 %25, label %26, label %36 + +26: ; preds = %20 + %27 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %28 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %27, i32 0, i32 5 + %29 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %28, align 8 + %30 = load i32, i32* %5, align 4 + %31 = sext i32 %30 to i64 + %32 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %29, i64 %31 + store %struct.awnsb_node_t* null, %struct.awnsb_node_t** %32, align 8 + br label %33 + +33: ; preds = %26 + %34 = load i32, i32* %5, align 4 + %35 = add nsw i32 %34, 1 + store i32 %35, i32* %5, align 4 + br label %20, !llvm.loop !6 + +36: ; preds = %20 + ret void } -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - ; Function Attrs: nounwind -declare noalias i8* @malloc(i64 noundef) #2 - -declare void @__VERIFIER_loop_bound(i32 noundef) #3 - -; Function Attrs: noinline nounwind uwtable -define dso_local void @ticket_awnsb_mutex_destroy(%struct.ticket_awnsb_mutex_t* noundef %0) #0 !dbg !101 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !104, metadata !DIExpression()), !dbg !105 - %2 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 0, !dbg !106 - store atomic i32 0, i32* %2 seq_cst, align 8, !dbg !106 - %3 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !107 - store atomic i32 0, i32* %3 seq_cst, align 4, !dbg !107 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 5, !dbg !108 - %5 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %4, align 8, !dbg !108 - %6 = bitcast %struct.awnsb_node_t** %5 to i8*, !dbg !109 - call void @free(i8* noundef %6) #5, !dbg !110 - ret void, !dbg !111 +declare noalias i8* @malloc(i64 noundef) #1 + +declare void @__VERIFIER_loop_bound(i32 noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @ticket_awnsb_mutex_destroy(%struct.ticket_awnsb_mutex_t* noundef %0) #0 { + %2 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %2, align 8 + %5 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %6 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %5, i32 0, i32 0 + store i32 0, i32* %3, align 4 + %7 = load i32, i32* %3, align 4 + store atomic i32 %7, i32* %6 seq_cst, align 8 + %8 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %9 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %8, i32 0, i32 2 + store i32 0, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + store atomic i32 %10, i32* %9 seq_cst, align 4 + %11 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %12 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %11, i32 0, i32 5 + %13 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %12, align 8 + %14 = bitcast %struct.awnsb_node_t** %13 to i8* + call void @free(i8* noundef %14) #4 + ret void } ; Function Attrs: nounwind -declare void @free(i8* noundef) #2 - -; Function Attrs: noinline nounwind uwtable -define dso_local void @ticket_awnsb_mutex_lock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 !dbg !112 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !113, metadata !DIExpression()), !dbg !114 - %2 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 0, !dbg !115 - %3 = atomicrmw add i32* %2, i32 1 monotonic, align 4, !dbg !116 - call void @llvm.dbg.value(metadata i32 %3, metadata !117, metadata !DIExpression()), !dbg !114 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !119 - %5 = load atomic i32, i32* %4 acquire, align 4, !dbg !121 - %6 = icmp eq i32 %5, %3, !dbg !122 - br i1 %6, label %43, label %7, !dbg !123 - -7: ; preds = %1 - %8 = add i32 %3, -1, !dbg !124 - br label %9, !dbg !124 - -9: ; preds = %13, %7 - %10 = load atomic i32, i32* %4 monotonic, align 4, !dbg !125 - %11 = sub nsw i32 %3, 1, !dbg !126 - %12 = icmp sge i32 %10, %11, !dbg !127 - br i1 %12, label %13, label %._crit_edge, !dbg !124 - -._crit_edge: ; preds = %9 - %.phi.trans.insert = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 4 - %.pre = load i32, i32* %.phi.trans.insert, align 8, !dbg !128 - br label %16, !dbg !124 - -13: ; preds = %9 - %14 = load atomic i32, i32* %4 acquire, align 4, !dbg !129 - %15 = icmp eq i32 %14, %3, !dbg !132 - br i1 %15, label %43, label %9, !dbg !133, !llvm.loop !134 - -16: ; preds = %._crit_edge, %16 - %17 = load atomic i32, i32* %4 monotonic, align 4, !dbg !136 - %18 = sub nsw i32 %3, %17, !dbg !137 - %19 = sub nsw i32 %.pre, 1, !dbg !138 - %20 = icmp sge i32 %18, %19, !dbg !139 - br i1 %20, label %16, label %21, !dbg !140, !llvm.loop !141 - -21: ; preds = %16 - %scevgep = getelementptr %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i64 0, i32 4, !dbg !140 - call void @llvm.dbg.value(metadata %struct.awnsb_node_t* @tlNode, metadata !143, metadata !DIExpression()), !dbg !114 - store atomic i32 0, i32* getelementptr inbounds (%struct.awnsb_node_t, %struct.awnsb_node_t* @tlNode, i64 0, i32 0) monotonic, align 4, !dbg !144 - %22 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 5, !dbg !145 - %23 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %22, align 8, !dbg !145 - %24 = load i32, i32* %scevgep, align 8, !dbg !146 - %25 = srem i32 %3, %24, !dbg !147 - %26 = sext i32 %25 to i64, !dbg !148 - %27 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %23, i64 %26, !dbg !148 - %28 = bitcast %struct.awnsb_node_t** %27 to i64*, !dbg !149 - store atomic i64 ptrtoint (%struct.awnsb_node_t* @tlNode to i64), i64* %28 release, align 8, !dbg !149 - %29 = load atomic i32, i32* %4 monotonic, align 4, !dbg !150 - %30 = icmp slt i32 %29, %8, !dbg !152 - br i1 %30, label %31, label %36, !dbg !153 - -31: ; preds = %31, %21 - %32 = load atomic i32, i32* getelementptr inbounds (%struct.awnsb_node_t, %struct.awnsb_node_t* @tlNode, i64 0, i32 0) monotonic, align 4, !dbg !154 - %33 = icmp ne i32 %32, 0, !dbg !156 - %34 = xor i1 %33, true, !dbg !156 - br i1 %34, label %31, label %35, !dbg !157, !llvm.loop !158 - -35: ; preds = %31 - store atomic i32 %3, i32* %4 monotonic, align 4, !dbg !160 - br label %43, !dbg !161 - -36: ; preds = %39, %21 - %37 = load atomic i32, i32* %4 acquire, align 4, !dbg !162 - %38 = icmp ne i32 %37, %3, !dbg !164 - br i1 %38, label %39, label %43, !dbg !165 - -39: ; preds = %36 - %40 = load atomic i32, i32* getelementptr inbounds (%struct.awnsb_node_t, %struct.awnsb_node_t* @tlNode, i64 0, i32 0) acquire, align 4, !dbg !166 - %41 = icmp ne i32 %40, 0, !dbg !166 - br i1 %41, label %42, label %36, !dbg !169, !llvm.loop !170 - -42: ; preds = %39 - store atomic i32 %3, i32* %4 monotonic, align 4, !dbg !172 - br label %43, !dbg !174 - -43: ; preds = %36, %13, %1, %42, %35 - ret void, !dbg !175 +declare void @free(i8* noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @ticket_awnsb_mutex_lock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 { + %2 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + %7 = alloca i32, align 4 + %8 = alloca i32, align 4 + %9 = alloca i32, align 4 + %10 = alloca %struct.awnsb_node_t*, align 8 + %11 = alloca i32, align 4 + %12 = alloca %struct.awnsb_node_t*, align 8 + %13 = alloca i32, align 4 + %14 = alloca i32, align 4 + %15 = alloca i32, align 4 + %16 = alloca i32, align 4 + %17 = alloca i32, align 4 + %18 = alloca i32, align 4 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %2, align 8 + %19 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %20 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %19, i32 0, i32 0 + store i32 1, i32* %4, align 4 + %21 = load i32, i32* %4, align 4 + %22 = atomicrmw add i32* %20, i32 %21 monotonic, align 4 + store i32 %22, i32* %5, align 4 + %23 = load i32, i32* %5, align 4 + store i32 %23, i32* %3, align 4 + %24 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %25 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %24, i32 0, i32 2 + %26 = load atomic i32, i32* %25 acquire, align 4 + store i32 %26, i32* %6, align 4 + %27 = load i32, i32* %6, align 4 + %28 = load i32, i32* %3, align 4 + %29 = icmp eq i32 %27, %28 + br i1 %29, label %30, label %31 + +30: ; preds = %1 + br label %123 + +31: ; preds = %1 + br label %32 + +32: ; preds = %48, %31 + %33 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %34 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %33, i32 0, i32 2 + %35 = load atomic i32, i32* %34 monotonic, align 4 + store i32 %35, i32* %7, align 4 + %36 = load i32, i32* %7, align 4 + %37 = load i32, i32* %3, align 4 + %38 = sub nsw i32 %37, 1 + %39 = icmp sge i32 %36, %38 + br i1 %39, label %40, label %49 + +40: ; preds = %32 + %41 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %42 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %41, i32 0, i32 2 + %43 = load atomic i32, i32* %42 acquire, align 4 + store i32 %43, i32* %8, align 4 + %44 = load i32, i32* %8, align 4 + %45 = load i32, i32* %3, align 4 + %46 = icmp eq i32 %44, %45 + br i1 %46, label %47, label %48 + +47: ; preds = %40 + br label %123 + +48: ; preds = %40 + br label %32, !llvm.loop !8 + +49: ; preds = %32 + br label %50 + +50: ; preds = %62, %49 + %51 = load i32, i32* %3, align 4 + %52 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %53 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %52, i32 0, i32 2 + %54 = load atomic i32, i32* %53 monotonic, align 4 + store i32 %54, i32* %9, align 4 + %55 = load i32, i32* %9, align 4 + %56 = sub nsw i32 %51, %55 + %57 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %58 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %57, i32 0, i32 4 + %59 = load i32, i32* %58, align 8 + %60 = sub nsw i32 %59, 1 + %61 = icmp sge i32 %56, %60 + br i1 %61, label %62, label %63 + +62: ; preds = %50 + br label %50, !llvm.loop !9 + +63: ; preds = %50 + store %struct.awnsb_node_t* @tlNode, %struct.awnsb_node_t** %10, align 8 + %64 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %10, align 8 + %65 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %64, i32 0, i32 0 + store i32 0, i32* %11, align 4 + %66 = load i32, i32* %11, align 4 + store atomic i32 %66, i32* %65 monotonic, align 4 + %67 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %68 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %67, i32 0, i32 5 + %69 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %68, align 8 + %70 = load i32, i32* %3, align 4 + %71 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %72 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %71, i32 0, i32 4 + %73 = load i32, i32* %72, align 8 + %74 = srem i32 %70, %73 + %75 = sext i32 %74 to i64 + %76 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %69, i64 %75 + %77 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %10, align 8 + store %struct.awnsb_node_t* %77, %struct.awnsb_node_t** %12, align 8 + %78 = bitcast %struct.awnsb_node_t** %76 to i64* + %79 = bitcast %struct.awnsb_node_t** %12 to i64* + %80 = load i64, i64* %79, align 8 + store atomic i64 %80, i64* %78 release, align 8 + %81 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %82 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %81, i32 0, i32 2 + %83 = load atomic i32, i32* %82 monotonic, align 4 + store i32 %83, i32* %13, align 4 + %84 = load i32, i32* %13, align 4 + %85 = load i32, i32* %3, align 4 + %86 = sub nsw i32 %85, 1 + %87 = icmp slt i32 %84, %86 + br i1 %87, label %88, label %102 + +88: ; preds = %63 + br label %89 + +89: ; preds = %96, %88 + %90 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %10, align 8 + %91 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %90, i32 0, i32 0 + %92 = load atomic i32, i32* %91 monotonic, align 4 + store i32 %92, i32* %14, align 4 + %93 = load i32, i32* %14, align 4 + %94 = icmp ne i32 %93, 0 + %95 = xor i1 %94, true + br i1 %95, label %96, label %97 + +96: ; preds = %89 + br label %89, !llvm.loop !10 + +97: ; preds = %89 + %98 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %99 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %98, i32 0, i32 2 + %100 = load i32, i32* %3, align 4 + store i32 %100, i32* %15, align 4 + %101 = load i32, i32* %15, align 4 + store atomic i32 %101, i32* %99 monotonic, align 4 + br label %123 + +102: ; preds = %63 + br label %103 + +103: ; preds = %121, %102 + %104 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %105 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %104, i32 0, i32 2 + %106 = load atomic i32, i32* %105 acquire, align 4 + store i32 %106, i32* %16, align 4 + %107 = load i32, i32* %16, align 4 + %108 = load i32, i32* %3, align 4 + %109 = icmp ne i32 %107, %108 + br i1 %109, label %110, label %122 + +110: ; preds = %103 + %111 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %10, align 8 + %112 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %111, i32 0, i32 0 + %113 = load atomic i32, i32* %112 acquire, align 4 + store i32 %113, i32* %17, align 4 + %114 = load i32, i32* %17, align 4 + %115 = icmp ne i32 %114, 0 + br i1 %115, label %116, label %121 + +116: ; preds = %110 + %117 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %118 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %117, i32 0, i32 2 + %119 = load i32, i32* %3, align 4 + store i32 %119, i32* %18, align 4 + %120 = load i32, i32* %18, align 4 + store atomic i32 %120, i32* %118 monotonic, align 4 + br label %123 + +121: ; preds = %110 + br label %103, !llvm.loop !11 + +122: ; preds = %103 + br label %123 + +123: ; preds = %30, %47, %116, %122, %97 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local void @ticket_awnsb_mutex_unlock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 !dbg !176 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !177, metadata !DIExpression()), !dbg !178 - %2 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !179 - %3 = load atomic i32, i32* %2 monotonic, align 4, !dbg !180 - call void @llvm.dbg.value(metadata i32 %3, metadata !181, metadata !DIExpression()), !dbg !178 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 5, !dbg !182 - %5 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %4, align 8, !dbg !182 - %6 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 4, !dbg !183 - %7 = load i32, i32* %6, align 8, !dbg !183 - %8 = srem i32 %3, %7, !dbg !184 - %9 = sext i32 %8 to i64, !dbg !185 - %10 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %5, i64 %9, !dbg !185 - %11 = bitcast %struct.awnsb_node_t** %10 to i64*, !dbg !186 - store atomic i64 0, i64* %11 monotonic, align 8, !dbg !186 - %12 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %4, align 8, !dbg !187 - %13 = add nsw i32 %3, 1, !dbg !188 - %14 = load i32, i32* %6, align 8, !dbg !189 - %15 = srem i32 %13, %14, !dbg !190 - %16 = sext i32 %15 to i64, !dbg !191 - %17 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %12, i64 %16, !dbg !191 - %18 = bitcast %struct.awnsb_node_t** %17 to i64*, !dbg !192 - %19 = load atomic i64, i64* %18 acquire, align 8, !dbg !192 - %20 = inttoptr i64 %19 to %struct.awnsb_node_t*, !dbg !192 - call void @llvm.dbg.value(metadata %struct.awnsb_node_t* %20, metadata !193, metadata !DIExpression()), !dbg !178 - %21 = icmp ne %struct.awnsb_node_t* %20, null, !dbg !194 - br i1 %21, label %22, label %24, !dbg !196 - -22: ; preds = %1 - %23 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %20, i32 0, i32 0, !dbg !197 - store atomic i32 1, i32* %23 release, align 4, !dbg !199 - br label %25, !dbg !200 - -24: ; preds = %1 - store atomic i32 %13, i32* %2 release, align 4, !dbg !201 - br label %25 - -25: ; preds = %24, %22 - ret void, !dbg !203 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @ticket_awnsb_mutex_unlock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 { + %2 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca %struct.awnsb_node_t*, align 8 + %6 = alloca %struct.awnsb_node_t*, align 8 + %7 = alloca %struct.awnsb_node_t*, align 8 + %8 = alloca i32, align 4 + %9 = alloca i32, align 4 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %2, align 8 + %10 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %11 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %10, i32 0, i32 2 + %12 = load atomic i32, i32* %11 monotonic, align 4 + store i32 %12, i32* %4, align 4 + %13 = load i32, i32* %4, align 4 + store i32 %13, i32* %3, align 4 + %14 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %15 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %14, i32 0, i32 5 + %16 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %15, align 8 + %17 = load i32, i32* %3, align 4 + %18 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %19 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %18, i32 0, i32 4 + %20 = load i32, i32* %19, align 8 + %21 = srem i32 %17, %20 + %22 = sext i32 %21 to i64 + %23 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %16, i64 %22 + store %struct.awnsb_node_t* null, %struct.awnsb_node_t** %5, align 8 + %24 = bitcast %struct.awnsb_node_t** %23 to i64* + %25 = bitcast %struct.awnsb_node_t** %5 to i64* + %26 = load i64, i64* %25, align 8 + store atomic i64 %26, i64* %24 monotonic, align 8 + %27 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %28 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %27, i32 0, i32 5 + %29 = load %struct.awnsb_node_t**, %struct.awnsb_node_t*** %28, align 8 + %30 = load i32, i32* %3, align 4 + %31 = add nsw i32 %30, 1 + %32 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %33 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %32, i32 0, i32 4 + %34 = load i32, i32* %33, align 8 + %35 = srem i32 %31, %34 + %36 = sext i32 %35 to i64 + %37 = getelementptr inbounds %struct.awnsb_node_t*, %struct.awnsb_node_t** %29, i64 %36 + %38 = bitcast %struct.awnsb_node_t** %37 to i64* + %39 = bitcast %struct.awnsb_node_t** %7 to i64* + %40 = load atomic i64, i64* %38 acquire, align 8 + store i64 %40, i64* %39, align 8 + %41 = bitcast i64* %39 to %struct.awnsb_node_t** + %42 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %41, align 8 + store %struct.awnsb_node_t* %42, %struct.awnsb_node_t** %6, align 8 + %43 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %6, align 8 + %44 = icmp ne %struct.awnsb_node_t* %43, null + br i1 %44, label %45, label %49 + +45: ; preds = %1 + %46 = load %struct.awnsb_node_t*, %struct.awnsb_node_t** %6, align 8 + %47 = getelementptr inbounds %struct.awnsb_node_t, %struct.awnsb_node_t* %46, i32 0, i32 0 + store i32 1, i32* %8, align 4 + %48 = load i32, i32* %8, align 4 + store atomic i32 %48, i32* %47 release, align 4 + br label %55 + +49: ; preds = %1 + %50 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %2, align 8 + %51 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %50, i32 0, i32 2 + %52 = load i32, i32* %3, align 4 + %53 = add nsw i32 %52, 1 + store i32 %53, i32* %9, align 4 + %54 = load i32, i32* %9, align 4 + store atomic i32 %54, i32* %51 release, align 4 + br label %55 + +55: ; preds = %49, %45 + ret void } -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @ticket_awnsb_mutex_trylock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 !dbg !204 { - call void @llvm.dbg.value(metadata %struct.ticket_awnsb_mutex_t* %0, metadata !207, metadata !DIExpression()), !dbg !208 - %2 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 2, !dbg !209 - %3 = load atomic i32, i32* %2 seq_cst, align 4, !dbg !209 - call void @llvm.dbg.value(metadata i32 %3, metadata !210, metadata !DIExpression()), !dbg !208 - %4 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %0, i32 0, i32 0, !dbg !211 - %5 = load atomic i32, i32* %4 monotonic, align 8, !dbg !212 - call void @llvm.dbg.value(metadata i32 %5, metadata !213, metadata !DIExpression()), !dbg !208 - %6 = icmp ne i32 %3, %5, !dbg !214 - br i1 %6, label %13, label %7, !dbg !216 - -7: ; preds = %1 - %8 = load atomic i32, i32* %4 seq_cst, align 4, !dbg !217 - %9 = add nsw i32 %8, 1, !dbg !217 - %10 = cmpxchg i32* %4, i32 %3, i32 %9 seq_cst seq_cst, align 4, !dbg !217 - %11 = extractvalue { i32, i1 } %10, 1, !dbg !217 - %12 = zext i1 %11 to i8, !dbg !217 - %spec.select = select i1 %11, i32 0, i32 16, !dbg !219 - br label %13, !dbg !219 - -13: ; preds = %7, %1 - %.0 = phi i32 [ 16, %1 ], [ %spec.select, %7 ], !dbg !208 - ret i32 %.0, !dbg !220 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @ticket_awnsb_mutex_trylock(%struct.ticket_awnsb_mutex_t* noundef %0) #0 { + %2 = alloca i32, align 4 + %3 = alloca %struct.ticket_awnsb_mutex_t*, align 8 + %4 = alloca i32, align 4 + %5 = alloca i32, align 4 + %6 = alloca i32, align 4 + %7 = alloca i32, align 4 + %8 = alloca i32, align 4 + %9 = alloca i8, align 1 + store %struct.ticket_awnsb_mutex_t* %0, %struct.ticket_awnsb_mutex_t** %3, align 8 + %10 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %11 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %10, i32 0, i32 2 + %12 = load atomic i32, i32* %11 seq_cst, align 4 + store i32 %12, i32* %5, align 4 + %13 = load i32, i32* %5, align 4 + store i32 %13, i32* %4, align 4 + %14 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %15 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %14, i32 0, i32 0 + %16 = load atomic i32, i32* %15 monotonic, align 8 + store i32 %16, i32* %7, align 4 + %17 = load i32, i32* %7, align 4 + store i32 %17, i32* %6, align 4 + %18 = load i32, i32* %4, align 4 + %19 = load i32, i32* %6, align 4 + %20 = icmp ne i32 %18, %19 + br i1 %20, label %21, label %22 + +21: ; preds = %1 + store i32 16, i32* %2, align 4 + br label %41 + +22: ; preds = %1 + %23 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %24 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %23, i32 0, i32 0 + %25 = load %struct.ticket_awnsb_mutex_t*, %struct.ticket_awnsb_mutex_t** %3, align 8 + %26 = getelementptr inbounds %struct.ticket_awnsb_mutex_t, %struct.ticket_awnsb_mutex_t* %25, i32 0, i32 0 + %27 = load atomic i32, i32* %26 seq_cst, align 4 + %28 = add nsw i32 %27, 1 + store i32 %28, i32* %8, align 4 + %29 = load i32, i32* %6, align 4 + %30 = load i32, i32* %8, align 4 + %31 = cmpxchg i32* %24, i32 %29, i32 %30 seq_cst seq_cst, align 4 + %32 = extractvalue { i32, i1 } %31, 0 + %33 = extractvalue { i32, i1 } %31, 1 + br i1 %33, label %35, label %34 + +34: ; preds = %22 + store i32 %32, i32* %6, align 4 + br label %35 + +35: ; preds = %34, %22 + %36 = zext i1 %33 to i8 + store i8 %36, i8* %9, align 1 + %37 = load i8, i8* %9, align 1 + %38 = trunc i8 %37 to i1 + br i1 %38, label %40, label %39 + +39: ; preds = %35 + store i32 16, i32* %2, align 4 + br label %41 + +40: ; preds = %35 + store i32 0, i32* %2, align 4 + br label %41 + +41: ; preds = %40, %39, %21 + %42 = load i32, i32* %2, align 4 + ret i32 %42 } -; Function Attrs: noinline nounwind uwtable -define dso_local i8* @thread_n(i8* noundef %0) #0 !dbg !221 { - call void @llvm.dbg.value(metadata i8* %0, metadata !224, metadata !DIExpression()), !dbg !225 - %2 = ptrtoint i8* %0 to i64, !dbg !226 - call void @llvm.dbg.value(metadata i64 %2, metadata !227, metadata !DIExpression()), !dbg !225 - call void @ticket_awnsb_mutex_lock(%struct.ticket_awnsb_mutex_t* noundef @lock), !dbg !228 - %3 = trunc i64 %2 to i32, !dbg !229 - store i32 %3, i32* @shared, align 4, !dbg !230 - call void @llvm.dbg.value(metadata i32 %3, metadata !231, metadata !DIExpression()), !dbg !225 - %4 = sext i32 %3 to i64, !dbg !232 - %5 = icmp eq i64 %4, %2, !dbg !232 - br i1 %5, label %7, label %6, !dbg !235 - -6: ; preds = %1 - call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([60 x i8], [60 x i8]* @.str.1, i64 0, i64 0), i32 noundef 20, i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @__PRETTY_FUNCTION__.thread_n, i64 0, i64 0)) #6, !dbg !232 - unreachable, !dbg !232 - -7: ; preds = %1 - %8 = load i32, i32* @sum, align 4, !dbg !236 - %9 = add nsw i32 %8, 1, !dbg !236 - store i32 %9, i32* @sum, align 4, !dbg !236 - call void @ticket_awnsb_mutex_unlock(%struct.ticket_awnsb_mutex_t* noundef @lock), !dbg !237 - ret i8* null, !dbg !238 +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8* @thread_n(i8* noundef %0) #0 { + %2 = alloca i8*, align 8 + %3 = alloca i64, align 8 + %4 = alloca i32, align 4 + store i8* %0, i8** %2, align 8 + %5 = load i8*, i8** %2, align 8 + %6 = ptrtoint i8* %5 to i64 + store i64 %6, i64* %3, align 8 + call void @ticket_awnsb_mutex_lock(%struct.ticket_awnsb_mutex_t* noundef @lock) + %7 = load i64, i64* %3, align 8 + %8 = trunc i64 %7 to i32 + store i32 %8, i32* @shared, align 4 + %9 = load i32, i32* @shared, align 4 + store i32 %9, i32* %4, align 4 + %10 = load i32, i32* %4, align 4 + %11 = sext i32 %10 to i64 + %12 = load i64, i64* %3, align 8 + %13 = icmp eq i64 %11, %12 + br i1 %13, label %14, label %15 + +14: ; preds = %1 + br label %16 + +15: ; preds = %1 + call void @__assert_fail(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i8* noundef getelementptr inbounds ([38 x i8], [38 x i8]* @.str.1, i64 0, i64 0), i32 noundef 20, i8* noundef getelementptr inbounds ([23 x i8], [23 x i8]* @__PRETTY_FUNCTION__.thread_n, i64 0, i64 0)) #5 + unreachable + +16: ; preds = %14 + %17 = load i32, i32* @sum, align 4 + %18 = add nsw i32 %17, 1 + store i32 %18, i32* @sum, align 4 + call void @ticket_awnsb_mutex_unlock(%struct.ticket_awnsb_mutex_t* noundef @lock) + ret i8* null } ; Function Attrs: noreturn nounwind -declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #4 - -; Function Attrs: noinline nounwind uwtable -define dso_local i32 @main() #0 !dbg !239 { - %1 = alloca [3 x i64], align 16 - call void @llvm.dbg.declare(metadata [3 x i64]* %1, metadata !242, metadata !DIExpression()), !dbg !248 - call void @ticket_awnsb_mutex_init(%struct.ticket_awnsb_mutex_t* noundef @lock, i32 noundef 3), !dbg !249 - call void @llvm.dbg.value(metadata i32 0, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i64 0, metadata !250, metadata !DIExpression()), !dbg !252 - %2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0, !dbg !253 - %3 = call i32 @pthread_create(i64* noundef %2, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef null) #5, !dbg !255 - call void @llvm.dbg.value(metadata i64 1, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i64 1, metadata !250, metadata !DIExpression()), !dbg !252 - %4 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1, !dbg !253 - %5 = call i32 @pthread_create(i64* noundef %4, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef inttoptr (i64 1 to i8*)) #5, !dbg !255 - call void @llvm.dbg.value(metadata i64 2, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i64 2, metadata !250, metadata !DIExpression()), !dbg !252 - %6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2, !dbg !253 - %7 = call i32 @pthread_create(i64* noundef %6, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef inttoptr (i64 2 to i8*)) #5, !dbg !255 - call void @llvm.dbg.value(metadata i64 3, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i64 3, metadata !250, metadata !DIExpression()), !dbg !252 - call void @llvm.dbg.value(metadata i32 0, metadata !256, metadata !DIExpression()), !dbg !258 - call void @llvm.dbg.value(metadata i64 0, metadata !256, metadata !DIExpression()), !dbg !258 - %8 = load i64, i64* %2, align 8, !dbg !259 - %9 = call i32 @pthread_join(i64 noundef %8, i8** noundef null), !dbg !261 - call void @llvm.dbg.value(metadata i64 1, metadata !256, metadata !DIExpression()), !dbg !258 - call void @llvm.dbg.value(metadata i64 1, metadata !256, metadata !DIExpression()), !dbg !258 - %10 = load i64, i64* %4, align 8, !dbg !259 - %11 = call i32 @pthread_join(i64 noundef %10, i8** noundef null), !dbg !261 - call void @llvm.dbg.value(metadata i64 2, metadata !256, metadata !DIExpression()), !dbg !258 - call void @llvm.dbg.value(metadata i64 2, metadata !256, metadata !DIExpression()), !dbg !258 - %12 = load i64, i64* %6, align 8, !dbg !259 - %13 = call i32 @pthread_join(i64 noundef %12, i8** noundef null), !dbg !261 - call void @llvm.dbg.value(metadata i64 3, metadata !256, metadata !DIExpression()), !dbg !258 - call void @llvm.dbg.value(metadata i64 3, metadata !256, metadata !DIExpression()), !dbg !258 - %14 = load i32, i32* @sum, align 4, !dbg !262 - %15 = icmp eq i32 %14, 3, !dbg !262 - br i1 %15, label %17, label %16, !dbg !265 - -16: ; preds = %0 - call void @__assert_fail(i8* noundef getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([60 x i8], [60 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #6, !dbg !262 - unreachable, !dbg !262 - -17: ; preds = %0 - ret i32 0, !dbg !266 +declare void @__assert_fail(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca [3 x i64], align 16 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + call void @ticket_awnsb_mutex_init(%struct.ticket_awnsb_mutex_t* noundef @lock, i32 noundef 3) + store i32 0, i32* %3, align 4 + br label %5 + +5: ; preds = %16, %0 + %6 = load i32, i32* %3, align 4 + %7 = icmp slt i32 %6, 3 + br i1 %7, label %8, label %19 + +8: ; preds = %5 + %9 = load i32, i32* %3, align 4 + %10 = sext i32 %9 to i64 + %11 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %10 + %12 = load i32, i32* %3, align 4 + %13 = sext i32 %12 to i64 + %14 = inttoptr i64 %13 to i8* + %15 = call i32 @pthread_create(i64* noundef %11, %union.pthread_attr_t* noundef null, i8* (i8*)* noundef @thread_n, i8* noundef %14) #4 + br label %16 + +16: ; preds = %8 + %17 = load i32, i32* %3, align 4 + %18 = add nsw i32 %17, 1 + store i32 %18, i32* %3, align 4 + br label %5, !llvm.loop !12 + +19: ; preds = %5 + store i32 0, i32* %4, align 4 + br label %20 + +20: ; preds = %29, %19 + %21 = load i32, i32* %4, align 4 + %22 = icmp slt i32 %21, 3 + br i1 %22, label %23, label %32 + +23: ; preds = %20 + %24 = load i32, i32* %4, align 4 + %25 = sext i32 %24 to i64 + %26 = getelementptr inbounds [3 x i64], [3 x i64]* %2, i64 0, i64 %25 + %27 = load i64, i64* %26, align 8 + %28 = call i32 @pthread_join(i64 noundef %27, i8** noundef null) + br label %29 + +29: ; preds = %23 + %30 = load i32, i32* %4, align 4 + %31 = add nsw i32 %30, 1 + store i32 %31, i32* %4, align 4 + br label %20, !llvm.loop !13 + +32: ; preds = %20 + %33 = load i32, i32* @sum, align 4 + %34 = icmp eq i32 %33, 3 + br i1 %34, label %35, label %36 + +35: ; preds = %32 + br label %37 + +36: ; preds = %32 + call void @__assert_fail(i8* noundef getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i8* noundef getelementptr inbounds ([38 x i8], [38 x i8]* @.str.1, i64 0, i64 0), i32 noundef 38, i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__PRETTY_FUNCTION__.main, i64 0, i64 0)) #5 + unreachable + +37: ; preds = %35 + call void @ticket_awnsb_mutex_destroy(%struct.ticket_awnsb_mutex_t* noundef @lock) + ret i32 0 } ; Function Attrs: nounwind -declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 - -declare i32 @pthread_join(i64 noundef, i8** noundef) #3 - -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.value(metadata, metadata, metadata) #1 - -attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nounwind } -attributes #6 = { noreturn nounwind } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!55, !56, !57, !58, !59, !60, !61} -!llvm.ident = !{!62} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "tlNode", scope: !2, file: !20, line: 143, type: !19, isLocal: true, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Ubuntu clang version 14.0.6", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !15, globals: !34, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "/home/ponce/git/Dat3M/benchmarks/locks/ticket_awnsb_mutex.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "20563f8b3b1d8adf516623558b564708") -!4 = !{!5} -!5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "memory_order", file: !6, line: 56, baseType: !7, size: 32, elements: !8) -!6 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stdatomic.h", directory: "", checksumkind: CSK_MD5, checksum: "de5d66a1ef2f5448cc1919ff39db92bc") -!7 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!8 = !{!9, !10, !11, !12, !13, !14} -!9 = !DIEnumerator(name: "memory_order_relaxed", value: 0) -!10 = !DIEnumerator(name: "memory_order_consume", value: 1) -!11 = !DIEnumerator(name: "memory_order_acquire", value: 2) -!12 = !DIEnumerator(name: "memory_order_release", value: 3) -!13 = !DIEnumerator(name: "memory_order_acq_rel", value: 4) -!14 = !DIEnumerator(name: "memory_order_seq_cst", value: 5) -!15 = !{!16, !26, !27, !28, !31} -!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) -!17 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !18) -!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) -!19 = !DIDerivedType(tag: DW_TAG_typedef, name: "awnsb_node_t", file: !20, line: 125, baseType: !21) -!20 = !DIFile(filename: "benchmarks/locks/ticket_awnsb_mutex.h", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "03045fdddbaf6ab40e7d6c6e55719514") -!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !20, line: 123, size: 32, elements: !22) -!22 = !{!23} -!23 = !DIDerivedType(tag: DW_TAG_member, name: "lockIsMine", scope: !21, file: !20, line: 124, baseType: !24, size: 32) -!24 = !DIDerivedType(tag: DW_TAG_typedef, name: "atomic_int", file: !6, line: 92, baseType: !25) -!25 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !26) -!26 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!28 = !DIDerivedType(tag: DW_TAG_typedef, name: "intptr_t", file: !29, line: 87, baseType: !30) -!29 = !DIFile(filename: "/usr/include/stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "24103e292ae21916e87130b926c8d2f8") -!30 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !32, line: 46, baseType: !33) -!32 = !DIFile(filename: "/usr/lib/llvm-14/lib/clang/14.0.6/include/stddef.h", directory: "", checksumkind: CSK_MD5, checksum: "2499dd2361b915724b073282bea3a7bc") -!33 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!34 = !{!35, !0, !38, !40} -!35 = !DIGlobalVariableExpression(var: !36, expr: !DIExpression()) -!36 = distinct !DIGlobalVariable(name: "sum", scope: !2, file: !37, line: 11, type: !26, isLocal: false, isDefinition: true) -!37 = !DIFile(filename: "benchmarks/locks/ticket_awnsb_mutex.c", directory: "/home/ponce/git/Dat3M", checksumkind: CSK_MD5, checksum: "20563f8b3b1d8adf516623558b564708") -!38 = !DIGlobalVariableExpression(var: !39, expr: !DIExpression()) -!39 = distinct !DIGlobalVariable(name: "shared", scope: !2, file: !37, line: 9, type: !26, isLocal: false, isDefinition: true) -!40 = !DIGlobalVariableExpression(var: !41, expr: !DIExpression()) -!41 = distinct !DIGlobalVariable(name: "lock", scope: !2, file: !37, line: 10, type: !42, isLocal: false, isDefinition: true) -!42 = !DIDerivedType(tag: DW_TAG_typedef, name: "ticket_awnsb_mutex_t", file: !20, line: 135, baseType: !43) -!43 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !20, line: 127, size: 320, elements: !44) -!44 = !{!45, !46, !51, !52, !53, !54} -!45 = !DIDerivedType(tag: DW_TAG_member, name: "ingress", scope: !43, file: !20, line: 129, baseType: !24, size: 32) -!46 = !DIDerivedType(tag: DW_TAG_member, name: "padding1", scope: !43, file: !20, line: 130, baseType: !47, size: 64, offset: 32) -!47 = !DICompositeType(tag: DW_TAG_array_type, baseType: !48, size: 64, elements: !49) -!48 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -!49 = !{!50} -!50 = !DISubrange(count: 8) -!51 = !DIDerivedType(tag: DW_TAG_member, name: "egress", scope: !43, file: !20, line: 131, baseType: !24, size: 32, offset: 96) -!52 = !DIDerivedType(tag: DW_TAG_member, name: "padding2", scope: !43, file: !20, line: 132, baseType: !47, size: 64, offset: 128) -!53 = !DIDerivedType(tag: DW_TAG_member, name: "maxArrayWaiters", scope: !43, file: !20, line: 133, baseType: !26, size: 32, offset: 192) -!54 = !DIDerivedType(tag: DW_TAG_member, name: "waitersArray", scope: !43, file: !20, line: 134, baseType: !16, size: 64, offset: 256) -!55 = !{i32 7, !"Dwarf Version", i32 5} -!56 = !{i32 2, !"Debug Info Version", i32 3} -!57 = !{i32 1, !"wchar_size", i32 4} -!58 = !{i32 7, !"PIC Level", i32 2} -!59 = !{i32 7, !"PIE Level", i32 2} -!60 = !{i32 7, !"uwtable", i32 1} -!61 = !{i32 7, !"frame-pointer", i32 2} -!62 = !{!"Ubuntu clang version 14.0.6"} -!63 = distinct !DISubprogram(name: "ticket_awnsb_mutex_init", scope: !20, file: !20, line: 153, type: !64, scopeLine: 154, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!64 = !DISubroutineType(types: !65) -!65 = !{null, !66, !26} -!66 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !42, size: 64) -!67 = !{} -!68 = !DILocalVariable(name: "self", arg: 1, scope: !63, file: !20, line: 153, type: !66) -!69 = !DILocation(line: 0, scope: !63) -!70 = !DILocalVariable(name: "maxArrayWaiters", arg: 2, scope: !63, file: !20, line: 153, type: !26) -!71 = !DILocation(line: 155, column: 24, scope: !63) -!72 = !DILocation(line: 155, column: 5, scope: !63) -!73 = !DILocation(line: 156, column: 24, scope: !63) -!74 = !DILocation(line: 156, column: 5, scope: !63) -!75 = !DILocation(line: 157, column: 11, scope: !63) -!76 = !DILocation(line: 157, column: 27, scope: !63) -!77 = !DILocation(line: 158, column: 59, scope: !63) -!78 = !DILocation(line: 158, column: 80, scope: !63) -!79 = !DILocation(line: 158, column: 52, scope: !63) -!80 = !DILocation(line: 158, column: 26, scope: !63) -!81 = !DILocation(line: 158, column: 11, scope: !63) -!82 = !DILocation(line: 158, column: 24, scope: !63) -!83 = !DILocation(line: 159, column: 5, scope: !63) -!84 = !DILocalVariable(name: "i", scope: !85, file: !20, line: 160, type: !26) -!85 = distinct !DILexicalBlock(scope: !63, file: !20, line: 160, column: 5) -!86 = !DILocation(line: 0, scope: !85) -!87 = !DILocation(line: 160, column: 10, scope: !85) -!88 = !DILocation(line: 160, column: 31, scope: !89) -!89 = distinct !DILexicalBlock(scope: !85, file: !20, line: 160, column: 5) -!90 = !DILocation(line: 160, column: 23, scope: !89) -!91 = !DILocation(line: 160, column: 5, scope: !85) -!92 = !DILocation(line: 160, column: 72, scope: !89) -!93 = !DILocation(line: 160, column: 66, scope: !89) -!94 = !DILocation(line: 160, column: 53, scope: !89) -!95 = !DILocation(line: 160, column: 49, scope: !89) -!96 = !DILocation(line: 160, column: 5, scope: !89) -!97 = distinct !{!97, !91, !98, !99} -!98 = !DILocation(line: 160, column: 93, scope: !85) -!99 = !{!"llvm.loop.mustprogress"} -!100 = !DILocation(line: 161, column: 1, scope: !63) -!101 = distinct !DISubprogram(name: "ticket_awnsb_mutex_destroy", scope: !20, file: !20, line: 164, type: !102, scopeLine: 165, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!102 = !DISubroutineType(types: !103) -!103 = !{null, !66} -!104 = !DILocalVariable(name: "self", arg: 1, scope: !101, file: !20, line: 164, type: !66) -!105 = !DILocation(line: 0, scope: !101) -!106 = !DILocation(line: 166, column: 5, scope: !101) -!107 = !DILocation(line: 167, column: 5, scope: !101) -!108 = !DILocation(line: 168, column: 16, scope: !101) -!109 = !DILocation(line: 168, column: 10, scope: !101) -!110 = !DILocation(line: 168, column: 5, scope: !101) -!111 = !DILocation(line: 169, column: 1, scope: !101) -!112 = distinct !DISubprogram(name: "ticket_awnsb_mutex_lock", scope: !20, file: !20, line: 179, type: !102, scopeLine: 180, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!113 = !DILocalVariable(name: "self", arg: 1, scope: !112, file: !20, line: 179, type: !66) -!114 = !DILocation(line: 0, scope: !112) -!115 = !DILocation(line: 181, column: 57, scope: !112) -!116 = !DILocation(line: 181, column: 24, scope: !112) -!117 = !DILocalVariable(name: "ticket", scope: !112, file: !20, line: 181, type: !118) -!118 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !26) -!119 = !DILocation(line: 185, column: 37, scope: !120) -!120 = distinct !DILexicalBlock(scope: !112, file: !20, line: 185, column: 9) -!121 = !DILocation(line: 185, column: 9, scope: !120) -!122 = !DILocation(line: 185, column: 67, scope: !120) -!123 = !DILocation(line: 185, column: 9, scope: !112) -!124 = !DILocation(line: 187, column: 5, scope: !112) -!125 = !DILocation(line: 187, column: 12, scope: !112) -!126 = !DILocation(line: 187, column: 79, scope: !112) -!127 = !DILocation(line: 187, column: 70, scope: !112) -!128 = !DILocation(line: 191, column: 87, scope: !112) -!129 = !DILocation(line: 188, column: 13, scope: !130) -!130 = distinct !DILexicalBlock(scope: !131, file: !20, line: 188, column: 13) -!131 = distinct !DILexicalBlock(scope: !112, file: !20, line: 187, column: 83) -!132 = !DILocation(line: 188, column: 71, scope: !130) -!133 = !DILocation(line: 188, column: 13, scope: !131) -!134 = distinct !{!134, !124, !135, !99} -!135 = !DILocation(line: 189, column: 5, scope: !112) -!136 = !DILocation(line: 191, column: 19, scope: !112) -!137 = !DILocation(line: 191, column: 18, scope: !112) -!138 = !DILocation(line: 191, column: 102, scope: !112) -!139 = !DILocation(line: 191, column: 77, scope: !112) -!140 = !DILocation(line: 191, column: 5, scope: !112) -!141 = distinct !{!141, !140, !142, !99} -!142 = !DILocation(line: 191, column: 106, scope: !112) -!143 = !DILocalVariable(name: "wnode", scope: !112, file: !20, line: 194, type: !18) -!144 = !DILocation(line: 196, column: 5, scope: !112) -!145 = !DILocation(line: 197, column: 34, scope: !112) -!146 = !DILocation(line: 197, column: 68, scope: !112) -!147 = !DILocation(line: 197, column: 60, scope: !112) -!148 = !DILocation(line: 197, column: 28, scope: !112) -!149 = !DILocation(line: 197, column: 5, scope: !112) -!150 = !DILocation(line: 199, column: 9, scope: !151) -!151 = distinct !DILexicalBlock(scope: !112, file: !20, line: 199, column: 9) -!152 = !DILocation(line: 199, column: 67, scope: !151) -!153 = !DILocation(line: 199, column: 9, scope: !112) -!154 = !DILocation(line: 201, column: 17, scope: !155) -!155 = distinct !DILexicalBlock(scope: !151, file: !20, line: 199, column: 79) -!156 = !DILocation(line: 201, column: 16, scope: !155) -!157 = !DILocation(line: 201, column: 9, scope: !155) -!158 = distinct !{!158, !157, !159, !99} -!159 = !DILocation(line: 201, column: 80, scope: !155) -!160 = !DILocation(line: 202, column: 9, scope: !155) -!161 = !DILocation(line: 203, column: 5, scope: !155) -!162 = !DILocation(line: 205, column: 16, scope: !163) -!163 = distinct !DILexicalBlock(scope: !151, file: !20, line: 203, column: 12) -!164 = !DILocation(line: 205, column: 74, scope: !163) -!165 = !DILocation(line: 205, column: 9, scope: !163) -!166 = !DILocation(line: 206, column: 17, scope: !167) -!167 = distinct !DILexicalBlock(scope: !168, file: !20, line: 206, column: 17) -!168 = distinct !DILexicalBlock(scope: !163, file: !20, line: 205, column: 85) -!169 = !DILocation(line: 206, column: 17, scope: !168) -!170 = distinct !{!170, !165, !171, !99} -!171 = !DILocation(line: 210, column: 9, scope: !163) -!172 = !DILocation(line: 207, column: 17, scope: !173) -!173 = distinct !DILexicalBlock(scope: !167, file: !20, line: 206, column: 81) -!174 = !DILocation(line: 208, column: 17, scope: !173) -!175 = !DILocation(line: 213, column: 1, scope: !112) -!176 = distinct !DISubprogram(name: "ticket_awnsb_mutex_unlock", scope: !20, file: !20, line: 222, type: !102, scopeLine: 223, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!177 = !DILocalVariable(name: "self", arg: 1, scope: !176, file: !20, line: 222, type: !66) -!178 = !DILocation(line: 0, scope: !176) -!179 = !DILocation(line: 224, column: 46, scope: !176) -!180 = !DILocation(line: 224, column: 18, scope: !176) -!181 = !DILocalVariable(name: "ticket", scope: !176, file: !20, line: 224, type: !26) -!182 = !DILocation(line: 226, column: 34, scope: !176) -!183 = !DILocation(line: 226, column: 68, scope: !176) -!184 = !DILocation(line: 226, column: 60, scope: !176) -!185 = !DILocation(line: 226, column: 28, scope: !176) -!186 = !DILocation(line: 226, column: 5, scope: !176) -!187 = !DILocation(line: 228, column: 56, scope: !176) -!188 = !DILocation(line: 228, column: 82, scope: !176) -!189 = !DILocation(line: 228, column: 94, scope: !176) -!190 = !DILocation(line: 228, column: 86, scope: !176) -!191 = !DILocation(line: 228, column: 50, scope: !176) -!192 = !DILocation(line: 228, column: 28, scope: !176) -!193 = !DILocalVariable(name: "wnode", scope: !176, file: !20, line: 228, type: !18) -!194 = !DILocation(line: 229, column: 15, scope: !195) -!195 = distinct !DILexicalBlock(scope: !176, file: !20, line: 229, column: 9) -!196 = !DILocation(line: 229, column: 9, scope: !176) -!197 = !DILocation(line: 231, column: 39, scope: !198) -!198 = distinct !DILexicalBlock(scope: !195, file: !20, line: 229, column: 24) -!199 = !DILocation(line: 231, column: 9, scope: !198) -!200 = !DILocation(line: 232, column: 5, scope: !198) -!201 = !DILocation(line: 233, column: 9, scope: !202) -!202 = distinct !DILexicalBlock(scope: !195, file: !20, line: 232, column: 12) -!203 = !DILocation(line: 235, column: 1, scope: !176) -!204 = distinct !DISubprogram(name: "ticket_awnsb_mutex_trylock", scope: !20, file: !20, line: 243, type: !205, scopeLine: 244, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!205 = !DISubroutineType(types: !206) -!206 = !{!26, !66} -!207 = !DILocalVariable(name: "self", arg: 1, scope: !204, file: !20, line: 243, type: !66) -!208 = !DILocation(line: 0, scope: !204) -!209 = !DILocation(line: 245, column: 18, scope: !204) -!210 = !DILocalVariable(name: "localE", scope: !204, file: !20, line: 245, type: !26) -!211 = !DILocation(line: 246, column: 46, scope: !204) -!212 = !DILocation(line: 246, column: 18, scope: !204) -!213 = !DILocalVariable(name: "localI", scope: !204, file: !20, line: 246, type: !26) -!214 = !DILocation(line: 247, column: 16, scope: !215) -!215 = distinct !DILexicalBlock(scope: !204, file: !20, line: 247, column: 9) -!216 = !DILocation(line: 247, column: 9, scope: !204) -!217 = !DILocation(line: 248, column: 10, scope: !218) -!218 = distinct !DILexicalBlock(scope: !204, file: !20, line: 248, column: 9) -!219 = !DILocation(line: 248, column: 9, scope: !204) -!220 = !DILocation(line: 251, column: 1, scope: !204) -!221 = distinct !DISubprogram(name: "thread_n", scope: !37, file: !37, line: 13, type: !222, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!222 = !DISubroutineType(types: !223) -!223 = !{!27, !27} -!224 = !DILocalVariable(name: "arg", arg: 1, scope: !221, file: !37, line: 13, type: !27) -!225 = !DILocation(line: 0, scope: !221) -!226 = !DILocation(line: 15, column: 23, scope: !221) -!227 = !DILocalVariable(name: "index", scope: !221, file: !37, line: 15, type: !28) -!228 = !DILocation(line: 17, column: 5, scope: !221) -!229 = !DILocation(line: 18, column: 14, scope: !221) -!230 = !DILocation(line: 18, column: 12, scope: !221) -!231 = !DILocalVariable(name: "r", scope: !221, file: !37, line: 19, type: !26) -!232 = !DILocation(line: 20, column: 5, scope: !233) -!233 = distinct !DILexicalBlock(scope: !234, file: !37, line: 20, column: 5) -!234 = distinct !DILexicalBlock(scope: !221, file: !37, line: 20, column: 5) -!235 = !DILocation(line: 20, column: 5, scope: !234) -!236 = !DILocation(line: 21, column: 8, scope: !221) -!237 = !DILocation(line: 22, column: 5, scope: !221) -!238 = !DILocation(line: 23, column: 5, scope: !221) -!239 = distinct !DISubprogram(name: "main", scope: !37, file: !37, line: 26, type: !240, scopeLine: 27, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !67) -!240 = !DISubroutineType(types: !241) -!241 = !{!26} -!242 = !DILocalVariable(name: "t", scope: !239, file: !37, line: 28, type: !243) -!243 = !DICompositeType(tag: DW_TAG_array_type, baseType: !244, size: 192, elements: !246) -!244 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !245, line: 27, baseType: !33) -!245 = !DIFile(filename: "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h", directory: "", checksumkind: CSK_MD5, checksum: "2d764266ce95ab26d4a4767c2ec78176") -!246 = !{!247} -!247 = !DISubrange(count: 3) -!248 = !DILocation(line: 28, column: 15, scope: !239) -!249 = !DILocation(line: 30, column: 5, scope: !239) -!250 = !DILocalVariable(name: "i", scope: !251, file: !37, line: 32, type: !26) -!251 = distinct !DILexicalBlock(scope: !239, file: !37, line: 32, column: 5) -!252 = !DILocation(line: 0, scope: !251) -!253 = !DILocation(line: 33, column: 25, scope: !254) -!254 = distinct !DILexicalBlock(scope: !251, file: !37, line: 32, column: 5) -!255 = !DILocation(line: 33, column: 9, scope: !254) -!256 = !DILocalVariable(name: "i", scope: !257, file: !37, line: 35, type: !26) -!257 = distinct !DILexicalBlock(scope: !239, file: !37, line: 35, column: 5) -!258 = !DILocation(line: 0, scope: !257) -!259 = !DILocation(line: 36, column: 22, scope: !260) -!260 = distinct !DILexicalBlock(scope: !257, file: !37, line: 35, column: 5) -!261 = !DILocation(line: 36, column: 9, scope: !260) -!262 = !DILocation(line: 38, column: 5, scope: !263) -!263 = distinct !DILexicalBlock(scope: !264, file: !37, line: 38, column: 5) -!264 = distinct !DILexicalBlock(scope: !239, file: !37, line: 38, column: 5) -!265 = !DILocation(line: 38, column: 5, scope: !264) -!266 = !DILocation(line: 40, column: 5, scope: !239) +declare i32 @pthread_create(i64* noundef, %union.pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #1 + +declare i32 @pthread_join(i64 noundef, i8** noundef) #2 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { noreturn nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { nounwind } +attributes #5 = { noreturn nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 1} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} +!9 = distinct !{!9, !7} +!10 = distinct !{!10, !7} +!11 = distinct !{!11, !7} +!12 = distinct !{!12, !7} +!13 = distinct !{!13, !7} diff --git a/dartagnan/src/test/resources/miscellaneous/pthread.ll b/dartagnan/src/test/resources/miscellaneous/pthread.ll index 5305cb3095..a127000600 100644 --- a/dartagnan/src/test/resources/miscellaneous/pthread.ll +++ b/dartagnan/src/test/resources/miscellaneous/pthread.ll @@ -1,1294 +1,1282 @@ -; ModuleID = '/Users/thomashaas/IdeaProjects/Dat3M/benchmarks/miscellaneous/pthread.c' -source_filename = "/Users/thomashaas/IdeaProjects/Dat3M/benchmarks/miscellaneous/pthread.c" -target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" -target triple = "arm64-apple-macosx14.0.0" - -%struct._opaque_pthread_mutex_t = type { i64, [56 x i8] } -%struct._opaque_pthread_cond_t = type { i64, [40 x i8] } -%struct._opaque_pthread_t = type { i64, %struct.__darwin_pthread_handler_rec*, [8176 x i8] } -%struct.__darwin_pthread_handler_rec = type { void (i8*)*, i8*, %struct.__darwin_pthread_handler_rec* } -%struct._opaque_pthread_attr_t = type { i64, [56 x i8] } -%struct._opaque_pthread_mutexattr_t = type { i64, [8 x i8] } -%struct._opaque_pthread_condattr_t = type { i64, [8 x i8] } +; ModuleID = 'benchmarks/miscellaneous/pthread.c' +source_filename = "benchmarks/miscellaneous/pthread.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%union.pthread_mutex_t = type { %struct.__pthread_mutex_s } +%struct.__pthread_mutex_s = type { i32, i32, i32, i32, i32, %union.anon } +%union.anon = type { %struct.__pthread_internal_slist } +%struct.__pthread_internal_slist = type { ptr } +%union.pthread_cond_t = type { %struct.__pthread_cond_s } +%struct.__pthread_cond_s = type { %union.__atomic_wide_counter, %union.__atomic_wide_counter, [2 x i32], [2 x i32], i32, i32, [2 x i32] } +%union.__atomic_wide_counter = type { i64 } +%union.pthread_attr_t = type { i64, [32 x i8] } +%union.pthread_mutexattr_t = type { i32 } +%union.pthread_condattr_t = type { i32 } %struct.timespec = type { i64, i64 } -%struct._opaque_pthread_rwlock_t = type { i64, [192 x i8] } -%struct._opaque_pthread_rwlockattr_t = type { i64, [16 x i8] } - -@__func__.thread_create = private unnamed_addr constant [14 x i8] c"thread_create\00", align 1 -@.str = private unnamed_addr constant [10 x i8] c"pthread.c\00", align 1 -@.str.1 = private unnamed_addr constant [12 x i8] c"status == 0\00", align 1 -@__func__.thread_join = private unnamed_addr constant [12 x i8] c"thread_join\00", align 1 -@__func__.mutex_init = private unnamed_addr constant [11 x i8] c"mutex_init\00", align 1 -@__func__.mutex_destroy = private unnamed_addr constant [14 x i8] c"mutex_destroy\00", align 1 -@__func__.mutex_lock = private unnamed_addr constant [11 x i8] c"mutex_lock\00", align 1 -@__func__.mutex_unlock = private unnamed_addr constant [13 x i8] c"mutex_unlock\00", align 1 -@__func__.mutex_test = private unnamed_addr constant [11 x i8] c"mutex_test\00", align 1 -@.str.2 = private unnamed_addr constant [9 x i8] c"!success\00", align 1 -@.str.3 = private unnamed_addr constant [8 x i8] c"success\00", align 1 -@__func__.cond_init = private unnamed_addr constant [10 x i8] c"cond_init\00", align 1 -@__func__.cond_destroy = private unnamed_addr constant [13 x i8] c"cond_destroy\00", align 1 -@__func__.cond_signal = private unnamed_addr constant [12 x i8] c"cond_signal\00", align 1 -@__func__.cond_broadcast = private unnamed_addr constant [15 x i8] c"cond_broadcast\00", align 1 -@phase = global i32 0, align 4, !dbg !0 -@cond_mutex = global %struct._opaque_pthread_mutex_t zeroinitializer, align 8, !dbg !9 -@cond = global %struct._opaque_pthread_cond_t zeroinitializer, align 8, !dbg !24 -@__func__.cond_test = private unnamed_addr constant [10 x i8] c"cond_test\00", align 1 -@.str.4 = private unnamed_addr constant [18 x i8] c"result == message\00", align 1 -@__func__.rwlock_init = private unnamed_addr constant [12 x i8] c"rwlock_init\00", align 1 -@__func__.rwlock_destroy = private unnamed_addr constant [15 x i8] c"rwlock_destroy\00", align 1 -@__func__.rwlock_wrlock = private unnamed_addr constant [14 x i8] c"rwlock_wrlock\00", align 1 -@__func__.rwlock_rdlock = private unnamed_addr constant [14 x i8] c"rwlock_rdlock\00", align 1 -@__func__.rwlock_unlock = private unnamed_addr constant [14 x i8] c"rwlock_unlock\00", align 1 -@__func__.rwlock_test = private unnamed_addr constant [12 x i8] c"rwlock_test\00", align 1 -@latest_thread = global %struct._opaque_pthread_t* null, align 8, !dbg !36 -@local_data = global i64 0, align 8, !dbg !59 -@__func__.key_worker = private unnamed_addr constant [11 x i8] c"key_worker\00", align 1 -@.str.5 = private unnamed_addr constant [28 x i8] c"my_local_data == &my_secret\00", align 1 -@__func__.key_test = private unnamed_addr constant [9 x i8] c"key_test\00", align 1 - -; Function Attrs: noinline nounwind ssp uwtable -define %struct._opaque_pthread_t* @thread_create(i8* (i8*)* noundef %0, i8* noundef %1) #0 !dbg !77 { - %3 = alloca i8* (i8*)*, align 8 - %4 = alloca i8*, align 8 - %5 = alloca %struct._opaque_pthread_t*, align 8 - %6 = alloca %struct._opaque_pthread_attr_t, align 8 +%union.pthread_rwlockattr_t = type { i64 } +%union.pthread_rwlock_t = type { i64, [24 x i8] } + +@__func__.thread_create = private unnamed_addr constant [14 x i8] c"thread_create\00", align 1, !dbg !0 +@.str = private unnamed_addr constant [10 x i8] c"pthread.c\00", align 1, !dbg !8 +@.str.1 = private unnamed_addr constant [12 x i8] c"status == 0\00", align 1, !dbg !13 +@__func__.thread_join = private unnamed_addr constant [12 x i8] c"thread_join\00", align 1, !dbg !18 +@__func__.mutex_init = private unnamed_addr constant [11 x i8] c"mutex_init\00", align 1, !dbg !21 +@__func__.mutex_destroy = private unnamed_addr constant [14 x i8] c"mutex_destroy\00", align 1, !dbg !26 +@__func__.mutex_lock = private unnamed_addr constant [11 x i8] c"mutex_lock\00", align 1, !dbg !28 +@__func__.mutex_unlock = private unnamed_addr constant [13 x i8] c"mutex_unlock\00", align 1, !dbg !30 +@__func__.mutex_test = private unnamed_addr constant [11 x i8] c"mutex_test\00", align 1, !dbg !35 +@.str.2 = private unnamed_addr constant [9 x i8] c"!success\00", align 1, !dbg !37 +@.str.3 = private unnamed_addr constant [8 x i8] c"success\00", align 1, !dbg !42 +@__func__.cond_init = private unnamed_addr constant [10 x i8] c"cond_init\00", align 1, !dbg !47 +@__func__.cond_destroy = private unnamed_addr constant [13 x i8] c"cond_destroy\00", align 1, !dbg !50 +@__func__.cond_signal = private unnamed_addr constant [12 x i8] c"cond_signal\00", align 1, !dbg !52 +@__func__.cond_broadcast = private unnamed_addr constant [15 x i8] c"cond_broadcast\00", align 1, !dbg !54 +@phase = dso_local global i32 0, align 4, !dbg !59 +@cond_mutex = dso_local global %union.pthread_mutex_t zeroinitializer, align 8, !dbg !140 +@cond = dso_local global %union.pthread_cond_t zeroinitializer, align 8, !dbg !175 +@__func__.cond_test = private unnamed_addr constant [10 x i8] c"cond_test\00", align 1, !dbg !92 +@.str.4 = private unnamed_addr constant [18 x i8] c"result == message\00", align 1, !dbg !94 +@__func__.rwlock_init = private unnamed_addr constant [12 x i8] c"rwlock_init\00", align 1, !dbg !99 +@__func__.rwlock_destroy = private unnamed_addr constant [15 x i8] c"rwlock_destroy\00", align 1, !dbg !101 +@__func__.rwlock_wrlock = private unnamed_addr constant [14 x i8] c"rwlock_wrlock\00", align 1, !dbg !103 +@__func__.rwlock_rdlock = private unnamed_addr constant [14 x i8] c"rwlock_rdlock\00", align 1, !dbg !105 +@__func__.rwlock_unlock = private unnamed_addr constant [14 x i8] c"rwlock_unlock\00", align 1, !dbg !107 +@__func__.rwlock_test = private unnamed_addr constant [12 x i8] c"rwlock_test\00", align 1, !dbg !109 +@latest_thread = dso_local global i64 0, align 8, !dbg !209 +@local_data = dso_local global i32 0, align 4, !dbg !213 +@__func__.key_worker = private unnamed_addr constant [11 x i8] c"key_worker\00", align 1, !dbg !111 +@.str.5 = private unnamed_addr constant [28 x i8] c"my_local_data == &my_secret\00", align 1, !dbg !113 +@__func__.key_test = private unnamed_addr constant [9 x i8] c"key_test\00", align 1, !dbg !118 +@__func__.detach_test_detach = private unnamed_addr constant [19 x i8] c"detach_test_detach\00", align 1, !dbg !121 +@.str.6 = private unnamed_addr constant [12 x i8] c"status != 0\00", align 1, !dbg !126 +@__func__.detach_test_attr = private unnamed_addr constant [17 x i8] c"detach_test_attr\00", align 1, !dbg !128 +@.str.7 = private unnamed_addr constant [54 x i8] c"status == 0 && detachstate == PTHREAD_CREATE_JOINABLE\00", align 1, !dbg !133 +@.str.8 = private unnamed_addr constant [54 x i8] c"status == 0 && detachstate == PTHREAD_CREATE_DETACHED\00", align 1, !dbg !138 + +; Function Attrs: noinline nounwind uwtable +define dso_local i64 @thread_create(ptr noundef %0, ptr noundef %1) #0 !dbg !224 { + %3 = alloca ptr, align 8 + %4 = alloca ptr, align 8 + %5 = alloca i64, align 8 + %6 = alloca %union.pthread_attr_t, align 8 %7 = alloca i32, align 4 - store i8* (i8*)* %0, i8* (i8*)** %3, align 8 - call void @llvm.dbg.declare(metadata i8* (i8*)** %3, metadata !84, metadata !DIExpression()), !dbg !85 - store i8* %1, i8** %4, align 8 - call void @llvm.dbg.declare(metadata i8** %4, metadata !86, metadata !DIExpression()), !dbg !87 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_t** %5, metadata !88, metadata !DIExpression()), !dbg !89 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_attr_t* %6, metadata !90, metadata !DIExpression()), !dbg !98 - %8 = call i32 @pthread_attr_init(%struct._opaque_pthread_attr_t* noundef %6), !dbg !99 - call void @llvm.dbg.declare(metadata i32* %7, metadata !100, metadata !DIExpression()), !dbg !101 - %9 = load i8* (i8*)*, i8* (i8*)** %3, align 8, !dbg !102 - %10 = load i8*, i8** %4, align 8, !dbg !103 - %11 = call i32 @pthread_create(%struct._opaque_pthread_t** noundef %5, %struct._opaque_pthread_attr_t* noundef %6, i8* (i8*)* noundef %9, i8* noundef %10), !dbg !104 - store i32 %11, i32* %7, align 4, !dbg !101 - %12 = load i32, i32* %7, align 4, !dbg !105 - %13 = icmp eq i32 %12, 0, !dbg !105 - %14 = xor i1 %13, true, !dbg !105 - %15 = zext i1 %14 to i32, !dbg !105 - %16 = sext i32 %15 to i64, !dbg !105 - %17 = icmp ne i64 %16, 0, !dbg !105 - br i1 %17, label %18, label %20, !dbg !105 + store ptr %0, ptr %3, align 8 + #dbg_declare(ptr %3, !231, !DIExpression(), !232) + store ptr %1, ptr %4, align 8 + #dbg_declare(ptr %4, !233, !DIExpression(), !234) + #dbg_declare(ptr %5, !235, !DIExpression(), !236) + #dbg_declare(ptr %6, !237, !DIExpression(), !246) + %8 = call i32 @pthread_attr_init(ptr noundef %6) #6, !dbg !247 + #dbg_declare(ptr %7, !248, !DIExpression(), !249) + %9 = load ptr, ptr %3, align 8, !dbg !250 + %10 = load ptr, ptr %4, align 8, !dbg !251 + %11 = call i32 @pthread_create(ptr noundef %5, ptr noundef %6, ptr noundef %9, ptr noundef %10) #7, !dbg !252 + store i32 %11, ptr %7, align 4, !dbg !249 + %12 = load i32, ptr %7, align 4, !dbg !253 + %13 = icmp eq i32 %12, 0, !dbg !253 + %14 = xor i1 %13, true, !dbg !253 + %15 = zext i1 %14 to i32, !dbg !253 + %16 = sext i32 %15 to i64, !dbg !253 + %17 = icmp ne i64 %16, 0, !dbg !253 + br i1 %17, label %18, label %20, !dbg !253 18: ; preds = %2 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__func__.thread_create, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 18, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !105 - unreachable, !dbg !105 + call void @__assert_rtn(ptr noundef @__func__.thread_create, ptr noundef @.str, i32 noundef 18, ptr noundef @.str.1) #8, !dbg !253 + unreachable, !dbg !253 19: ; No predecessors! - br label %21, !dbg !105 + br label %21, !dbg !253 20: ; preds = %2 - br label %21, !dbg !105 + br label %21, !dbg !253 21: ; preds = %20, %19 - %22 = call i32 @pthread_attr_destroy(%struct._opaque_pthread_attr_t* noundef %6), !dbg !106 - %23 = load %struct._opaque_pthread_t*, %struct._opaque_pthread_t** %5, align 8, !dbg !107 - ret %struct._opaque_pthread_t* %23, !dbg !108 + %22 = call i32 @pthread_attr_destroy(ptr noundef %6) #6, !dbg !254 + %23 = load i64, ptr %5, align 8, !dbg !255 + ret i64 %23, !dbg !256 } -; Function Attrs: nofree nosync nounwind readnone speculatable willreturn -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 +; Function Attrs: nocallback nounwind +declare i32 @pthread_attr_init(ptr noundef) #1 -declare i32 @pthread_attr_init(%struct._opaque_pthread_attr_t* noundef) #2 - -declare i32 @pthread_create(%struct._opaque_pthread_t** noundef, %struct._opaque_pthread_attr_t* noundef, i8* (i8*)* noundef, i8* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #2 ; Function Attrs: cold noreturn -declare void @__assert_rtn(i8* noundef, i8* noundef, i32 noundef, i8* noundef) #3 +declare void @__assert_rtn(ptr noundef, ptr noundef, i32 noundef, ptr noundef) #3 -declare i32 @pthread_attr_destroy(%struct._opaque_pthread_attr_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_attr_destroy(ptr noundef) #1 -; Function Attrs: noinline nounwind ssp uwtable -define i8* @thread_join(%struct._opaque_pthread_t* noundef %0) #0 !dbg !109 { - %2 = alloca %struct._opaque_pthread_t*, align 8 - %3 = alloca i8*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local ptr @thread_join(i64 noundef %0) #0 !dbg !257 { + %2 = alloca i64, align 8 + %3 = alloca ptr, align 8 %4 = alloca i32, align 4 - store %struct._opaque_pthread_t* %0, %struct._opaque_pthread_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_t** %2, metadata !112, metadata !DIExpression()), !dbg !113 - call void @llvm.dbg.declare(metadata i8** %3, metadata !114, metadata !DIExpression()), !dbg !115 - call void @llvm.dbg.declare(metadata i32* %4, metadata !116, metadata !DIExpression()), !dbg !117 - %5 = load %struct._opaque_pthread_t*, %struct._opaque_pthread_t** %2, align 8, !dbg !118 - %6 = call i32 @"\01_pthread_join"(%struct._opaque_pthread_t* noundef %5, i8** noundef %3), !dbg !119 - store i32 %6, i32* %4, align 4, !dbg !117 - %7 = load i32, i32* %4, align 4, !dbg !120 - %8 = icmp eq i32 %7, 0, !dbg !120 - %9 = xor i1 %8, true, !dbg !120 - %10 = zext i1 %9 to i32, !dbg !120 - %11 = sext i32 %10 to i64, !dbg !120 - %12 = icmp ne i64 %11, 0, !dbg !120 - br i1 %12, label %13, label %15, !dbg !120 + store i64 %0, ptr %2, align 8 + #dbg_declare(ptr %2, !260, !DIExpression(), !261) + #dbg_declare(ptr %3, !262, !DIExpression(), !263) + #dbg_declare(ptr %4, !264, !DIExpression(), !265) + %5 = load i64, ptr %2, align 8, !dbg !266 + %6 = call i32 @pthread_join(i64 noundef %5, ptr noundef %3), !dbg !267 + store i32 %6, ptr %4, align 4, !dbg !265 + %7 = load i32, ptr %4, align 4, !dbg !268 + %8 = icmp eq i32 %7, 0, !dbg !268 + %9 = xor i1 %8, true, !dbg !268 + %10 = zext i1 %9 to i32, !dbg !268 + %11 = sext i32 %10 to i64, !dbg !268 + %12 = icmp ne i64 %11, 0, !dbg !268 + br i1 %12, label %13, label %15, !dbg !268 13: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.thread_join, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 27, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !120 - unreachable, !dbg !120 + call void @__assert_rtn(ptr noundef @__func__.thread_join, ptr noundef @.str, i32 noundef 27, ptr noundef @.str.1) #8, !dbg !268 + unreachable, !dbg !268 14: ; No predecessors! - br label %16, !dbg !120 + br label %16, !dbg !268 15: ; preds = %1 - br label %16, !dbg !120 + br label %16, !dbg !268 16: ; preds = %15, %14 - %17 = load i8*, i8** %3, align 8, !dbg !121 - ret i8* %17, !dbg !122 + %17 = load ptr, ptr %3, align 8, !dbg !269 + ret ptr %17, !dbg !270 } -declare i32 @"\01_pthread_join"(%struct._opaque_pthread_t* noundef, i8** noundef) #2 +declare i32 @pthread_join(i64 noundef, ptr noundef) #4 -; Function Attrs: noinline nounwind ssp uwtable -define void @mutex_init(%struct._opaque_pthread_mutex_t* noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3, i32 noundef %4) #0 !dbg !123 { - %6 = alloca %struct._opaque_pthread_mutex_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @mutex_init(ptr noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3) #0 !dbg !271 { + %5 = alloca ptr, align 8 + %6 = alloca i32, align 4 %7 = alloca i32, align 4 %8 = alloca i32, align 4 %9 = alloca i32, align 4 %10 = alloca i32, align 4 - %11 = alloca i32, align 4 - %12 = alloca i32, align 4 - %13 = alloca %struct._opaque_pthread_mutexattr_t, align 8 - store %struct._opaque_pthread_mutex_t* %0, %struct._opaque_pthread_mutex_t** %6, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutex_t** %6, metadata !127, metadata !DIExpression()), !dbg !128 - store i32 %1, i32* %7, align 4 - call void @llvm.dbg.declare(metadata i32* %7, metadata !129, metadata !DIExpression()), !dbg !130 - store i32 %2, i32* %8, align 4 - call void @llvm.dbg.declare(metadata i32* %8, metadata !131, metadata !DIExpression()), !dbg !132 - store i32 %3, i32* %9, align 4 - call void @llvm.dbg.declare(metadata i32* %9, metadata !133, metadata !DIExpression()), !dbg !134 - store i32 %4, i32* %10, align 4 - call void @llvm.dbg.declare(metadata i32* %10, metadata !135, metadata !DIExpression()), !dbg !136 - call void @llvm.dbg.declare(metadata i32* %11, metadata !137, metadata !DIExpression()), !dbg !138 - call void @llvm.dbg.declare(metadata i32* %12, metadata !139, metadata !DIExpression()), !dbg !140 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutexattr_t* %13, metadata !141, metadata !DIExpression()), !dbg !152 - %14 = call i32 @pthread_mutexattr_init(%struct._opaque_pthread_mutexattr_t* noundef %13), !dbg !153 - store i32 %14, i32* %11, align 4, !dbg !154 - %15 = load i32, i32* %11, align 4, !dbg !155 - %16 = icmp eq i32 %15, 0, !dbg !155 - %17 = xor i1 %16, true, !dbg !155 - %18 = zext i1 %17 to i32, !dbg !155 - %19 = sext i32 %18 to i64, !dbg !155 - %20 = icmp ne i64 %19, 0, !dbg !155 - br i1 %20, label %21, label %23, !dbg !155 - -21: ; preds = %5 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 49, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !155 - unreachable, !dbg !155 - -22: ; No predecessors! - br label %24, !dbg !155 - -23: ; preds = %5 - br label %24, !dbg !155 - -24: ; preds = %23, %22 - %25 = load i32, i32* %7, align 4, !dbg !156 - %26 = call i32 @pthread_mutexattr_settype(%struct._opaque_pthread_mutexattr_t* noundef %13, i32 noundef %25), !dbg !157 - store i32 %26, i32* %11, align 4, !dbg !158 - %27 = load i32, i32* %11, align 4, !dbg !159 - %28 = icmp eq i32 %27, 0, !dbg !159 - %29 = xor i1 %28, true, !dbg !159 - %30 = zext i1 %29 to i32, !dbg !159 - %31 = sext i32 %30 to i64, !dbg !159 - %32 = icmp ne i64 %31, 0, !dbg !159 - br i1 %32, label %33, label %35, !dbg !159 - -33: ; preds = %24 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 52, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !159 - unreachable, !dbg !159 - -34: ; No predecessors! - br label %36, !dbg !159 - -35: ; preds = %24 - br label %36, !dbg !159 - -36: ; preds = %35, %34 - %37 = call i32 @pthread_mutexattr_gettype(%struct._opaque_pthread_mutexattr_t* noundef %13, i32* noundef %12), !dbg !160 - store i32 %37, i32* %11, align 4, !dbg !161 - %38 = load i32, i32* %11, align 4, !dbg !162 - %39 = icmp eq i32 %38, 0, !dbg !162 - %40 = xor i1 %39, true, !dbg !162 - %41 = zext i1 %40 to i32, !dbg !162 - %42 = sext i32 %41 to i64, !dbg !162 - %43 = icmp ne i64 %42, 0, !dbg !162 - br i1 %43, label %44, label %46, !dbg !162 - -44: ; preds = %36 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 54, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !162 - unreachable, !dbg !162 - -45: ; No predecessors! - br label %47, !dbg !162 - -46: ; preds = %36 - br label %47, !dbg !162 - -47: ; preds = %46, %45 - %48 = load i32, i32* %8, align 4, !dbg !163 - %49 = call i32 @pthread_mutexattr_setprotocol(%struct._opaque_pthread_mutexattr_t* noundef %13, i32 noundef %48), !dbg !164 - store i32 %49, i32* %11, align 4, !dbg !165 - %50 = load i32, i32* %11, align 4, !dbg !166 - %51 = icmp eq i32 %50, 0, !dbg !166 - %52 = xor i1 %51, true, !dbg !166 - %53 = zext i1 %52 to i32, !dbg !166 - %54 = sext i32 %53 to i64, !dbg !166 - %55 = icmp ne i64 %54, 0, !dbg !166 - br i1 %55, label %56, label %58, !dbg !166 - -56: ; preds = %47 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 57, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !166 - unreachable, !dbg !166 - -57: ; No predecessors! - br label %59, !dbg !166 - -58: ; preds = %47 - br label %59, !dbg !166 - -59: ; preds = %58, %57 - %60 = call i32 @pthread_mutexattr_getprotocol(%struct._opaque_pthread_mutexattr_t* noundef %13, i32* noundef %12), !dbg !167 - store i32 %60, i32* %11, align 4, !dbg !168 - %61 = load i32, i32* %11, align 4, !dbg !169 - %62 = icmp eq i32 %61, 0, !dbg !169 - %63 = xor i1 %62, true, !dbg !169 - %64 = zext i1 %63 to i32, !dbg !169 - %65 = sext i32 %64 to i64, !dbg !169 - %66 = icmp ne i64 %65, 0, !dbg !169 - br i1 %66, label %67, label %69, !dbg !169 - -67: ; preds = %59 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 59, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !169 - unreachable, !dbg !169 + %11 = alloca %union.pthread_mutexattr_t, align 4 + store ptr %0, ptr %5, align 8 + #dbg_declare(ptr %5, !275, !DIExpression(), !276) + store i32 %1, ptr %6, align 4 + #dbg_declare(ptr %6, !277, !DIExpression(), !278) + store i32 %2, ptr %7, align 4 + #dbg_declare(ptr %7, !279, !DIExpression(), !280) + store i32 %3, ptr %8, align 4 + #dbg_declare(ptr %8, !281, !DIExpression(), !282) + #dbg_declare(ptr %9, !283, !DIExpression(), !284) + #dbg_declare(ptr %10, !285, !DIExpression(), !286) + #dbg_declare(ptr %11, !287, !DIExpression(), !296) + %12 = call i32 @pthread_mutexattr_init(ptr noundef %11) #6, !dbg !297 + store i32 %12, ptr %9, align 4, !dbg !298 + %13 = load i32, ptr %9, align 4, !dbg !299 + %14 = icmp eq i32 %13, 0, !dbg !299 + %15 = xor i1 %14, true, !dbg !299 + %16 = zext i1 %15 to i32, !dbg !299 + %17 = sext i32 %16 to i64, !dbg !299 + %18 = icmp ne i64 %17, 0, !dbg !299 + br i1 %18, label %19, label %21, !dbg !299 + +19: ; preds = %4 + call void @__assert_rtn(ptr noundef @__func__.mutex_init, ptr noundef @.str, i32 noundef 47, ptr noundef @.str.1) #8, !dbg !299 + unreachable, !dbg !299 -68: ; No predecessors! - br label %70, !dbg !169 +20: ; No predecessors! + br label %22, !dbg !299 -69: ; preds = %59 - br label %70, !dbg !169 +21: ; preds = %4 + br label %22, !dbg !299 -70: ; preds = %69, %68 - %71 = load i32, i32* %9, align 4, !dbg !170 - %72 = call i32 @pthread_mutexattr_setpolicy_np(%struct._opaque_pthread_mutexattr_t* noundef %13, i32 noundef %71), !dbg !171 - store i32 %72, i32* %11, align 4, !dbg !172 - %73 = load i32, i32* %11, align 4, !dbg !173 - %74 = icmp eq i32 %73, 0, !dbg !173 - %75 = xor i1 %74, true, !dbg !173 - %76 = zext i1 %75 to i32, !dbg !173 - %77 = sext i32 %76 to i64, !dbg !173 - %78 = icmp ne i64 %77, 0, !dbg !173 - br i1 %78, label %79, label %81, !dbg !173 - -79: ; preds = %70 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 62, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !173 - unreachable, !dbg !173 - -80: ; No predecessors! - br label %82, !dbg !173 - -81: ; preds = %70 - br label %82, !dbg !173 - -82: ; preds = %81, %80 - %83 = call i32 @pthread_mutexattr_getpolicy_np(%struct._opaque_pthread_mutexattr_t* noundef %13, i32* noundef %12), !dbg !174 - store i32 %83, i32* %11, align 4, !dbg !175 - %84 = load i32, i32* %11, align 4, !dbg !176 - %85 = icmp eq i32 %84, 0, !dbg !176 - %86 = xor i1 %85, true, !dbg !176 - %87 = zext i1 %86 to i32, !dbg !176 - %88 = sext i32 %87 to i64, !dbg !176 - %89 = icmp ne i64 %88, 0, !dbg !176 - br i1 %89, label %90, label %92, !dbg !176 - -90: ; preds = %82 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 64, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !176 - unreachable, !dbg !176 - -91: ; No predecessors! - br label %93, !dbg !176 - -92: ; preds = %82 - br label %93, !dbg !176 - -93: ; preds = %92, %91 - %94 = load i32, i32* %10, align 4, !dbg !177 - %95 = call i32 @pthread_mutexattr_setprioceiling(%struct._opaque_pthread_mutexattr_t* noundef %13, i32 noundef %94), !dbg !178 - store i32 %95, i32* %11, align 4, !dbg !179 - %96 = load i32, i32* %11, align 4, !dbg !180 - %97 = icmp eq i32 %96, 0, !dbg !180 - %98 = xor i1 %97, true, !dbg !180 - %99 = zext i1 %98 to i32, !dbg !180 - %100 = sext i32 %99 to i64, !dbg !180 - %101 = icmp ne i64 %100, 0, !dbg !180 - br i1 %101, label %102, label %104, !dbg !180 - -102: ; preds = %93 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 67, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !180 - unreachable, !dbg !180 - -103: ; No predecessors! - br label %105, !dbg !180 - -104: ; preds = %93 - br label %105, !dbg !180 - -105: ; preds = %104, %103 - %106 = call i32 @pthread_mutexattr_getprioceiling(%struct._opaque_pthread_mutexattr_t* noundef %13, i32* noundef %12), !dbg !181 - store i32 %106, i32* %11, align 4, !dbg !182 - %107 = load i32, i32* %11, align 4, !dbg !183 - %108 = icmp eq i32 %107, 0, !dbg !183 - %109 = xor i1 %108, true, !dbg !183 - %110 = zext i1 %109 to i32, !dbg !183 - %111 = sext i32 %110 to i64, !dbg !183 - %112 = icmp ne i64 %111, 0, !dbg !183 - br i1 %112, label %113, label %115, !dbg !183 - -113: ; preds = %105 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 69, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !183 - unreachable, !dbg !183 - -114: ; No predecessors! - br label %116, !dbg !183 - -115: ; preds = %105 - br label %116, !dbg !183 - -116: ; preds = %115, %114 - %117 = load %struct._opaque_pthread_mutex_t*, %struct._opaque_pthread_mutex_t** %6, align 8, !dbg !184 - %118 = call i32 @pthread_mutex_init(%struct._opaque_pthread_mutex_t* noundef %117, %struct._opaque_pthread_mutexattr_t* noundef %13), !dbg !185 - store i32 %118, i32* %11, align 4, !dbg !186 - %119 = load i32, i32* %11, align 4, !dbg !187 - %120 = icmp eq i32 %119, 0, !dbg !187 - %121 = xor i1 %120, true, !dbg !187 - %122 = zext i1 %121 to i32, !dbg !187 - %123 = sext i32 %122 to i64, !dbg !187 - %124 = icmp ne i64 %123, 0, !dbg !187 - br i1 %124, label %125, label %127, !dbg !187 - -125: ; preds = %116 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 72, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !187 - unreachable, !dbg !187 - -126: ; No predecessors! - br label %128, !dbg !187 - -127: ; preds = %116 - br label %128, !dbg !187 - -128: ; preds = %127, %126 - %129 = call i32 @"\01_pthread_mutexattr_destroy"(%struct._opaque_pthread_mutexattr_t* noundef %13), !dbg !188 - store i32 %129, i32* %11, align 4, !dbg !189 - %130 = load i32, i32* %11, align 4, !dbg !190 - %131 = icmp eq i32 %130, 0, !dbg !190 - %132 = xor i1 %131, true, !dbg !190 - %133 = zext i1 %132 to i32, !dbg !190 - %134 = sext i32 %133 to i64, !dbg !190 - %135 = icmp ne i64 %134, 0, !dbg !190 - br i1 %135, label %136, label %138, !dbg !190 - -136: ; preds = %128 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 74, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !190 - unreachable, !dbg !190 - -137: ; No predecessors! - br label %139, !dbg !190 - -138: ; preds = %128 - br label %139, !dbg !190 - -139: ; preds = %138, %137 - ret void, !dbg !191 -} +22: ; preds = %21, %20 + %23 = load i32, ptr %6, align 4, !dbg !300 + %24 = call i32 @pthread_mutexattr_settype(ptr noundef %11, i32 noundef %23) #6, !dbg !301 + store i32 %24, ptr %9, align 4, !dbg !302 + %25 = load i32, ptr %9, align 4, !dbg !303 + %26 = icmp eq i32 %25, 0, !dbg !303 + %27 = xor i1 %26, true, !dbg !303 + %28 = zext i1 %27 to i32, !dbg !303 + %29 = sext i32 %28 to i64, !dbg !303 + %30 = icmp ne i64 %29, 0, !dbg !303 + br i1 %30, label %31, label %33, !dbg !303 + +31: ; preds = %22 + call void @__assert_rtn(ptr noundef @__func__.mutex_init, ptr noundef @.str, i32 noundef 50, ptr noundef @.str.1) #8, !dbg !303 + unreachable, !dbg !303 + +32: ; No predecessors! + br label %34, !dbg !303 -declare i32 @pthread_mutexattr_init(%struct._opaque_pthread_mutexattr_t* noundef) #2 +33: ; preds = %22 + br label %34, !dbg !303 -declare i32 @pthread_mutexattr_settype(%struct._opaque_pthread_mutexattr_t* noundef, i32 noundef) #2 +34: ; preds = %33, %32 + %35 = call i32 @pthread_mutexattr_gettype(ptr noundef %11, ptr noundef %10) #6, !dbg !304 + store i32 %35, ptr %9, align 4, !dbg !305 + %36 = load i32, ptr %9, align 4, !dbg !306 + %37 = icmp eq i32 %36, 0, !dbg !306 + %38 = xor i1 %37, true, !dbg !306 + %39 = zext i1 %38 to i32, !dbg !306 + %40 = sext i32 %39 to i64, !dbg !306 + %41 = icmp ne i64 %40, 0, !dbg !306 + br i1 %41, label %42, label %44, !dbg !306 + +42: ; preds = %34 + call void @__assert_rtn(ptr noundef @__func__.mutex_init, ptr noundef @.str, i32 noundef 52, ptr noundef @.str.1) #8, !dbg !306 + unreachable, !dbg !306 + +43: ; No predecessors! + br label %45, !dbg !306 + +44: ; preds = %34 + br label %45, !dbg !306 + +45: ; preds = %44, %43 + %46 = load i32, ptr %7, align 4, !dbg !307 + %47 = call i32 @pthread_mutexattr_setprotocol(ptr noundef %11, i32 noundef %46) #6, !dbg !308 + store i32 %47, ptr %9, align 4, !dbg !309 + %48 = load i32, ptr %9, align 4, !dbg !310 + %49 = icmp eq i32 %48, 0, !dbg !310 + %50 = xor i1 %49, true, !dbg !310 + %51 = zext i1 %50 to i32, !dbg !310 + %52 = sext i32 %51 to i64, !dbg !310 + %53 = icmp ne i64 %52, 0, !dbg !310 + br i1 %53, label %54, label %56, !dbg !310 + +54: ; preds = %45 + call void @__assert_rtn(ptr noundef @__func__.mutex_init, ptr noundef @.str, i32 noundef 55, ptr noundef @.str.1) #8, !dbg !310 + unreachable, !dbg !310 + +55: ; No predecessors! + br label %57, !dbg !310 + +56: ; preds = %45 + br label %57, !dbg !310 + +57: ; preds = %56, %55 + %58 = call i32 @pthread_mutexattr_getprotocol(ptr noundef %11, ptr noundef %10) #6, !dbg !311 + store i32 %58, ptr %9, align 4, !dbg !312 + %59 = load i32, ptr %9, align 4, !dbg !313 + %60 = icmp eq i32 %59, 0, !dbg !313 + %61 = xor i1 %60, true, !dbg !313 + %62 = zext i1 %61 to i32, !dbg !313 + %63 = sext i32 %62 to i64, !dbg !313 + %64 = icmp ne i64 %63, 0, !dbg !313 + br i1 %64, label %65, label %67, !dbg !313 + +65: ; preds = %57 + call void @__assert_rtn(ptr noundef @__func__.mutex_init, ptr noundef @.str, i32 noundef 57, ptr noundef @.str.1) #8, !dbg !313 + unreachable, !dbg !313 + +66: ; No predecessors! + br label %68, !dbg !313 + +67: ; preds = %57 + br label %68, !dbg !313 + +68: ; preds = %67, %66 + %69 = load i32, ptr %8, align 4, !dbg !314 + %70 = call i32 @pthread_mutexattr_setprioceiling(ptr noundef %11, i32 noundef %69) #6, !dbg !315 + store i32 %70, ptr %9, align 4, !dbg !316 + %71 = load i32, ptr %9, align 4, !dbg !317 + %72 = icmp eq i32 %71, 0, !dbg !317 + %73 = xor i1 %72, true, !dbg !317 + %74 = zext i1 %73 to i32, !dbg !317 + %75 = sext i32 %74 to i64, !dbg !317 + %76 = icmp ne i64 %75, 0, !dbg !317 + br i1 %76, label %77, label %79, !dbg !317 + +77: ; preds = %68 + call void @__assert_rtn(ptr noundef @__func__.mutex_init, ptr noundef @.str, i32 noundef 60, ptr noundef @.str.1) #8, !dbg !317 + unreachable, !dbg !317 + +78: ; No predecessors! + br label %80, !dbg !317 + +79: ; preds = %68 + br label %80, !dbg !317 + +80: ; preds = %79, %78 + %81 = call i32 @pthread_mutexattr_getprioceiling(ptr noundef %11, ptr noundef %10) #6, !dbg !318 + store i32 %81, ptr %9, align 4, !dbg !319 + %82 = load i32, ptr %9, align 4, !dbg !320 + %83 = icmp eq i32 %82, 0, !dbg !320 + %84 = xor i1 %83, true, !dbg !320 + %85 = zext i1 %84 to i32, !dbg !320 + %86 = sext i32 %85 to i64, !dbg !320 + %87 = icmp ne i64 %86, 0, !dbg !320 + br i1 %87, label %88, label %90, !dbg !320 + +88: ; preds = %80 + call void @__assert_rtn(ptr noundef @__func__.mutex_init, ptr noundef @.str, i32 noundef 62, ptr noundef @.str.1) #8, !dbg !320 + unreachable, !dbg !320 + +89: ; No predecessors! + br label %91, !dbg !320 + +90: ; preds = %80 + br label %91, !dbg !320 + +91: ; preds = %90, %89 + %92 = load ptr, ptr %5, align 8, !dbg !321 + %93 = call i32 @pthread_mutex_init(ptr noundef %92, ptr noundef %11) #6, !dbg !322 + store i32 %93, ptr %9, align 4, !dbg !323 + %94 = load i32, ptr %9, align 4, !dbg !324 + %95 = icmp eq i32 %94, 0, !dbg !324 + %96 = xor i1 %95, true, !dbg !324 + %97 = zext i1 %96 to i32, !dbg !324 + %98 = sext i32 %97 to i64, !dbg !324 + %99 = icmp ne i64 %98, 0, !dbg !324 + br i1 %99, label %100, label %102, !dbg !324 + +100: ; preds = %91 + call void @__assert_rtn(ptr noundef @__func__.mutex_init, ptr noundef @.str, i32 noundef 65, ptr noundef @.str.1) #8, !dbg !324 + unreachable, !dbg !324 + +101: ; No predecessors! + br label %103, !dbg !324 + +102: ; preds = %91 + br label %103, !dbg !324 + +103: ; preds = %102, %101 + %104 = call i32 @pthread_mutexattr_destroy(ptr noundef %11) #6, !dbg !325 + store i32 %104, ptr %9, align 4, !dbg !326 + %105 = load i32, ptr %9, align 4, !dbg !327 + %106 = icmp eq i32 %105, 0, !dbg !327 + %107 = xor i1 %106, true, !dbg !327 + %108 = zext i1 %107 to i32, !dbg !327 + %109 = sext i32 %108 to i64, !dbg !327 + %110 = icmp ne i64 %109, 0, !dbg !327 + br i1 %110, label %111, label %113, !dbg !327 + +111: ; preds = %103 + call void @__assert_rtn(ptr noundef @__func__.mutex_init, ptr noundef @.str, i32 noundef 67, ptr noundef @.str.1) #8, !dbg !327 + unreachable, !dbg !327 + +112: ; No predecessors! + br label %114, !dbg !327 + +113: ; preds = %103 + br label %114, !dbg !327 + +114: ; preds = %113, %112 + ret void, !dbg !328 +} -declare i32 @pthread_mutexattr_gettype(%struct._opaque_pthread_mutexattr_t* noundef, i32* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutexattr_init(ptr noundef) #1 -declare i32 @pthread_mutexattr_setprotocol(%struct._opaque_pthread_mutexattr_t* noundef, i32 noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutexattr_settype(ptr noundef, i32 noundef) #1 -declare i32 @pthread_mutexattr_getprotocol(%struct._opaque_pthread_mutexattr_t* noundef, i32* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutexattr_gettype(ptr noundef, ptr noundef) #1 -declare i32 @pthread_mutexattr_setpolicy_np(%struct._opaque_pthread_mutexattr_t* noundef, i32 noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutexattr_setprotocol(ptr noundef, i32 noundef) #1 -declare i32 @pthread_mutexattr_getpolicy_np(%struct._opaque_pthread_mutexattr_t* noundef, i32* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutexattr_getprotocol(ptr noundef, ptr noundef) #1 -declare i32 @pthread_mutexattr_setprioceiling(%struct._opaque_pthread_mutexattr_t* noundef, i32 noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutexattr_setprioceiling(ptr noundef, i32 noundef) #1 -declare i32 @pthread_mutexattr_getprioceiling(%struct._opaque_pthread_mutexattr_t* noundef, i32* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutexattr_getprioceiling(ptr noundef, ptr noundef) #1 -declare i32 @pthread_mutex_init(%struct._opaque_pthread_mutex_t* noundef, %struct._opaque_pthread_mutexattr_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutex_init(ptr noundef, ptr noundef) #1 -declare i32 @"\01_pthread_mutexattr_destroy"(%struct._opaque_pthread_mutexattr_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutexattr_destroy(ptr noundef) #1 -; Function Attrs: noinline nounwind ssp uwtable -define void @mutex_destroy(%struct._opaque_pthread_mutex_t* noundef %0) #0 !dbg !192 { - %2 = alloca %struct._opaque_pthread_mutex_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @mutex_destroy(ptr noundef %0) #0 !dbg !329 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_mutex_t* %0, %struct._opaque_pthread_mutex_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutex_t** %2, metadata !195, metadata !DIExpression()), !dbg !196 - call void @llvm.dbg.declare(metadata i32* %3, metadata !197, metadata !DIExpression()), !dbg !198 - %4 = load %struct._opaque_pthread_mutex_t*, %struct._opaque_pthread_mutex_t** %2, align 8, !dbg !199 - %5 = call i32 @pthread_mutex_destroy(%struct._opaque_pthread_mutex_t* noundef %4), !dbg !200 - store i32 %5, i32* %3, align 4, !dbg !198 - %6 = load i32, i32* %3, align 4, !dbg !201 - %7 = icmp eq i32 %6, 0, !dbg !201 - %8 = xor i1 %7, true, !dbg !201 - %9 = zext i1 %8 to i32, !dbg !201 - %10 = sext i32 %9 to i64, !dbg !201 - %11 = icmp ne i64 %10, 0, !dbg !201 - br i1 %11, label %12, label %14, !dbg !201 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !332, !DIExpression(), !333) + #dbg_declare(ptr %3, !334, !DIExpression(), !335) + %4 = load ptr, ptr %2, align 8, !dbg !336 + %5 = call i32 @pthread_mutex_destroy(ptr noundef %4) #6, !dbg !337 + store i32 %5, ptr %3, align 4, !dbg !335 + %6 = load i32, ptr %3, align 4, !dbg !338 + %7 = icmp eq i32 %6, 0, !dbg !338 + %8 = xor i1 %7, true, !dbg !338 + %9 = zext i1 %8 to i32, !dbg !338 + %10 = sext i32 %9 to i64, !dbg !338 + %11 = icmp ne i64 %10, 0, !dbg !338 + br i1 %11, label %12, label %14, !dbg !338 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__func__.mutex_destroy, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 80, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !201 - unreachable, !dbg !201 + call void @__assert_rtn(ptr noundef @__func__.mutex_destroy, ptr noundef @.str, i32 noundef 73, ptr noundef @.str.1) #8, !dbg !338 + unreachable, !dbg !338 13: ; No predecessors! - br label %15, !dbg !201 + br label %15, !dbg !338 14: ; preds = %1 - br label %15, !dbg !201 + br label %15, !dbg !338 15: ; preds = %14, %13 - ret void, !dbg !202 + ret void, !dbg !339 } -declare i32 @pthread_mutex_destroy(%struct._opaque_pthread_mutex_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_mutex_destroy(ptr noundef) #1 -; Function Attrs: noinline nounwind ssp uwtable -define void @mutex_lock(%struct._opaque_pthread_mutex_t* noundef %0) #0 !dbg !203 { - %2 = alloca %struct._opaque_pthread_mutex_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @mutex_lock(ptr noundef %0) #0 !dbg !340 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_mutex_t* %0, %struct._opaque_pthread_mutex_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutex_t** %2, metadata !204, metadata !DIExpression()), !dbg !205 - call void @llvm.dbg.declare(metadata i32* %3, metadata !206, metadata !DIExpression()), !dbg !207 - %4 = load %struct._opaque_pthread_mutex_t*, %struct._opaque_pthread_mutex_t** %2, align 8, !dbg !208 - %5 = call i32 @pthread_mutex_lock(%struct._opaque_pthread_mutex_t* noundef %4), !dbg !209 - store i32 %5, i32* %3, align 4, !dbg !207 - %6 = load i32, i32* %3, align 4, !dbg !210 - %7 = icmp eq i32 %6, 0, !dbg !210 - %8 = xor i1 %7, true, !dbg !210 - %9 = zext i1 %8 to i32, !dbg !210 - %10 = sext i32 %9 to i64, !dbg !210 - %11 = icmp ne i64 %10, 0, !dbg !210 - br i1 %11, label %12, label %14, !dbg !210 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !341, !DIExpression(), !342) + #dbg_declare(ptr %3, !343, !DIExpression(), !344) + %4 = load ptr, ptr %2, align 8, !dbg !345 + %5 = call i32 @pthread_mutex_lock(ptr noundef %4) #7, !dbg !346 + store i32 %5, ptr %3, align 4, !dbg !344 + %6 = load i32, ptr %3, align 4, !dbg !347 + %7 = icmp eq i32 %6, 0, !dbg !347 + %8 = xor i1 %7, true, !dbg !347 + %9 = zext i1 %8 to i32, !dbg !347 + %10 = sext i32 %9 to i64, !dbg !347 + %11 = icmp ne i64 %10, 0, !dbg !347 + br i1 %11, label %12, label %14, !dbg !347 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_lock, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 86, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !210 - unreachable, !dbg !210 + call void @__assert_rtn(ptr noundef @__func__.mutex_lock, ptr noundef @.str, i32 noundef 79, ptr noundef @.str.1) #8, !dbg !347 + unreachable, !dbg !347 13: ; No predecessors! - br label %15, !dbg !210 + br label %15, !dbg !347 14: ; preds = %1 - br label %15, !dbg !210 + br label %15, !dbg !347 15: ; preds = %14, %13 - ret void, !dbg !211 + ret void, !dbg !348 } -declare i32 @pthread_mutex_lock(%struct._opaque_pthread_mutex_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_mutex_lock(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define zeroext i1 @mutex_trylock(%struct._opaque_pthread_mutex_t* noundef %0) #0 !dbg !212 { - %2 = alloca %struct._opaque_pthread_mutex_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local zeroext i1 @mutex_trylock(ptr noundef %0) #0 !dbg !349 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_mutex_t* %0, %struct._opaque_pthread_mutex_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutex_t** %2, metadata !216, metadata !DIExpression()), !dbg !217 - call void @llvm.dbg.declare(metadata i32* %3, metadata !218, metadata !DIExpression()), !dbg !219 - %4 = load %struct._opaque_pthread_mutex_t*, %struct._opaque_pthread_mutex_t** %2, align 8, !dbg !220 - %5 = call i32 @pthread_mutex_trylock(%struct._opaque_pthread_mutex_t* noundef %4), !dbg !221 - store i32 %5, i32* %3, align 4, !dbg !219 - %6 = load i32, i32* %3, align 4, !dbg !222 - %7 = icmp eq i32 %6, 0, !dbg !223 - ret i1 %7, !dbg !224 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !353, !DIExpression(), !354) + #dbg_declare(ptr %3, !355, !DIExpression(), !356) + %4 = load ptr, ptr %2, align 8, !dbg !357 + %5 = call i32 @pthread_mutex_trylock(ptr noundef %4) #7, !dbg !358 + store i32 %5, ptr %3, align 4, !dbg !356 + %6 = load i32, ptr %3, align 4, !dbg !359 + %7 = icmp eq i32 %6, 0, !dbg !360 + ret i1 %7, !dbg !361 } -declare i32 @pthread_mutex_trylock(%struct._opaque_pthread_mutex_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_mutex_trylock(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define void @mutex_unlock(%struct._opaque_pthread_mutex_t* noundef %0) #0 !dbg !225 { - %2 = alloca %struct._opaque_pthread_mutex_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @mutex_unlock(ptr noundef %0) #0 !dbg !362 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_mutex_t* %0, %struct._opaque_pthread_mutex_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutex_t** %2, metadata !226, metadata !DIExpression()), !dbg !227 - call void @llvm.dbg.declare(metadata i32* %3, metadata !228, metadata !DIExpression()), !dbg !229 - %4 = load %struct._opaque_pthread_mutex_t*, %struct._opaque_pthread_mutex_t** %2, align 8, !dbg !230 - %5 = call i32 @pthread_mutex_unlock(%struct._opaque_pthread_mutex_t* noundef %4), !dbg !231 - store i32 %5, i32* %3, align 4, !dbg !229 - %6 = load i32, i32* %3, align 4, !dbg !232 - %7 = icmp eq i32 %6, 0, !dbg !232 - %8 = xor i1 %7, true, !dbg !232 - %9 = zext i1 %8 to i32, !dbg !232 - %10 = sext i32 %9 to i64, !dbg !232 - %11 = icmp ne i64 %10, 0, !dbg !232 - br i1 %11, label %12, label %14, !dbg !232 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !363, !DIExpression(), !364) + #dbg_declare(ptr %3, !365, !DIExpression(), !366) + %4 = load ptr, ptr %2, align 8, !dbg !367 + %5 = call i32 @pthread_mutex_unlock(ptr noundef %4) #7, !dbg !368 + store i32 %5, ptr %3, align 4, !dbg !366 + %6 = load i32, ptr %3, align 4, !dbg !369 + %7 = icmp eq i32 %6, 0, !dbg !369 + %8 = xor i1 %7, true, !dbg !369 + %9 = zext i1 %8 to i32, !dbg !369 + %10 = sext i32 %9 to i64, !dbg !369 + %11 = icmp ne i64 %10, 0, !dbg !369 + br i1 %11, label %12, label %14, !dbg !369 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @__func__.mutex_unlock, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 99, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !232 - unreachable, !dbg !232 + call void @__assert_rtn(ptr noundef @__func__.mutex_unlock, ptr noundef @.str, i32 noundef 92, ptr noundef @.str.1) #8, !dbg !369 + unreachable, !dbg !369 13: ; No predecessors! - br label %15, !dbg !232 + br label %15, !dbg !369 14: ; preds = %1 - br label %15, !dbg !232 + br label %15, !dbg !369 15: ; preds = %14, %13 - ret void, !dbg !233 + ret void, !dbg !370 } -declare i32 @pthread_mutex_unlock(%struct._opaque_pthread_mutex_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_mutex_unlock(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define void @mutex_test() #0 !dbg !234 { - %1 = alloca %struct._opaque_pthread_mutex_t, align 8 - %2 = alloca %struct._opaque_pthread_mutex_t, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @mutex_test() #0 !dbg !371 { + %1 = alloca %union.pthread_mutex_t, align 8 + %2 = alloca %union.pthread_mutex_t, align 8 %3 = alloca i8, align 1 %4 = alloca i8, align 1 %5 = alloca i8, align 1 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutex_t* %1, metadata !237, metadata !DIExpression()), !dbg !238 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutex_t* %2, metadata !239, metadata !DIExpression()), !dbg !240 - call void @mutex_init(%struct._opaque_pthread_mutex_t* noundef %1, i32 noundef 1, i32 noundef 1, i32 noundef 1, i32 noundef 1), !dbg !241 - call void @mutex_init(%struct._opaque_pthread_mutex_t* noundef %2, i32 noundef 2, i32 noundef 2, i32 noundef 3, i32 noundef 2), !dbg !242 - call void @mutex_lock(%struct._opaque_pthread_mutex_t* noundef %1), !dbg !243 - call void @llvm.dbg.declare(metadata i8* %3, metadata !245, metadata !DIExpression()), !dbg !246 - %6 = call zeroext i1 @mutex_trylock(%struct._opaque_pthread_mutex_t* noundef %1), !dbg !247 - %7 = zext i1 %6 to i8, !dbg !246 - store i8 %7, i8* %3, align 1, !dbg !246 - %8 = load i8, i8* %3, align 1, !dbg !248 - %9 = trunc i8 %8 to i1, !dbg !248 - %10 = xor i1 %9, true, !dbg !248 - %11 = xor i1 %10, true, !dbg !248 - %12 = zext i1 %11 to i32, !dbg !248 - %13 = sext i32 %12 to i64, !dbg !248 - %14 = icmp ne i64 %13, 0, !dbg !248 - br i1 %14, label %15, label %17, !dbg !248 + #dbg_declare(ptr %1, !374, !DIExpression(), !375) + #dbg_declare(ptr %2, !376, !DIExpression(), !377) + call void @mutex_init(ptr noundef %1, i32 noundef 2, i32 noundef 1, i32 noundef 1), !dbg !378 + call void @mutex_init(ptr noundef %2, i32 noundef 1, i32 noundef 2, i32 noundef 2), !dbg !379 + call void @mutex_lock(ptr noundef %1), !dbg !380 + #dbg_declare(ptr %3, !382, !DIExpression(), !383) + %6 = call zeroext i1 @mutex_trylock(ptr noundef %1), !dbg !384 + %7 = zext i1 %6 to i8, !dbg !383 + store i8 %7, ptr %3, align 1, !dbg !383 + %8 = load i8, ptr %3, align 1, !dbg !385 + %9 = trunc i8 %8 to i1, !dbg !385 + %10 = xor i1 %9, true, !dbg !385 + %11 = xor i1 %10, true, !dbg !385 + %12 = zext i1 %11 to i32, !dbg !385 + %13 = sext i32 %12 to i64, !dbg !385 + %14 = icmp ne i64 %13, 0, !dbg !385 + br i1 %14, label %15, label %17, !dbg !385 15: ; preds = %0 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 113, i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.2, i64 0, i64 0)) #4, !dbg !248 - unreachable, !dbg !248 + call void @__assert_rtn(ptr noundef @__func__.mutex_test, ptr noundef @.str, i32 noundef 106, ptr noundef @.str.2) #8, !dbg !385 + unreachable, !dbg !385 16: ; No predecessors! - br label %18, !dbg !248 + br label %18, !dbg !385 17: ; preds = %0 - br label %18, !dbg !248 + br label %18, !dbg !385 18: ; preds = %17, %16 - call void @mutex_unlock(%struct._opaque_pthread_mutex_t* noundef %1), !dbg !249 - call void @mutex_lock(%struct._opaque_pthread_mutex_t* noundef %2), !dbg !250 - call void @llvm.dbg.declare(metadata i8* %4, metadata !252, metadata !DIExpression()), !dbg !254 - %19 = call zeroext i1 @mutex_trylock(%struct._opaque_pthread_mutex_t* noundef %1), !dbg !255 - %20 = zext i1 %19 to i8, !dbg !254 - store i8 %20, i8* %4, align 1, !dbg !254 - %21 = load i8, i8* %4, align 1, !dbg !256 - %22 = trunc i8 %21 to i1, !dbg !256 - %23 = xor i1 %22, true, !dbg !256 - %24 = zext i1 %23 to i32, !dbg !256 - %25 = sext i32 %24 to i64, !dbg !256 - %26 = icmp ne i64 %25, 0, !dbg !256 - br i1 %26, label %27, label %29, !dbg !256 + call void @mutex_unlock(ptr noundef %1), !dbg !386 + call void @mutex_lock(ptr noundef %2), !dbg !387 + #dbg_declare(ptr %4, !389, !DIExpression(), !391) + %19 = call zeroext i1 @mutex_trylock(ptr noundef %1), !dbg !392 + %20 = zext i1 %19 to i8, !dbg !391 + store i8 %20, ptr %4, align 1, !dbg !391 + %21 = load i8, ptr %4, align 1, !dbg !393 + %22 = trunc i8 %21 to i1, !dbg !393 + %23 = xor i1 %22, true, !dbg !393 + %24 = zext i1 %23 to i32, !dbg !393 + %25 = sext i32 %24 to i64, !dbg !393 + %26 = icmp ne i64 %25, 0, !dbg !393 + br i1 %26, label %27, label %29, !dbg !393 27: ; preds = %18 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 122, i8* noundef getelementptr inbounds ([8 x i8], [8 x i8]* @.str.3, i64 0, i64 0)) #4, !dbg !256 - unreachable, !dbg !256 + call void @__assert_rtn(ptr noundef @__func__.mutex_test, ptr noundef @.str, i32 noundef 115, ptr noundef @.str.3) #8, !dbg !393 + unreachable, !dbg !393 28: ; No predecessors! - br label %30, !dbg !256 + br label %30, !dbg !393 29: ; preds = %18 - br label %30, !dbg !256 + br label %30, !dbg !393 30: ; preds = %29, %28 - call void @mutex_unlock(%struct._opaque_pthread_mutex_t* noundef %1), !dbg !257 - call void @llvm.dbg.declare(metadata i8* %5, metadata !258, metadata !DIExpression()), !dbg !260 - %31 = call zeroext i1 @mutex_trylock(%struct._opaque_pthread_mutex_t* noundef %1), !dbg !261 - %32 = zext i1 %31 to i8, !dbg !260 - store i8 %32, i8* %5, align 1, !dbg !260 - %33 = load i8, i8* %5, align 1, !dbg !262 - %34 = trunc i8 %33 to i1, !dbg !262 - %35 = xor i1 %34, true, !dbg !262 - %36 = zext i1 %35 to i32, !dbg !262 - %37 = sext i32 %36 to i64, !dbg !262 - %38 = icmp ne i64 %37, 0, !dbg !262 - br i1 %38, label %39, label %41, !dbg !262 + call void @mutex_unlock(ptr noundef %1), !dbg !394 + #dbg_declare(ptr %5, !395, !DIExpression(), !397) + %31 = call zeroext i1 @mutex_trylock(ptr noundef %1), !dbg !398 + %32 = zext i1 %31 to i8, !dbg !397 + store i8 %32, ptr %5, align 1, !dbg !397 + %33 = load i8, ptr %5, align 1, !dbg !399 + %34 = trunc i8 %33 to i1, !dbg !399 + %35 = xor i1 %34, true, !dbg !399 + %36 = zext i1 %35 to i32, !dbg !399 + %37 = sext i32 %36 to i64, !dbg !399 + %38 = icmp ne i64 %37, 0, !dbg !399 + br i1 %38, label %39, label %41, !dbg !399 39: ; preds = %30 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.mutex_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 128, i8* noundef getelementptr inbounds ([8 x i8], [8 x i8]* @.str.3, i64 0, i64 0)) #4, !dbg !262 - unreachable, !dbg !262 + call void @__assert_rtn(ptr noundef @__func__.mutex_test, ptr noundef @.str, i32 noundef 121, ptr noundef @.str.3) #8, !dbg !399 + unreachable, !dbg !399 40: ; No predecessors! - br label %42, !dbg !262 + br label %42, !dbg !399 41: ; preds = %30 - br label %42, !dbg !262 + br label %42, !dbg !399 42: ; preds = %41, %40 - call void @mutex_unlock(%struct._opaque_pthread_mutex_t* noundef %1), !dbg !263 - call void @mutex_unlock(%struct._opaque_pthread_mutex_t* noundef %2), !dbg !264 - call void @mutex_destroy(%struct._opaque_pthread_mutex_t* noundef %2), !dbg !265 - call void @mutex_destroy(%struct._opaque_pthread_mutex_t* noundef %1), !dbg !266 - ret void, !dbg !267 + call void @mutex_unlock(ptr noundef %1), !dbg !400 + call void @mutex_unlock(ptr noundef %2), !dbg !401 + call void @mutex_destroy(ptr noundef %2), !dbg !402 + call void @mutex_destroy(ptr noundef %1), !dbg !403 + ret void, !dbg !404 } -; Function Attrs: noinline nounwind ssp uwtable -define void @cond_init(%struct._opaque_pthread_cond_t* noundef %0) #0 !dbg !268 { - %2 = alloca %struct._opaque_pthread_cond_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @cond_init(ptr noundef %0) #0 !dbg !405 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - %4 = alloca %struct._opaque_pthread_condattr_t, align 8 - store %struct._opaque_pthread_cond_t* %0, %struct._opaque_pthread_cond_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_cond_t** %2, metadata !272, metadata !DIExpression()), !dbg !273 - call void @llvm.dbg.declare(metadata i32* %3, metadata !274, metadata !DIExpression()), !dbg !275 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_condattr_t* %4, metadata !276, metadata !DIExpression()), !dbg !284 - %5 = call i32 @pthread_condattr_init(%struct._opaque_pthread_condattr_t* noundef %4), !dbg !285 - store i32 %5, i32* %3, align 4, !dbg !286 - %6 = load i32, i32* %3, align 4, !dbg !287 - %7 = icmp eq i32 %6, 0, !dbg !287 - %8 = xor i1 %7, true, !dbg !287 - %9 = zext i1 %8 to i32, !dbg !287 - %10 = sext i32 %9 to i64, !dbg !287 - %11 = icmp ne i64 %10, 0, !dbg !287 - br i1 %11, label %12, label %14, !dbg !287 + %4 = alloca %union.pthread_condattr_t, align 4 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !409, !DIExpression(), !410) + #dbg_declare(ptr %3, !411, !DIExpression(), !412) + #dbg_declare(ptr %4, !413, !DIExpression(), !419) + %5 = call i32 @pthread_condattr_init(ptr noundef %4) #6, !dbg !420 + store i32 %5, ptr %3, align 4, !dbg !421 + %6 = load i32, ptr %3, align 4, !dbg !422 + %7 = icmp eq i32 %6, 0, !dbg !422 + %8 = xor i1 %7, true, !dbg !422 + %9 = zext i1 %8 to i32, !dbg !422 + %10 = sext i32 %9 to i64, !dbg !422 + %11 = icmp ne i64 %10, 0, !dbg !422 + br i1 %11, label %12, label %14, !dbg !422 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @__func__.cond_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 154, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !287 - unreachable, !dbg !287 + call void @__assert_rtn(ptr noundef @__func__.cond_init, ptr noundef @.str, i32 noundef 147, ptr noundef @.str.1) #8, !dbg !422 + unreachable, !dbg !422 13: ; No predecessors! - br label %15, !dbg !287 + br label %15, !dbg !422 14: ; preds = %1 - br label %15, !dbg !287 + br label %15, !dbg !422 15: ; preds = %14, %13 - %16 = load %struct._opaque_pthread_cond_t*, %struct._opaque_pthread_cond_t** %2, align 8, !dbg !288 - %17 = call i32 @"\01_pthread_cond_init"(%struct._opaque_pthread_cond_t* noundef %16, %struct._opaque_pthread_condattr_t* noundef %4), !dbg !289 - store i32 %17, i32* %3, align 4, !dbg !290 - %18 = load i32, i32* %3, align 4, !dbg !291 - %19 = icmp eq i32 %18, 0, !dbg !291 - %20 = xor i1 %19, true, !dbg !291 - %21 = zext i1 %20 to i32, !dbg !291 - %22 = sext i32 %21 to i64, !dbg !291 - %23 = icmp ne i64 %22, 0, !dbg !291 - br i1 %23, label %24, label %26, !dbg !291 + %16 = load ptr, ptr %2, align 8, !dbg !423 + %17 = call i32 @pthread_cond_init(ptr noundef %16, ptr noundef %4) #6, !dbg !424 + store i32 %17, ptr %3, align 4, !dbg !425 + %18 = load i32, ptr %3, align 4, !dbg !426 + %19 = icmp eq i32 %18, 0, !dbg !426 + %20 = xor i1 %19, true, !dbg !426 + %21 = zext i1 %20 to i32, !dbg !426 + %22 = sext i32 %21 to i64, !dbg !426 + %23 = icmp ne i64 %22, 0, !dbg !426 + br i1 %23, label %24, label %26, !dbg !426 24: ; preds = %15 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @__func__.cond_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 157, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !291 - unreachable, !dbg !291 + call void @__assert_rtn(ptr noundef @__func__.cond_init, ptr noundef @.str, i32 noundef 150, ptr noundef @.str.1) #8, !dbg !426 + unreachable, !dbg !426 25: ; No predecessors! - br label %27, !dbg !291 + br label %27, !dbg !426 26: ; preds = %15 - br label %27, !dbg !291 + br label %27, !dbg !426 27: ; preds = %26, %25 - %28 = call i32 @pthread_condattr_destroy(%struct._opaque_pthread_condattr_t* noundef %4), !dbg !292 - store i32 %28, i32* %3, align 4, !dbg !293 - %29 = load i32, i32* %3, align 4, !dbg !294 - %30 = icmp eq i32 %29, 0, !dbg !294 - %31 = xor i1 %30, true, !dbg !294 - %32 = zext i1 %31 to i32, !dbg !294 - %33 = sext i32 %32 to i64, !dbg !294 - %34 = icmp ne i64 %33, 0, !dbg !294 - br i1 %34, label %35, label %37, !dbg !294 + %28 = call i32 @pthread_condattr_destroy(ptr noundef %4) #6, !dbg !427 + store i32 %28, ptr %3, align 4, !dbg !428 + %29 = load i32, ptr %3, align 4, !dbg !429 + %30 = icmp eq i32 %29, 0, !dbg !429 + %31 = xor i1 %30, true, !dbg !429 + %32 = zext i1 %31 to i32, !dbg !429 + %33 = sext i32 %32 to i64, !dbg !429 + %34 = icmp ne i64 %33, 0, !dbg !429 + br i1 %34, label %35, label %37, !dbg !429 35: ; preds = %27 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @__func__.cond_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 160, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !294 - unreachable, !dbg !294 + call void @__assert_rtn(ptr noundef @__func__.cond_init, ptr noundef @.str, i32 noundef 153, ptr noundef @.str.1) #8, !dbg !429 + unreachable, !dbg !429 36: ; No predecessors! - br label %38, !dbg !294 + br label %38, !dbg !429 37: ; preds = %27 - br label %38, !dbg !294 + br label %38, !dbg !429 38: ; preds = %37, %36 - ret void, !dbg !295 + ret void, !dbg !430 } -declare i32 @pthread_condattr_init(%struct._opaque_pthread_condattr_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_condattr_init(ptr noundef) #1 -declare i32 @"\01_pthread_cond_init"(%struct._opaque_pthread_cond_t* noundef, %struct._opaque_pthread_condattr_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_cond_init(ptr noundef, ptr noundef) #1 -declare i32 @pthread_condattr_destroy(%struct._opaque_pthread_condattr_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_condattr_destroy(ptr noundef) #1 -; Function Attrs: noinline nounwind ssp uwtable -define void @cond_destroy(%struct._opaque_pthread_cond_t* noundef %0) #0 !dbg !296 { - %2 = alloca %struct._opaque_pthread_cond_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @cond_destroy(ptr noundef %0) #0 !dbg !431 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_cond_t* %0, %struct._opaque_pthread_cond_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_cond_t** %2, metadata !297, metadata !DIExpression()), !dbg !298 - call void @llvm.dbg.declare(metadata i32* %3, metadata !299, metadata !DIExpression()), !dbg !300 - %4 = load %struct._opaque_pthread_cond_t*, %struct._opaque_pthread_cond_t** %2, align 8, !dbg !301 - %5 = call i32 @pthread_cond_destroy(%struct._opaque_pthread_cond_t* noundef %4), !dbg !302 - store i32 %5, i32* %3, align 4, !dbg !300 - %6 = load i32, i32* %3, align 4, !dbg !303 - %7 = icmp eq i32 %6, 0, !dbg !303 - %8 = xor i1 %7, true, !dbg !303 - %9 = zext i1 %8 to i32, !dbg !303 - %10 = sext i32 %9 to i64, !dbg !303 - %11 = icmp ne i64 %10, 0, !dbg !303 - br i1 %11, label %12, label %14, !dbg !303 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !432, !DIExpression(), !433) + #dbg_declare(ptr %3, !434, !DIExpression(), !435) + %4 = load ptr, ptr %2, align 8, !dbg !436 + %5 = call i32 @pthread_cond_destroy(ptr noundef %4) #6, !dbg !437 + store i32 %5, ptr %3, align 4, !dbg !435 + %6 = load i32, ptr %3, align 4, !dbg !438 + %7 = icmp eq i32 %6, 0, !dbg !438 + %8 = xor i1 %7, true, !dbg !438 + %9 = zext i1 %8 to i32, !dbg !438 + %10 = sext i32 %9 to i64, !dbg !438 + %11 = icmp ne i64 %10, 0, !dbg !438 + br i1 %11, label %12, label %14, !dbg !438 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([13 x i8], [13 x i8]* @__func__.cond_destroy, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 166, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !303 - unreachable, !dbg !303 + call void @__assert_rtn(ptr noundef @__func__.cond_destroy, ptr noundef @.str, i32 noundef 159, ptr noundef @.str.1) #8, !dbg !438 + unreachable, !dbg !438 13: ; No predecessors! - br label %15, !dbg !303 + br label %15, !dbg !438 14: ; preds = %1 - br label %15, !dbg !303 + br label %15, !dbg !438 15: ; preds = %14, %13 - ret void, !dbg !304 + ret void, !dbg !439 } -declare i32 @pthread_cond_destroy(%struct._opaque_pthread_cond_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_cond_destroy(ptr noundef) #1 -; Function Attrs: noinline nounwind ssp uwtable -define void @cond_signal(%struct._opaque_pthread_cond_t* noundef %0) #0 !dbg !305 { - %2 = alloca %struct._opaque_pthread_cond_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @cond_signal(ptr noundef %0) #0 !dbg !440 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_cond_t* %0, %struct._opaque_pthread_cond_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_cond_t** %2, metadata !306, metadata !DIExpression()), !dbg !307 - call void @llvm.dbg.declare(metadata i32* %3, metadata !308, metadata !DIExpression()), !dbg !309 - %4 = load %struct._opaque_pthread_cond_t*, %struct._opaque_pthread_cond_t** %2, align 8, !dbg !310 - %5 = call i32 @pthread_cond_signal(%struct._opaque_pthread_cond_t* noundef %4), !dbg !311 - store i32 %5, i32* %3, align 4, !dbg !309 - %6 = load i32, i32* %3, align 4, !dbg !312 - %7 = icmp eq i32 %6, 0, !dbg !312 - %8 = xor i1 %7, true, !dbg !312 - %9 = zext i1 %8 to i32, !dbg !312 - %10 = sext i32 %9 to i64, !dbg !312 - %11 = icmp ne i64 %10, 0, !dbg !312 - br i1 %11, label %12, label %14, !dbg !312 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !441, !DIExpression(), !442) + #dbg_declare(ptr %3, !443, !DIExpression(), !444) + %4 = load ptr, ptr %2, align 8, !dbg !445 + %5 = call i32 @pthread_cond_signal(ptr noundef %4) #7, !dbg !446 + store i32 %5, ptr %3, align 4, !dbg !444 + %6 = load i32, ptr %3, align 4, !dbg !447 + %7 = icmp eq i32 %6, 0, !dbg !447 + %8 = xor i1 %7, true, !dbg !447 + %9 = zext i1 %8 to i32, !dbg !447 + %10 = sext i32 %9 to i64, !dbg !447 + %11 = icmp ne i64 %10, 0, !dbg !447 + br i1 %11, label %12, label %14, !dbg !447 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.cond_signal, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 172, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !312 - unreachable, !dbg !312 + call void @__assert_rtn(ptr noundef @__func__.cond_signal, ptr noundef @.str, i32 noundef 165, ptr noundef @.str.1) #8, !dbg !447 + unreachable, !dbg !447 13: ; No predecessors! - br label %15, !dbg !312 + br label %15, !dbg !447 14: ; preds = %1 - br label %15, !dbg !312 + br label %15, !dbg !447 15: ; preds = %14, %13 - ret void, !dbg !313 + ret void, !dbg !448 } -declare i32 @pthread_cond_signal(%struct._opaque_pthread_cond_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_cond_signal(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define void @cond_broadcast(%struct._opaque_pthread_cond_t* noundef %0) #0 !dbg !314 { - %2 = alloca %struct._opaque_pthread_cond_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @cond_broadcast(ptr noundef %0) #0 !dbg !449 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_cond_t* %0, %struct._opaque_pthread_cond_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_cond_t** %2, metadata !315, metadata !DIExpression()), !dbg !316 - call void @llvm.dbg.declare(metadata i32* %3, metadata !317, metadata !DIExpression()), !dbg !318 - %4 = load %struct._opaque_pthread_cond_t*, %struct._opaque_pthread_cond_t** %2, align 8, !dbg !319 - %5 = call i32 @pthread_cond_broadcast(%struct._opaque_pthread_cond_t* noundef %4), !dbg !320 - store i32 %5, i32* %3, align 4, !dbg !318 - %6 = load i32, i32* %3, align 4, !dbg !321 - %7 = icmp eq i32 %6, 0, !dbg !321 - %8 = xor i1 %7, true, !dbg !321 - %9 = zext i1 %8 to i32, !dbg !321 - %10 = sext i32 %9 to i64, !dbg !321 - %11 = icmp ne i64 %10, 0, !dbg !321 - br i1 %11, label %12, label %14, !dbg !321 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !450, !DIExpression(), !451) + #dbg_declare(ptr %3, !452, !DIExpression(), !453) + %4 = load ptr, ptr %2, align 8, !dbg !454 + %5 = call i32 @pthread_cond_broadcast(ptr noundef %4) #7, !dbg !455 + store i32 %5, ptr %3, align 4, !dbg !453 + %6 = load i32, ptr %3, align 4, !dbg !456 + %7 = icmp eq i32 %6, 0, !dbg !456 + %8 = xor i1 %7, true, !dbg !456 + %9 = zext i1 %8 to i32, !dbg !456 + %10 = sext i32 %9 to i64, !dbg !456 + %11 = icmp ne i64 %10, 0, !dbg !456 + br i1 %11, label %12, label %14, !dbg !456 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([15 x i8], [15 x i8]* @__func__.cond_broadcast, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 178, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !321 - unreachable, !dbg !321 + call void @__assert_rtn(ptr noundef @__func__.cond_broadcast, ptr noundef @.str, i32 noundef 171, ptr noundef @.str.1) #8, !dbg !456 + unreachable, !dbg !456 13: ; No predecessors! - br label %15, !dbg !321 + br label %15, !dbg !456 14: ; preds = %1 - br label %15, !dbg !321 + br label %15, !dbg !456 15: ; preds = %14, %13 - ret void, !dbg !322 + ret void, !dbg !457 } -declare i32 @pthread_cond_broadcast(%struct._opaque_pthread_cond_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_cond_broadcast(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define void @cond_wait(%struct._opaque_pthread_cond_t* noundef %0, %struct._opaque_pthread_mutex_t* noundef %1) #0 !dbg !323 { - %3 = alloca %struct._opaque_pthread_cond_t*, align 8 - %4 = alloca %struct._opaque_pthread_mutex_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @cond_wait(ptr noundef %0, ptr noundef %1) #0 !dbg !458 { + %3 = alloca ptr, align 8 + %4 = alloca ptr, align 8 %5 = alloca i32, align 4 - store %struct._opaque_pthread_cond_t* %0, %struct._opaque_pthread_cond_t** %3, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_cond_t** %3, metadata !326, metadata !DIExpression()), !dbg !327 - store %struct._opaque_pthread_mutex_t* %1, %struct._opaque_pthread_mutex_t** %4, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutex_t** %4, metadata !328, metadata !DIExpression()), !dbg !329 - call void @llvm.dbg.declare(metadata i32* %5, metadata !330, metadata !DIExpression()), !dbg !331 - %6 = load %struct._opaque_pthread_cond_t*, %struct._opaque_pthread_cond_t** %3, align 8, !dbg !332 - %7 = load %struct._opaque_pthread_mutex_t*, %struct._opaque_pthread_mutex_t** %4, align 8, !dbg !333 - %8 = call i32 @"\01_pthread_cond_wait"(%struct._opaque_pthread_cond_t* noundef %6, %struct._opaque_pthread_mutex_t* noundef %7), !dbg !334 - store i32 %8, i32* %5, align 4, !dbg !331 - ret void, !dbg !335 + store ptr %0, ptr %3, align 8 + #dbg_declare(ptr %3, !461, !DIExpression(), !462) + store ptr %1, ptr %4, align 8 + #dbg_declare(ptr %4, !463, !DIExpression(), !464) + #dbg_declare(ptr %5, !465, !DIExpression(), !466) + %6 = load ptr, ptr %3, align 8, !dbg !467 + %7 = load ptr, ptr %4, align 8, !dbg !468 + %8 = call i32 @pthread_cond_wait(ptr noundef %6, ptr noundef %7), !dbg !469 + store i32 %8, ptr %5, align 4, !dbg !466 + ret void, !dbg !470 } -declare i32 @"\01_pthread_cond_wait"(%struct._opaque_pthread_cond_t* noundef, %struct._opaque_pthread_mutex_t* noundef) #2 +declare i32 @pthread_cond_wait(ptr noundef, ptr noundef) #4 -; Function Attrs: noinline nounwind ssp uwtable -define void @cond_timedwait(%struct._opaque_pthread_cond_t* noundef %0, %struct._opaque_pthread_mutex_t* noundef %1, i64 noundef %2) #0 !dbg !336 { - %4 = alloca %struct._opaque_pthread_cond_t*, align 8 - %5 = alloca %struct._opaque_pthread_mutex_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @cond_timedwait(ptr noundef %0, ptr noundef %1, i64 noundef %2) #0 !dbg !471 { + %4 = alloca ptr, align 8 + %5 = alloca ptr, align 8 %6 = alloca i64, align 8 %7 = alloca %struct.timespec, align 8 %8 = alloca i32, align 4 - store %struct._opaque_pthread_cond_t* %0, %struct._opaque_pthread_cond_t** %4, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_cond_t** %4, metadata !340, metadata !DIExpression()), !dbg !341 - store %struct._opaque_pthread_mutex_t* %1, %struct._opaque_pthread_mutex_t** %5, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_mutex_t** %5, metadata !342, metadata !DIExpression()), !dbg !343 - store i64 %2, i64* %6, align 8 - call void @llvm.dbg.declare(metadata i64* %6, metadata !344, metadata !DIExpression()), !dbg !345 - call void @llvm.dbg.declare(metadata %struct.timespec* %7, metadata !346, metadata !DIExpression()), !dbg !354 - %9 = load i64, i64* %6, align 8, !dbg !355 - call void @llvm.dbg.declare(metadata i32* %8, metadata !356, metadata !DIExpression()), !dbg !357 - %10 = load %struct._opaque_pthread_cond_t*, %struct._opaque_pthread_cond_t** %4, align 8, !dbg !358 - %11 = load %struct._opaque_pthread_mutex_t*, %struct._opaque_pthread_mutex_t** %5, align 8, !dbg !359 - %12 = call i32 @"\01_pthread_cond_timedwait"(%struct._opaque_pthread_cond_t* noundef %10, %struct._opaque_pthread_mutex_t* noundef %11, %struct.timespec* noundef %7), !dbg !360 - store i32 %12, i32* %8, align 4, !dbg !357 - ret void, !dbg !361 + store ptr %0, ptr %4, align 8 + #dbg_declare(ptr %4, !474, !DIExpression(), !475) + store ptr %1, ptr %5, align 8 + #dbg_declare(ptr %5, !476, !DIExpression(), !477) + store i64 %2, ptr %6, align 8 + #dbg_declare(ptr %6, !478, !DIExpression(), !479) + #dbg_declare(ptr %7, !480, !DIExpression(), !487) + %9 = load i64, ptr %6, align 8, !dbg !488 + #dbg_declare(ptr %8, !489, !DIExpression(), !490) + %10 = load ptr, ptr %4, align 8, !dbg !491 + %11 = load ptr, ptr %5, align 8, !dbg !492 + %12 = call i32 @pthread_cond_timedwait(ptr noundef %10, ptr noundef %11, ptr noundef %7), !dbg !493 + store i32 %12, ptr %8, align 4, !dbg !490 + ret void, !dbg !494 } -declare i32 @"\01_pthread_cond_timedwait"(%struct._opaque_pthread_cond_t* noundef, %struct._opaque_pthread_mutex_t* noundef, %struct.timespec* noundef) #2 +declare i32 @pthread_cond_timedwait(ptr noundef, ptr noundef, ptr noundef) #4 -; Function Attrs: noinline nounwind ssp uwtable -define i8* @cond_worker(i8* noundef %0) #0 !dbg !362 { - %2 = alloca i8*, align 8 - %3 = alloca i8*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local ptr @cond_worker(ptr noundef %0) #0 !dbg !495 { + %2 = alloca ptr, align 8 + %3 = alloca ptr, align 8 %4 = alloca i8, align 1 - store i8* %0, i8** %3, align 8 - call void @llvm.dbg.declare(metadata i8** %3, metadata !363, metadata !DIExpression()), !dbg !364 - call void @llvm.dbg.declare(metadata i8* %4, metadata !365, metadata !DIExpression()), !dbg !366 - store i8 1, i8* %4, align 1, !dbg !366 - call void @mutex_lock(%struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !367 - %5 = load i32, i32* @phase, align 4, !dbg !369 - %6 = add nsw i32 %5, 1, !dbg !369 - store i32 %6, i32* @phase, align 4, !dbg !369 - call void @cond_wait(%struct._opaque_pthread_cond_t* noundef @cond, %struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !370 - %7 = load i32, i32* @phase, align 4, !dbg !371 - %8 = add nsw i32 %7, 1, !dbg !371 - store i32 %8, i32* @phase, align 4, !dbg !371 - %9 = load i32, i32* @phase, align 4, !dbg !372 - %10 = icmp slt i32 %9, 2, !dbg !373 - %11 = zext i1 %10 to i8, !dbg !374 - store i8 %11, i8* %4, align 1, !dbg !374 - call void @mutex_unlock(%struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !375 - %12 = load i8, i8* %4, align 1, !dbg !376 - %13 = trunc i8 %12 to i1, !dbg !376 - br i1 %13, label %14, label %17, !dbg !378 + store ptr %0, ptr %3, align 8 + #dbg_declare(ptr %3, !496, !DIExpression(), !497) + #dbg_declare(ptr %4, !498, !DIExpression(), !499) + store i8 1, ptr %4, align 1, !dbg !499 + call void @mutex_lock(ptr noundef @cond_mutex), !dbg !500 + %5 = load i32, ptr @phase, align 4, !dbg !502 + %6 = add nsw i32 %5, 1, !dbg !502 + store i32 %6, ptr @phase, align 4, !dbg !502 + call void @cond_wait(ptr noundef @cond, ptr noundef @cond_mutex), !dbg !503 + %7 = load i32, ptr @phase, align 4, !dbg !504 + %8 = add nsw i32 %7, 1, !dbg !504 + store i32 %8, ptr @phase, align 4, !dbg !504 + %9 = load i32, ptr @phase, align 4, !dbg !505 + %10 = icmp slt i32 %9, 2, !dbg !506 + %11 = zext i1 %10 to i8, !dbg !507 + store i8 %11, ptr %4, align 1, !dbg !507 + call void @mutex_unlock(ptr noundef @cond_mutex), !dbg !508 + %12 = load i8, ptr %4, align 1, !dbg !509 + %13 = trunc i8 %12 to i1, !dbg !509 + br i1 %13, label %14, label %17, !dbg !511 14: ; preds = %1 - %15 = load i8*, i8** %3, align 8, !dbg !379 - %16 = getelementptr inbounds i8, i8* %15, i64 1, !dbg !380 - store i8* %16, i8** %2, align 8, !dbg !381 - br label %32, !dbg !381 + %15 = load ptr, ptr %3, align 8, !dbg !512 + %16 = getelementptr inbounds i8, ptr %15, i64 1, !dbg !513 + store ptr %16, ptr %2, align 8, !dbg !514 + br label %32, !dbg !514 17: ; preds = %1 - store i8 1, i8* %4, align 1, !dbg !382 - call void @mutex_lock(%struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !383 - %18 = load i32, i32* @phase, align 4, !dbg !385 - %19 = add nsw i32 %18, 1, !dbg !385 - store i32 %19, i32* @phase, align 4, !dbg !385 - call void @cond_timedwait(%struct._opaque_pthread_cond_t* noundef @cond, %struct._opaque_pthread_mutex_t* noundef @cond_mutex, i64 noundef 10), !dbg !386 - %20 = load i32, i32* @phase, align 4, !dbg !387 - %21 = add nsw i32 %20, 1, !dbg !387 - store i32 %21, i32* @phase, align 4, !dbg !387 - %22 = load i32, i32* @phase, align 4, !dbg !388 - %23 = icmp sgt i32 %22, 6, !dbg !389 - %24 = zext i1 %23 to i8, !dbg !390 - store i8 %24, i8* %4, align 1, !dbg !390 - call void @mutex_unlock(%struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !391 - %25 = load i8, i8* %4, align 1, !dbg !392 - %26 = trunc i8 %25 to i1, !dbg !392 - br i1 %26, label %27, label %30, !dbg !394 + store i8 1, ptr %4, align 1, !dbg !515 + call void @mutex_lock(ptr noundef @cond_mutex), !dbg !516 + %18 = load i32, ptr @phase, align 4, !dbg !518 + %19 = add nsw i32 %18, 1, !dbg !518 + store i32 %19, ptr @phase, align 4, !dbg !518 + call void @cond_timedwait(ptr noundef @cond, ptr noundef @cond_mutex, i64 noundef 10), !dbg !519 + %20 = load i32, ptr @phase, align 4, !dbg !520 + %21 = add nsw i32 %20, 1, !dbg !520 + store i32 %21, ptr @phase, align 4, !dbg !520 + %22 = load i32, ptr @phase, align 4, !dbg !521 + %23 = icmp sgt i32 %22, 6, !dbg !522 + %24 = zext i1 %23 to i8, !dbg !523 + store i8 %24, ptr %4, align 1, !dbg !523 + call void @mutex_unlock(ptr noundef @cond_mutex), !dbg !524 + %25 = load i8, ptr %4, align 1, !dbg !525 + %26 = trunc i8 %25 to i1, !dbg !525 + br i1 %26, label %27, label %30, !dbg !527 27: ; preds = %17 - %28 = load i8*, i8** %3, align 8, !dbg !395 - %29 = getelementptr inbounds i8, i8* %28, i64 2, !dbg !396 - store i8* %29, i8** %2, align 8, !dbg !397 - br label %32, !dbg !397 + %28 = load ptr, ptr %3, align 8, !dbg !528 + %29 = getelementptr inbounds i8, ptr %28, i64 2, !dbg !529 + store ptr %29, ptr %2, align 8, !dbg !530 + br label %32, !dbg !530 30: ; preds = %17 - %31 = load i8*, i8** %3, align 8, !dbg !398 - store i8* %31, i8** %2, align 8, !dbg !399 - br label %32, !dbg !399 + %31 = load ptr, ptr %3, align 8, !dbg !531 + store ptr %31, ptr %2, align 8, !dbg !532 + br label %32, !dbg !532 32: ; preds = %30, %27, %14 - %33 = load i8*, i8** %2, align 8, !dbg !400 - ret i8* %33, !dbg !400 + %33 = load ptr, ptr %2, align 8, !dbg !533 + ret ptr %33, !dbg !533 } -; Function Attrs: noinline nounwind ssp uwtable -define void @cond_test() #0 !dbg !401 { - %1 = alloca i8*, align 8 - %2 = alloca %struct._opaque_pthread_t*, align 8 - %3 = alloca i8*, align 8 - call void @llvm.dbg.declare(metadata i8** %1, metadata !402, metadata !DIExpression()), !dbg !403 - store i8* inttoptr (i64 42 to i8*), i8** %1, align 8, !dbg !403 - call void @mutex_init(%struct._opaque_pthread_mutex_t* noundef @cond_mutex, i32 noundef 0, i32 noundef 0, i32 noundef 3, i32 noundef 0), !dbg !404 - call void @cond_init(%struct._opaque_pthread_cond_t* noundef @cond), !dbg !405 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_t** %2, metadata !406, metadata !DIExpression()), !dbg !407 - %4 = load i8*, i8** %1, align 8, !dbg !408 - %5 = call %struct._opaque_pthread_t* @thread_create(i8* (i8*)* noundef @cond_worker, i8* noundef %4), !dbg !409 - store %struct._opaque_pthread_t* %5, %struct._opaque_pthread_t** %2, align 8, !dbg !407 - call void @mutex_lock(%struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !410 - %6 = load i32, i32* @phase, align 4, !dbg !412 - %7 = add nsw i32 %6, 1, !dbg !412 - store i32 %7, i32* @phase, align 4, !dbg !412 - call void @cond_signal(%struct._opaque_pthread_cond_t* noundef @cond), !dbg !413 - call void @mutex_unlock(%struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !414 - call void @mutex_lock(%struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !415 - %8 = load i32, i32* @phase, align 4, !dbg !417 - %9 = add nsw i32 %8, 1, !dbg !417 - store i32 %9, i32* @phase, align 4, !dbg !417 - call void @cond_broadcast(%struct._opaque_pthread_cond_t* noundef @cond), !dbg !418 - call void @mutex_unlock(%struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !419 - call void @llvm.dbg.declare(metadata i8** %3, metadata !420, metadata !DIExpression()), !dbg !421 - %10 = load %struct._opaque_pthread_t*, %struct._opaque_pthread_t** %2, align 8, !dbg !422 - %11 = call i8* @thread_join(%struct._opaque_pthread_t* noundef %10), !dbg !423 - store i8* %11, i8** %3, align 8, !dbg !421 - %12 = load i8*, i8** %3, align 8, !dbg !424 - %13 = load i8*, i8** %1, align 8, !dbg !424 - %14 = icmp eq i8* %12, %13, !dbg !424 - %15 = xor i1 %14, true, !dbg !424 - %16 = zext i1 %15 to i32, !dbg !424 - %17 = sext i32 %16 to i64, !dbg !424 - %18 = icmp ne i64 %17, 0, !dbg !424 - br i1 %18, label %19, label %21, !dbg !424 +; Function Attrs: noinline nounwind uwtable +define dso_local void @cond_test() #0 !dbg !534 { + %1 = alloca ptr, align 8 + %2 = alloca i64, align 8 + %3 = alloca ptr, align 8 + #dbg_declare(ptr %1, !535, !DIExpression(), !536) + store ptr inttoptr (i64 42 to ptr), ptr %1, align 8, !dbg !536 + call void @mutex_init(ptr noundef @cond_mutex, i32 noundef 0, i32 noundef 0, i32 noundef 0), !dbg !537 + call void @cond_init(ptr noundef @cond), !dbg !538 + #dbg_declare(ptr %2, !539, !DIExpression(), !540) + %4 = load ptr, ptr %1, align 8, !dbg !541 + %5 = call i64 @thread_create(ptr noundef @cond_worker, ptr noundef %4), !dbg !542 + store i64 %5, ptr %2, align 8, !dbg !540 + call void @mutex_lock(ptr noundef @cond_mutex), !dbg !543 + %6 = load i32, ptr @phase, align 4, !dbg !545 + %7 = add nsw i32 %6, 1, !dbg !545 + store i32 %7, ptr @phase, align 4, !dbg !545 + call void @cond_signal(ptr noundef @cond), !dbg !546 + call void @mutex_unlock(ptr noundef @cond_mutex), !dbg !547 + call void @mutex_lock(ptr noundef @cond_mutex), !dbg !548 + %8 = load i32, ptr @phase, align 4, !dbg !550 + %9 = add nsw i32 %8, 1, !dbg !550 + store i32 %9, ptr @phase, align 4, !dbg !550 + call void @cond_broadcast(ptr noundef @cond), !dbg !551 + call void @mutex_unlock(ptr noundef @cond_mutex), !dbg !552 + #dbg_declare(ptr %3, !553, !DIExpression(), !554) + %10 = load i64, ptr %2, align 8, !dbg !555 + %11 = call ptr @thread_join(i64 noundef %10), !dbg !556 + store ptr %11, ptr %3, align 8, !dbg !554 + %12 = load ptr, ptr %3, align 8, !dbg !557 + %13 = load ptr, ptr %1, align 8, !dbg !557 + %14 = icmp eq ptr %12, %13, !dbg !557 + %15 = xor i1 %14, true, !dbg !557 + %16 = zext i1 %15 to i32, !dbg !557 + %17 = sext i32 %16 to i64, !dbg !557 + %18 = icmp ne i64 %17, 0, !dbg !557 + br i1 %18, label %19, label %21, !dbg !557 19: ; preds = %0 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @__func__.cond_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 252, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @.str.4, i64 0, i64 0)) #4, !dbg !424 - unreachable, !dbg !424 + call void @__assert_rtn(ptr noundef @__func__.cond_test, ptr noundef @.str, i32 noundef 245, ptr noundef @.str.4) #8, !dbg !557 + unreachable, !dbg !557 20: ; No predecessors! - br label %22, !dbg !424 + br label %22, !dbg !557 21: ; preds = %0 - br label %22, !dbg !424 + br label %22, !dbg !557 22: ; preds = %21, %20 - call void @cond_destroy(%struct._opaque_pthread_cond_t* noundef @cond), !dbg !425 - call void @mutex_destroy(%struct._opaque_pthread_mutex_t* noundef @cond_mutex), !dbg !426 - ret void, !dbg !427 + call void @cond_destroy(ptr noundef @cond), !dbg !558 + call void @mutex_destroy(ptr noundef @cond_mutex), !dbg !559 + ret void, !dbg !560 } -; Function Attrs: noinline nounwind ssp uwtable -define void @rwlock_init(%struct._opaque_pthread_rwlock_t* noundef %0, i32 noundef %1) #0 !dbg !428 { - %3 = alloca %struct._opaque_pthread_rwlock_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @rwlock_init(ptr noundef %0, i32 noundef %1) #0 !dbg !561 { + %3 = alloca ptr, align 8 %4 = alloca i32, align 4 %5 = alloca i32, align 4 %6 = alloca i32, align 4 - %7 = alloca %struct._opaque_pthread_rwlockattr_t, align 8 - store %struct._opaque_pthread_rwlock_t* %0, %struct._opaque_pthread_rwlock_t** %3, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_rwlock_t** %3, metadata !442, metadata !DIExpression()), !dbg !443 - store i32 %1, i32* %4, align 4 - call void @llvm.dbg.declare(metadata i32* %4, metadata !444, metadata !DIExpression()), !dbg !445 - call void @llvm.dbg.declare(metadata i32* %5, metadata !446, metadata !DIExpression()), !dbg !447 - call void @llvm.dbg.declare(metadata i32* %6, metadata !448, metadata !DIExpression()), !dbg !449 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_rwlockattr_t* %7, metadata !450, metadata !DIExpression()), !dbg !461 - %8 = call i32 @pthread_rwlockattr_init(%struct._opaque_pthread_rwlockattr_t* noundef %7), !dbg !462 - store i32 %8, i32* %5, align 4, !dbg !463 - %9 = load i32, i32* %5, align 4, !dbg !464 - %10 = icmp eq i32 %9, 0, !dbg !464 - %11 = xor i1 %10, true, !dbg !464 - %12 = zext i1 %11 to i32, !dbg !464 - %13 = sext i32 %12 to i64, !dbg !464 - %14 = icmp ne i64 %13, 0, !dbg !464 - br i1 %14, label %15, label %17, !dbg !464 + %7 = alloca %union.pthread_rwlockattr_t, align 8 + store ptr %0, ptr %3, align 8 + #dbg_declare(ptr %3, !589, !DIExpression(), !590) + store i32 %1, ptr %4, align 4 + #dbg_declare(ptr %4, !591, !DIExpression(), !592) + #dbg_declare(ptr %5, !593, !DIExpression(), !594) + #dbg_declare(ptr %6, !595, !DIExpression(), !596) + #dbg_declare(ptr %7, !597, !DIExpression(), !603) + %8 = call i32 @pthread_rwlockattr_init(ptr noundef %7) #6, !dbg !604 + store i32 %8, ptr %5, align 4, !dbg !605 + %9 = load i32, ptr %5, align 4, !dbg !606 + %10 = icmp eq i32 %9, 0, !dbg !606 + %11 = xor i1 %10, true, !dbg !606 + %12 = zext i1 %11 to i32, !dbg !606 + %13 = sext i32 %12 to i64, !dbg !606 + %14 = icmp ne i64 %13, 0, !dbg !606 + br i1 %14, label %15, label %17, !dbg !606 15: ; preds = %2 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 269, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !464 - unreachable, !dbg !464 + call void @__assert_rtn(ptr noundef @__func__.rwlock_init, ptr noundef @.str, i32 noundef 262, ptr noundef @.str.1) #8, !dbg !606 + unreachable, !dbg !606 16: ; No predecessors! - br label %18, !dbg !464 + br label %18, !dbg !606 17: ; preds = %2 - br label %18, !dbg !464 + br label %18, !dbg !606 18: ; preds = %17, %16 - %19 = load i32, i32* %4, align 4, !dbg !465 - %20 = call i32 @pthread_rwlockattr_setpshared(%struct._opaque_pthread_rwlockattr_t* noundef %7, i32 noundef %19), !dbg !466 - store i32 %20, i32* %5, align 4, !dbg !467 - %21 = load i32, i32* %5, align 4, !dbg !468 - %22 = icmp eq i32 %21, 0, !dbg !468 - %23 = xor i1 %22, true, !dbg !468 - %24 = zext i1 %23 to i32, !dbg !468 - %25 = sext i32 %24 to i64, !dbg !468 - %26 = icmp ne i64 %25, 0, !dbg !468 - br i1 %26, label %27, label %29, !dbg !468 + %19 = load i32, ptr %4, align 4, !dbg !607 + %20 = call i32 @pthread_rwlockattr_setpshared(ptr noundef %7, i32 noundef %19) #6, !dbg !608 + store i32 %20, ptr %5, align 4, !dbg !609 + %21 = load i32, ptr %5, align 4, !dbg !610 + %22 = icmp eq i32 %21, 0, !dbg !610 + %23 = xor i1 %22, true, !dbg !610 + %24 = zext i1 %23 to i32, !dbg !610 + %25 = sext i32 %24 to i64, !dbg !610 + %26 = icmp ne i64 %25, 0, !dbg !610 + br i1 %26, label %27, label %29, !dbg !610 27: ; preds = %18 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 272, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !468 - unreachable, !dbg !468 + call void @__assert_rtn(ptr noundef @__func__.rwlock_init, ptr noundef @.str, i32 noundef 265, ptr noundef @.str.1) #8, !dbg !610 + unreachable, !dbg !610 28: ; No predecessors! - br label %30, !dbg !468 + br label %30, !dbg !610 29: ; preds = %18 - br label %30, !dbg !468 + br label %30, !dbg !610 30: ; preds = %29, %28 - %31 = call i32 @pthread_rwlockattr_getpshared(%struct._opaque_pthread_rwlockattr_t* noundef %7, i32* noundef %6), !dbg !469 - store i32 %31, i32* %5, align 4, !dbg !470 - %32 = load i32, i32* %5, align 4, !dbg !471 - %33 = icmp eq i32 %32, 0, !dbg !471 - %34 = xor i1 %33, true, !dbg !471 - %35 = zext i1 %34 to i32, !dbg !471 - %36 = sext i32 %35 to i64, !dbg !471 - %37 = icmp ne i64 %36, 0, !dbg !471 - br i1 %37, label %38, label %40, !dbg !471 + %31 = call i32 @pthread_rwlockattr_getpshared(ptr noundef %7, ptr noundef %6) #6, !dbg !611 + store i32 %31, ptr %5, align 4, !dbg !612 + %32 = load i32, ptr %5, align 4, !dbg !613 + %33 = icmp eq i32 %32, 0, !dbg !613 + %34 = xor i1 %33, true, !dbg !613 + %35 = zext i1 %34 to i32, !dbg !613 + %36 = sext i32 %35 to i64, !dbg !613 + %37 = icmp ne i64 %36, 0, !dbg !613 + br i1 %37, label %38, label %40, !dbg !613 38: ; preds = %30 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 274, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !471 - unreachable, !dbg !471 + call void @__assert_rtn(ptr noundef @__func__.rwlock_init, ptr noundef @.str, i32 noundef 267, ptr noundef @.str.1) #8, !dbg !613 + unreachable, !dbg !613 39: ; No predecessors! - br label %41, !dbg !471 + br label %41, !dbg !613 40: ; preds = %30 - br label %41, !dbg !471 + br label %41, !dbg !613 41: ; preds = %40, %39 - %42 = load %struct._opaque_pthread_rwlock_t*, %struct._opaque_pthread_rwlock_t** %3, align 8, !dbg !472 - %43 = call i32 @"\01_pthread_rwlock_init"(%struct._opaque_pthread_rwlock_t* noundef %42, %struct._opaque_pthread_rwlockattr_t* noundef %7), !dbg !473 - store i32 %43, i32* %5, align 4, !dbg !474 - %44 = load i32, i32* %5, align 4, !dbg !475 - %45 = icmp eq i32 %44, 0, !dbg !475 - %46 = xor i1 %45, true, !dbg !475 - %47 = zext i1 %46 to i32, !dbg !475 - %48 = sext i32 %47 to i64, !dbg !475 - %49 = icmp ne i64 %48, 0, !dbg !475 - br i1 %49, label %50, label %52, !dbg !475 + %42 = load ptr, ptr %3, align 8, !dbg !614 + %43 = call i32 @pthread_rwlock_init(ptr noundef %42, ptr noundef %7) #6, !dbg !615 + store i32 %43, ptr %5, align 4, !dbg !616 + %44 = load i32, ptr %5, align 4, !dbg !617 + %45 = icmp eq i32 %44, 0, !dbg !617 + %46 = xor i1 %45, true, !dbg !617 + %47 = zext i1 %46 to i32, !dbg !617 + %48 = sext i32 %47 to i64, !dbg !617 + %49 = icmp ne i64 %48, 0, !dbg !617 + br i1 %49, label %50, label %52, !dbg !617 50: ; preds = %41 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 277, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !475 - unreachable, !dbg !475 + call void @__assert_rtn(ptr noundef @__func__.rwlock_init, ptr noundef @.str, i32 noundef 270, ptr noundef @.str.1) #8, !dbg !617 + unreachable, !dbg !617 51: ; No predecessors! - br label %53, !dbg !475 + br label %53, !dbg !617 52: ; preds = %41 - br label %53, !dbg !475 + br label %53, !dbg !617 53: ; preds = %52, %51 - %54 = call i32 @pthread_rwlockattr_destroy(%struct._opaque_pthread_rwlockattr_t* noundef %7), !dbg !476 - store i32 %54, i32* %5, align 4, !dbg !477 - %55 = load i32, i32* %5, align 4, !dbg !478 - %56 = icmp eq i32 %55, 0, !dbg !478 - %57 = xor i1 %56, true, !dbg !478 - %58 = zext i1 %57 to i32, !dbg !478 - %59 = sext i32 %58 to i64, !dbg !478 - %60 = icmp ne i64 %59, 0, !dbg !478 - br i1 %60, label %61, label %63, !dbg !478 + %54 = call i32 @pthread_rwlockattr_destroy(ptr noundef %7) #6, !dbg !618 + store i32 %54, ptr %5, align 4, !dbg !619 + %55 = load i32, ptr %5, align 4, !dbg !620 + %56 = icmp eq i32 %55, 0, !dbg !620 + %57 = xor i1 %56, true, !dbg !620 + %58 = zext i1 %57 to i32, !dbg !620 + %59 = sext i32 %58 to i64, !dbg !620 + %60 = icmp ne i64 %59, 0, !dbg !620 + br i1 %60, label %61, label %63, !dbg !620 61: ; preds = %53 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_init, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 279, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !478 - unreachable, !dbg !478 + call void @__assert_rtn(ptr noundef @__func__.rwlock_init, ptr noundef @.str, i32 noundef 272, ptr noundef @.str.1) #8, !dbg !620 + unreachable, !dbg !620 62: ; No predecessors! - br label %64, !dbg !478 + br label %64, !dbg !620 63: ; preds = %53 - br label %64, !dbg !478 + br label %64, !dbg !620 64: ; preds = %63, %62 - ret void, !dbg !479 + ret void, !dbg !621 } -declare i32 @pthread_rwlockattr_init(%struct._opaque_pthread_rwlockattr_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_rwlockattr_init(ptr noundef) #1 -declare i32 @pthread_rwlockattr_setpshared(%struct._opaque_pthread_rwlockattr_t* noundef, i32 noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_rwlockattr_setpshared(ptr noundef, i32 noundef) #1 -declare i32 @pthread_rwlockattr_getpshared(%struct._opaque_pthread_rwlockattr_t* noundef, i32* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_rwlockattr_getpshared(ptr noundef, ptr noundef) #1 -declare i32 @"\01_pthread_rwlock_init"(%struct._opaque_pthread_rwlock_t* noundef, %struct._opaque_pthread_rwlockattr_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_rwlock_init(ptr noundef, ptr noundef) #1 -declare i32 @pthread_rwlockattr_destroy(%struct._opaque_pthread_rwlockattr_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_rwlockattr_destroy(ptr noundef) #1 -; Function Attrs: noinline nounwind ssp uwtable -define void @rwlock_destroy(%struct._opaque_pthread_rwlock_t* noundef %0) #0 !dbg !480 { - %2 = alloca %struct._opaque_pthread_rwlock_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @rwlock_destroy(ptr noundef %0) #0 !dbg !622 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_rwlock_t* %0, %struct._opaque_pthread_rwlock_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_rwlock_t** %2, metadata !483, metadata !DIExpression()), !dbg !484 - call void @llvm.dbg.declare(metadata i32* %3, metadata !485, metadata !DIExpression()), !dbg !486 - %4 = load %struct._opaque_pthread_rwlock_t*, %struct._opaque_pthread_rwlock_t** %2, align 8, !dbg !487 - %5 = call i32 @"\01_pthread_rwlock_destroy"(%struct._opaque_pthread_rwlock_t* noundef %4), !dbg !488 - store i32 %5, i32* %3, align 4, !dbg !486 - %6 = load i32, i32* %3, align 4, !dbg !489 - %7 = icmp eq i32 %6, 0, !dbg !489 - %8 = xor i1 %7, true, !dbg !489 - %9 = zext i1 %8 to i32, !dbg !489 - %10 = sext i32 %9 to i64, !dbg !489 - %11 = icmp ne i64 %10, 0, !dbg !489 - br i1 %11, label %12, label %14, !dbg !489 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !625, !DIExpression(), !626) + #dbg_declare(ptr %3, !627, !DIExpression(), !628) + %4 = load ptr, ptr %2, align 8, !dbg !629 + %5 = call i32 @pthread_rwlock_destroy(ptr noundef %4) #6, !dbg !630 + store i32 %5, ptr %3, align 4, !dbg !628 + %6 = load i32, ptr %3, align 4, !dbg !631 + %7 = icmp eq i32 %6, 0, !dbg !631 + %8 = xor i1 %7, true, !dbg !631 + %9 = zext i1 %8 to i32, !dbg !631 + %10 = sext i32 %9 to i64, !dbg !631 + %11 = icmp ne i64 %10, 0, !dbg !631 + br i1 %11, label %12, label %14, !dbg !631 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([15 x i8], [15 x i8]* @__func__.rwlock_destroy, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 285, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !489 - unreachable, !dbg !489 + call void @__assert_rtn(ptr noundef @__func__.rwlock_destroy, ptr noundef @.str, i32 noundef 278, ptr noundef @.str.1) #8, !dbg !631 + unreachable, !dbg !631 13: ; No predecessors! - br label %15, !dbg !489 + br label %15, !dbg !631 14: ; preds = %1 - br label %15, !dbg !489 + br label %15, !dbg !631 15: ; preds = %14, %13 - ret void, !dbg !490 + ret void, !dbg !632 } -declare i32 @"\01_pthread_rwlock_destroy"(%struct._opaque_pthread_rwlock_t* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_rwlock_destroy(ptr noundef) #1 -; Function Attrs: noinline nounwind ssp uwtable -define void @rwlock_wrlock(%struct._opaque_pthread_rwlock_t* noundef %0) #0 !dbg !491 { - %2 = alloca %struct._opaque_pthread_rwlock_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @rwlock_wrlock(ptr noundef %0) #0 !dbg !633 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_rwlock_t* %0, %struct._opaque_pthread_rwlock_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_rwlock_t** %2, metadata !492, metadata !DIExpression()), !dbg !493 - call void @llvm.dbg.declare(metadata i32* %3, metadata !494, metadata !DIExpression()), !dbg !495 - %4 = load %struct._opaque_pthread_rwlock_t*, %struct._opaque_pthread_rwlock_t** %2, align 8, !dbg !496 - %5 = call i32 @"\01_pthread_rwlock_wrlock"(%struct._opaque_pthread_rwlock_t* noundef %4), !dbg !497 - store i32 %5, i32* %3, align 4, !dbg !495 - %6 = load i32, i32* %3, align 4, !dbg !498 - %7 = icmp eq i32 %6, 0, !dbg !498 - %8 = xor i1 %7, true, !dbg !498 - %9 = zext i1 %8 to i32, !dbg !498 - %10 = sext i32 %9 to i64, !dbg !498 - %11 = icmp ne i64 %10, 0, !dbg !498 - br i1 %11, label %12, label %14, !dbg !498 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !634, !DIExpression(), !635) + #dbg_declare(ptr %3, !636, !DIExpression(), !637) + %4 = load ptr, ptr %2, align 8, !dbg !638 + %5 = call i32 @pthread_rwlock_wrlock(ptr noundef %4) #7, !dbg !639 + store i32 %5, ptr %3, align 4, !dbg !637 + %6 = load i32, ptr %3, align 4, !dbg !640 + %7 = icmp eq i32 %6, 0, !dbg !640 + %8 = xor i1 %7, true, !dbg !640 + %9 = zext i1 %8 to i32, !dbg !640 + %10 = sext i32 %9 to i64, !dbg !640 + %11 = icmp ne i64 %10, 0, !dbg !640 + br i1 %11, label %12, label %14, !dbg !640 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__func__.rwlock_wrlock, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 291, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !498 - unreachable, !dbg !498 + call void @__assert_rtn(ptr noundef @__func__.rwlock_wrlock, ptr noundef @.str, i32 noundef 284, ptr noundef @.str.1) #8, !dbg !640 + unreachable, !dbg !640 13: ; No predecessors! - br label %15, !dbg !498 + br label %15, !dbg !640 14: ; preds = %1 - br label %15, !dbg !498 + br label %15, !dbg !640 15: ; preds = %14, %13 - ret void, !dbg !499 + ret void, !dbg !641 } -declare i32 @"\01_pthread_rwlock_wrlock"(%struct._opaque_pthread_rwlock_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_rwlock_wrlock(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define zeroext i1 @rwlock_trywrlock(%struct._opaque_pthread_rwlock_t* noundef %0) #0 !dbg !500 { - %2 = alloca %struct._opaque_pthread_rwlock_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local zeroext i1 @rwlock_trywrlock(ptr noundef %0) #0 !dbg !642 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_rwlock_t* %0, %struct._opaque_pthread_rwlock_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_rwlock_t** %2, metadata !503, metadata !DIExpression()), !dbg !504 - call void @llvm.dbg.declare(metadata i32* %3, metadata !505, metadata !DIExpression()), !dbg !506 - %4 = load %struct._opaque_pthread_rwlock_t*, %struct._opaque_pthread_rwlock_t** %2, align 8, !dbg !507 - %5 = call i32 @"\01_pthread_rwlock_trywrlock"(%struct._opaque_pthread_rwlock_t* noundef %4), !dbg !508 - store i32 %5, i32* %3, align 4, !dbg !506 - %6 = load i32, i32* %3, align 4, !dbg !509 - %7 = icmp eq i32 %6, 0, !dbg !510 - ret i1 %7, !dbg !511 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !645, !DIExpression(), !646) + #dbg_declare(ptr %3, !647, !DIExpression(), !648) + %4 = load ptr, ptr %2, align 8, !dbg !649 + %5 = call i32 @pthread_rwlock_trywrlock(ptr noundef %4) #7, !dbg !650 + store i32 %5, ptr %3, align 4, !dbg !648 + %6 = load i32, ptr %3, align 4, !dbg !651 + %7 = icmp eq i32 %6, 0, !dbg !652 + ret i1 %7, !dbg !653 } -declare i32 @"\01_pthread_rwlock_trywrlock"(%struct._opaque_pthread_rwlock_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_rwlock_trywrlock(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define void @rwlock_rdlock(%struct._opaque_pthread_rwlock_t* noundef %0) #0 !dbg !512 { - %2 = alloca %struct._opaque_pthread_rwlock_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @rwlock_rdlock(ptr noundef %0) #0 !dbg !654 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_rwlock_t* %0, %struct._opaque_pthread_rwlock_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_rwlock_t** %2, metadata !513, metadata !DIExpression()), !dbg !514 - call void @llvm.dbg.declare(metadata i32* %3, metadata !515, metadata !DIExpression()), !dbg !516 - %4 = load %struct._opaque_pthread_rwlock_t*, %struct._opaque_pthread_rwlock_t** %2, align 8, !dbg !517 - %5 = call i32 @"\01_pthread_rwlock_rdlock"(%struct._opaque_pthread_rwlock_t* noundef %4), !dbg !518 - store i32 %5, i32* %3, align 4, !dbg !516 - %6 = load i32, i32* %3, align 4, !dbg !519 - %7 = icmp eq i32 %6, 0, !dbg !519 - %8 = xor i1 %7, true, !dbg !519 - %9 = zext i1 %8 to i32, !dbg !519 - %10 = sext i32 %9 to i64, !dbg !519 - %11 = icmp ne i64 %10, 0, !dbg !519 - br i1 %11, label %12, label %14, !dbg !519 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !655, !DIExpression(), !656) + #dbg_declare(ptr %3, !657, !DIExpression(), !658) + %4 = load ptr, ptr %2, align 8, !dbg !659 + %5 = call i32 @pthread_rwlock_rdlock(ptr noundef %4) #7, !dbg !660 + store i32 %5, ptr %3, align 4, !dbg !658 + %6 = load i32, ptr %3, align 4, !dbg !661 + %7 = icmp eq i32 %6, 0, !dbg !661 + %8 = xor i1 %7, true, !dbg !661 + %9 = zext i1 %8 to i32, !dbg !661 + %10 = sext i32 %9 to i64, !dbg !661 + %11 = icmp ne i64 %10, 0, !dbg !661 + br i1 %11, label %12, label %14, !dbg !661 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__func__.rwlock_rdlock, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 304, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !519 - unreachable, !dbg !519 + call void @__assert_rtn(ptr noundef @__func__.rwlock_rdlock, ptr noundef @.str, i32 noundef 297, ptr noundef @.str.1) #8, !dbg !661 + unreachable, !dbg !661 13: ; No predecessors! - br label %15, !dbg !519 + br label %15, !dbg !661 14: ; preds = %1 - br label %15, !dbg !519 + br label %15, !dbg !661 15: ; preds = %14, %13 - ret void, !dbg !520 + ret void, !dbg !662 } -declare i32 @"\01_pthread_rwlock_rdlock"(%struct._opaque_pthread_rwlock_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_rwlock_rdlock(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define zeroext i1 @rwlock_tryrdlock(%struct._opaque_pthread_rwlock_t* noundef %0) #0 !dbg !521 { - %2 = alloca %struct._opaque_pthread_rwlock_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local zeroext i1 @rwlock_tryrdlock(ptr noundef %0) #0 !dbg !663 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_rwlock_t* %0, %struct._opaque_pthread_rwlock_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_rwlock_t** %2, metadata !522, metadata !DIExpression()), !dbg !523 - call void @llvm.dbg.declare(metadata i32* %3, metadata !524, metadata !DIExpression()), !dbg !525 - %4 = load %struct._opaque_pthread_rwlock_t*, %struct._opaque_pthread_rwlock_t** %2, align 8, !dbg !526 - %5 = call i32 @"\01_pthread_rwlock_tryrdlock"(%struct._opaque_pthread_rwlock_t* noundef %4), !dbg !527 - store i32 %5, i32* %3, align 4, !dbg !525 - %6 = load i32, i32* %3, align 4, !dbg !528 - %7 = icmp eq i32 %6, 0, !dbg !529 - ret i1 %7, !dbg !530 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !664, !DIExpression(), !665) + #dbg_declare(ptr %3, !666, !DIExpression(), !667) + %4 = load ptr, ptr %2, align 8, !dbg !668 + %5 = call i32 @pthread_rwlock_tryrdlock(ptr noundef %4) #7, !dbg !669 + store i32 %5, ptr %3, align 4, !dbg !667 + %6 = load i32, ptr %3, align 4, !dbg !670 + %7 = icmp eq i32 %6, 0, !dbg !671 + ret i1 %7, !dbg !672 } -declare i32 @"\01_pthread_rwlock_tryrdlock"(%struct._opaque_pthread_rwlock_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_rwlock_tryrdlock(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define void @rwlock_unlock(%struct._opaque_pthread_rwlock_t* noundef %0) #0 !dbg !531 { - %2 = alloca %struct._opaque_pthread_rwlock_t*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @rwlock_unlock(ptr noundef %0) #0 !dbg !673 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - store %struct._opaque_pthread_rwlock_t* %0, %struct._opaque_pthread_rwlock_t** %2, align 8 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_rwlock_t** %2, metadata !532, metadata !DIExpression()), !dbg !533 - call void @llvm.dbg.declare(metadata i32* %3, metadata !534, metadata !DIExpression()), !dbg !535 - %4 = load %struct._opaque_pthread_rwlock_t*, %struct._opaque_pthread_rwlock_t** %2, align 8, !dbg !536 - %5 = call i32 @"\01_pthread_rwlock_unlock"(%struct._opaque_pthread_rwlock_t* noundef %4), !dbg !537 - store i32 %5, i32* %3, align 4, !dbg !535 - %6 = load i32, i32* %3, align 4, !dbg !538 - %7 = icmp eq i32 %6, 0, !dbg !538 - %8 = xor i1 %7, true, !dbg !538 - %9 = zext i1 %8 to i32, !dbg !538 - %10 = sext i32 %9 to i64, !dbg !538 - %11 = icmp ne i64 %10, 0, !dbg !538 - br i1 %11, label %12, label %14, !dbg !538 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !674, !DIExpression(), !675) + #dbg_declare(ptr %3, !676, !DIExpression(), !677) + %4 = load ptr, ptr %2, align 8, !dbg !678 + %5 = call i32 @pthread_rwlock_unlock(ptr noundef %4) #7, !dbg !679 + store i32 %5, ptr %3, align 4, !dbg !677 + %6 = load i32, ptr %3, align 4, !dbg !680 + %7 = icmp eq i32 %6, 0, !dbg !680 + %8 = xor i1 %7, true, !dbg !680 + %9 = zext i1 %8 to i32, !dbg !680 + %10 = sext i32 %9 to i64, !dbg !680 + %11 = icmp ne i64 %10, 0, !dbg !680 + br i1 %11, label %12, label %14, !dbg !680 12: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([14 x i8], [14 x i8]* @__func__.rwlock_unlock, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 317, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !538 - unreachable, !dbg !538 + call void @__assert_rtn(ptr noundef @__func__.rwlock_unlock, ptr noundef @.str, i32 noundef 310, ptr noundef @.str.1) #8, !dbg !680 + unreachable, !dbg !680 13: ; No predecessors! - br label %15, !dbg !538 + br label %15, !dbg !680 14: ; preds = %1 - br label %15, !dbg !538 + br label %15, !dbg !680 15: ; preds = %14, %13 - ret void, !dbg !539 + ret void, !dbg !681 } -declare i32 @"\01_pthread_rwlock_unlock"(%struct._opaque_pthread_rwlock_t* noundef) #2 +; Function Attrs: nounwind +declare i32 @pthread_rwlock_unlock(ptr noundef) #2 -; Function Attrs: noinline nounwind ssp uwtable -define void @rwlock_test() #0 !dbg !540 { - %1 = alloca %struct._opaque_pthread_rwlock_t, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local void @rwlock_test() #0 !dbg !682 { + %1 = alloca %union.pthread_rwlock_t, align 8 %2 = alloca i32, align 4 %3 = alloca i8, align 1 %4 = alloca i32, align 4 @@ -1296,1089 +1284,1541 @@ define void @rwlock_test() #0 !dbg !540 { %6 = alloca i8, align 1 %7 = alloca i32, align 4 %8 = alloca i8, align 1 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_rwlock_t* %1, metadata !541, metadata !DIExpression()), !dbg !542 - call void @rwlock_init(%struct._opaque_pthread_rwlock_t* noundef %1, i32 noundef 2), !dbg !543 - call void @llvm.dbg.declare(metadata i32* %2, metadata !544, metadata !DIExpression()), !dbg !546 - store i32 4, i32* %2, align 4, !dbg !546 - call void @rwlock_wrlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !547 - call void @llvm.dbg.declare(metadata i8* %3, metadata !549, metadata !DIExpression()), !dbg !550 - %9 = call zeroext i1 @rwlock_trywrlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !551 - %10 = zext i1 %9 to i8, !dbg !550 - store i8 %10, i8* %3, align 1, !dbg !550 - %11 = load i8, i8* %3, align 1, !dbg !552 - %12 = trunc i8 %11 to i1, !dbg !552 - %13 = xor i1 %12, true, !dbg !552 - %14 = xor i1 %13, true, !dbg !552 - %15 = zext i1 %14 to i32, !dbg !552 - %16 = sext i32 %15 to i64, !dbg !552 - %17 = icmp ne i64 %16, 0, !dbg !552 - br i1 %17, label %18, label %20, !dbg !552 + #dbg_declare(ptr %1, !683, !DIExpression(), !684) + call void @rwlock_init(ptr noundef %1, i32 noundef 0), !dbg !685 + #dbg_declare(ptr %2, !686, !DIExpression(), !688) + store i32 4, ptr %2, align 4, !dbg !688 + call void @rwlock_wrlock(ptr noundef %1), !dbg !689 + #dbg_declare(ptr %3, !691, !DIExpression(), !692) + %9 = call zeroext i1 @rwlock_trywrlock(ptr noundef %1), !dbg !693 + %10 = zext i1 %9 to i8, !dbg !692 + store i8 %10, ptr %3, align 1, !dbg !692 + %11 = load i8, ptr %3, align 1, !dbg !694 + %12 = trunc i8 %11 to i1, !dbg !694 + %13 = xor i1 %12, true, !dbg !694 + %14 = xor i1 %13, true, !dbg !694 + %15 = zext i1 %14 to i32, !dbg !694 + %16 = sext i32 %15 to i64, !dbg !694 + %17 = icmp ne i64 %16, 0, !dbg !694 + br i1 %17, label %18, label %20, !dbg !694 18: ; preds = %0 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 329, i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.2, i64 0, i64 0)) #4, !dbg !552 - unreachable, !dbg !552 + call void @__assert_rtn(ptr noundef @__func__.rwlock_test, ptr noundef @.str, i32 noundef 322, ptr noundef @.str.2) #8, !dbg !694 + unreachable, !dbg !694 19: ; No predecessors! - br label %21, !dbg !552 + br label %21, !dbg !694 20: ; preds = %0 - br label %21, !dbg !552 + br label %21, !dbg !694 21: ; preds = %20, %19 - %22 = call zeroext i1 @rwlock_tryrdlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !553 - %23 = zext i1 %22 to i8, !dbg !554 - store i8 %23, i8* %3, align 1, !dbg !554 - %24 = load i8, i8* %3, align 1, !dbg !555 - %25 = trunc i8 %24 to i1, !dbg !555 - %26 = xor i1 %25, true, !dbg !555 - %27 = xor i1 %26, true, !dbg !555 - %28 = zext i1 %27 to i32, !dbg !555 - %29 = sext i32 %28 to i64, !dbg !555 - %30 = icmp ne i64 %29, 0, !dbg !555 - br i1 %30, label %31, label %33, !dbg !555 + %22 = call zeroext i1 @rwlock_tryrdlock(ptr noundef %1), !dbg !695 + %23 = zext i1 %22 to i8, !dbg !696 + store i8 %23, ptr %3, align 1, !dbg !696 + %24 = load i8, ptr %3, align 1, !dbg !697 + %25 = trunc i8 %24 to i1, !dbg !697 + %26 = xor i1 %25, true, !dbg !697 + %27 = xor i1 %26, true, !dbg !697 + %28 = zext i1 %27 to i32, !dbg !697 + %29 = sext i32 %28 to i64, !dbg !697 + %30 = icmp ne i64 %29, 0, !dbg !697 + br i1 %30, label %31, label %33, !dbg !697 31: ; preds = %21 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 331, i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.2, i64 0, i64 0)) #4, !dbg !555 - unreachable, !dbg !555 + call void @__assert_rtn(ptr noundef @__func__.rwlock_test, ptr noundef @.str, i32 noundef 324, ptr noundef @.str.2) #8, !dbg !697 + unreachable, !dbg !697 32: ; No predecessors! - br label %34, !dbg !555 + br label %34, !dbg !697 33: ; preds = %21 - br label %34, !dbg !555 + br label %34, !dbg !697 34: ; preds = %33, %32 - call void @rwlock_unlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !556 - call void @__VERIFIER_loop_bound(i32 noundef 5), !dbg !557 - call void @llvm.dbg.declare(metadata i32* %4, metadata !559, metadata !DIExpression()), !dbg !561 - store i32 0, i32* %4, align 4, !dbg !561 - br label %35, !dbg !562 + call void @rwlock_unlock(ptr noundef %1), !dbg !698 + call void @__VERIFIER_loop_bound(i32 noundef 5), !dbg !699 + #dbg_declare(ptr %4, !701, !DIExpression(), !703) + store i32 0, ptr %4, align 4, !dbg !703 + br label %35, !dbg !704 35: ; preds = %51, %34 - %36 = load i32, i32* %4, align 4, !dbg !563 - %37 = icmp slt i32 %36, 4, !dbg !565 - br i1 %37, label %38, label %54, !dbg !566 + %36 = load i32, ptr %4, align 4, !dbg !705 + %37 = icmp slt i32 %36, 4, !dbg !707 + br i1 %37, label %38, label %54, !dbg !708 38: ; preds = %35 - call void @llvm.dbg.declare(metadata i8* %5, metadata !567, metadata !DIExpression()), !dbg !569 - %39 = call zeroext i1 @rwlock_tryrdlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !570 - %40 = zext i1 %39 to i8, !dbg !569 - store i8 %40, i8* %5, align 1, !dbg !569 - %41 = load i8, i8* %5, align 1, !dbg !571 - %42 = trunc i8 %41 to i1, !dbg !571 - %43 = xor i1 %42, true, !dbg !571 - %44 = zext i1 %43 to i32, !dbg !571 - %45 = sext i32 %44 to i64, !dbg !571 - %46 = icmp ne i64 %45, 0, !dbg !571 - br i1 %46, label %47, label %49, !dbg !571 + #dbg_declare(ptr %5, !709, !DIExpression(), !711) + %39 = call zeroext i1 @rwlock_tryrdlock(ptr noundef %1), !dbg !712 + %40 = zext i1 %39 to i8, !dbg !711 + store i8 %40, ptr %5, align 1, !dbg !711 + %41 = load i8, ptr %5, align 1, !dbg !713 + %42 = trunc i8 %41 to i1, !dbg !713 + %43 = xor i1 %42, true, !dbg !713 + %44 = zext i1 %43 to i32, !dbg !713 + %45 = sext i32 %44 to i64, !dbg !713 + %46 = icmp ne i64 %45, 0, !dbg !713 + br i1 %46, label %47, label %49, !dbg !713 47: ; preds = %38 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 340, i8* noundef getelementptr inbounds ([8 x i8], [8 x i8]* @.str.3, i64 0, i64 0)) #4, !dbg !571 - unreachable, !dbg !571 + call void @__assert_rtn(ptr noundef @__func__.rwlock_test, ptr noundef @.str, i32 noundef 333, ptr noundef @.str.3) #8, !dbg !713 + unreachable, !dbg !713 48: ; No predecessors! - br label %50, !dbg !571 + br label %50, !dbg !713 49: ; preds = %38 - br label %50, !dbg !571 + br label %50, !dbg !713 50: ; preds = %49, %48 - br label %51, !dbg !572 + br label %51, !dbg !714 51: ; preds = %50 - %52 = load i32, i32* %4, align 4, !dbg !573 - %53 = add nsw i32 %52, 1, !dbg !573 - store i32 %53, i32* %4, align 4, !dbg !573 - br label %35, !dbg !574, !llvm.loop !575 + %52 = load i32, ptr %4, align 4, !dbg !715 + %53 = add nsw i32 %52, 1, !dbg !715 + store i32 %53, ptr %4, align 4, !dbg !715 + br label %35, !dbg !716, !llvm.loop !717 54: ; preds = %35 - call void @llvm.dbg.declare(metadata i8* %6, metadata !578, metadata !DIExpression()), !dbg !580 - %55 = call zeroext i1 @rwlock_trywrlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !581 - %56 = zext i1 %55 to i8, !dbg !580 - store i8 %56, i8* %6, align 1, !dbg !580 - %57 = load i8, i8* %6, align 1, !dbg !582 - %58 = trunc i8 %57 to i1, !dbg !582 - %59 = xor i1 %58, true, !dbg !582 - %60 = xor i1 %59, true, !dbg !582 - %61 = zext i1 %60 to i32, !dbg !582 - %62 = sext i32 %61 to i64, !dbg !582 - %63 = icmp ne i64 %62, 0, !dbg !582 - br i1 %63, label %64, label %66, !dbg !582 + #dbg_declare(ptr %6, !720, !DIExpression(), !722) + %55 = call zeroext i1 @rwlock_trywrlock(ptr noundef %1), !dbg !723 + %56 = zext i1 %55 to i8, !dbg !722 + store i8 %56, ptr %6, align 1, !dbg !722 + %57 = load i8, ptr %6, align 1, !dbg !724 + %58 = trunc i8 %57 to i1, !dbg !724 + %59 = xor i1 %58, true, !dbg !724 + %60 = xor i1 %59, true, !dbg !724 + %61 = zext i1 %60 to i32, !dbg !724 + %62 = sext i32 %61 to i64, !dbg !724 + %63 = icmp ne i64 %62, 0, !dbg !724 + br i1 %63, label %64, label %66, !dbg !724 64: ; preds = %54 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 345, i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.2, i64 0, i64 0)) #4, !dbg !582 - unreachable, !dbg !582 + call void @__assert_rtn(ptr noundef @__func__.rwlock_test, ptr noundef @.str, i32 noundef 338, ptr noundef @.str.2) #8, !dbg !724 + unreachable, !dbg !724 65: ; No predecessors! - br label %67, !dbg !582 + br label %67, !dbg !724 66: ; preds = %54 - br label %67, !dbg !582 + br label %67, !dbg !724 67: ; preds = %66, %65 - call void @__VERIFIER_loop_bound(i32 noundef 5), !dbg !583 - call void @llvm.dbg.declare(metadata i32* %7, metadata !584, metadata !DIExpression()), !dbg !586 - store i32 0, i32* %7, align 4, !dbg !586 - br label %68, !dbg !587 + call void @__VERIFIER_loop_bound(i32 noundef 5), !dbg !725 + #dbg_declare(ptr %7, !726, !DIExpression(), !728) + store i32 0, ptr %7, align 4, !dbg !728 + br label %68, !dbg !729 68: ; preds = %72, %67 - %69 = load i32, i32* %7, align 4, !dbg !588 - %70 = icmp slt i32 %69, 4, !dbg !590 - br i1 %70, label %71, label %75, !dbg !591 + %69 = load i32, ptr %7, align 4, !dbg !730 + %70 = icmp slt i32 %69, 4, !dbg !732 + br i1 %70, label %71, label %75, !dbg !733 71: ; preds = %68 - call void @rwlock_unlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !592 - br label %72, !dbg !594 + call void @rwlock_unlock(ptr noundef %1), !dbg !734 + br label %72, !dbg !736 72: ; preds = %71 - %73 = load i32, i32* %7, align 4, !dbg !595 - %74 = add nsw i32 %73, 1, !dbg !595 - store i32 %74, i32* %7, align 4, !dbg !595 - br label %68, !dbg !596, !llvm.loop !597 + %73 = load i32, ptr %7, align 4, !dbg !737 + %74 = add nsw i32 %73, 1, !dbg !737 + store i32 %74, ptr %7, align 4, !dbg !737 + br label %68, !dbg !738, !llvm.loop !739 75: ; preds = %68 - call void @rwlock_wrlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !599 - call void @llvm.dbg.declare(metadata i8* %8, metadata !601, metadata !DIExpression()), !dbg !602 - %76 = call zeroext i1 @rwlock_trywrlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !603 - %77 = zext i1 %76 to i8, !dbg !602 - store i8 %77, i8* %8, align 1, !dbg !602 - %78 = load i8, i8* %8, align 1, !dbg !604 - %79 = trunc i8 %78 to i1, !dbg !604 - %80 = xor i1 %79, true, !dbg !604 - %81 = xor i1 %80, true, !dbg !604 - %82 = zext i1 %81 to i32, !dbg !604 - %83 = sext i32 %82 to i64, !dbg !604 - %84 = icmp ne i64 %83, 0, !dbg !604 - br i1 %84, label %85, label %87, !dbg !604 + call void @rwlock_wrlock(ptr noundef %1), !dbg !741 + #dbg_declare(ptr %8, !743, !DIExpression(), !744) + %76 = call zeroext i1 @rwlock_trywrlock(ptr noundef %1), !dbg !745 + %77 = zext i1 %76 to i8, !dbg !744 + store i8 %77, ptr %8, align 1, !dbg !744 + %78 = load i8, ptr %8, align 1, !dbg !746 + %79 = trunc i8 %78 to i1, !dbg !746 + %80 = xor i1 %79, true, !dbg !746 + %81 = xor i1 %80, true, !dbg !746 + %82 = zext i1 %81 to i32, !dbg !746 + %83 = sext i32 %82 to i64, !dbg !746 + %84 = icmp ne i64 %83, 0, !dbg !746 + br i1 %84, label %85, label %87, !dbg !746 85: ; preds = %75 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @__func__.rwlock_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 357, i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @.str.2, i64 0, i64 0)) #4, !dbg !604 - unreachable, !dbg !604 + call void @__assert_rtn(ptr noundef @__func__.rwlock_test, ptr noundef @.str, i32 noundef 350, ptr noundef @.str.2) #8, !dbg !746 + unreachable, !dbg !746 86: ; No predecessors! - br label %88, !dbg !604 + br label %88, !dbg !746 87: ; preds = %75 - br label %88, !dbg !604 + br label %88, !dbg !746 88: ; preds = %87, %86 - call void @rwlock_unlock(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !605 - call void @rwlock_destroy(%struct._opaque_pthread_rwlock_t* noundef %1), !dbg !606 - ret void, !dbg !607 + call void @rwlock_unlock(ptr noundef %1), !dbg !747 + call void @rwlock_destroy(ptr noundef %1), !dbg !748 + ret void, !dbg !749 } -declare void @__VERIFIER_loop_bound(i32 noundef) #2 +declare void @__VERIFIER_loop_bound(i32 noundef) #4 -; Function Attrs: noinline nounwind ssp uwtable -define void @key_destroy(i8* noundef %0) #0 !dbg !608 { - %2 = alloca i8*, align 8 - store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !609, metadata !DIExpression()), !dbg !610 - %3 = call %struct._opaque_pthread_t* @pthread_self(), !dbg !611 - store %struct._opaque_pthread_t* %3, %struct._opaque_pthread_t** @latest_thread, align 8, !dbg !612 - ret void, !dbg !613 +; Function Attrs: noinline nounwind uwtable +define dso_local void @key_destroy(ptr noundef %0) #0 !dbg !750 { + %2 = alloca ptr, align 8 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !753, !DIExpression(), !754) + %3 = call i64 @pthread_self() #9, !dbg !755 + store i64 %3, ptr @latest_thread, align 8, !dbg !756 + ret void, !dbg !757 } -declare %struct._opaque_pthread_t* @pthread_self() #2 +; Function Attrs: nocallback nounwind willreturn memory(none) +declare i64 @pthread_self() #5 -; Function Attrs: noinline nounwind ssp uwtable -define i8* @key_worker(i8* noundef %0) #0 !dbg !614 { - %2 = alloca i8*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local ptr @key_worker(ptr noundef %0) #0 !dbg !758 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 %4 = alloca i32, align 4 - %5 = alloca i8*, align 8 - store i8* %0, i8** %2, align 8 - call void @llvm.dbg.declare(metadata i8** %2, metadata !615, metadata !DIExpression()), !dbg !616 - call void @llvm.dbg.declare(metadata i32* %3, metadata !617, metadata !DIExpression()), !dbg !618 - store i32 1, i32* %3, align 4, !dbg !618 - call void @llvm.dbg.declare(metadata i32* %4, metadata !619, metadata !DIExpression()), !dbg !620 - %6 = load i64, i64* @local_data, align 8, !dbg !621 - %7 = bitcast i32* %3 to i8*, !dbg !622 - %8 = call i32 @pthread_setspecific(i64 noundef %6, i8* noundef %7), !dbg !623 - store i32 %8, i32* %4, align 4, !dbg !620 - %9 = load i32, i32* %4, align 4, !dbg !624 - %10 = icmp eq i32 %9, 0, !dbg !624 - %11 = xor i1 %10, true, !dbg !624 - %12 = zext i1 %11 to i32, !dbg !624 - %13 = sext i32 %12 to i64, !dbg !624 - %14 = icmp ne i64 %13, 0, !dbg !624 - br i1 %14, label %15, label %17, !dbg !624 + %5 = alloca ptr, align 8 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !759, !DIExpression(), !760) + #dbg_declare(ptr %3, !761, !DIExpression(), !762) + store i32 1, ptr %3, align 4, !dbg !762 + #dbg_declare(ptr %4, !763, !DIExpression(), !764) + %6 = load i32, ptr @local_data, align 4, !dbg !765 + %7 = call i32 @pthread_setspecific(i32 noundef %6, ptr noundef %3) #6, !dbg !766 + store i32 %7, ptr %4, align 4, !dbg !764 + %8 = load i32, ptr %4, align 4, !dbg !767 + %9 = icmp eq i32 %8, 0, !dbg !767 + %10 = xor i1 %9, true, !dbg !767 + %11 = zext i1 %10 to i32, !dbg !767 + %12 = sext i32 %11 to i64, !dbg !767 + %13 = icmp ne i64 %12, 0, !dbg !767 + br i1 %13, label %14, label %16, !dbg !767 -15: ; preds = %1 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.key_worker, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 379, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !624 - unreachable, !dbg !624 +14: ; preds = %1 + call void @__assert_rtn(ptr noundef @__func__.key_worker, ptr noundef @.str, i32 noundef 372, ptr noundef @.str.1) #8, !dbg !767 + unreachable, !dbg !767 + +15: ; No predecessors! + br label %17, !dbg !767 + +16: ; preds = %1 + br label %17, !dbg !767 + +17: ; preds = %16, %15 + #dbg_declare(ptr %5, !768, !DIExpression(), !769) + %18 = load i32, ptr @local_data, align 4, !dbg !770 + %19 = call ptr @pthread_getspecific(i32 noundef %18) #6, !dbg !771 + store ptr %19, ptr %5, align 8, !dbg !769 + %20 = load ptr, ptr %5, align 8, !dbg !772 + %21 = icmp eq ptr %20, %3, !dbg !772 + %22 = xor i1 %21, true, !dbg !772 + %23 = zext i1 %22 to i32, !dbg !772 + %24 = sext i32 %23 to i64, !dbg !772 + %25 = icmp ne i64 %24, 0, !dbg !772 + br i1 %25, label %26, label %28, !dbg !772 + +26: ; preds = %17 + call void @__assert_rtn(ptr noundef @__func__.key_worker, ptr noundef @.str, i32 noundef 375, ptr noundef @.str.5) #8, !dbg !772 + unreachable, !dbg !772 + +27: ; No predecessors! + br label %29, !dbg !772 + +28: ; preds = %17 + br label %29, !dbg !772 + +29: ; preds = %28, %27 + %30 = load ptr, ptr %2, align 8, !dbg !773 + ret ptr %30, !dbg !774 +} -16: ; No predecessors! - br label %18, !dbg !624 +; Function Attrs: nocallback nounwind +declare i32 @pthread_setspecific(i32 noundef, ptr noundef) #1 -17: ; preds = %1 - br label %18, !dbg !624 +; Function Attrs: nocallback nounwind +declare ptr @pthread_getspecific(i32 noundef) #1 -18: ; preds = %17, %16 - call void @llvm.dbg.declare(metadata i8** %5, metadata !625, metadata !DIExpression()), !dbg !626 - %19 = load i64, i64* @local_data, align 8, !dbg !627 - %20 = call i8* @pthread_getspecific(i64 noundef %19), !dbg !628 - store i8* %20, i8** %5, align 8, !dbg !626 - %21 = load i8*, i8** %5, align 8, !dbg !629 - %22 = bitcast i32* %3 to i8*, !dbg !629 - %23 = icmp eq i8* %21, %22, !dbg !629 - %24 = xor i1 %23, true, !dbg !629 - %25 = zext i1 %24 to i32, !dbg !629 - %26 = sext i32 %25 to i64, !dbg !629 - %27 = icmp ne i64 %26, 0, !dbg !629 - br i1 %27, label %28, label %30, !dbg !629 - -28: ; preds = %18 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([11 x i8], [11 x i8]* @__func__.key_worker, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 382, i8* noundef getelementptr inbounds ([28 x i8], [28 x i8]* @.str.5, i64 0, i64 0)) #4, !dbg !629 - unreachable, !dbg !629 - -29: ; No predecessors! - br label %31, !dbg !629 - -30: ; preds = %18 - br label %31, !dbg !629 - -31: ; preds = %30, %29 - %32 = load i8*, i8** %2, align 8, !dbg !630 - ret i8* %32, !dbg !631 +; Function Attrs: noinline nounwind uwtable +define dso_local void @key_test() #0 !dbg !775 { + %1 = alloca i32, align 4 + %2 = alloca ptr, align 8 + %3 = alloca i32, align 4 + %4 = alloca i64, align 8 + %5 = alloca ptr, align 8 + %6 = alloca ptr, align 8 + #dbg_declare(ptr %1, !776, !DIExpression(), !777) + store i32 2, ptr %1, align 4, !dbg !777 + #dbg_declare(ptr %2, !778, !DIExpression(), !779) + store ptr inttoptr (i64 41 to ptr), ptr %2, align 8, !dbg !779 + #dbg_declare(ptr %3, !780, !DIExpression(), !781) + %7 = call i32 @pthread_key_create(ptr noundef @local_data, ptr noundef @key_destroy) #6, !dbg !782 + #dbg_declare(ptr %4, !783, !DIExpression(), !784) + %8 = load ptr, ptr %2, align 8, !dbg !785 + %9 = call i64 @thread_create(ptr noundef @key_worker, ptr noundef %8), !dbg !786 + store i64 %9, ptr %4, align 8, !dbg !784 + %10 = load i32, ptr @local_data, align 4, !dbg !787 + %11 = call i32 @pthread_setspecific(i32 noundef %10, ptr noundef %1) #6, !dbg !788 + store i32 %11, ptr %3, align 4, !dbg !789 + %12 = load i32, ptr %3, align 4, !dbg !790 + %13 = icmp eq i32 %12, 0, !dbg !790 + %14 = xor i1 %13, true, !dbg !790 + %15 = zext i1 %14 to i32, !dbg !790 + %16 = sext i32 %15 to i64, !dbg !790 + %17 = icmp ne i64 %16, 0, !dbg !790 + br i1 %17, label %18, label %20, !dbg !790 + +18: ; preds = %0 + call void @__assert_rtn(ptr noundef @__func__.key_test, ptr noundef @.str, i32 noundef 391, ptr noundef @.str.1) #8, !dbg !790 + unreachable, !dbg !790 + +19: ; No predecessors! + br label %21, !dbg !790 + +20: ; preds = %0 + br label %21, !dbg !790 + +21: ; preds = %20, %19 + #dbg_declare(ptr %5, !791, !DIExpression(), !792) + %22 = load i32, ptr @local_data, align 4, !dbg !793 + %23 = call ptr @pthread_getspecific(i32 noundef %22) #6, !dbg !794 + store ptr %23, ptr %5, align 8, !dbg !792 + %24 = load ptr, ptr %5, align 8, !dbg !795 + %25 = icmp eq ptr %24, %1, !dbg !795 + %26 = xor i1 %25, true, !dbg !795 + %27 = zext i1 %26 to i32, !dbg !795 + %28 = sext i32 %27 to i64, !dbg !795 + %29 = icmp ne i64 %28, 0, !dbg !795 + br i1 %29, label %30, label %32, !dbg !795 + +30: ; preds = %21 + call void @__assert_rtn(ptr noundef @__func__.key_test, ptr noundef @.str, i32 noundef 394, ptr noundef @.str.5) #8, !dbg !795 + unreachable, !dbg !795 + +31: ; No predecessors! + br label %33, !dbg !795 + +32: ; preds = %21 + br label %33, !dbg !795 + +33: ; preds = %32, %31 + %34 = load i32, ptr @local_data, align 4, !dbg !796 + %35 = call i32 @pthread_setspecific(i32 noundef %34, ptr noundef null) #6, !dbg !797 + store i32 %35, ptr %3, align 4, !dbg !798 + %36 = load i32, ptr %3, align 4, !dbg !799 + %37 = icmp eq i32 %36, 0, !dbg !799 + %38 = xor i1 %37, true, !dbg !799 + %39 = zext i1 %38 to i32, !dbg !799 + %40 = sext i32 %39 to i64, !dbg !799 + %41 = icmp ne i64 %40, 0, !dbg !799 + br i1 %41, label %42, label %44, !dbg !799 + +42: ; preds = %33 + call void @__assert_rtn(ptr noundef @__func__.key_test, ptr noundef @.str, i32 noundef 397, ptr noundef @.str.1) #8, !dbg !799 + unreachable, !dbg !799 + +43: ; No predecessors! + br label %45, !dbg !799 + +44: ; preds = %33 + br label %45, !dbg !799 + +45: ; preds = %44, %43 + #dbg_declare(ptr %6, !800, !DIExpression(), !801) + %46 = load i64, ptr %4, align 8, !dbg !802 + %47 = call ptr @thread_join(i64 noundef %46), !dbg !803 + store ptr %47, ptr %6, align 8, !dbg !801 + %48 = load ptr, ptr %6, align 8, !dbg !804 + %49 = load ptr, ptr %2, align 8, !dbg !804 + %50 = icmp eq ptr %48, %49, !dbg !804 + %51 = xor i1 %50, true, !dbg !804 + %52 = zext i1 %51 to i32, !dbg !804 + %53 = sext i32 %52 to i64, !dbg !804 + %54 = icmp ne i64 %53, 0, !dbg !804 + br i1 %54, label %55, label %57, !dbg !804 + +55: ; preds = %45 + call void @__assert_rtn(ptr noundef @__func__.key_test, ptr noundef @.str, i32 noundef 400, ptr noundef @.str.4) #8, !dbg !804 + unreachable, !dbg !804 + +56: ; No predecessors! + br label %58, !dbg !804 + +57: ; preds = %45 + br label %58, !dbg !804 + +58: ; preds = %57, %56 + %59 = load i32, ptr @local_data, align 4, !dbg !805 + %60 = call i32 @pthread_key_delete(i32 noundef %59) #6, !dbg !806 + store i32 %60, ptr %3, align 4, !dbg !807 + %61 = load i32, ptr %3, align 4, !dbg !808 + %62 = icmp eq i32 %61, 0, !dbg !808 + %63 = xor i1 %62, true, !dbg !808 + %64 = zext i1 %63 to i32, !dbg !808 + %65 = sext i32 %64 to i64, !dbg !808 + %66 = icmp ne i64 %65, 0, !dbg !808 + br i1 %66, label %67, label %69, !dbg !808 + +67: ; preds = %58 + call void @__assert_rtn(ptr noundef @__func__.key_test, ptr noundef @.str, i32 noundef 403, ptr noundef @.str.1) #8, !dbg !808 + unreachable, !dbg !808 + +68: ; No predecessors! + br label %70, !dbg !808 + +69: ; preds = %58 + br label %70, !dbg !808 + +70: ; preds = %69, %68 + ret void, !dbg !809 } -declare i32 @pthread_setspecific(i64 noundef, i8* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_key_create(ptr noundef, ptr noundef) #1 -declare i8* @pthread_getspecific(i64 noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_key_delete(i32 noundef) #1 -; Function Attrs: noinline nounwind ssp uwtable -define void @key_test() #0 !dbg !632 { - %1 = alloca i32, align 4 - %2 = alloca i8*, align 8 +; Function Attrs: noinline nounwind uwtable +define dso_local ptr @detach_test_worker0(ptr noundef %0) #0 !dbg !810 { + %2 = alloca ptr, align 8 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !811, !DIExpression(), !812) + ret ptr null, !dbg !813 +} + +; Function Attrs: noinline nounwind uwtable +define dso_local ptr @detach_test_detach(ptr noundef %0) #0 !dbg !814 { + %2 = alloca ptr, align 8 %3 = alloca i32, align 4 - %4 = alloca %struct._opaque_pthread_t*, align 8 - %5 = alloca i8*, align 8 - %6 = alloca i8*, align 8 - call void @llvm.dbg.declare(metadata i32* %1, metadata !633, metadata !DIExpression()), !dbg !634 - store i32 2, i32* %1, align 4, !dbg !634 - call void @llvm.dbg.declare(metadata i8** %2, metadata !635, metadata !DIExpression()), !dbg !636 - store i8* inttoptr (i64 41 to i8*), i8** %2, align 8, !dbg !636 - call void @llvm.dbg.declare(metadata i32* %3, metadata !637, metadata !DIExpression()), !dbg !638 - %7 = call i32 @pthread_key_create(i64* noundef @local_data, void (i8*)* noundef @key_destroy), !dbg !639 - call void @llvm.dbg.declare(metadata %struct._opaque_pthread_t** %4, metadata !640, metadata !DIExpression()), !dbg !641 - %8 = load i8*, i8** %2, align 8, !dbg !642 - %9 = call %struct._opaque_pthread_t* @thread_create(i8* (i8*)* noundef @key_worker, i8* noundef %8), !dbg !643 - store %struct._opaque_pthread_t* %9, %struct._opaque_pthread_t** %4, align 8, !dbg !641 - %10 = load i64, i64* @local_data, align 8, !dbg !644 - %11 = bitcast i32* %1 to i8*, !dbg !645 - %12 = call i32 @pthread_setspecific(i64 noundef %10, i8* noundef %11), !dbg !646 - store i32 %12, i32* %3, align 4, !dbg !647 - %13 = load i32, i32* %3, align 4, !dbg !648 - %14 = icmp eq i32 %13, 0, !dbg !648 - %15 = xor i1 %14, true, !dbg !648 - %16 = zext i1 %15 to i32, !dbg !648 - %17 = sext i32 %16 to i64, !dbg !648 - %18 = icmp ne i64 %17, 0, !dbg !648 - br i1 %18, label %19, label %21, !dbg !648 + %4 = alloca i64, align 8 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !815, !DIExpression(), !816) + #dbg_declare(ptr %3, !817, !DIExpression(), !818) + #dbg_declare(ptr %4, !819, !DIExpression(), !820) + %5 = call i64 @thread_create(ptr noundef @detach_test_worker0, ptr noundef null), !dbg !821 + store i64 %5, ptr %4, align 8, !dbg !820 + %6 = load i64, ptr %4, align 8, !dbg !822 + %7 = call i32 @pthread_detach(i64 noundef %6) #6, !dbg !823 + store i32 %7, ptr %3, align 4, !dbg !824 + %8 = load i32, ptr %3, align 4, !dbg !825 + %9 = icmp eq i32 %8, 0, !dbg !825 + %10 = xor i1 %9, true, !dbg !825 + %11 = zext i1 %10 to i32, !dbg !825 + %12 = sext i32 %11 to i64, !dbg !825 + %13 = icmp ne i64 %12, 0, !dbg !825 + br i1 %13, label %14, label %16, !dbg !825 -19: ; preds = %0 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @__func__.key_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 398, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !648 - unreachable, !dbg !648 +14: ; preds = %1 + call void @__assert_rtn(ptr noundef @__func__.detach_test_detach, ptr noundef @.str, i32 noundef 420, ptr noundef @.str.1) #8, !dbg !825 + unreachable, !dbg !825 + +15: ; No predecessors! + br label %17, !dbg !825 + +16: ; preds = %1 + br label %17, !dbg !825 + +17: ; preds = %16, %15 + %18 = load i64, ptr %4, align 8, !dbg !826 + %19 = call i32 @pthread_join(i64 noundef %18, ptr noundef null), !dbg !827 + store i32 %19, ptr %3, align 4, !dbg !828 + %20 = load i32, ptr %3, align 4, !dbg !829 + %21 = icmp ne i32 %20, 0, !dbg !829 + %22 = xor i1 %21, true, !dbg !829 + %23 = zext i1 %22 to i32, !dbg !829 + %24 = sext i32 %23 to i64, !dbg !829 + %25 = icmp ne i64 %24, 0, !dbg !829 + br i1 %25, label %26, label %28, !dbg !829 + +26: ; preds = %17 + call void @__assert_rtn(ptr noundef @__func__.detach_test_detach, ptr noundef @.str, i32 noundef 423, ptr noundef @.str.6) #8, !dbg !829 + unreachable, !dbg !829 + +27: ; No predecessors! + br label %29, !dbg !829 + +28: ; preds = %17 + br label %29, !dbg !829 + +29: ; preds = %28, %27 + ret ptr null, !dbg !830 +} -20: ; No predecessors! - br label %22, !dbg !648 +; Function Attrs: nocallback nounwind +declare i32 @pthread_detach(i64 noundef) #1 -21: ; preds = %0 - br label %22, !dbg !648 +; Function Attrs: noinline nounwind uwtable +define dso_local ptr @detach_test_attr(ptr noundef %0) #0 !dbg !831 { + %2 = alloca ptr, align 8 + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca i64, align 8 + %6 = alloca %union.pthread_attr_t, align 8 + store ptr %0, ptr %2, align 8 + #dbg_declare(ptr %2, !832, !DIExpression(), !833) + #dbg_declare(ptr %3, !834, !DIExpression(), !835) + #dbg_declare(ptr %4, !836, !DIExpression(), !837) + #dbg_declare(ptr %5, !838, !DIExpression(), !839) + #dbg_declare(ptr %6, !840, !DIExpression(), !841) + %7 = call i32 @pthread_attr_init(ptr noundef %6) #6, !dbg !842 + store i32 %7, ptr %3, align 4, !dbg !843 + %8 = load i32, ptr %3, align 4, !dbg !844 + %9 = icmp eq i32 %8, 0, !dbg !844 + %10 = xor i1 %9, true, !dbg !844 + %11 = zext i1 %10 to i32, !dbg !844 + %12 = sext i32 %11 to i64, !dbg !844 + %13 = icmp ne i64 %12, 0, !dbg !844 + br i1 %13, label %14, label %16, !dbg !844 -22: ; preds = %21, %20 - call void @llvm.dbg.declare(metadata i8** %5, metadata !649, metadata !DIExpression()), !dbg !650 - %23 = load i64, i64* @local_data, align 8, !dbg !651 - %24 = call i8* @pthread_getspecific(i64 noundef %23), !dbg !652 - store i8* %24, i8** %5, align 8, !dbg !650 - %25 = load i8*, i8** %5, align 8, !dbg !653 - %26 = bitcast i32* %1 to i8*, !dbg !653 - %27 = icmp eq i8* %25, %26, !dbg !653 - %28 = xor i1 %27, true, !dbg !653 - %29 = zext i1 %28 to i32, !dbg !653 - %30 = sext i32 %29 to i64, !dbg !653 - %31 = icmp ne i64 %30, 0, !dbg !653 - br i1 %31, label %32, label %34, !dbg !653 - -32: ; preds = %22 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @__func__.key_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 401, i8* noundef getelementptr inbounds ([28 x i8], [28 x i8]* @.str.5, i64 0, i64 0)) #4, !dbg !653 - unreachable, !dbg !653 - -33: ; No predecessors! - br label %35, !dbg !653 - -34: ; preds = %22 - br label %35, !dbg !653 - -35: ; preds = %34, %33 - %36 = load i64, i64* @local_data, align 8, !dbg !654 - %37 = call i32 @pthread_setspecific(i64 noundef %36, i8* noundef null), !dbg !655 - store i32 %37, i32* %3, align 4, !dbg !656 - %38 = load i32, i32* %3, align 4, !dbg !657 - %39 = icmp eq i32 %38, 0, !dbg !657 - %40 = xor i1 %39, true, !dbg !657 - %41 = zext i1 %40 to i32, !dbg !657 - %42 = sext i32 %41 to i64, !dbg !657 - %43 = icmp ne i64 %42, 0, !dbg !657 - br i1 %43, label %44, label %46, !dbg !657 - -44: ; preds = %35 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @__func__.key_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 404, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !657 - unreachable, !dbg !657 - -45: ; No predecessors! - br label %47, !dbg !657 - -46: ; preds = %35 - br label %47, !dbg !657 - -47: ; preds = %46, %45 - call void @llvm.dbg.declare(metadata i8** %6, metadata !658, metadata !DIExpression()), !dbg !659 - %48 = load %struct._opaque_pthread_t*, %struct._opaque_pthread_t** %4, align 8, !dbg !660 - %49 = call i8* @thread_join(%struct._opaque_pthread_t* noundef %48), !dbg !661 - store i8* %49, i8** %6, align 8, !dbg !659 - %50 = load i8*, i8** %6, align 8, !dbg !662 - %51 = load i8*, i8** %2, align 8, !dbg !662 - %52 = icmp eq i8* %50, %51, !dbg !662 - %53 = xor i1 %52, true, !dbg !662 - %54 = zext i1 %53 to i32, !dbg !662 - %55 = sext i32 %54 to i64, !dbg !662 - %56 = icmp ne i64 %55, 0, !dbg !662 - br i1 %56, label %57, label %59, !dbg !662 - -57: ; preds = %47 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @__func__.key_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 407, i8* noundef getelementptr inbounds ([18 x i8], [18 x i8]* @.str.4, i64 0, i64 0)) #4, !dbg !662 - unreachable, !dbg !662 +14: ; preds = %1 + call void @__assert_rtn(ptr noundef @__func__.detach_test_attr, ptr noundef @.str, i32 noundef 434, ptr noundef @.str.1) #8, !dbg !844 + unreachable, !dbg !844 + +15: ; No predecessors! + br label %17, !dbg !844 + +16: ; preds = %1 + br label %17, !dbg !844 + +17: ; preds = %16, %15 + %18 = call i32 @pthread_attr_getdetachstate(ptr noundef %6, ptr noundef %4) #6, !dbg !845 + store i32 %18, ptr %3, align 4, !dbg !846 + %19 = load i32, ptr %3, align 4, !dbg !847 + %20 = icmp eq i32 %19, 0, !dbg !847 + br i1 %20, label %21, label %24, !dbg !847 + +21: ; preds = %17 + %22 = load i32, ptr %4, align 4, !dbg !847 + %23 = icmp eq i32 %22, 0, !dbg !847 + br label %24 + +24: ; preds = %21, %17 + %25 = phi i1 [ false, %17 ], [ %23, %21 ], !dbg !848 + %26 = xor i1 %25, true, !dbg !847 + %27 = zext i1 %26 to i32, !dbg !847 + %28 = sext i32 %27 to i64, !dbg !847 + %29 = icmp ne i64 %28, 0, !dbg !847 + br i1 %29, label %30, label %32, !dbg !847 + +30: ; preds = %24 + call void @__assert_rtn(ptr noundef @__func__.detach_test_attr, ptr noundef @.str, i32 noundef 436, ptr noundef @.str.7) #8, !dbg !847 + unreachable, !dbg !847 + +31: ; No predecessors! + br label %33, !dbg !847 + +32: ; preds = %24 + br label %33, !dbg !847 + +33: ; preds = %32, %31 + %34 = call i32 @pthread_attr_setdetachstate(ptr noundef %6, i32 noundef 1) #6, !dbg !849 + store i32 %34, ptr %3, align 4, !dbg !850 + %35 = load i32, ptr %3, align 4, !dbg !851 + %36 = icmp eq i32 %35, 0, !dbg !851 + %37 = xor i1 %36, true, !dbg !851 + %38 = zext i1 %37 to i32, !dbg !851 + %39 = sext i32 %38 to i64, !dbg !851 + %40 = icmp ne i64 %39, 0, !dbg !851 + br i1 %40, label %41, label %43, !dbg !851 + +41: ; preds = %33 + call void @__assert_rtn(ptr noundef @__func__.detach_test_attr, ptr noundef @.str, i32 noundef 438, ptr noundef @.str.1) #8, !dbg !851 + unreachable, !dbg !851 + +42: ; No predecessors! + br label %44, !dbg !851 + +43: ; preds = %33 + br label %44, !dbg !851 + +44: ; preds = %43, %42 + %45 = call i32 @pthread_attr_getdetachstate(ptr noundef %6, ptr noundef %4) #6, !dbg !852 + store i32 %45, ptr %3, align 4, !dbg !853 + %46 = load i32, ptr %3, align 4, !dbg !854 + %47 = icmp eq i32 %46, 0, !dbg !854 + br i1 %47, label %48, label %51, !dbg !854 + +48: ; preds = %44 + %49 = load i32, ptr %4, align 4, !dbg !854 + %50 = icmp eq i32 %49, 1, !dbg !854 + br label %51 + +51: ; preds = %48, %44 + %52 = phi i1 [ false, %44 ], [ %50, %48 ], !dbg !848 + %53 = xor i1 %52, true, !dbg !854 + %54 = zext i1 %53 to i32, !dbg !854 + %55 = sext i32 %54 to i64, !dbg !854 + %56 = icmp ne i64 %55, 0, !dbg !854 + br i1 %56, label %57, label %59, !dbg !854 + +57: ; preds = %51 + call void @__assert_rtn(ptr noundef @__func__.detach_test_attr, ptr noundef @.str, i32 noundef 440, ptr noundef @.str.8) #8, !dbg !854 + unreachable, !dbg !854 58: ; No predecessors! - br label %60, !dbg !662 + br label %60, !dbg !854 -59: ; preds = %47 - br label %60, !dbg !662 +59: ; preds = %51 + br label %60, !dbg !854 60: ; preds = %59, %58 - %61 = load i64, i64* @local_data, align 8, !dbg !663 - %62 = call i32 @pthread_key_delete(i64 noundef %61), !dbg !664 - store i32 %62, i32* %3, align 4, !dbg !665 - %63 = load i32, i32* %3, align 4, !dbg !666 - %64 = icmp eq i32 %63, 0, !dbg !666 - %65 = xor i1 %64, true, !dbg !666 - %66 = zext i1 %65 to i32, !dbg !666 - %67 = sext i32 %66 to i64, !dbg !666 - %68 = icmp ne i64 %67, 0, !dbg !666 - br i1 %68, label %69, label %71, !dbg !666 - -69: ; preds = %60 - call void @__assert_rtn(i8* noundef getelementptr inbounds ([9 x i8], [9 x i8]* @__func__.key_test, i64 0, i64 0), i8* noundef getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i32 noundef 410, i8* noundef getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0)) #4, !dbg !666 - unreachable, !dbg !666 - -70: ; No predecessors! - br label %72, !dbg !666 - -71: ; preds = %60 - br label %72, !dbg !666 - -72: ; preds = %71, %70 - ret void, !dbg !667 + %61 = call i32 @pthread_create(ptr noundef %5, ptr noundef %6, ptr noundef @detach_test_worker0, ptr noundef null) #7, !dbg !855 + store i32 %61, ptr %3, align 4, !dbg !856 + %62 = load i32, ptr %3, align 4, !dbg !857 + %63 = icmp eq i32 %62, 0, !dbg !857 + %64 = xor i1 %63, true, !dbg !857 + %65 = zext i1 %64 to i32, !dbg !857 + %66 = sext i32 %65 to i64, !dbg !857 + %67 = icmp ne i64 %66, 0, !dbg !857 + br i1 %67, label %68, label %70, !dbg !857 + +68: ; preds = %60 + call void @__assert_rtn(ptr noundef @__func__.detach_test_attr, ptr noundef @.str, i32 noundef 442, ptr noundef @.str.1) #8, !dbg !857 + unreachable, !dbg !857 + +69: ; No predecessors! + br label %71, !dbg !857 + +70: ; preds = %60 + br label %71, !dbg !857 + +71: ; preds = %70, %69 + %72 = call i32 @pthread_attr_destroy(ptr noundef %6) #6, !dbg !858 + %73 = load i64, ptr %5, align 8, !dbg !859 + %74 = call i32 @pthread_join(i64 noundef %73, ptr noundef null), !dbg !860 + store i32 %74, ptr %3, align 4, !dbg !861 + %75 = load i32, ptr %3, align 4, !dbg !862 + %76 = icmp ne i32 %75, 0, !dbg !862 + %77 = xor i1 %76, true, !dbg !862 + %78 = zext i1 %77 to i32, !dbg !862 + %79 = sext i32 %78 to i64, !dbg !862 + %80 = icmp ne i64 %79, 0, !dbg !862 + br i1 %80, label %81, label %83, !dbg !862 + +81: ; preds = %71 + call void @__assert_rtn(ptr noundef @__func__.detach_test_attr, ptr noundef @.str, i32 noundef 446, ptr noundef @.str.6) #8, !dbg !862 + unreachable, !dbg !862 + +82: ; No predecessors! + br label %84, !dbg !862 + +83: ; preds = %71 + br label %84, !dbg !862 + +84: ; preds = %83, %82 + ret ptr null, !dbg !863 } -declare i32 @pthread_key_create(i64* noundef, void (i8*)* noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_attr_getdetachstate(ptr noundef, ptr noundef) #1 -declare i32 @pthread_key_delete(i64 noundef) #2 +; Function Attrs: nocallback nounwind +declare i32 @pthread_attr_setdetachstate(ptr noundef, i32 noundef) #1 -; Function Attrs: noinline nounwind ssp uwtable -define i32 @main() #0 !dbg !668 { - call void @mutex_test(), !dbg !671 - call void @cond_test(), !dbg !672 - call void @rwlock_test(), !dbg !673 - call void @key_test(), !dbg !674 - ret i32 0, !dbg !675 +; Function Attrs: noinline nounwind uwtable +define dso_local void @detach_test() #0 !dbg !864 { + %1 = call i64 @thread_create(ptr noundef @detach_test_detach, ptr noundef null), !dbg !865 + %2 = call i64 @thread_create(ptr noundef @detach_test_attr, ptr noundef null), !dbg !866 + ret void, !dbg !867 } -attributes #0 = { noinline nounwind ssp uwtable "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.5a,+zcm,+zcz" } -attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -attributes #2 = { "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.5a,+zcm,+zcz" } -attributes #3 = { cold noreturn "disable-tail-calls"="true" "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.5a,+zcm,+zcz" } -attributes #4 = { cold noreturn } +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @main() #0 !dbg !868 { + call void @mutex_test(), !dbg !871 + call void @cond_test(), !dbg !872 + call void @rwlock_test(), !dbg !873 + call void @key_test(), !dbg !874 + call void @detach_test(), !dbg !875 + ret i32 0, !dbg !876 +} -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!66, !67, !68, !69, !70, !71, !72, !73, !74, !75} -!llvm.ident = !{!76} +attributes #0 = { noinline nounwind uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { cold noreturn "disable-tail-calls"="true" "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #4 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #5 = { nocallback nounwind willreturn memory(none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #6 = { nocallback nounwind } +attributes #7 = { nounwind } +attributes #8 = { cold noreturn } +attributes #9 = { nocallback nounwind willreturn memory(none) } + +!llvm.dbg.cu = !{!61} +!llvm.module.flags = !{!216, !217, !218, !219, !220, !221, !222} +!llvm.ident = !{!223} !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "phase", scope: !2, file: !11, line: 200, type: !65, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Homebrew clang version 14.0.6", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !4, globals: !8, splitDebugInlining: false, nameTableKind: None, sysroot: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk", sdk: "MacOSX13.sdk") -!3 = !DIFile(filename: "/Users/thomashaas/IdeaProjects/Dat3M/benchmarks/miscellaneous/pthread.c", directory: "/Users/thomashaas/IdeaProjects/Dat3M") -!4 = !{!5, !7} -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64) -!6 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!8 = !{!0, !9, !24, !36, !59} -!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression()) -!10 = distinct !DIGlobalVariable(name: "cond_mutex", scope: !2, file: !11, line: 198, type: !12, isLocal: false, isDefinition: true) -!11 = !DIFile(filename: "benchmarks/miscellaneous/pthread.c", directory: "/Users/thomashaas/IdeaProjects/Dat3M") -!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_mutex_t", file: !13, line: 31, baseType: !14) -!13 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_mutex_t.h", directory: "") -!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_pthread_mutex_t", file: !15, line: 113, baseType: !16) -!15 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_types.h", directory: "") -!16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "_opaque_pthread_mutex_t", file: !15, line: 78, size: 512, elements: !17) -!17 = !{!18, !20} -!18 = !DIDerivedType(tag: DW_TAG_member, name: "__sig", scope: !16, file: !15, line: 79, baseType: !19, size: 64) -!19 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) -!20 = !DIDerivedType(tag: DW_TAG_member, name: "__opaque", scope: !16, file: !15, line: 80, baseType: !21, size: 448, offset: 64) -!21 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 448, elements: !22) -!22 = !{!23} -!23 = !DISubrange(count: 56) -!24 = !DIGlobalVariableExpression(var: !25, expr: !DIExpression()) -!25 = distinct !DIGlobalVariable(name: "cond", scope: !2, file: !11, line: 199, type: !26, isLocal: false, isDefinition: true) -!26 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_cond_t", file: !27, line: 31, baseType: !28) -!27 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_cond_t.h", directory: "") -!28 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_pthread_cond_t", file: !15, line: 110, baseType: !29) -!29 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "_opaque_pthread_cond_t", file: !15, line: 68, size: 384, elements: !30) -!30 = !{!31, !32} -!31 = !DIDerivedType(tag: DW_TAG_member, name: "__sig", scope: !29, file: !15, line: 69, baseType: !19, size: 64) -!32 = !DIDerivedType(tag: DW_TAG_member, name: "__opaque", scope: !29, file: !15, line: 70, baseType: !33, size: 320, offset: 64) -!33 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 320, elements: !34) -!34 = !{!35} -!35 = !DISubrange(count: 40) -!36 = !DIGlobalVariableExpression(var: !37, expr: !DIExpression()) -!37 = distinct !DIGlobalVariable(name: "latest_thread", scope: !2, file: !11, line: 366, type: !38, isLocal: false, isDefinition: true) -!38 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !39, line: 31, baseType: !40) -!39 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_t.h", directory: "") -!40 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_pthread_t", file: !15, line: 118, baseType: !41) -!41 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !42, size: 64) -!42 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "_opaque_pthread_t", file: !15, line: 103, size: 65536, elements: !43) -!43 = !{!44, !45, !55} -!44 = !DIDerivedType(tag: DW_TAG_member, name: "__sig", scope: !42, file: !15, line: 104, baseType: !19, size: 64) -!45 = !DIDerivedType(tag: DW_TAG_member, name: "__cleanup_stack", scope: !42, file: !15, line: 105, baseType: !46, size: 64, offset: 64) -!46 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !47, size: 64) -!47 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__darwin_pthread_handler_rec", file: !15, line: 57, size: 192, elements: !48) -!48 = !{!49, !53, !54} -!49 = !DIDerivedType(tag: DW_TAG_member, name: "__routine", scope: !47, file: !15, line: 58, baseType: !50, size: 64) -!50 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !51, size: 64) -!51 = !DISubroutineType(types: !52) -!52 = !{null, !7} -!53 = !DIDerivedType(tag: DW_TAG_member, name: "__arg", scope: !47, file: !15, line: 59, baseType: !7, size: 64, offset: 64) -!54 = !DIDerivedType(tag: DW_TAG_member, name: "__next", scope: !47, file: !15, line: 60, baseType: !46, size: 64, offset: 128) -!55 = !DIDerivedType(tag: DW_TAG_member, name: "__opaque", scope: !42, file: !15, line: 106, baseType: !56, size: 65408, offset: 128) -!56 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 65408, elements: !57) +!1 = distinct !DIGlobalVariable(scope: null, file: !2, line: 18, type: !3, isLocal: true, isDefinition: true) +!2 = !DIFile(filename: "benchmarks/miscellaneous/pthread.c", directory: "/Users/r/git/dat3m", checksumkind: CSK_MD5, checksum: "de2181b4e1bbeb1b49680be5c0678bee") +!3 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 112, elements: !6) +!4 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !5) +!5 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!6 = !{!7} +!7 = !DISubrange(count: 14) +!8 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression()) +!9 = distinct !DIGlobalVariable(scope: null, file: !2, line: 18, type: !10, isLocal: true, isDefinition: true) +!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 80, elements: !11) +!11 = !{!12} +!12 = !DISubrange(count: 10) +!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression()) +!14 = distinct !DIGlobalVariable(scope: null, file: !2, line: 18, type: !15, isLocal: true, isDefinition: true) +!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 96, elements: !16) +!16 = !{!17} +!17 = !DISubrange(count: 12) +!18 = !DIGlobalVariableExpression(var: !19, expr: !DIExpression()) +!19 = distinct !DIGlobalVariable(scope: null, file: !2, line: 27, type: !20, isLocal: true, isDefinition: true) +!20 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 96, elements: !16) +!21 = !DIGlobalVariableExpression(var: !22, expr: !DIExpression()) +!22 = distinct !DIGlobalVariable(scope: null, file: !2, line: 47, type: !23, isLocal: true, isDefinition: true) +!23 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 88, elements: !24) +!24 = !{!25} +!25 = !DISubrange(count: 11) +!26 = !DIGlobalVariableExpression(var: !27, expr: !DIExpression()) +!27 = distinct !DIGlobalVariable(scope: null, file: !2, line: 73, type: !3, isLocal: true, isDefinition: true) +!28 = !DIGlobalVariableExpression(var: !29, expr: !DIExpression()) +!29 = distinct !DIGlobalVariable(scope: null, file: !2, line: 79, type: !23, isLocal: true, isDefinition: true) +!30 = !DIGlobalVariableExpression(var: !31, expr: !DIExpression()) +!31 = distinct !DIGlobalVariable(scope: null, file: !2, line: 92, type: !32, isLocal: true, isDefinition: true) +!32 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 104, elements: !33) +!33 = !{!34} +!34 = !DISubrange(count: 13) +!35 = !DIGlobalVariableExpression(var: !36, expr: !DIExpression()) +!36 = distinct !DIGlobalVariable(scope: null, file: !2, line: 106, type: !23, isLocal: true, isDefinition: true) +!37 = !DIGlobalVariableExpression(var: !38, expr: !DIExpression()) +!38 = distinct !DIGlobalVariable(scope: null, file: !2, line: 106, type: !39, isLocal: true, isDefinition: true) +!39 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 72, elements: !40) +!40 = !{!41} +!41 = !DISubrange(count: 9) +!42 = !DIGlobalVariableExpression(var: !43, expr: !DIExpression()) +!43 = distinct !DIGlobalVariable(scope: null, file: !2, line: 115, type: !44, isLocal: true, isDefinition: true) +!44 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 64, elements: !45) +!45 = !{!46} +!46 = !DISubrange(count: 8) +!47 = !DIGlobalVariableExpression(var: !48, expr: !DIExpression()) +!48 = distinct !DIGlobalVariable(scope: null, file: !2, line: 147, type: !49, isLocal: true, isDefinition: true) +!49 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 80, elements: !11) +!50 = !DIGlobalVariableExpression(var: !51, expr: !DIExpression()) +!51 = distinct !DIGlobalVariable(scope: null, file: !2, line: 159, type: !32, isLocal: true, isDefinition: true) +!52 = !DIGlobalVariableExpression(var: !53, expr: !DIExpression()) +!53 = distinct !DIGlobalVariable(scope: null, file: !2, line: 165, type: !20, isLocal: true, isDefinition: true) +!54 = !DIGlobalVariableExpression(var: !55, expr: !DIExpression()) +!55 = distinct !DIGlobalVariable(scope: null, file: !2, line: 171, type: !56, isLocal: true, isDefinition: true) +!56 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 120, elements: !57) !57 = !{!58} -!58 = !DISubrange(count: 8176) +!58 = !DISubrange(count: 15) !59 = !DIGlobalVariableExpression(var: !60, expr: !DIExpression()) -!60 = distinct !DIGlobalVariable(name: "local_data", scope: !2, file: !11, line: 367, type: !61, isLocal: false, isDefinition: true) -!61 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_key_t", file: !62, line: 31, baseType: !63) -!62 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_key_t.h", directory: "") -!63 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_pthread_key_t", file: !15, line: 112, baseType: !64) -!64 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!65 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!66 = !{i32 7, !"Dwarf Version", i32 4} -!67 = !{i32 2, !"Debug Info Version", i32 3} -!68 = !{i32 1, !"wchar_size", i32 4} -!69 = !{i32 1, !"branch-target-enforcement", i32 0} -!70 = !{i32 1, !"sign-return-address", i32 0} -!71 = !{i32 1, !"sign-return-address-all", i32 0} -!72 = !{i32 1, !"sign-return-address-with-bkey", i32 0} -!73 = !{i32 7, !"PIC Level", i32 2} -!74 = !{i32 7, !"uwtable", i32 1} -!75 = !{i32 7, !"frame-pointer", i32 1} -!76 = !{!"Homebrew clang version 14.0.6"} -!77 = distinct !DISubprogram(name: "thread_create", scope: !11, file: !11, line: 12, type: !78, scopeLine: 13, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!78 = !DISubroutineType(types: !79) -!79 = !{!38, !80, !7} -!80 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !81, size: 64) -!81 = !DISubroutineType(types: !82) -!82 = !{!7, !7} -!83 = !{} -!84 = !DILocalVariable(name: "runner", arg: 1, scope: !77, file: !11, line: 12, type: !80) -!85 = !DILocation(line: 12, column: 32, scope: !77) -!86 = !DILocalVariable(name: "data", arg: 2, scope: !77, file: !11, line: 12, type: !7) -!87 = !DILocation(line: 12, column: 54, scope: !77) -!88 = !DILocalVariable(name: "id", scope: !77, file: !11, line: 14, type: !38) -!89 = !DILocation(line: 14, column: 15, scope: !77) -!90 = !DILocalVariable(name: "attr", scope: !77, file: !11, line: 15, type: !91) -!91 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_attr_t", file: !92, line: 31, baseType: !93) -!92 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_attr_t.h", directory: "") -!93 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_pthread_attr_t", file: !15, line: 109, baseType: !94) -!94 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "_opaque_pthread_attr_t", file: !15, line: 63, size: 512, elements: !95) -!95 = !{!96, !97} -!96 = !DIDerivedType(tag: DW_TAG_member, name: "__sig", scope: !94, file: !15, line: 64, baseType: !19, size: 64) -!97 = !DIDerivedType(tag: DW_TAG_member, name: "__opaque", scope: !94, file: !15, line: 65, baseType: !21, size: 448, offset: 64) -!98 = !DILocation(line: 15, column: 20, scope: !77) -!99 = !DILocation(line: 16, column: 5, scope: !77) -!100 = !DILocalVariable(name: "status", scope: !77, file: !11, line: 17, type: !65) -!101 = !DILocation(line: 17, column: 9, scope: !77) -!102 = !DILocation(line: 17, column: 45, scope: !77) -!103 = !DILocation(line: 17, column: 53, scope: !77) -!104 = !DILocation(line: 17, column: 18, scope: !77) -!105 = !DILocation(line: 18, column: 5, scope: !77) -!106 = !DILocation(line: 19, column: 5, scope: !77) -!107 = !DILocation(line: 20, column: 12, scope: !77) -!108 = !DILocation(line: 20, column: 5, scope: !77) -!109 = distinct !DISubprogram(name: "thread_join", scope: !11, file: !11, line: 23, type: !110, scopeLine: 24, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!110 = !DISubroutineType(types: !111) -!111 = !{!7, !38} -!112 = !DILocalVariable(name: "id", arg: 1, scope: !109, file: !11, line: 23, type: !38) -!113 = !DILocation(line: 23, column: 29, scope: !109) -!114 = !DILocalVariable(name: "result", scope: !109, file: !11, line: 25, type: !7) -!115 = !DILocation(line: 25, column: 11, scope: !109) -!116 = !DILocalVariable(name: "status", scope: !109, file: !11, line: 26, type: !65) -!117 = !DILocation(line: 26, column: 9, scope: !109) -!118 = !DILocation(line: 26, column: 31, scope: !109) -!119 = !DILocation(line: 26, column: 18, scope: !109) -!120 = !DILocation(line: 27, column: 5, scope: !109) -!121 = !DILocation(line: 28, column: 12, scope: !109) -!122 = !DILocation(line: 28, column: 5, scope: !109) -!123 = distinct !DISubprogram(name: "mutex_init", scope: !11, file: !11, line: 43, type: !124, scopeLine: 44, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!124 = !DISubroutineType(types: !125) -!125 = !{null, !126, !65, !65, !65, !65} -!126 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) -!127 = !DILocalVariable(name: "lock", arg: 1, scope: !123, file: !11, line: 43, type: !126) -!128 = !DILocation(line: 43, column: 34, scope: !123) -!129 = !DILocalVariable(name: "type", arg: 2, scope: !123, file: !11, line: 43, type: !65) -!130 = !DILocation(line: 43, column: 44, scope: !123) -!131 = !DILocalVariable(name: "protocol", arg: 3, scope: !123, file: !11, line: 43, type: !65) -!132 = !DILocation(line: 43, column: 54, scope: !123) -!133 = !DILocalVariable(name: "policy", arg: 4, scope: !123, file: !11, line: 43, type: !65) -!134 = !DILocation(line: 43, column: 68, scope: !123) -!135 = !DILocalVariable(name: "prioceiling", arg: 5, scope: !123, file: !11, line: 43, type: !65) -!136 = !DILocation(line: 43, column: 80, scope: !123) -!137 = !DILocalVariable(name: "status", scope: !123, file: !11, line: 45, type: !65) -!138 = !DILocation(line: 45, column: 9, scope: !123) -!139 = !DILocalVariable(name: "value", scope: !123, file: !11, line: 46, type: !65) -!140 = !DILocation(line: 46, column: 9, scope: !123) -!141 = !DILocalVariable(name: "attributes", scope: !123, file: !11, line: 47, type: !142) -!142 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_mutexattr_t", file: !143, line: 31, baseType: !144) -!143 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_mutexattr_t.h", directory: "") -!144 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_pthread_mutexattr_t", file: !15, line: 114, baseType: !145) -!145 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "_opaque_pthread_mutexattr_t", file: !15, line: 83, size: 128, elements: !146) -!146 = !{!147, !148} -!147 = !DIDerivedType(tag: DW_TAG_member, name: "__sig", scope: !145, file: !15, line: 84, baseType: !19, size: 64) -!148 = !DIDerivedType(tag: DW_TAG_member, name: "__opaque", scope: !145, file: !15, line: 85, baseType: !149, size: 64, offset: 64) -!149 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 64, elements: !150) -!150 = !{!151} -!151 = !DISubrange(count: 8) -!152 = !DILocation(line: 47, column: 25, scope: !123) -!153 = !DILocation(line: 48, column: 14, scope: !123) -!154 = !DILocation(line: 48, column: 12, scope: !123) -!155 = !DILocation(line: 49, column: 5, scope: !123) -!156 = !DILocation(line: 51, column: 53, scope: !123) -!157 = !DILocation(line: 51, column: 14, scope: !123) -!158 = !DILocation(line: 51, column: 12, scope: !123) -!159 = !DILocation(line: 52, column: 5, scope: !123) -!160 = !DILocation(line: 53, column: 14, scope: !123) -!161 = !DILocation(line: 53, column: 12, scope: !123) -!162 = !DILocation(line: 54, column: 5, scope: !123) -!163 = !DILocation(line: 56, column: 57, scope: !123) -!164 = !DILocation(line: 56, column: 14, scope: !123) -!165 = !DILocation(line: 56, column: 12, scope: !123) -!166 = !DILocation(line: 57, column: 5, scope: !123) -!167 = !DILocation(line: 58, column: 14, scope: !123) -!168 = !DILocation(line: 58, column: 12, scope: !123) -!169 = !DILocation(line: 59, column: 5, scope: !123) -!170 = !DILocation(line: 61, column: 58, scope: !123) -!171 = !DILocation(line: 61, column: 14, scope: !123) -!172 = !DILocation(line: 61, column: 12, scope: !123) -!173 = !DILocation(line: 62, column: 5, scope: !123) -!174 = !DILocation(line: 63, column: 14, scope: !123) -!175 = !DILocation(line: 63, column: 12, scope: !123) -!176 = !DILocation(line: 64, column: 5, scope: !123) -!177 = !DILocation(line: 66, column: 60, scope: !123) -!178 = !DILocation(line: 66, column: 14, scope: !123) -!179 = !DILocation(line: 66, column: 12, scope: !123) -!180 = !DILocation(line: 67, column: 5, scope: !123) -!181 = !DILocation(line: 68, column: 14, scope: !123) -!182 = !DILocation(line: 68, column: 12, scope: !123) -!183 = !DILocation(line: 69, column: 5, scope: !123) -!184 = !DILocation(line: 71, column: 33, scope: !123) -!185 = !DILocation(line: 71, column: 14, scope: !123) -!186 = !DILocation(line: 71, column: 12, scope: !123) -!187 = !DILocation(line: 72, column: 5, scope: !123) -!188 = !DILocation(line: 73, column: 14, scope: !123) -!189 = !DILocation(line: 73, column: 12, scope: !123) -!190 = !DILocation(line: 74, column: 5, scope: !123) -!191 = !DILocation(line: 75, column: 1, scope: !123) -!192 = distinct !DISubprogram(name: "mutex_destroy", scope: !11, file: !11, line: 77, type: !193, scopeLine: 78, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!193 = !DISubroutineType(types: !194) -!194 = !{null, !126} -!195 = !DILocalVariable(name: "lock", arg: 1, scope: !192, file: !11, line: 77, type: !126) -!196 = !DILocation(line: 77, column: 37, scope: !192) -!197 = !DILocalVariable(name: "status", scope: !192, file: !11, line: 79, type: !65) -!198 = !DILocation(line: 79, column: 9, scope: !192) -!199 = !DILocation(line: 79, column: 40, scope: !192) -!200 = !DILocation(line: 79, column: 18, scope: !192) -!201 = !DILocation(line: 80, column: 5, scope: !192) -!202 = !DILocation(line: 81, column: 1, scope: !192) -!203 = distinct !DISubprogram(name: "mutex_lock", scope: !11, file: !11, line: 83, type: !193, scopeLine: 84, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!204 = !DILocalVariable(name: "lock", arg: 1, scope: !203, file: !11, line: 83, type: !126) -!205 = !DILocation(line: 83, column: 34, scope: !203) -!206 = !DILocalVariable(name: "status", scope: !203, file: !11, line: 85, type: !65) -!207 = !DILocation(line: 85, column: 9, scope: !203) -!208 = !DILocation(line: 85, column: 37, scope: !203) -!209 = !DILocation(line: 85, column: 18, scope: !203) -!210 = !DILocation(line: 86, column: 5, scope: !203) -!211 = !DILocation(line: 87, column: 1, scope: !203) -!212 = distinct !DISubprogram(name: "mutex_trylock", scope: !11, file: !11, line: 89, type: !213, scopeLine: 90, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!213 = !DISubroutineType(types: !214) -!214 = !{!215, !126} -!215 = !DIBasicType(name: "_Bool", size: 8, encoding: DW_ATE_boolean) -!216 = !DILocalVariable(name: "lock", arg: 1, scope: !212, file: !11, line: 89, type: !126) -!217 = !DILocation(line: 89, column: 37, scope: !212) -!218 = !DILocalVariable(name: "status", scope: !212, file: !11, line: 91, type: !65) -!219 = !DILocation(line: 91, column: 9, scope: !212) -!220 = !DILocation(line: 91, column: 40, scope: !212) -!221 = !DILocation(line: 91, column: 18, scope: !212) -!222 = !DILocation(line: 93, column: 12, scope: !212) -!223 = !DILocation(line: 93, column: 19, scope: !212) -!224 = !DILocation(line: 93, column: 5, scope: !212) -!225 = distinct !DISubprogram(name: "mutex_unlock", scope: !11, file: !11, line: 96, type: !193, scopeLine: 97, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!226 = !DILocalVariable(name: "lock", arg: 1, scope: !225, file: !11, line: 96, type: !126) -!227 = !DILocation(line: 96, column: 36, scope: !225) -!228 = !DILocalVariable(name: "status", scope: !225, file: !11, line: 98, type: !65) -!229 = !DILocation(line: 98, column: 9, scope: !225) -!230 = !DILocation(line: 98, column: 39, scope: !225) -!231 = !DILocation(line: 98, column: 18, scope: !225) -!232 = !DILocation(line: 99, column: 5, scope: !225) -!233 = !DILocation(line: 100, column: 1, scope: !225) -!234 = distinct !DISubprogram(name: "mutex_test", scope: !11, file: !11, line: 102, type: !235, scopeLine: 103, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!235 = !DISubroutineType(types: !236) -!236 = !{null} -!237 = !DILocalVariable(name: "mutex0", scope: !234, file: !11, line: 104, type: !12) -!238 = !DILocation(line: 104, column: 21, scope: !234) -!239 = !DILocalVariable(name: "mutex1", scope: !234, file: !11, line: 105, type: !12) -!240 = !DILocation(line: 105, column: 21, scope: !234) -!241 = !DILocation(line: 107, column: 5, scope: !234) -!242 = !DILocation(line: 108, column: 5, scope: !234) -!243 = !DILocation(line: 111, column: 9, scope: !244) -!244 = distinct !DILexicalBlock(scope: !234, file: !11, line: 110, column: 5) -!245 = !DILocalVariable(name: "success", scope: !244, file: !11, line: 112, type: !215) -!246 = !DILocation(line: 112, column: 14, scope: !244) -!247 = !DILocation(line: 112, column: 24, scope: !244) -!248 = !DILocation(line: 113, column: 9, scope: !244) -!249 = !DILocation(line: 114, column: 9, scope: !244) -!250 = !DILocation(line: 118, column: 9, scope: !251) -!251 = distinct !DILexicalBlock(scope: !234, file: !11, line: 117, column: 5) -!252 = !DILocalVariable(name: "success", scope: !253, file: !11, line: 121, type: !215) -!253 = distinct !DILexicalBlock(scope: !251, file: !11, line: 120, column: 9) -!254 = !DILocation(line: 121, column: 18, scope: !253) -!255 = !DILocation(line: 121, column: 28, scope: !253) -!256 = !DILocation(line: 122, column: 13, scope: !253) -!257 = !DILocation(line: 123, column: 13, scope: !253) -!258 = !DILocalVariable(name: "success", scope: !259, file: !11, line: 127, type: !215) -!259 = distinct !DILexicalBlock(scope: !251, file: !11, line: 126, column: 9) -!260 = !DILocation(line: 127, column: 18, scope: !259) -!261 = !DILocation(line: 127, column: 28, scope: !259) -!262 = !DILocation(line: 128, column: 13, scope: !259) -!263 = !DILocation(line: 129, column: 13, scope: !259) -!264 = !DILocation(line: 139, column: 9, scope: !251) -!265 = !DILocation(line: 142, column: 5, scope: !234) -!266 = !DILocation(line: 143, column: 5, scope: !234) -!267 = !DILocation(line: 144, column: 1, scope: !234) -!268 = distinct !DISubprogram(name: "cond_init", scope: !11, file: !11, line: 148, type: !269, scopeLine: 149, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!269 = !DISubroutineType(types: !270) -!270 = !{null, !271} -!271 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !26, size: 64) -!272 = !DILocalVariable(name: "cond", arg: 1, scope: !268, file: !11, line: 148, type: !271) -!273 = !DILocation(line: 148, column: 32, scope: !268) -!274 = !DILocalVariable(name: "status", scope: !268, file: !11, line: 150, type: !65) -!275 = !DILocation(line: 150, column: 9, scope: !268) -!276 = !DILocalVariable(name: "attr", scope: !268, file: !11, line: 151, type: !277) -!277 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_condattr_t", file: !278, line: 31, baseType: !279) -!278 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_condattr_t.h", directory: "") -!279 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_pthread_condattr_t", file: !15, line: 111, baseType: !280) -!280 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "_opaque_pthread_condattr_t", file: !15, line: 73, size: 128, elements: !281) -!281 = !{!282, !283} -!282 = !DIDerivedType(tag: DW_TAG_member, name: "__sig", scope: !280, file: !15, line: 74, baseType: !19, size: 64) -!283 = !DIDerivedType(tag: DW_TAG_member, name: "__opaque", scope: !280, file: !15, line: 75, baseType: !149, size: 64, offset: 64) -!284 = !DILocation(line: 151, column: 24, scope: !268) -!285 = !DILocation(line: 153, column: 14, scope: !268) -!286 = !DILocation(line: 153, column: 12, scope: !268) -!287 = !DILocation(line: 154, column: 5, scope: !268) -!288 = !DILocation(line: 156, column: 32, scope: !268) -!289 = !DILocation(line: 156, column: 14, scope: !268) -!290 = !DILocation(line: 156, column: 12, scope: !268) -!291 = !DILocation(line: 157, column: 5, scope: !268) -!292 = !DILocation(line: 159, column: 14, scope: !268) -!293 = !DILocation(line: 159, column: 12, scope: !268) -!294 = !DILocation(line: 160, column: 5, scope: !268) -!295 = !DILocation(line: 161, column: 1, scope: !268) -!296 = distinct !DISubprogram(name: "cond_destroy", scope: !11, file: !11, line: 163, type: !269, scopeLine: 164, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!297 = !DILocalVariable(name: "cond", arg: 1, scope: !296, file: !11, line: 163, type: !271) -!298 = !DILocation(line: 163, column: 35, scope: !296) -!299 = !DILocalVariable(name: "status", scope: !296, file: !11, line: 165, type: !65) -!300 = !DILocation(line: 165, column: 9, scope: !296) -!301 = !DILocation(line: 165, column: 39, scope: !296) -!302 = !DILocation(line: 165, column: 18, scope: !296) -!303 = !DILocation(line: 166, column: 5, scope: !296) -!304 = !DILocation(line: 167, column: 1, scope: !296) -!305 = distinct !DISubprogram(name: "cond_signal", scope: !11, file: !11, line: 169, type: !269, scopeLine: 170, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!306 = !DILocalVariable(name: "cond", arg: 1, scope: !305, file: !11, line: 169, type: !271) -!307 = !DILocation(line: 169, column: 34, scope: !305) -!308 = !DILocalVariable(name: "status", scope: !305, file: !11, line: 171, type: !65) -!309 = !DILocation(line: 171, column: 9, scope: !305) -!310 = !DILocation(line: 171, column: 38, scope: !305) -!311 = !DILocation(line: 171, column: 18, scope: !305) -!312 = !DILocation(line: 172, column: 5, scope: !305) -!313 = !DILocation(line: 173, column: 1, scope: !305) -!314 = distinct !DISubprogram(name: "cond_broadcast", scope: !11, file: !11, line: 175, type: !269, scopeLine: 176, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!315 = !DILocalVariable(name: "cond", arg: 1, scope: !314, file: !11, line: 175, type: !271) -!316 = !DILocation(line: 175, column: 37, scope: !314) -!317 = !DILocalVariable(name: "status", scope: !314, file: !11, line: 177, type: !65) -!318 = !DILocation(line: 177, column: 9, scope: !314) -!319 = !DILocation(line: 177, column: 41, scope: !314) -!320 = !DILocation(line: 177, column: 18, scope: !314) -!321 = !DILocation(line: 178, column: 5, scope: !314) -!322 = !DILocation(line: 179, column: 1, scope: !314) -!323 = distinct !DISubprogram(name: "cond_wait", scope: !11, file: !11, line: 181, type: !324, scopeLine: 182, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!324 = !DISubroutineType(types: !325) -!325 = !{null, !271, !126} -!326 = !DILocalVariable(name: "cond", arg: 1, scope: !323, file: !11, line: 181, type: !271) -!327 = !DILocation(line: 181, column: 32, scope: !323) -!328 = !DILocalVariable(name: "lock", arg: 2, scope: !323, file: !11, line: 181, type: !126) -!329 = !DILocation(line: 181, column: 55, scope: !323) -!330 = !DILocalVariable(name: "status", scope: !323, file: !11, line: 183, type: !65) -!331 = !DILocation(line: 183, column: 9, scope: !323) -!332 = !DILocation(line: 183, column: 36, scope: !323) -!333 = !DILocation(line: 183, column: 42, scope: !323) -!334 = !DILocation(line: 183, column: 18, scope: !323) -!335 = !DILocation(line: 185, column: 1, scope: !323) -!336 = distinct !DISubprogram(name: "cond_timedwait", scope: !11, file: !11, line: 187, type: !337, scopeLine: 188, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!337 = !DISubroutineType(types: !338) -!338 = !{null, !271, !126, !339} -!339 = !DIBasicType(name: "long long", size: 64, encoding: DW_ATE_signed) -!340 = !DILocalVariable(name: "cond", arg: 1, scope: !336, file: !11, line: 187, type: !271) -!341 = !DILocation(line: 187, column: 37, scope: !336) -!342 = !DILocalVariable(name: "lock", arg: 2, scope: !336, file: !11, line: 187, type: !126) -!343 = !DILocation(line: 187, column: 60, scope: !336) -!344 = !DILocalVariable(name: "millis", arg: 3, scope: !336, file: !11, line: 187, type: !339) -!345 = !DILocation(line: 187, column: 76, scope: !336) -!346 = !DILocalVariable(name: "ts", scope: !336, file: !11, line: 190, type: !347) -!347 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "timespec", file: !348, line: 33, size: 128, elements: !349) -!348 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_types/_timespec.h", directory: "") -!349 = !{!350, !353} -!350 = !DIDerivedType(tag: DW_TAG_member, name: "tv_sec", scope: !347, file: !348, line: 35, baseType: !351, size: 64) -!351 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_time_t", file: !352, line: 98, baseType: !19) -!352 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/arm/_types.h", directory: "") -!353 = !DIDerivedType(tag: DW_TAG_member, name: "tv_nsec", scope: !347, file: !348, line: 36, baseType: !19, size: 64, offset: 64) -!354 = !DILocation(line: 190, column: 21, scope: !336) -!355 = !DILocation(line: 194, column: 11, scope: !336) -!356 = !DILocalVariable(name: "status", scope: !336, file: !11, line: 195, type: !65) -!357 = !DILocation(line: 195, column: 9, scope: !336) -!358 = !DILocation(line: 195, column: 41, scope: !336) -!359 = !DILocation(line: 195, column: 47, scope: !336) -!360 = !DILocation(line: 195, column: 18, scope: !336) -!361 = !DILocation(line: 196, column: 1, scope: !336) -!362 = distinct !DISubprogram(name: "cond_worker", scope: !11, file: !11, line: 202, type: !81, scopeLine: 203, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!363 = !DILocalVariable(name: "message", arg: 1, scope: !362, file: !11, line: 202, type: !7) -!364 = !DILocation(line: 202, column: 25, scope: !362) -!365 = !DILocalVariable(name: "idle", scope: !362, file: !11, line: 204, type: !215) -!366 = !DILocation(line: 204, column: 10, scope: !362) -!367 = !DILocation(line: 206, column: 9, scope: !368) -!368 = distinct !DILexicalBlock(scope: !362, file: !11, line: 205, column: 5) -!369 = !DILocation(line: 207, column: 9, scope: !368) -!370 = !DILocation(line: 208, column: 9, scope: !368) -!371 = !DILocation(line: 209, column: 9, scope: !368) -!372 = !DILocation(line: 210, column: 16, scope: !368) -!373 = !DILocation(line: 210, column: 22, scope: !368) -!374 = !DILocation(line: 210, column: 14, scope: !368) -!375 = !DILocation(line: 211, column: 9, scope: !368) -!376 = !DILocation(line: 213, column: 9, scope: !377) -!377 = distinct !DILexicalBlock(scope: !362, file: !11, line: 213, column: 9) -!378 = !DILocation(line: 213, column: 9, scope: !362) -!379 = !DILocation(line: 214, column: 25, scope: !377) -!380 = !DILocation(line: 214, column: 34, scope: !377) -!381 = !DILocation(line: 214, column: 9, scope: !377) -!382 = !DILocation(line: 215, column: 10, scope: !362) -!383 = !DILocation(line: 217, column: 9, scope: !384) -!384 = distinct !DILexicalBlock(scope: !362, file: !11, line: 216, column: 5) -!385 = !DILocation(line: 218, column: 9, scope: !384) -!386 = !DILocation(line: 219, column: 9, scope: !384) -!387 = !DILocation(line: 220, column: 9, scope: !384) -!388 = !DILocation(line: 221, column: 16, scope: !384) -!389 = !DILocation(line: 221, column: 22, scope: !384) -!390 = !DILocation(line: 221, column: 14, scope: !384) -!391 = !DILocation(line: 222, column: 9, scope: !384) -!392 = !DILocation(line: 224, column: 9, scope: !393) -!393 = distinct !DILexicalBlock(scope: !362, file: !11, line: 224, column: 9) -!394 = !DILocation(line: 224, column: 9, scope: !362) -!395 = !DILocation(line: 225, column: 25, scope: !393) -!396 = !DILocation(line: 225, column: 34, scope: !393) -!397 = !DILocation(line: 225, column: 9, scope: !393) -!398 = !DILocation(line: 226, column: 12, scope: !362) -!399 = !DILocation(line: 226, column: 5, scope: !362) -!400 = !DILocation(line: 227, column: 1, scope: !362) -!401 = distinct !DISubprogram(name: "cond_test", scope: !11, file: !11, line: 229, type: !235, scopeLine: 230, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!402 = !DILocalVariable(name: "message", scope: !401, file: !11, line: 231, type: !7) -!403 = !DILocation(line: 231, column: 11, scope: !401) -!404 = !DILocation(line: 232, column: 5, scope: !401) -!405 = !DILocation(line: 233, column: 5, scope: !401) -!406 = !DILocalVariable(name: "worker", scope: !401, file: !11, line: 235, type: !38) -!407 = !DILocation(line: 235, column: 15, scope: !401) -!408 = !DILocation(line: 235, column: 51, scope: !401) -!409 = !DILocation(line: 235, column: 24, scope: !401) -!410 = !DILocation(line: 238, column: 9, scope: !411) -!411 = distinct !DILexicalBlock(scope: !401, file: !11, line: 237, column: 5) -!412 = !DILocation(line: 239, column: 9, scope: !411) -!413 = !DILocation(line: 240, column: 9, scope: !411) -!414 = !DILocation(line: 241, column: 9, scope: !411) -!415 = !DILocation(line: 245, column: 9, scope: !416) -!416 = distinct !DILexicalBlock(scope: !401, file: !11, line: 244, column: 5) -!417 = !DILocation(line: 246, column: 9, scope: !416) -!418 = !DILocation(line: 247, column: 9, scope: !416) -!419 = !DILocation(line: 248, column: 9, scope: !416) -!420 = !DILocalVariable(name: "result", scope: !401, file: !11, line: 251, type: !7) -!421 = !DILocation(line: 251, column: 11, scope: !401) -!422 = !DILocation(line: 251, column: 32, scope: !401) -!423 = !DILocation(line: 251, column: 20, scope: !401) -!424 = !DILocation(line: 252, column: 5, scope: !401) -!425 = !DILocation(line: 254, column: 5, scope: !401) -!426 = !DILocation(line: 255, column: 5, scope: !401) -!427 = !DILocation(line: 256, column: 1, scope: !401) -!428 = distinct !DISubprogram(name: "rwlock_init", scope: !11, file: !11, line: 263, type: !429, scopeLine: 264, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!429 = !DISubroutineType(types: !430) -!430 = !{null, !431, !65} -!431 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !432, size: 64) -!432 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_rwlock_t", file: !433, line: 31, baseType: !434) -!433 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_rwlock_t.h", directory: "") -!434 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_pthread_rwlock_t", file: !15, line: 116, baseType: !435) -!435 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "_opaque_pthread_rwlock_t", file: !15, line: 93, size: 1600, elements: !436) -!436 = !{!437, !438} -!437 = !DIDerivedType(tag: DW_TAG_member, name: "__sig", scope: !435, file: !15, line: 94, baseType: !19, size: 64) -!438 = !DIDerivedType(tag: DW_TAG_member, name: "__opaque", scope: !435, file: !15, line: 95, baseType: !439, size: 1536, offset: 64) -!439 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 1536, elements: !440) -!440 = !{!441} -!441 = !DISubrange(count: 192) -!442 = !DILocalVariable(name: "lock", arg: 1, scope: !428, file: !11, line: 263, type: !431) -!443 = !DILocation(line: 263, column: 36, scope: !428) -!444 = !DILocalVariable(name: "shared", arg: 2, scope: !428, file: !11, line: 263, type: !65) -!445 = !DILocation(line: 263, column: 46, scope: !428) -!446 = !DILocalVariable(name: "status", scope: !428, file: !11, line: 265, type: !65) -!447 = !DILocation(line: 265, column: 9, scope: !428) -!448 = !DILocalVariable(name: "value", scope: !428, file: !11, line: 266, type: !65) -!449 = !DILocation(line: 266, column: 9, scope: !428) -!450 = !DILocalVariable(name: "attributes", scope: !428, file: !11, line: 267, type: !451) -!451 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_rwlockattr_t", file: !452, line: 31, baseType: !453) -!452 = !DIFile(filename: "/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/_pthread/_pthread_rwlockattr_t.h", directory: "") -!453 = !DIDerivedType(tag: DW_TAG_typedef, name: "__darwin_pthread_rwlockattr_t", file: !15, line: 117, baseType: !454) -!454 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "_opaque_pthread_rwlockattr_t", file: !15, line: 98, size: 192, elements: !455) -!455 = !{!456, !457} -!456 = !DIDerivedType(tag: DW_TAG_member, name: "__sig", scope: !454, file: !15, line: 99, baseType: !19, size: 64) -!457 = !DIDerivedType(tag: DW_TAG_member, name: "__opaque", scope: !454, file: !15, line: 100, baseType: !458, size: 128, offset: 64) -!458 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 128, elements: !459) -!459 = !{!460} -!460 = !DISubrange(count: 16) -!461 = !DILocation(line: 267, column: 26, scope: !428) -!462 = !DILocation(line: 268, column: 14, scope: !428) -!463 = !DILocation(line: 268, column: 12, scope: !428) -!464 = !DILocation(line: 269, column: 5, scope: !428) -!465 = !DILocation(line: 271, column: 57, scope: !428) -!466 = !DILocation(line: 271, column: 14, scope: !428) -!467 = !DILocation(line: 271, column: 12, scope: !428) -!468 = !DILocation(line: 272, column: 5, scope: !428) -!469 = !DILocation(line: 273, column: 14, scope: !428) -!470 = !DILocation(line: 273, column: 12, scope: !428) -!471 = !DILocation(line: 274, column: 5, scope: !428) -!472 = !DILocation(line: 276, column: 34, scope: !428) -!473 = !DILocation(line: 276, column: 14, scope: !428) -!474 = !DILocation(line: 276, column: 12, scope: !428) -!475 = !DILocation(line: 277, column: 5, scope: !428) -!476 = !DILocation(line: 278, column: 14, scope: !428) -!477 = !DILocation(line: 278, column: 12, scope: !428) -!478 = !DILocation(line: 279, column: 5, scope: !428) -!479 = !DILocation(line: 280, column: 1, scope: !428) -!480 = distinct !DISubprogram(name: "rwlock_destroy", scope: !11, file: !11, line: 282, type: !481, scopeLine: 283, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!481 = !DISubroutineType(types: !482) -!482 = !{null, !431} -!483 = !DILocalVariable(name: "lock", arg: 1, scope: !480, file: !11, line: 282, type: !431) -!484 = !DILocation(line: 282, column: 39, scope: !480) -!485 = !DILocalVariable(name: "status", scope: !480, file: !11, line: 284, type: !65) -!486 = !DILocation(line: 284, column: 9, scope: !480) -!487 = !DILocation(line: 284, column: 41, scope: !480) -!488 = !DILocation(line: 284, column: 18, scope: !480) -!489 = !DILocation(line: 285, column: 5, scope: !480) -!490 = !DILocation(line: 286, column: 1, scope: !480) -!491 = distinct !DISubprogram(name: "rwlock_wrlock", scope: !11, file: !11, line: 288, type: !481, scopeLine: 289, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!492 = !DILocalVariable(name: "lock", arg: 1, scope: !491, file: !11, line: 288, type: !431) -!493 = !DILocation(line: 288, column: 38, scope: !491) -!494 = !DILocalVariable(name: "status", scope: !491, file: !11, line: 290, type: !65) -!495 = !DILocation(line: 290, column: 9, scope: !491) -!496 = !DILocation(line: 290, column: 40, scope: !491) -!497 = !DILocation(line: 290, column: 18, scope: !491) -!498 = !DILocation(line: 291, column: 5, scope: !491) -!499 = !DILocation(line: 292, column: 1, scope: !491) -!500 = distinct !DISubprogram(name: "rwlock_trywrlock", scope: !11, file: !11, line: 294, type: !501, scopeLine: 295, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!501 = !DISubroutineType(types: !502) -!502 = !{!215, !431} -!503 = !DILocalVariable(name: "lock", arg: 1, scope: !500, file: !11, line: 294, type: !431) -!504 = !DILocation(line: 294, column: 41, scope: !500) -!505 = !DILocalVariable(name: "status", scope: !500, file: !11, line: 296, type: !65) -!506 = !DILocation(line: 296, column: 9, scope: !500) -!507 = !DILocation(line: 296, column: 43, scope: !500) -!508 = !DILocation(line: 296, column: 18, scope: !500) -!509 = !DILocation(line: 298, column: 12, scope: !500) -!510 = !DILocation(line: 298, column: 19, scope: !500) -!511 = !DILocation(line: 298, column: 5, scope: !500) -!512 = distinct !DISubprogram(name: "rwlock_rdlock", scope: !11, file: !11, line: 301, type: !481, scopeLine: 302, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!513 = !DILocalVariable(name: "lock", arg: 1, scope: !512, file: !11, line: 301, type: !431) -!514 = !DILocation(line: 301, column: 38, scope: !512) -!515 = !DILocalVariable(name: "status", scope: !512, file: !11, line: 303, type: !65) -!516 = !DILocation(line: 303, column: 9, scope: !512) -!517 = !DILocation(line: 303, column: 40, scope: !512) -!518 = !DILocation(line: 303, column: 18, scope: !512) -!519 = !DILocation(line: 304, column: 5, scope: !512) -!520 = !DILocation(line: 305, column: 1, scope: !512) -!521 = distinct !DISubprogram(name: "rwlock_tryrdlock", scope: !11, file: !11, line: 307, type: !501, scopeLine: 308, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!522 = !DILocalVariable(name: "lock", arg: 1, scope: !521, file: !11, line: 307, type: !431) -!523 = !DILocation(line: 307, column: 41, scope: !521) -!524 = !DILocalVariable(name: "status", scope: !521, file: !11, line: 309, type: !65) -!525 = !DILocation(line: 309, column: 9, scope: !521) -!526 = !DILocation(line: 309, column: 43, scope: !521) -!527 = !DILocation(line: 309, column: 18, scope: !521) -!528 = !DILocation(line: 311, column: 12, scope: !521) -!529 = !DILocation(line: 311, column: 19, scope: !521) -!530 = !DILocation(line: 311, column: 5, scope: !521) -!531 = distinct !DISubprogram(name: "rwlock_unlock", scope: !11, file: !11, line: 314, type: !481, scopeLine: 315, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!532 = !DILocalVariable(name: "lock", arg: 1, scope: !531, file: !11, line: 314, type: !431) -!533 = !DILocation(line: 314, column: 38, scope: !531) -!534 = !DILocalVariable(name: "status", scope: !531, file: !11, line: 316, type: !65) -!535 = !DILocation(line: 316, column: 9, scope: !531) -!536 = !DILocation(line: 316, column: 40, scope: !531) -!537 = !DILocation(line: 316, column: 18, scope: !531) -!538 = !DILocation(line: 317, column: 5, scope: !531) -!539 = !DILocation(line: 318, column: 1, scope: !531) -!540 = distinct !DISubprogram(name: "rwlock_test", scope: !11, file: !11, line: 320, type: !235, scopeLine: 321, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!541 = !DILocalVariable(name: "lock", scope: !540, file: !11, line: 322, type: !432) -!542 = !DILocation(line: 322, column: 22, scope: !540) -!543 = !DILocation(line: 323, column: 5, scope: !540) -!544 = !DILocalVariable(name: "test_depth", scope: !540, file: !11, line: 324, type: !545) -!545 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !65) -!546 = !DILocation(line: 324, column: 15, scope: !540) -!547 = !DILocation(line: 327, column: 9, scope: !548) -!548 = distinct !DILexicalBlock(scope: !540, file: !11, line: 326, column: 5) -!549 = !DILocalVariable(name: "success", scope: !548, file: !11, line: 328, type: !215) -!550 = !DILocation(line: 328, column: 14, scope: !548) -!551 = !DILocation(line: 328, column: 24, scope: !548) -!552 = !DILocation(line: 329, column: 9, scope: !548) -!553 = !DILocation(line: 330, column: 19, scope: !548) -!554 = !DILocation(line: 330, column: 17, scope: !548) -!555 = !DILocation(line: 331, column: 9, scope: !548) -!556 = !DILocation(line: 332, column: 9, scope: !548) -!557 = !DILocation(line: 336, column: 9, scope: !558) -!558 = distinct !DILexicalBlock(scope: !540, file: !11, line: 335, column: 5) -!559 = !DILocalVariable(name: "i", scope: !560, file: !11, line: 337, type: !65) -!560 = distinct !DILexicalBlock(scope: !558, file: !11, line: 337, column: 9) -!561 = !DILocation(line: 337, column: 18, scope: !560) -!562 = !DILocation(line: 337, column: 14, scope: !560) -!563 = !DILocation(line: 337, column: 25, scope: !564) -!564 = distinct !DILexicalBlock(scope: !560, file: !11, line: 337, column: 9) -!565 = !DILocation(line: 337, column: 27, scope: !564) -!566 = !DILocation(line: 337, column: 9, scope: !560) -!567 = !DILocalVariable(name: "success", scope: !568, file: !11, line: 339, type: !215) -!568 = distinct !DILexicalBlock(scope: !564, file: !11, line: 338, column: 9) -!569 = !DILocation(line: 339, column: 18, scope: !568) -!570 = !DILocation(line: 339, column: 28, scope: !568) -!571 = !DILocation(line: 340, column: 13, scope: !568) -!572 = !DILocation(line: 341, column: 9, scope: !568) -!573 = !DILocation(line: 337, column: 42, scope: !564) -!574 = !DILocation(line: 337, column: 9, scope: !564) -!575 = distinct !{!575, !566, !576, !577} -!576 = !DILocation(line: 341, column: 9, scope: !560) -!577 = !{!"llvm.loop.mustprogress"} -!578 = !DILocalVariable(name: "success", scope: !579, file: !11, line: 344, type: !215) -!579 = distinct !DILexicalBlock(scope: !558, file: !11, line: 343, column: 9) -!580 = !DILocation(line: 344, column: 18, scope: !579) -!581 = !DILocation(line: 344, column: 28, scope: !579) -!582 = !DILocation(line: 345, column: 13, scope: !579) -!583 = !DILocation(line: 348, column: 9, scope: !558) -!584 = !DILocalVariable(name: "i", scope: !585, file: !11, line: 349, type: !65) -!585 = distinct !DILexicalBlock(scope: !558, file: !11, line: 349, column: 9) -!586 = !DILocation(line: 349, column: 18, scope: !585) -!587 = !DILocation(line: 349, column: 14, scope: !585) -!588 = !DILocation(line: 349, column: 25, scope: !589) -!589 = distinct !DILexicalBlock(scope: !585, file: !11, line: 349, column: 9) -!590 = !DILocation(line: 349, column: 27, scope: !589) -!591 = !DILocation(line: 349, column: 9, scope: !585) -!592 = !DILocation(line: 350, column: 13, scope: !593) -!593 = distinct !DILexicalBlock(scope: !589, file: !11, line: 349, column: 46) -!594 = !DILocation(line: 351, column: 9, scope: !593) -!595 = !DILocation(line: 349, column: 42, scope: !589) -!596 = !DILocation(line: 349, column: 9, scope: !589) -!597 = distinct !{!597, !591, !598, !577} -!598 = !DILocation(line: 351, column: 9, scope: !585) -!599 = !DILocation(line: 355, column: 9, scope: !600) -!600 = distinct !DILexicalBlock(scope: !540, file: !11, line: 354, column: 5) -!601 = !DILocalVariable(name: "success", scope: !600, file: !11, line: 356, type: !215) -!602 = !DILocation(line: 356, column: 14, scope: !600) -!603 = !DILocation(line: 356, column: 24, scope: !600) -!604 = !DILocation(line: 357, column: 9, scope: !600) -!605 = !DILocation(line: 358, column: 9, scope: !600) -!606 = !DILocation(line: 361, column: 5, scope: !540) -!607 = !DILocation(line: 362, column: 1, scope: !540) -!608 = distinct !DISubprogram(name: "key_destroy", scope: !11, file: !11, line: 369, type: !51, scopeLine: 370, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!609 = !DILocalVariable(name: "unused_value", arg: 1, scope: !608, file: !11, line: 369, type: !7) -!610 = !DILocation(line: 369, column: 24, scope: !608) -!611 = !DILocation(line: 371, column: 21, scope: !608) -!612 = !DILocation(line: 371, column: 19, scope: !608) -!613 = !DILocation(line: 372, column: 1, scope: !608) -!614 = distinct !DISubprogram(name: "key_worker", scope: !11, file: !11, line: 374, type: !81, scopeLine: 375, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!615 = !DILocalVariable(name: "message", arg: 1, scope: !614, file: !11, line: 374, type: !7) -!616 = !DILocation(line: 374, column: 24, scope: !614) -!617 = !DILocalVariable(name: "my_secret", scope: !614, file: !11, line: 376, type: !65) -!618 = !DILocation(line: 376, column: 9, scope: !614) -!619 = !DILocalVariable(name: "status", scope: !614, file: !11, line: 378, type: !65) -!620 = !DILocation(line: 378, column: 9, scope: !614) -!621 = !DILocation(line: 378, column: 38, scope: !614) -!622 = !DILocation(line: 378, column: 50, scope: !614) -!623 = !DILocation(line: 378, column: 18, scope: !614) -!624 = !DILocation(line: 379, column: 5, scope: !614) -!625 = !DILocalVariable(name: "my_local_data", scope: !614, file: !11, line: 381, type: !7) -!626 = !DILocation(line: 381, column: 11, scope: !614) -!627 = !DILocation(line: 381, column: 47, scope: !614) -!628 = !DILocation(line: 381, column: 27, scope: !614) -!629 = !DILocation(line: 382, column: 5, scope: !614) -!630 = !DILocation(line: 384, column: 12, scope: !614) -!631 = !DILocation(line: 384, column: 5, scope: !614) -!632 = distinct !DISubprogram(name: "key_test", scope: !11, file: !11, line: 387, type: !235, scopeLine: 388, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!633 = !DILocalVariable(name: "my_secret", scope: !632, file: !11, line: 389, type: !65) -!634 = !DILocation(line: 389, column: 9, scope: !632) -!635 = !DILocalVariable(name: "message", scope: !632, file: !11, line: 390, type: !7) -!636 = !DILocation(line: 390, column: 11, scope: !632) -!637 = !DILocalVariable(name: "status", scope: !632, file: !11, line: 391, type: !65) -!638 = !DILocation(line: 391, column: 9, scope: !632) -!639 = !DILocation(line: 393, column: 5, scope: !632) -!640 = !DILocalVariable(name: "worker", scope: !632, file: !11, line: 395, type: !38) -!641 = !DILocation(line: 395, column: 15, scope: !632) -!642 = !DILocation(line: 395, column: 50, scope: !632) -!643 = !DILocation(line: 395, column: 24, scope: !632) -!644 = !DILocation(line: 397, column: 34, scope: !632) -!645 = !DILocation(line: 397, column: 46, scope: !632) -!646 = !DILocation(line: 397, column: 14, scope: !632) -!647 = !DILocation(line: 397, column: 12, scope: !632) -!648 = !DILocation(line: 398, column: 5, scope: !632) -!649 = !DILocalVariable(name: "my_local_data", scope: !632, file: !11, line: 400, type: !7) -!650 = !DILocation(line: 400, column: 11, scope: !632) -!651 = !DILocation(line: 400, column: 47, scope: !632) -!652 = !DILocation(line: 400, column: 27, scope: !632) -!653 = !DILocation(line: 401, column: 5, scope: !632) -!654 = !DILocation(line: 403, column: 34, scope: !632) -!655 = !DILocation(line: 403, column: 14, scope: !632) -!656 = !DILocation(line: 403, column: 12, scope: !632) -!657 = !DILocation(line: 404, column: 5, scope: !632) -!658 = !DILocalVariable(name: "result", scope: !632, file: !11, line: 406, type: !7) -!659 = !DILocation(line: 406, column: 11, scope: !632) -!660 = !DILocation(line: 406, column: 32, scope: !632) -!661 = !DILocation(line: 406, column: 20, scope: !632) -!662 = !DILocation(line: 407, column: 5, scope: !632) -!663 = !DILocation(line: 409, column: 33, scope: !632) -!664 = !DILocation(line: 409, column: 14, scope: !632) -!665 = !DILocation(line: 409, column: 12, scope: !632) -!666 = !DILocation(line: 410, column: 5, scope: !632) -!667 = !DILocation(line: 413, column: 1, scope: !632) -!668 = distinct !DISubprogram(name: "main", scope: !11, file: !11, line: 415, type: !669, scopeLine: 416, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !83) -!669 = !DISubroutineType(types: !670) -!670 = !{!65} -!671 = !DILocation(line: 417, column: 5, scope: !668) -!672 = !DILocation(line: 418, column: 5, scope: !668) -!673 = !DILocation(line: 419, column: 5, scope: !668) -!674 = !DILocation(line: 420, column: 5, scope: !668) -!675 = !DILocation(line: 421, column: 1, scope: !668) +!60 = distinct !DIGlobalVariable(name: "phase", scope: !61, file: !2, line: 193, type: !149, isLocal: false, isDefinition: true) +!61 = distinct !DICompileUnit(language: DW_LANG_C11, file: !2, producer: "Homebrew clang version 19.1.7", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !62, retainedTypes: !88, globals: !91, splitDebugInlining: false, nameTableKind: None) +!62 = !{!63, !75, !80, !84} +!63 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !64, line: 672, baseType: !65, size: 32, elements: !66) +!64 = !DIFile(filename: "./include/pthread.h", directory: "/Users/r/git/dat3m", checksumkind: CSK_MD5, checksum: "cd7d21805be506b5b7d56065fce8a5bf") +!65 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!66 = !{!67, !68, !69, !70, !71, !72, !73, !74} +!67 = !DIEnumerator(name: "PTHREAD_MUTEX_TIMED_NP", value: 0) +!68 = !DIEnumerator(name: "PTHREAD_MUTEX_RECURSIVE_NP", value: 1) +!69 = !DIEnumerator(name: "PTHREAD_MUTEX_ERRORCHECK_NP", value: 2) +!70 = !DIEnumerator(name: "PTHREAD_MUTEX_ADAPTIVE_NP", value: 3) +!71 = !DIEnumerator(name: "PTHREAD_MUTEX_NORMAL", value: 0) +!72 = !DIEnumerator(name: "PTHREAD_MUTEX_RECURSIVE", value: 1) +!73 = !DIEnumerator(name: "PTHREAD_MUTEX_ERRORCHECK", value: 2) +!74 = !DIEnumerator(name: "PTHREAD_MUTEX_DEFAULT", value: 0) +!75 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !64, line: 691, baseType: !65, size: 32, elements: !76) +!76 = !{!77, !78, !79} +!77 = !DIEnumerator(name: "PTHREAD_PRIO_NONE", value: 0) +!78 = !DIEnumerator(name: "PTHREAD_PRIO_INHERIT", value: 1) +!79 = !DIEnumerator(name: "PTHREAD_PRIO_PROTECT", value: 2) +!80 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !64, line: 714, baseType: !65, size: 32, elements: !81) +!81 = !{!82, !83} +!82 = !DIEnumerator(name: "PTHREAD_PROCESS_PRIVATE", value: 0) +!83 = !DIEnumerator(name: "PTHREAD_PROCESS_SHARED", value: 1) +!84 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !64, line: 667, baseType: !65, size: 32, elements: !85) +!85 = !{!86, !87} +!86 = !DIEnumerator(name: "PTHREAD_CREATE_JOINABLE", value: 0) +!87 = !DIEnumerator(name: "PTHREAD_CREATE_DETACHED", value: 1) +!88 = !{!89, !90} +!89 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !5, size: 64) +!90 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!91 = !{!0, !8, !13, !18, !21, !26, !28, !30, !35, !37, !42, !47, !50, !52, !54, !59, !92, !94, !99, !101, !103, !105, !107, !109, !111, !113, !118, !121, !126, !128, !133, !138, !140, !175, !209, !213} +!92 = !DIGlobalVariableExpression(var: !93, expr: !DIExpression()) +!93 = distinct !DIGlobalVariable(scope: null, file: !2, line: 245, type: !49, isLocal: true, isDefinition: true) +!94 = !DIGlobalVariableExpression(var: !95, expr: !DIExpression()) +!95 = distinct !DIGlobalVariable(scope: null, file: !2, line: 245, type: !96, isLocal: true, isDefinition: true) +!96 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 144, elements: !97) +!97 = !{!98} +!98 = !DISubrange(count: 18) +!99 = !DIGlobalVariableExpression(var: !100, expr: !DIExpression()) +!100 = distinct !DIGlobalVariable(scope: null, file: !2, line: 262, type: !20, isLocal: true, isDefinition: true) +!101 = !DIGlobalVariableExpression(var: !102, expr: !DIExpression()) +!102 = distinct !DIGlobalVariable(scope: null, file: !2, line: 278, type: !56, isLocal: true, isDefinition: true) +!103 = !DIGlobalVariableExpression(var: !104, expr: !DIExpression()) +!104 = distinct !DIGlobalVariable(scope: null, file: !2, line: 284, type: !3, isLocal: true, isDefinition: true) +!105 = !DIGlobalVariableExpression(var: !106, expr: !DIExpression()) +!106 = distinct !DIGlobalVariable(scope: null, file: !2, line: 297, type: !3, isLocal: true, isDefinition: true) +!107 = !DIGlobalVariableExpression(var: !108, expr: !DIExpression()) +!108 = distinct !DIGlobalVariable(scope: null, file: !2, line: 310, type: !3, isLocal: true, isDefinition: true) +!109 = !DIGlobalVariableExpression(var: !110, expr: !DIExpression()) +!110 = distinct !DIGlobalVariable(scope: null, file: !2, line: 322, type: !20, isLocal: true, isDefinition: true) +!111 = !DIGlobalVariableExpression(var: !112, expr: !DIExpression()) +!112 = distinct !DIGlobalVariable(scope: null, file: !2, line: 372, type: !23, isLocal: true, isDefinition: true) +!113 = !DIGlobalVariableExpression(var: !114, expr: !DIExpression()) +!114 = distinct !DIGlobalVariable(scope: null, file: !2, line: 375, type: !115, isLocal: true, isDefinition: true) +!115 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 224, elements: !116) +!116 = !{!117} +!117 = !DISubrange(count: 28) +!118 = !DIGlobalVariableExpression(var: !119, expr: !DIExpression()) +!119 = distinct !DIGlobalVariable(scope: null, file: !2, line: 391, type: !120, isLocal: true, isDefinition: true) +!120 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 72, elements: !40) +!121 = !DIGlobalVariableExpression(var: !122, expr: !DIExpression()) +!122 = distinct !DIGlobalVariable(scope: null, file: !2, line: 420, type: !123, isLocal: true, isDefinition: true) +!123 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 152, elements: !124) +!124 = !{!125} +!125 = !DISubrange(count: 19) +!126 = !DIGlobalVariableExpression(var: !127, expr: !DIExpression()) +!127 = distinct !DIGlobalVariable(scope: null, file: !2, line: 423, type: !15, isLocal: true, isDefinition: true) +!128 = !DIGlobalVariableExpression(var: !129, expr: !DIExpression()) +!129 = distinct !DIGlobalVariable(scope: null, file: !2, line: 434, type: !130, isLocal: true, isDefinition: true) +!130 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 136, elements: !131) +!131 = !{!132} +!132 = !DISubrange(count: 17) +!133 = !DIGlobalVariableExpression(var: !134, expr: !DIExpression()) +!134 = distinct !DIGlobalVariable(scope: null, file: !2, line: 436, type: !135, isLocal: true, isDefinition: true) +!135 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 432, elements: !136) +!136 = !{!137} +!137 = !DISubrange(count: 54) +!138 = !DIGlobalVariableExpression(var: !139, expr: !DIExpression()) +!139 = distinct !DIGlobalVariable(scope: null, file: !2, line: 440, type: !135, isLocal: true, isDefinition: true) +!140 = !DIGlobalVariableExpression(var: !141, expr: !DIExpression()) +!141 = distinct !DIGlobalVariable(name: "cond_mutex", scope: !61, file: !2, line: 191, type: !142, isLocal: false, isDefinition: true) +!142 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_mutex_t", file: !64, line: 329, baseType: !143) +!143 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !64, line: 324, size: 256, elements: !144) +!144 = !{!145, !169, !173} +!145 = !DIDerivedType(tag: DW_TAG_member, name: "__data", scope: !143, file: !64, line: 326, baseType: !146, size: 256) +!146 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__pthread_mutex_s", file: !64, line: 258, size: 256, elements: !147) +!147 = !{!148, !150, !151, !152, !153, !154} +!148 = !DIDerivedType(tag: DW_TAG_member, name: "__lock", scope: !146, file: !64, line: 260, baseType: !149, size: 32) +!149 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!150 = !DIDerivedType(tag: DW_TAG_member, name: "__count", scope: !146, file: !64, line: 261, baseType: !65, size: 32, offset: 32) +!151 = !DIDerivedType(tag: DW_TAG_member, name: "__owner", scope: !146, file: !64, line: 262, baseType: !149, size: 32, offset: 64) +!152 = !DIDerivedType(tag: DW_TAG_member, name: "__kind", scope: !146, file: !64, line: 263, baseType: !149, size: 32, offset: 96) +!153 = !DIDerivedType(tag: DW_TAG_member, name: "__nusers", scope: !146, file: !64, line: 264, baseType: !65, size: 32, offset: 128) +!154 = !DIDerivedType(tag: DW_TAG_member, scope: !146, file: !64, line: 265, baseType: !155, size: 64, offset: 192) +!155 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !146, file: !64, line: 265, size: 64, elements: !156) +!156 = !{!157, !163} +!157 = !DIDerivedType(tag: DW_TAG_member, name: "__elision_data", scope: !155, file: !64, line: 271, baseType: !158, size: 32) +!158 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !155, file: !64, line: 267, size: 32, elements: !159) +!159 = !{!160, !162} +!160 = !DIDerivedType(tag: DW_TAG_member, name: "__espins", scope: !158, file: !64, line: 269, baseType: !161, size: 16) +!161 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!162 = !DIDerivedType(tag: DW_TAG_member, name: "__eelision", scope: !158, file: !64, line: 270, baseType: !161, size: 16, offset: 16) +!163 = !DIDerivedType(tag: DW_TAG_member, name: "__list", scope: !155, file: !64, line: 272, baseType: !164, size: 64) +!164 = !DIDerivedType(tag: DW_TAG_typedef, name: "__pthread_slist_t", file: !64, line: 257, baseType: !165) +!165 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__pthread_internal_slist", file: !64, line: 254, size: 64, elements: !166) +!166 = !{!167} +!167 = !DIDerivedType(tag: DW_TAG_member, name: "__next", scope: !165, file: !64, line: 256, baseType: !168, size: 64) +!168 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !165, size: 64) +!169 = !DIDerivedType(tag: DW_TAG_member, name: "__size", scope: !143, file: !64, line: 327, baseType: !170, size: 192) +!170 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 192, elements: !171) +!171 = !{!172} +!172 = !DISubrange(count: 24) +!173 = !DIDerivedType(tag: DW_TAG_member, name: "__align", scope: !143, file: !64, line: 328, baseType: !174, size: 64) +!174 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) +!175 = !DIGlobalVariableExpression(var: !176, expr: !DIExpression()) +!176 = distinct !DIGlobalVariable(name: "cond", scope: !61, file: !2, line: 192, type: !177, isLocal: false, isDefinition: true) +!177 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_cond_t", file: !64, line: 335, baseType: !178) +!178 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !64, line: 330, size: 384, elements: !179) +!179 = !{!180, !203, !207} +!180 = !DIDerivedType(tag: DW_TAG_member, name: "__data", scope: !178, file: !64, line: 332, baseType: !181, size: 384) +!181 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__pthread_cond_s", file: !64, line: 289, size: 384, elements: !182) +!182 = !{!183, !194, !195, !199, !200, !201, !202} +!183 = !DIDerivedType(tag: DW_TAG_member, name: "__wseq", scope: !181, file: !64, line: 291, baseType: !184, size: 64) +!184 = !DIDerivedType(tag: DW_TAG_typedef, name: "__atomic_wide_counter", file: !64, line: 248, baseType: !185) +!185 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !64, line: 240, size: 64, elements: !186) +!186 = !{!187, !189} +!187 = !DIDerivedType(tag: DW_TAG_member, name: "__value64", scope: !185, file: !64, line: 242, baseType: !188, size: 64) +!188 = !DIBasicType(name: "unsigned long long", size: 64, encoding: DW_ATE_unsigned) +!189 = !DIDerivedType(tag: DW_TAG_member, name: "__value32", scope: !185, file: !64, line: 247, baseType: !190, size: 64) +!190 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !185, file: !64, line: 243, size: 64, elements: !191) +!191 = !{!192, !193} +!192 = !DIDerivedType(tag: DW_TAG_member, name: "__low", scope: !190, file: !64, line: 245, baseType: !65, size: 32) +!193 = !DIDerivedType(tag: DW_TAG_member, name: "__high", scope: !190, file: !64, line: 246, baseType: !65, size: 32, offset: 32) +!194 = !DIDerivedType(tag: DW_TAG_member, name: "__g1_start", scope: !181, file: !64, line: 292, baseType: !184, size: 64, offset: 64) +!195 = !DIDerivedType(tag: DW_TAG_member, name: "__g_refs", scope: !181, file: !64, line: 293, baseType: !196, size: 64, offset: 128) +!196 = !DICompositeType(tag: DW_TAG_array_type, baseType: !65, size: 64, elements: !197) +!197 = !{!198} +!198 = !DISubrange(count: 2) +!199 = !DIDerivedType(tag: DW_TAG_member, name: "__g_size", scope: !181, file: !64, line: 294, baseType: !196, size: 64, offset: 192) +!200 = !DIDerivedType(tag: DW_TAG_member, name: "__g1_orig_size", scope: !181, file: !64, line: 295, baseType: !65, size: 32, offset: 256) +!201 = !DIDerivedType(tag: DW_TAG_member, name: "__wrefs", scope: !181, file: !64, line: 296, baseType: !65, size: 32, offset: 288) +!202 = !DIDerivedType(tag: DW_TAG_member, name: "__g_signals", scope: !181, file: !64, line: 297, baseType: !196, size: 64, offset: 320) +!203 = !DIDerivedType(tag: DW_TAG_member, name: "__size", scope: !178, file: !64, line: 333, baseType: !204, size: 384) +!204 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 384, elements: !205) +!205 = !{!206} +!206 = !DISubrange(count: 48) +!207 = !DIDerivedType(tag: DW_TAG_member, name: "__align", scope: !178, file: !64, line: 334, baseType: !208, size: 64) +!208 = !DIBasicType(name: "long long", size: 64, encoding: DW_ATE_signed) +!209 = !DIGlobalVariableExpression(var: !210, expr: !DIExpression()) +!210 = distinct !DIGlobalVariable(name: "latest_thread", scope: !61, file: !2, line: 359, type: !211, isLocal: false, isDefinition: true) +!211 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_t", file: !64, line: 305, baseType: !212) +!212 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) +!213 = !DIGlobalVariableExpression(var: !214, expr: !DIExpression()) +!214 = distinct !DIGlobalVariable(name: "local_data", scope: !61, file: !2, line: 360, type: !215, isLocal: false, isDefinition: true) +!215 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_key_t", file: !64, line: 316, baseType: !65) +!216 = !{i32 7, !"Dwarf Version", i32 5} +!217 = !{i32 2, !"Debug Info Version", i32 3} +!218 = !{i32 1, !"wchar_size", i32 4} +!219 = !{i32 8, !"PIC Level", i32 2} +!220 = !{i32 7, !"PIE Level", i32 2} +!221 = !{i32 7, !"uwtable", i32 2} +!222 = !{i32 7, !"frame-pointer", i32 2} +!223 = !{!"Homebrew clang version 19.1.7"} +!224 = distinct !DISubprogram(name: "thread_create", scope: !2, file: !2, line: 12, type: !225, scopeLine: 13, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!225 = !DISubroutineType(types: !226) +!226 = !{!211, !227, !90} +!227 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !228, size: 64) +!228 = !DISubroutineType(types: !229) +!229 = !{!90, !90} +!230 = !{} +!231 = !DILocalVariable(name: "runner", arg: 1, scope: !224, file: !2, line: 12, type: !227) +!232 = !DILocation(line: 12, column: 32, scope: !224) +!233 = !DILocalVariable(name: "data", arg: 2, scope: !224, file: !2, line: 12, type: !90) +!234 = !DILocation(line: 12, column: 54, scope: !224) +!235 = !DILocalVariable(name: "id", scope: !224, file: !2, line: 14, type: !211) +!236 = !DILocation(line: 14, column: 15, scope: !224) +!237 = !DILocalVariable(name: "attr", scope: !224, file: !2, line: 15, type: !238) +!238 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_attr_t", file: !64, line: 323, baseType: !239) +!239 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "pthread_attr_t", file: !64, line: 318, size: 320, elements: !240) +!240 = !{!241, !245} +!241 = !DIDerivedType(tag: DW_TAG_member, name: "__size", scope: !239, file: !64, line: 320, baseType: !242, size: 288) +!242 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 288, elements: !243) +!243 = !{!244} +!244 = !DISubrange(count: 36) +!245 = !DIDerivedType(tag: DW_TAG_member, name: "__align", scope: !239, file: !64, line: 321, baseType: !174, size: 64) +!246 = !DILocation(line: 15, column: 20, scope: !224) +!247 = !DILocation(line: 16, column: 5, scope: !224) +!248 = !DILocalVariable(name: "status", scope: !224, file: !2, line: 17, type: !149) +!249 = !DILocation(line: 17, column: 9, scope: !224) +!250 = !DILocation(line: 17, column: 45, scope: !224) +!251 = !DILocation(line: 17, column: 53, scope: !224) +!252 = !DILocation(line: 17, column: 18, scope: !224) +!253 = !DILocation(line: 18, column: 5, scope: !224) +!254 = !DILocation(line: 19, column: 5, scope: !224) +!255 = !DILocation(line: 20, column: 12, scope: !224) +!256 = !DILocation(line: 20, column: 5, scope: !224) +!257 = distinct !DISubprogram(name: "thread_join", scope: !2, file: !2, line: 23, type: !258, scopeLine: 24, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!258 = !DISubroutineType(types: !259) +!259 = !{!90, !211} +!260 = !DILocalVariable(name: "id", arg: 1, scope: !257, file: !2, line: 23, type: !211) +!261 = !DILocation(line: 23, column: 29, scope: !257) +!262 = !DILocalVariable(name: "result", scope: !257, file: !2, line: 25, type: !90) +!263 = !DILocation(line: 25, column: 11, scope: !257) +!264 = !DILocalVariable(name: "status", scope: !257, file: !2, line: 26, type: !149) +!265 = !DILocation(line: 26, column: 9, scope: !257) +!266 = !DILocation(line: 26, column: 31, scope: !257) +!267 = !DILocation(line: 26, column: 18, scope: !257) +!268 = !DILocation(line: 27, column: 5, scope: !257) +!269 = !DILocation(line: 28, column: 12, scope: !257) +!270 = !DILocation(line: 28, column: 5, scope: !257) +!271 = distinct !DISubprogram(name: "mutex_init", scope: !2, file: !2, line: 41, type: !272, scopeLine: 42, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!272 = !DISubroutineType(types: !273) +!273 = !{null, !274, !149, !149, !149} +!274 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !142, size: 64) +!275 = !DILocalVariable(name: "lock", arg: 1, scope: !271, file: !2, line: 41, type: !274) +!276 = !DILocation(line: 41, column: 34, scope: !271) +!277 = !DILocalVariable(name: "type", arg: 2, scope: !271, file: !2, line: 41, type: !149) +!278 = !DILocation(line: 41, column: 44, scope: !271) +!279 = !DILocalVariable(name: "protocol", arg: 3, scope: !271, file: !2, line: 41, type: !149) +!280 = !DILocation(line: 41, column: 54, scope: !271) +!281 = !DILocalVariable(name: "prioceiling", arg: 4, scope: !271, file: !2, line: 41, type: !149) +!282 = !DILocation(line: 41, column: 68, scope: !271) +!283 = !DILocalVariable(name: "status", scope: !271, file: !2, line: 43, type: !149) +!284 = !DILocation(line: 43, column: 9, scope: !271) +!285 = !DILocalVariable(name: "value", scope: !271, file: !2, line: 44, type: !149) +!286 = !DILocation(line: 44, column: 9, scope: !271) +!287 = !DILocalVariable(name: "attributes", scope: !271, file: !2, line: 45, type: !288) +!288 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_mutexattr_t", file: !64, line: 310, baseType: !289) +!289 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !64, line: 306, size: 32, elements: !290) +!290 = !{!291, !295} +!291 = !DIDerivedType(tag: DW_TAG_member, name: "__size", scope: !289, file: !64, line: 308, baseType: !292, size: 32) +!292 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 32, elements: !293) +!293 = !{!294} +!294 = !DISubrange(count: 4) +!295 = !DIDerivedType(tag: DW_TAG_member, name: "__align", scope: !289, file: !64, line: 309, baseType: !149, size: 32) +!296 = !DILocation(line: 45, column: 25, scope: !271) +!297 = !DILocation(line: 46, column: 14, scope: !271) +!298 = !DILocation(line: 46, column: 12, scope: !271) +!299 = !DILocation(line: 47, column: 5, scope: !271) +!300 = !DILocation(line: 49, column: 53, scope: !271) +!301 = !DILocation(line: 49, column: 14, scope: !271) +!302 = !DILocation(line: 49, column: 12, scope: !271) +!303 = !DILocation(line: 50, column: 5, scope: !271) +!304 = !DILocation(line: 51, column: 14, scope: !271) +!305 = !DILocation(line: 51, column: 12, scope: !271) +!306 = !DILocation(line: 52, column: 5, scope: !271) +!307 = !DILocation(line: 54, column: 57, scope: !271) +!308 = !DILocation(line: 54, column: 14, scope: !271) +!309 = !DILocation(line: 54, column: 12, scope: !271) +!310 = !DILocation(line: 55, column: 5, scope: !271) +!311 = !DILocation(line: 56, column: 14, scope: !271) +!312 = !DILocation(line: 56, column: 12, scope: !271) +!313 = !DILocation(line: 57, column: 5, scope: !271) +!314 = !DILocation(line: 59, column: 60, scope: !271) +!315 = !DILocation(line: 59, column: 14, scope: !271) +!316 = !DILocation(line: 59, column: 12, scope: !271) +!317 = !DILocation(line: 60, column: 5, scope: !271) +!318 = !DILocation(line: 61, column: 14, scope: !271) +!319 = !DILocation(line: 61, column: 12, scope: !271) +!320 = !DILocation(line: 62, column: 5, scope: !271) +!321 = !DILocation(line: 64, column: 33, scope: !271) +!322 = !DILocation(line: 64, column: 14, scope: !271) +!323 = !DILocation(line: 64, column: 12, scope: !271) +!324 = !DILocation(line: 65, column: 5, scope: !271) +!325 = !DILocation(line: 66, column: 14, scope: !271) +!326 = !DILocation(line: 66, column: 12, scope: !271) +!327 = !DILocation(line: 67, column: 5, scope: !271) +!328 = !DILocation(line: 68, column: 1, scope: !271) +!329 = distinct !DISubprogram(name: "mutex_destroy", scope: !2, file: !2, line: 70, type: !330, scopeLine: 71, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!330 = !DISubroutineType(types: !331) +!331 = !{null, !274} +!332 = !DILocalVariable(name: "lock", arg: 1, scope: !329, file: !2, line: 70, type: !274) +!333 = !DILocation(line: 70, column: 37, scope: !329) +!334 = !DILocalVariable(name: "status", scope: !329, file: !2, line: 72, type: !149) +!335 = !DILocation(line: 72, column: 9, scope: !329) +!336 = !DILocation(line: 72, column: 40, scope: !329) +!337 = !DILocation(line: 72, column: 18, scope: !329) +!338 = !DILocation(line: 73, column: 5, scope: !329) +!339 = !DILocation(line: 74, column: 1, scope: !329) +!340 = distinct !DISubprogram(name: "mutex_lock", scope: !2, file: !2, line: 76, type: !330, scopeLine: 77, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!341 = !DILocalVariable(name: "lock", arg: 1, scope: !340, file: !2, line: 76, type: !274) +!342 = !DILocation(line: 76, column: 34, scope: !340) +!343 = !DILocalVariable(name: "status", scope: !340, file: !2, line: 78, type: !149) +!344 = !DILocation(line: 78, column: 9, scope: !340) +!345 = !DILocation(line: 78, column: 37, scope: !340) +!346 = !DILocation(line: 78, column: 18, scope: !340) +!347 = !DILocation(line: 79, column: 5, scope: !340) +!348 = !DILocation(line: 80, column: 1, scope: !340) +!349 = distinct !DISubprogram(name: "mutex_trylock", scope: !2, file: !2, line: 82, type: !350, scopeLine: 83, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!350 = !DISubroutineType(types: !351) +!351 = !{!352, !274} +!352 = !DIBasicType(name: "_Bool", size: 8, encoding: DW_ATE_boolean) +!353 = !DILocalVariable(name: "lock", arg: 1, scope: !349, file: !2, line: 82, type: !274) +!354 = !DILocation(line: 82, column: 37, scope: !349) +!355 = !DILocalVariable(name: "status", scope: !349, file: !2, line: 84, type: !149) +!356 = !DILocation(line: 84, column: 9, scope: !349) +!357 = !DILocation(line: 84, column: 40, scope: !349) +!358 = !DILocation(line: 84, column: 18, scope: !349) +!359 = !DILocation(line: 86, column: 12, scope: !349) +!360 = !DILocation(line: 86, column: 19, scope: !349) +!361 = !DILocation(line: 86, column: 5, scope: !349) +!362 = distinct !DISubprogram(name: "mutex_unlock", scope: !2, file: !2, line: 89, type: !330, scopeLine: 90, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!363 = !DILocalVariable(name: "lock", arg: 1, scope: !362, file: !2, line: 89, type: !274) +!364 = !DILocation(line: 89, column: 36, scope: !362) +!365 = !DILocalVariable(name: "status", scope: !362, file: !2, line: 91, type: !149) +!366 = !DILocation(line: 91, column: 9, scope: !362) +!367 = !DILocation(line: 91, column: 39, scope: !362) +!368 = !DILocation(line: 91, column: 18, scope: !362) +!369 = !DILocation(line: 92, column: 5, scope: !362) +!370 = !DILocation(line: 93, column: 1, scope: !362) +!371 = distinct !DISubprogram(name: "mutex_test", scope: !2, file: !2, line: 95, type: !372, scopeLine: 96, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!372 = !DISubroutineType(types: !373) +!373 = !{null} +!374 = !DILocalVariable(name: "mutex0", scope: !371, file: !2, line: 97, type: !142) +!375 = !DILocation(line: 97, column: 21, scope: !371) +!376 = !DILocalVariable(name: "mutex1", scope: !371, file: !2, line: 98, type: !142) +!377 = !DILocation(line: 98, column: 21, scope: !371) +!378 = !DILocation(line: 100, column: 5, scope: !371) +!379 = !DILocation(line: 101, column: 5, scope: !371) +!380 = !DILocation(line: 104, column: 9, scope: !381) +!381 = distinct !DILexicalBlock(scope: !371, file: !2, line: 103, column: 5) +!382 = !DILocalVariable(name: "success", scope: !381, file: !2, line: 105, type: !352) +!383 = !DILocation(line: 105, column: 14, scope: !381) +!384 = !DILocation(line: 105, column: 24, scope: !381) +!385 = !DILocation(line: 106, column: 9, scope: !381) +!386 = !DILocation(line: 107, column: 9, scope: !381) +!387 = !DILocation(line: 111, column: 9, scope: !388) +!388 = distinct !DILexicalBlock(scope: !371, file: !2, line: 110, column: 5) +!389 = !DILocalVariable(name: "success", scope: !390, file: !2, line: 114, type: !352) +!390 = distinct !DILexicalBlock(scope: !388, file: !2, line: 113, column: 9) +!391 = !DILocation(line: 114, column: 18, scope: !390) +!392 = !DILocation(line: 114, column: 28, scope: !390) +!393 = !DILocation(line: 115, column: 13, scope: !390) +!394 = !DILocation(line: 116, column: 13, scope: !390) +!395 = !DILocalVariable(name: "success", scope: !396, file: !2, line: 120, type: !352) +!396 = distinct !DILexicalBlock(scope: !388, file: !2, line: 119, column: 9) +!397 = !DILocation(line: 120, column: 18, scope: !396) +!398 = !DILocation(line: 120, column: 28, scope: !396) +!399 = !DILocation(line: 121, column: 13, scope: !396) +!400 = !DILocation(line: 122, column: 13, scope: !396) +!401 = !DILocation(line: 132, column: 9, scope: !388) +!402 = !DILocation(line: 135, column: 5, scope: !371) +!403 = !DILocation(line: 136, column: 5, scope: !371) +!404 = !DILocation(line: 137, column: 1, scope: !371) +!405 = distinct !DISubprogram(name: "cond_init", scope: !2, file: !2, line: 141, type: !406, scopeLine: 142, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!406 = !DISubroutineType(types: !407) +!407 = !{null, !408} +!408 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !177, size: 64) +!409 = !DILocalVariable(name: "cond", arg: 1, scope: !405, file: !2, line: 141, type: !408) +!410 = !DILocation(line: 141, column: 32, scope: !405) +!411 = !DILocalVariable(name: "status", scope: !405, file: !2, line: 143, type: !149) +!412 = !DILocation(line: 143, column: 9, scope: !405) +!413 = !DILocalVariable(name: "attr", scope: !405, file: !2, line: 144, type: !414) +!414 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_condattr_t", file: !64, line: 315, baseType: !415) +!415 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !64, line: 311, size: 32, elements: !416) +!416 = !{!417, !418} +!417 = !DIDerivedType(tag: DW_TAG_member, name: "__size", scope: !415, file: !64, line: 313, baseType: !292, size: 32) +!418 = !DIDerivedType(tag: DW_TAG_member, name: "__align", scope: !415, file: !64, line: 314, baseType: !149, size: 32) +!419 = !DILocation(line: 144, column: 24, scope: !405) +!420 = !DILocation(line: 146, column: 14, scope: !405) +!421 = !DILocation(line: 146, column: 12, scope: !405) +!422 = !DILocation(line: 147, column: 5, scope: !405) +!423 = !DILocation(line: 149, column: 32, scope: !405) +!424 = !DILocation(line: 149, column: 14, scope: !405) +!425 = !DILocation(line: 149, column: 12, scope: !405) +!426 = !DILocation(line: 150, column: 5, scope: !405) +!427 = !DILocation(line: 152, column: 14, scope: !405) +!428 = !DILocation(line: 152, column: 12, scope: !405) +!429 = !DILocation(line: 153, column: 5, scope: !405) +!430 = !DILocation(line: 154, column: 1, scope: !405) +!431 = distinct !DISubprogram(name: "cond_destroy", scope: !2, file: !2, line: 156, type: !406, scopeLine: 157, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!432 = !DILocalVariable(name: "cond", arg: 1, scope: !431, file: !2, line: 156, type: !408) +!433 = !DILocation(line: 156, column: 35, scope: !431) +!434 = !DILocalVariable(name: "status", scope: !431, file: !2, line: 158, type: !149) +!435 = !DILocation(line: 158, column: 9, scope: !431) +!436 = !DILocation(line: 158, column: 39, scope: !431) +!437 = !DILocation(line: 158, column: 18, scope: !431) +!438 = !DILocation(line: 159, column: 5, scope: !431) +!439 = !DILocation(line: 160, column: 1, scope: !431) +!440 = distinct !DISubprogram(name: "cond_signal", scope: !2, file: !2, line: 162, type: !406, scopeLine: 163, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!441 = !DILocalVariable(name: "cond", arg: 1, scope: !440, file: !2, line: 162, type: !408) +!442 = !DILocation(line: 162, column: 34, scope: !440) +!443 = !DILocalVariable(name: "status", scope: !440, file: !2, line: 164, type: !149) +!444 = !DILocation(line: 164, column: 9, scope: !440) +!445 = !DILocation(line: 164, column: 38, scope: !440) +!446 = !DILocation(line: 164, column: 18, scope: !440) +!447 = !DILocation(line: 165, column: 5, scope: !440) +!448 = !DILocation(line: 166, column: 1, scope: !440) +!449 = distinct !DISubprogram(name: "cond_broadcast", scope: !2, file: !2, line: 168, type: !406, scopeLine: 169, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!450 = !DILocalVariable(name: "cond", arg: 1, scope: !449, file: !2, line: 168, type: !408) +!451 = !DILocation(line: 168, column: 37, scope: !449) +!452 = !DILocalVariable(name: "status", scope: !449, file: !2, line: 170, type: !149) +!453 = !DILocation(line: 170, column: 9, scope: !449) +!454 = !DILocation(line: 170, column: 41, scope: !449) +!455 = !DILocation(line: 170, column: 18, scope: !449) +!456 = !DILocation(line: 171, column: 5, scope: !449) +!457 = !DILocation(line: 172, column: 1, scope: !449) +!458 = distinct !DISubprogram(name: "cond_wait", scope: !2, file: !2, line: 174, type: !459, scopeLine: 175, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!459 = !DISubroutineType(types: !460) +!460 = !{null, !408, !274} +!461 = !DILocalVariable(name: "cond", arg: 1, scope: !458, file: !2, line: 174, type: !408) +!462 = !DILocation(line: 174, column: 32, scope: !458) +!463 = !DILocalVariable(name: "lock", arg: 2, scope: !458, file: !2, line: 174, type: !274) +!464 = !DILocation(line: 174, column: 55, scope: !458) +!465 = !DILocalVariable(name: "status", scope: !458, file: !2, line: 176, type: !149) +!466 = !DILocation(line: 176, column: 9, scope: !458) +!467 = !DILocation(line: 176, column: 36, scope: !458) +!468 = !DILocation(line: 176, column: 42, scope: !458) +!469 = !DILocation(line: 176, column: 18, scope: !458) +!470 = !DILocation(line: 178, column: 1, scope: !458) +!471 = distinct !DISubprogram(name: "cond_timedwait", scope: !2, file: !2, line: 180, type: !472, scopeLine: 181, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!472 = !DISubroutineType(types: !473) +!473 = !{null, !408, !274, !208} +!474 = !DILocalVariable(name: "cond", arg: 1, scope: !471, file: !2, line: 180, type: !408) +!475 = !DILocation(line: 180, column: 37, scope: !471) +!476 = !DILocalVariable(name: "lock", arg: 2, scope: !471, file: !2, line: 180, type: !274) +!477 = !DILocation(line: 180, column: 60, scope: !471) +!478 = !DILocalVariable(name: "millis", arg: 3, scope: !471, file: !2, line: 180, type: !208) +!479 = !DILocation(line: 180, column: 76, scope: !471) +!480 = !DILocalVariable(name: "ts", scope: !471, file: !2, line: 183, type: !481) +!481 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "timespec", file: !64, line: 212, size: 128, elements: !482) +!482 = !{!483, !485} +!483 = !DIDerivedType(tag: DW_TAG_member, name: "tv_sec", scope: !481, file: !64, line: 214, baseType: !484, size: 64) +!484 = !DIDerivedType(tag: DW_TAG_typedef, name: "__time_t", file: !64, line: 108, baseType: !174) +!485 = !DIDerivedType(tag: DW_TAG_member, name: "tv_nsec", scope: !481, file: !64, line: 215, baseType: !486, size: 64, offset: 64) +!486 = !DIDerivedType(tag: DW_TAG_typedef, name: "__syscall_slong_t", file: !64, line: 125, baseType: !174) +!487 = !DILocation(line: 183, column: 21, scope: !471) +!488 = !DILocation(line: 187, column: 11, scope: !471) +!489 = !DILocalVariable(name: "status", scope: !471, file: !2, line: 188, type: !149) +!490 = !DILocation(line: 188, column: 9, scope: !471) +!491 = !DILocation(line: 188, column: 41, scope: !471) +!492 = !DILocation(line: 188, column: 47, scope: !471) +!493 = !DILocation(line: 188, column: 18, scope: !471) +!494 = !DILocation(line: 189, column: 1, scope: !471) +!495 = distinct !DISubprogram(name: "cond_worker", scope: !2, file: !2, line: 195, type: !228, scopeLine: 196, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!496 = !DILocalVariable(name: "message", arg: 1, scope: !495, file: !2, line: 195, type: !90) +!497 = !DILocation(line: 195, column: 25, scope: !495) +!498 = !DILocalVariable(name: "idle", scope: !495, file: !2, line: 197, type: !352) +!499 = !DILocation(line: 197, column: 10, scope: !495) +!500 = !DILocation(line: 199, column: 9, scope: !501) +!501 = distinct !DILexicalBlock(scope: !495, file: !2, line: 198, column: 5) +!502 = !DILocation(line: 200, column: 9, scope: !501) +!503 = !DILocation(line: 201, column: 9, scope: !501) +!504 = !DILocation(line: 202, column: 9, scope: !501) +!505 = !DILocation(line: 203, column: 16, scope: !501) +!506 = !DILocation(line: 203, column: 22, scope: !501) +!507 = !DILocation(line: 203, column: 14, scope: !501) +!508 = !DILocation(line: 204, column: 9, scope: !501) +!509 = !DILocation(line: 206, column: 9, scope: !510) +!510 = distinct !DILexicalBlock(scope: !495, file: !2, line: 206, column: 9) +!511 = !DILocation(line: 206, column: 9, scope: !495) +!512 = !DILocation(line: 207, column: 25, scope: !510) +!513 = !DILocation(line: 207, column: 34, scope: !510) +!514 = !DILocation(line: 207, column: 9, scope: !510) +!515 = !DILocation(line: 208, column: 10, scope: !495) +!516 = !DILocation(line: 210, column: 9, scope: !517) +!517 = distinct !DILexicalBlock(scope: !495, file: !2, line: 209, column: 5) +!518 = !DILocation(line: 211, column: 9, scope: !517) +!519 = !DILocation(line: 212, column: 9, scope: !517) +!520 = !DILocation(line: 213, column: 9, scope: !517) +!521 = !DILocation(line: 214, column: 16, scope: !517) +!522 = !DILocation(line: 214, column: 22, scope: !517) +!523 = !DILocation(line: 214, column: 14, scope: !517) +!524 = !DILocation(line: 215, column: 9, scope: !517) +!525 = !DILocation(line: 217, column: 9, scope: !526) +!526 = distinct !DILexicalBlock(scope: !495, file: !2, line: 217, column: 9) +!527 = !DILocation(line: 217, column: 9, scope: !495) +!528 = !DILocation(line: 218, column: 25, scope: !526) +!529 = !DILocation(line: 218, column: 34, scope: !526) +!530 = !DILocation(line: 218, column: 9, scope: !526) +!531 = !DILocation(line: 219, column: 12, scope: !495) +!532 = !DILocation(line: 219, column: 5, scope: !495) +!533 = !DILocation(line: 220, column: 1, scope: !495) +!534 = distinct !DISubprogram(name: "cond_test", scope: !2, file: !2, line: 222, type: !372, scopeLine: 223, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!535 = !DILocalVariable(name: "message", scope: !534, file: !2, line: 224, type: !90) +!536 = !DILocation(line: 224, column: 11, scope: !534) +!537 = !DILocation(line: 225, column: 5, scope: !534) +!538 = !DILocation(line: 226, column: 5, scope: !534) +!539 = !DILocalVariable(name: "worker", scope: !534, file: !2, line: 228, type: !211) +!540 = !DILocation(line: 228, column: 15, scope: !534) +!541 = !DILocation(line: 228, column: 51, scope: !534) +!542 = !DILocation(line: 228, column: 24, scope: !534) +!543 = !DILocation(line: 231, column: 9, scope: !544) +!544 = distinct !DILexicalBlock(scope: !534, file: !2, line: 230, column: 5) +!545 = !DILocation(line: 232, column: 9, scope: !544) +!546 = !DILocation(line: 233, column: 9, scope: !544) +!547 = !DILocation(line: 234, column: 9, scope: !544) +!548 = !DILocation(line: 238, column: 9, scope: !549) +!549 = distinct !DILexicalBlock(scope: !534, file: !2, line: 237, column: 5) +!550 = !DILocation(line: 239, column: 9, scope: !549) +!551 = !DILocation(line: 240, column: 9, scope: !549) +!552 = !DILocation(line: 241, column: 9, scope: !549) +!553 = !DILocalVariable(name: "result", scope: !534, file: !2, line: 244, type: !90) +!554 = !DILocation(line: 244, column: 11, scope: !534) +!555 = !DILocation(line: 244, column: 32, scope: !534) +!556 = !DILocation(line: 244, column: 20, scope: !534) +!557 = !DILocation(line: 245, column: 5, scope: !534) +!558 = !DILocation(line: 247, column: 5, scope: !534) +!559 = !DILocation(line: 248, column: 5, scope: !534) +!560 = !DILocation(line: 249, column: 1, scope: !534) +!561 = distinct !DISubprogram(name: "rwlock_init", scope: !2, file: !2, line: 256, type: !562, scopeLine: 257, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!562 = !DISubroutineType(types: !563) +!563 = !{null, !564, !149} +!564 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !565, size: 64) +!565 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_rwlock_t", file: !64, line: 341, baseType: !566) +!566 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !64, line: 336, size: 256, elements: !567) +!567 = !{!568, !584, !588} +!568 = !DIDerivedType(tag: DW_TAG_member, name: "__data", scope: !566, file: !64, line: 338, baseType: !569, size: 256) +!569 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__pthread_rwlock_arch_t", file: !64, line: 275, size: 256, elements: !570) +!570 = !{!571, !572, !573, !574, !575, !576, !577, !579, !580, !582, !583} +!571 = !DIDerivedType(tag: DW_TAG_member, name: "__readers", scope: !569, file: !64, line: 277, baseType: !65, size: 32) +!572 = !DIDerivedType(tag: DW_TAG_member, name: "__writers", scope: !569, file: !64, line: 278, baseType: !65, size: 32, offset: 32) +!573 = !DIDerivedType(tag: DW_TAG_member, name: "__wrphase_futex", scope: !569, file: !64, line: 279, baseType: !65, size: 32, offset: 64) +!574 = !DIDerivedType(tag: DW_TAG_member, name: "__writers_futex", scope: !569, file: !64, line: 280, baseType: !65, size: 32, offset: 96) +!575 = !DIDerivedType(tag: DW_TAG_member, name: "__pad3", scope: !569, file: !64, line: 281, baseType: !65, size: 32, offset: 128) +!576 = !DIDerivedType(tag: DW_TAG_member, name: "__pad4", scope: !569, file: !64, line: 282, baseType: !65, size: 32, offset: 160) +!577 = !DIDerivedType(tag: DW_TAG_member, name: "__flags", scope: !569, file: !64, line: 283, baseType: !578, size: 8, offset: 192) +!578 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char) +!579 = !DIDerivedType(tag: DW_TAG_member, name: "__shared", scope: !569, file: !64, line: 284, baseType: !578, size: 8, offset: 200) +!580 = !DIDerivedType(tag: DW_TAG_member, name: "__rwelision", scope: !569, file: !64, line: 285, baseType: !581, size: 8, offset: 208) +!581 = !DIBasicType(name: "signed char", size: 8, encoding: DW_ATE_signed_char) +!582 = !DIDerivedType(tag: DW_TAG_member, name: "__pad2", scope: !569, file: !64, line: 286, baseType: !578, size: 8, offset: 216) +!583 = !DIDerivedType(tag: DW_TAG_member, name: "__cur_writer", scope: !569, file: !64, line: 287, baseType: !149, size: 32, offset: 224) +!584 = !DIDerivedType(tag: DW_TAG_member, name: "__size", scope: !566, file: !64, line: 339, baseType: !585, size: 256) +!585 = !DICompositeType(tag: DW_TAG_array_type, baseType: !5, size: 256, elements: !586) +!586 = !{!587} +!587 = !DISubrange(count: 32) +!588 = !DIDerivedType(tag: DW_TAG_member, name: "__align", scope: !566, file: !64, line: 340, baseType: !174, size: 64) +!589 = !DILocalVariable(name: "lock", arg: 1, scope: !561, file: !2, line: 256, type: !564) +!590 = !DILocation(line: 256, column: 36, scope: !561) +!591 = !DILocalVariable(name: "shared", arg: 2, scope: !561, file: !2, line: 256, type: !149) +!592 = !DILocation(line: 256, column: 46, scope: !561) +!593 = !DILocalVariable(name: "status", scope: !561, file: !2, line: 258, type: !149) +!594 = !DILocation(line: 258, column: 9, scope: !561) +!595 = !DILocalVariable(name: "value", scope: !561, file: !2, line: 259, type: !149) +!596 = !DILocation(line: 259, column: 9, scope: !561) +!597 = !DILocalVariable(name: "attributes", scope: !561, file: !2, line: 260, type: !598) +!598 = !DIDerivedType(tag: DW_TAG_typedef, name: "pthread_rwlockattr_t", file: !64, line: 346, baseType: !599) +!599 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !64, line: 342, size: 64, elements: !600) +!600 = !{!601, !602} +!601 = !DIDerivedType(tag: DW_TAG_member, name: "__size", scope: !599, file: !64, line: 344, baseType: !44, size: 64) +!602 = !DIDerivedType(tag: DW_TAG_member, name: "__align", scope: !599, file: !64, line: 345, baseType: !174, size: 64) +!603 = !DILocation(line: 260, column: 26, scope: !561) +!604 = !DILocation(line: 261, column: 14, scope: !561) +!605 = !DILocation(line: 261, column: 12, scope: !561) +!606 = !DILocation(line: 262, column: 5, scope: !561) +!607 = !DILocation(line: 264, column: 57, scope: !561) +!608 = !DILocation(line: 264, column: 14, scope: !561) +!609 = !DILocation(line: 264, column: 12, scope: !561) +!610 = !DILocation(line: 265, column: 5, scope: !561) +!611 = !DILocation(line: 266, column: 14, scope: !561) +!612 = !DILocation(line: 266, column: 12, scope: !561) +!613 = !DILocation(line: 267, column: 5, scope: !561) +!614 = !DILocation(line: 269, column: 34, scope: !561) +!615 = !DILocation(line: 269, column: 14, scope: !561) +!616 = !DILocation(line: 269, column: 12, scope: !561) +!617 = !DILocation(line: 270, column: 5, scope: !561) +!618 = !DILocation(line: 271, column: 14, scope: !561) +!619 = !DILocation(line: 271, column: 12, scope: !561) +!620 = !DILocation(line: 272, column: 5, scope: !561) +!621 = !DILocation(line: 273, column: 1, scope: !561) +!622 = distinct !DISubprogram(name: "rwlock_destroy", scope: !2, file: !2, line: 275, type: !623, scopeLine: 276, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!623 = !DISubroutineType(types: !624) +!624 = !{null, !564} +!625 = !DILocalVariable(name: "lock", arg: 1, scope: !622, file: !2, line: 275, type: !564) +!626 = !DILocation(line: 275, column: 39, scope: !622) +!627 = !DILocalVariable(name: "status", scope: !622, file: !2, line: 277, type: !149) +!628 = !DILocation(line: 277, column: 9, scope: !622) +!629 = !DILocation(line: 277, column: 41, scope: !622) +!630 = !DILocation(line: 277, column: 18, scope: !622) +!631 = !DILocation(line: 278, column: 5, scope: !622) +!632 = !DILocation(line: 279, column: 1, scope: !622) +!633 = distinct !DISubprogram(name: "rwlock_wrlock", scope: !2, file: !2, line: 281, type: !623, scopeLine: 282, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!634 = !DILocalVariable(name: "lock", arg: 1, scope: !633, file: !2, line: 281, type: !564) +!635 = !DILocation(line: 281, column: 38, scope: !633) +!636 = !DILocalVariable(name: "status", scope: !633, file: !2, line: 283, type: !149) +!637 = !DILocation(line: 283, column: 9, scope: !633) +!638 = !DILocation(line: 283, column: 40, scope: !633) +!639 = !DILocation(line: 283, column: 18, scope: !633) +!640 = !DILocation(line: 284, column: 5, scope: !633) +!641 = !DILocation(line: 285, column: 1, scope: !633) +!642 = distinct !DISubprogram(name: "rwlock_trywrlock", scope: !2, file: !2, line: 287, type: !643, scopeLine: 288, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!643 = !DISubroutineType(types: !644) +!644 = !{!352, !564} +!645 = !DILocalVariable(name: "lock", arg: 1, scope: !642, file: !2, line: 287, type: !564) +!646 = !DILocation(line: 287, column: 41, scope: !642) +!647 = !DILocalVariable(name: "status", scope: !642, file: !2, line: 289, type: !149) +!648 = !DILocation(line: 289, column: 9, scope: !642) +!649 = !DILocation(line: 289, column: 43, scope: !642) +!650 = !DILocation(line: 289, column: 18, scope: !642) +!651 = !DILocation(line: 291, column: 12, scope: !642) +!652 = !DILocation(line: 291, column: 19, scope: !642) +!653 = !DILocation(line: 291, column: 5, scope: !642) +!654 = distinct !DISubprogram(name: "rwlock_rdlock", scope: !2, file: !2, line: 294, type: !623, scopeLine: 295, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!655 = !DILocalVariable(name: "lock", arg: 1, scope: !654, file: !2, line: 294, type: !564) +!656 = !DILocation(line: 294, column: 38, scope: !654) +!657 = !DILocalVariable(name: "status", scope: !654, file: !2, line: 296, type: !149) +!658 = !DILocation(line: 296, column: 9, scope: !654) +!659 = !DILocation(line: 296, column: 40, scope: !654) +!660 = !DILocation(line: 296, column: 18, scope: !654) +!661 = !DILocation(line: 297, column: 5, scope: !654) +!662 = !DILocation(line: 298, column: 1, scope: !654) +!663 = distinct !DISubprogram(name: "rwlock_tryrdlock", scope: !2, file: !2, line: 300, type: !643, scopeLine: 301, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!664 = !DILocalVariable(name: "lock", arg: 1, scope: !663, file: !2, line: 300, type: !564) +!665 = !DILocation(line: 300, column: 41, scope: !663) +!666 = !DILocalVariable(name: "status", scope: !663, file: !2, line: 302, type: !149) +!667 = !DILocation(line: 302, column: 9, scope: !663) +!668 = !DILocation(line: 302, column: 43, scope: !663) +!669 = !DILocation(line: 302, column: 18, scope: !663) +!670 = !DILocation(line: 304, column: 12, scope: !663) +!671 = !DILocation(line: 304, column: 19, scope: !663) +!672 = !DILocation(line: 304, column: 5, scope: !663) +!673 = distinct !DISubprogram(name: "rwlock_unlock", scope: !2, file: !2, line: 307, type: !623, scopeLine: 308, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!674 = !DILocalVariable(name: "lock", arg: 1, scope: !673, file: !2, line: 307, type: !564) +!675 = !DILocation(line: 307, column: 38, scope: !673) +!676 = !DILocalVariable(name: "status", scope: !673, file: !2, line: 309, type: !149) +!677 = !DILocation(line: 309, column: 9, scope: !673) +!678 = !DILocation(line: 309, column: 40, scope: !673) +!679 = !DILocation(line: 309, column: 18, scope: !673) +!680 = !DILocation(line: 310, column: 5, scope: !673) +!681 = !DILocation(line: 311, column: 1, scope: !673) +!682 = distinct !DISubprogram(name: "rwlock_test", scope: !2, file: !2, line: 313, type: !372, scopeLine: 314, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!683 = !DILocalVariable(name: "lock", scope: !682, file: !2, line: 315, type: !565) +!684 = !DILocation(line: 315, column: 22, scope: !682) +!685 = !DILocation(line: 316, column: 5, scope: !682) +!686 = !DILocalVariable(name: "test_depth", scope: !682, file: !2, line: 317, type: !687) +!687 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !149) +!688 = !DILocation(line: 317, column: 15, scope: !682) +!689 = !DILocation(line: 320, column: 9, scope: !690) +!690 = distinct !DILexicalBlock(scope: !682, file: !2, line: 319, column: 5) +!691 = !DILocalVariable(name: "success", scope: !690, file: !2, line: 321, type: !352) +!692 = !DILocation(line: 321, column: 14, scope: !690) +!693 = !DILocation(line: 321, column: 24, scope: !690) +!694 = !DILocation(line: 322, column: 9, scope: !690) +!695 = !DILocation(line: 323, column: 19, scope: !690) +!696 = !DILocation(line: 323, column: 17, scope: !690) +!697 = !DILocation(line: 324, column: 9, scope: !690) +!698 = !DILocation(line: 325, column: 9, scope: !690) +!699 = !DILocation(line: 329, column: 9, scope: !700) +!700 = distinct !DILexicalBlock(scope: !682, file: !2, line: 328, column: 5) +!701 = !DILocalVariable(name: "i", scope: !702, file: !2, line: 330, type: !149) +!702 = distinct !DILexicalBlock(scope: !700, file: !2, line: 330, column: 9) +!703 = !DILocation(line: 330, column: 18, scope: !702) +!704 = !DILocation(line: 330, column: 14, scope: !702) +!705 = !DILocation(line: 330, column: 25, scope: !706) +!706 = distinct !DILexicalBlock(scope: !702, file: !2, line: 330, column: 9) +!707 = !DILocation(line: 330, column: 27, scope: !706) +!708 = !DILocation(line: 330, column: 9, scope: !702) +!709 = !DILocalVariable(name: "success", scope: !710, file: !2, line: 332, type: !352) +!710 = distinct !DILexicalBlock(scope: !706, file: !2, line: 331, column: 9) +!711 = !DILocation(line: 332, column: 18, scope: !710) +!712 = !DILocation(line: 332, column: 28, scope: !710) +!713 = !DILocation(line: 333, column: 13, scope: !710) +!714 = !DILocation(line: 334, column: 9, scope: !710) +!715 = !DILocation(line: 330, column: 42, scope: !706) +!716 = !DILocation(line: 330, column: 9, scope: !706) +!717 = distinct !{!717, !708, !718, !719} +!718 = !DILocation(line: 334, column: 9, scope: !702) +!719 = !{!"llvm.loop.mustprogress"} +!720 = !DILocalVariable(name: "success", scope: !721, file: !2, line: 337, type: !352) +!721 = distinct !DILexicalBlock(scope: !700, file: !2, line: 336, column: 9) +!722 = !DILocation(line: 337, column: 18, scope: !721) +!723 = !DILocation(line: 337, column: 28, scope: !721) +!724 = !DILocation(line: 338, column: 13, scope: !721) +!725 = !DILocation(line: 341, column: 9, scope: !700) +!726 = !DILocalVariable(name: "i", scope: !727, file: !2, line: 342, type: !149) +!727 = distinct !DILexicalBlock(scope: !700, file: !2, line: 342, column: 9) +!728 = !DILocation(line: 342, column: 18, scope: !727) +!729 = !DILocation(line: 342, column: 14, scope: !727) +!730 = !DILocation(line: 342, column: 25, scope: !731) +!731 = distinct !DILexicalBlock(scope: !727, file: !2, line: 342, column: 9) +!732 = !DILocation(line: 342, column: 27, scope: !731) +!733 = !DILocation(line: 342, column: 9, scope: !727) +!734 = !DILocation(line: 343, column: 13, scope: !735) +!735 = distinct !DILexicalBlock(scope: !731, file: !2, line: 342, column: 46) +!736 = !DILocation(line: 344, column: 9, scope: !735) +!737 = !DILocation(line: 342, column: 42, scope: !731) +!738 = !DILocation(line: 342, column: 9, scope: !731) +!739 = distinct !{!739, !733, !740, !719} +!740 = !DILocation(line: 344, column: 9, scope: !727) +!741 = !DILocation(line: 348, column: 9, scope: !742) +!742 = distinct !DILexicalBlock(scope: !682, file: !2, line: 347, column: 5) +!743 = !DILocalVariable(name: "success", scope: !742, file: !2, line: 349, type: !352) +!744 = !DILocation(line: 349, column: 14, scope: !742) +!745 = !DILocation(line: 349, column: 24, scope: !742) +!746 = !DILocation(line: 350, column: 9, scope: !742) +!747 = !DILocation(line: 351, column: 9, scope: !742) +!748 = !DILocation(line: 354, column: 5, scope: !682) +!749 = !DILocation(line: 355, column: 1, scope: !682) +!750 = distinct !DISubprogram(name: "key_destroy", scope: !2, file: !2, line: 362, type: !751, scopeLine: 363, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!751 = !DISubroutineType(types: !752) +!752 = !{null, !90} +!753 = !DILocalVariable(name: "unused_value", arg: 1, scope: !750, file: !2, line: 362, type: !90) +!754 = !DILocation(line: 362, column: 24, scope: !750) +!755 = !DILocation(line: 364, column: 21, scope: !750) +!756 = !DILocation(line: 364, column: 19, scope: !750) +!757 = !DILocation(line: 365, column: 1, scope: !750) +!758 = distinct !DISubprogram(name: "key_worker", scope: !2, file: !2, line: 367, type: !228, scopeLine: 368, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!759 = !DILocalVariable(name: "message", arg: 1, scope: !758, file: !2, line: 367, type: !90) +!760 = !DILocation(line: 367, column: 24, scope: !758) +!761 = !DILocalVariable(name: "my_secret", scope: !758, file: !2, line: 369, type: !149) +!762 = !DILocation(line: 369, column: 9, scope: !758) +!763 = !DILocalVariable(name: "status", scope: !758, file: !2, line: 371, type: !149) +!764 = !DILocation(line: 371, column: 9, scope: !758) +!765 = !DILocation(line: 371, column: 38, scope: !758) +!766 = !DILocation(line: 371, column: 18, scope: !758) +!767 = !DILocation(line: 372, column: 5, scope: !758) +!768 = !DILocalVariable(name: "my_local_data", scope: !758, file: !2, line: 374, type: !90) +!769 = !DILocation(line: 374, column: 11, scope: !758) +!770 = !DILocation(line: 374, column: 47, scope: !758) +!771 = !DILocation(line: 374, column: 27, scope: !758) +!772 = !DILocation(line: 375, column: 5, scope: !758) +!773 = !DILocation(line: 377, column: 12, scope: !758) +!774 = !DILocation(line: 377, column: 5, scope: !758) +!775 = distinct !DISubprogram(name: "key_test", scope: !2, file: !2, line: 380, type: !372, scopeLine: 381, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!776 = !DILocalVariable(name: "my_secret", scope: !775, file: !2, line: 382, type: !149) +!777 = !DILocation(line: 382, column: 9, scope: !775) +!778 = !DILocalVariable(name: "message", scope: !775, file: !2, line: 383, type: !90) +!779 = !DILocation(line: 383, column: 11, scope: !775) +!780 = !DILocalVariable(name: "status", scope: !775, file: !2, line: 384, type: !149) +!781 = !DILocation(line: 384, column: 9, scope: !775) +!782 = !DILocation(line: 386, column: 5, scope: !775) +!783 = !DILocalVariable(name: "worker", scope: !775, file: !2, line: 388, type: !211) +!784 = !DILocation(line: 388, column: 15, scope: !775) +!785 = !DILocation(line: 388, column: 50, scope: !775) +!786 = !DILocation(line: 388, column: 24, scope: !775) +!787 = !DILocation(line: 390, column: 34, scope: !775) +!788 = !DILocation(line: 390, column: 14, scope: !775) +!789 = !DILocation(line: 390, column: 12, scope: !775) +!790 = !DILocation(line: 391, column: 5, scope: !775) +!791 = !DILocalVariable(name: "my_local_data", scope: !775, file: !2, line: 393, type: !90) +!792 = !DILocation(line: 393, column: 11, scope: !775) +!793 = !DILocation(line: 393, column: 47, scope: !775) +!794 = !DILocation(line: 393, column: 27, scope: !775) +!795 = !DILocation(line: 394, column: 5, scope: !775) +!796 = !DILocation(line: 396, column: 34, scope: !775) +!797 = !DILocation(line: 396, column: 14, scope: !775) +!798 = !DILocation(line: 396, column: 12, scope: !775) +!799 = !DILocation(line: 397, column: 5, scope: !775) +!800 = !DILocalVariable(name: "result", scope: !775, file: !2, line: 399, type: !90) +!801 = !DILocation(line: 399, column: 11, scope: !775) +!802 = !DILocation(line: 399, column: 32, scope: !775) +!803 = !DILocation(line: 399, column: 20, scope: !775) +!804 = !DILocation(line: 400, column: 5, scope: !775) +!805 = !DILocation(line: 402, column: 33, scope: !775) +!806 = !DILocation(line: 402, column: 14, scope: !775) +!807 = !DILocation(line: 402, column: 12, scope: !775) +!808 = !DILocation(line: 403, column: 5, scope: !775) +!809 = !DILocation(line: 406, column: 1, scope: !775) +!810 = distinct !DISubprogram(name: "detach_test_worker0", scope: !2, file: !2, line: 410, type: !228, scopeLine: 411, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!811 = !DILocalVariable(name: "ignore", arg: 1, scope: !810, file: !2, line: 410, type: !90) +!812 = !DILocation(line: 410, column: 33, scope: !810) +!813 = !DILocation(line: 412, column: 5, scope: !810) +!814 = distinct !DISubprogram(name: "detach_test_detach", scope: !2, file: !2, line: 415, type: !228, scopeLine: 416, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!815 = !DILocalVariable(name: "ignore", arg: 1, scope: !814, file: !2, line: 415, type: !90) +!816 = !DILocation(line: 415, column: 32, scope: !814) +!817 = !DILocalVariable(name: "status", scope: !814, file: !2, line: 417, type: !149) +!818 = !DILocation(line: 417, column: 9, scope: !814) +!819 = !DILocalVariable(name: "w0", scope: !814, file: !2, line: 418, type: !211) +!820 = !DILocation(line: 418, column: 15, scope: !814) +!821 = !DILocation(line: 418, column: 20, scope: !814) +!822 = !DILocation(line: 419, column: 29, scope: !814) +!823 = !DILocation(line: 419, column: 14, scope: !814) +!824 = !DILocation(line: 419, column: 12, scope: !814) +!825 = !DILocation(line: 420, column: 5, scope: !814) +!826 = !DILocation(line: 422, column: 27, scope: !814) +!827 = !DILocation(line: 422, column: 14, scope: !814) +!828 = !DILocation(line: 422, column: 12, scope: !814) +!829 = !DILocation(line: 423, column: 5, scope: !814) +!830 = !DILocation(line: 424, column: 5, scope: !814) +!831 = distinct !DISubprogram(name: "detach_test_attr", scope: !2, file: !2, line: 427, type: !228, scopeLine: 428, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !61, retainedNodes: !230) +!832 = !DILocalVariable(name: "ignore", arg: 1, scope: !831, file: !2, line: 427, type: !90) +!833 = !DILocation(line: 427, column: 30, scope: !831) +!834 = !DILocalVariable(name: "status", scope: !831, file: !2, line: 429, type: !149) +!835 = !DILocation(line: 429, column: 9, scope: !831) +!836 = !DILocalVariable(name: "detachstate", scope: !831, file: !2, line: 430, type: !149) +!837 = !DILocation(line: 430, column: 9, scope: !831) +!838 = !DILocalVariable(name: "w0", scope: !831, file: !2, line: 431, type: !211) +!839 = !DILocation(line: 431, column: 15, scope: !831) +!840 = !DILocalVariable(name: "w0_attr", scope: !831, file: !2, line: 432, type: !238) +!841 = !DILocation(line: 432, column: 20, scope: !831) +!842 = !DILocation(line: 433, column: 14, scope: !831) +!843 = !DILocation(line: 433, column: 12, scope: !831) +!844 = !DILocation(line: 434, column: 5, scope: !831) +!845 = !DILocation(line: 435, column: 14, scope: !831) +!846 = !DILocation(line: 435, column: 12, scope: !831) +!847 = !DILocation(line: 436, column: 5, scope: !831) +!848 = !DILocation(line: 0, scope: !831) +!849 = !DILocation(line: 437, column: 14, scope: !831) +!850 = !DILocation(line: 437, column: 12, scope: !831) +!851 = !DILocation(line: 438, column: 5, scope: !831) +!852 = !DILocation(line: 439, column: 14, scope: !831) +!853 = !DILocation(line: 439, column: 12, scope: !831) +!854 = !DILocation(line: 440, column: 5, scope: !831) +!855 = !DILocation(line: 441, column: 14, scope: !831) +!856 = !DILocation(line: 441, column: 12, scope: !831) +!857 = !DILocation(line: 442, column: 5, scope: !831) +!858 = !DILocation(line: 443, column: 5, scope: !831) +!859 = !DILocation(line: 445, column: 27, scope: !831) +!860 = !DILocation(line: 445, column: 14, scope: !831) +!861 = !DILocation(line: 445, column: 12, scope: !831) +!862 = !DILocation(line: 446, column: 5, scope: !831) +!863 = !DILocation(line: 447, column: 5, scope: !831) +!864 = distinct !DISubprogram(name: "detach_test", scope: !2, file: !2, line: 450, type: !372, scopeLine: 451, spFlags: DISPFlagDefinition, unit: !61) +!865 = !DILocation(line: 452, column: 5, scope: !864) +!866 = !DILocation(line: 453, column: 5, scope: !864) +!867 = !DILocation(line: 454, column: 1, scope: !864) +!868 = distinct !DISubprogram(name: "main", scope: !2, file: !2, line: 456, type: !869, scopeLine: 457, spFlags: DISPFlagDefinition, unit: !61) +!869 = !DISubroutineType(types: !870) +!870 = !{!149} +!871 = !DILocation(line: 458, column: 5, scope: !868) +!872 = !DILocation(line: 459, column: 5, scope: !868) +!873 = !DILocation(line: 460, column: 5, scope: !868) +!874 = !DILocation(line: 461, column: 5, scope: !868) +!875 = !DILocation(line: 462, column: 5, scope: !868) +!876 = !DILocation(line: 463, column: 1, scope: !868)