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/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 1d9064b9b1..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 @@ -54,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() { @@ -111,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) { @@ -172,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); } 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 6344d5221c..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 @@ -44,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); } 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/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/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 284d09bde2..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 @@ -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), @@ -1065,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(); 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/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/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/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}