From 86788c02941970b097284440d273b8ac7c38096d Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Thu, 2 Jul 2026 16:37:16 +1000 Subject: [PATCH 1/8] Add sliced MTA coverage tests --- CMakeLists.txt | 17 + generate_bc.sh | 3 +- src/sliced_mta/smoke1_basic.c | 41 + src/sliced_mta/smoke2_interproc.c | 45 + src/sliced_mta/smoke3_rich_races.c | 90 + src/sliced_mta/smoke4_pointer_noise.c | 75 + src/sliced_mta/smoke5_workqueue_stats.c | 358 +++ test_cases_bc/sliced_mta/smoke1_basic.c.bc | 192 ++ .../sliced_mta/smoke2_interproc.c.bc | 272 +++ .../sliced_mta/smoke3_rich_races.c.bc | 267 +++ .../sliced_mta/smoke4_pointer_noise.c.bc | 474 ++++ .../sliced_mta/smoke5_workqueue_stats.c.bc | 2055 +++++++++++++++++ 12 files changed, 3888 insertions(+), 1 deletion(-) create mode 100644 src/sliced_mta/smoke1_basic.c create mode 100644 src/sliced_mta/smoke2_interproc.c create mode 100644 src/sliced_mta/smoke3_rich_races.c create mode 100644 src/sliced_mta/smoke4_pointer_noise.c create mode 100644 src/sliced_mta/smoke5_workqueue_stats.c create mode 100644 test_cases_bc/sliced_mta/smoke1_basic.c.bc create mode 100644 test_cases_bc/sliced_mta/smoke2_interproc.c.bc create mode 100644 test_cases_bc/sliced_mta/smoke3_rich_races.c.bc create mode 100644 test_cases_bc/sliced_mta/smoke4_pointer_noise.c.bc create mode 100644 test_cases_bc/sliced_mta/smoke5_workqueue_stats.c.bc diff --git a/CMakeLists.txt b/CMakeLists.txt index cf931f52d..a7f4ac4de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -174,6 +174,23 @@ foreach(i RANGE ${dvf_len2}) ) endforeach() endforeach() + +# sliced mta tests (ctest -R sliced_mta_tests -VV) +set(sliced_mta_cmd "mta -enable-slicing=true") +file(GLOB sliced_mta_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/sliced_mta/*.bc*") +string(REPLACE " " ";" commandtemp ${sliced_mta_cmd}) +set(command ${commandtemp}) +foreach(filename ${sliced_mta_files}) + if (${filename} MATCHES ".pre.bc" OR ${filename} MATCHES ".pre.svf.bc" OR ${filename} MATCHES ".svf.bc") + continue() + endif() + add_test( + NAME sliced_mta_tests/${filename} + COMMAND ${command} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endforeach() + # graphdb dvf and mta tests (write + read) # Usage: ctest -R graphdb-dvf_tests -VV list(APPEND graphdb_dvf_folders diff --git a/generate_bc.sh b/generate_bc.sh index 22a81fe63..870566e07 100755 --- a/generate_bc.sh +++ b/generate_bc.sh @@ -13,6 +13,7 @@ test_dirs=" mem_leak double_free mta + sliced_mta non_annotated_tests path_tests objtype_tests @@ -120,4 +121,4 @@ for td in $test_dirs; do done done -fi \ No newline at end of file +fi diff --git a/src/sliced_mta/smoke1_basic.c b/src/sliced_mta/smoke1_basic.c new file mode 100644 index 000000000..264856842 --- /dev/null +++ b/src/sliced_mta/smoke1_basic.c @@ -0,0 +1,41 @@ +// smoke1_basic.c -- a minimal smoke test for the MSli artifact. +// +// Two worker threads share a counter and a flag; main also touches them. Most of +// the program is independent local arithmetic (compute_*) that never touches the +// shared state, so MSli slices it away -- the analysed slice is far smaller than +// the whole program, yet the reported race statements are identical to the +// whole-program (FSAM) run. Analyses quickly. +#include + +int counter; // shared, written by several threads -> race +int flag; // shared, written/read concurrently -> race +int done_local; // thread-local-ish bookkeeping + +// --- independent computation that touches no shared state (sliced away) --- +static int compute_a(int x) { int s = x; for (int i = 0; i < 10; i++) s = s * 3 + i; return s; } +static int compute_b(int x) { return compute_a(x) ^ (x << 2); } +static int compute_c(int x) { int s = 0; for (int i = 0; i < 8; i++) s += compute_b(x + i); return s; } + +static void busy_work(int seed) { + volatile int sink = 0; + for (int i = 0; i < 4; i++) sink += compute_c(seed + i); +} + +void* worker(void* arg) { + busy_work((int)(long)arg); // noise -> sliced away + counter = counter + 1; // shared write -> races with the other workers + flag = 1; // shared write -> races with main's read + return 0; +} + +int main(void) { + pthread_t t1, t2; + busy_work(42); // noise -> sliced away + pthread_create(&t1, 0, worker, (void*)1); + pthread_create(&t2, 0, worker, (void*)2); + int r = flag; // concurrent read of flag -> race + counter = r; // concurrent write of counter -> race + pthread_join(t1, 0); + pthread_join(t2, 0); + return 0; +} diff --git a/src/sliced_mta/smoke2_interproc.c b/src/sliced_mta/smoke2_interproc.c new file mode 100644 index 000000000..462c5d7f3 --- /dev/null +++ b/src/sliced_mta/smoke2_interproc.c @@ -0,0 +1,45 @@ +// smoke2_interproc.c -- a second smoke test exercising interprocedural slicing. +// +// A pool of worker threads reaches a shared write through a chain of helper +// calls, and main writes the same object concurrently. A separate, larger body +// of helper functions (helper_0..helper_n) does only local work and is never on +// any path to the shared state, so MSli slices it out: the slice keeps just the +// few functions that carry value flow to the racy accesses, while the race +// statements match the whole-program run. Still analyses in a second or two. +#include + +int shared; // the raced object + +// --- the kept core: an interprocedural path to the shared write --- +static void write_shared(int v) { shared = v; } +static void mid_layer(int v) { write_shared(v + 1); } +static void entry_layer(int v) { mid_layer(v * 2); } + +// --- a large independent helper body that never touches `shared` (sliced away) --- +static int helper_0(int x) { return x * 7 + 1; } +static int helper_1(int x) { return helper_0(x) - 3; } +static int helper_2(int x) { return helper_1(x) ^ x; } +static int helper_3(int x) { return helper_2(x) + helper_0(x); } +static int helper_4(int x) { return helper_3(x) * 2; } +static int helper_5(int x) { return helper_4(x) - helper_1(x); } +static int helper_6(int x) { return helper_5(x) + helper_2(x); } +static int helper_7(int x) { return helper_6(x) ^ helper_3(x); } +static void local_only(int seed) { + volatile int sink = 0; + for (int i = 0; i < 6; i++) sink += helper_7(seed + i); +} + +void* worker(void* arg) { + local_only((int)(long)arg); // noise -> sliced away + entry_layer((int)(long)arg); // interprocedural path to `shared` -> race + return 0; +} + +int main(void) { + pthread_t pool[3]; + local_only(99); // noise -> sliced away + for (int i = 0; i < 3; i++) pthread_create(&pool[i], 0, worker, (void*)(long)i); + shared = 100; // main writes `shared` concurrently -> race + for (int i = 0; i < 3; i++) pthread_join(pool[i], 0); + return 0; +} diff --git a/src/sliced_mta/smoke3_rich_races.c b/src/sliced_mta/smoke3_rich_races.c new file mode 100644 index 000000000..30a7776c3 --- /dev/null +++ b/src/sliced_mta/smoke3_rich_races.c @@ -0,0 +1,90 @@ +// smoke3_rich_races.c -- a denser smoke test for preservation checks. +// +// This case has several independently reachable race statements: direct shared +// writes, pointer-indirect writes, interprocedural writes, and array element +// updates. The surrounding local-only computation is irrelevant to the races and +// should be sliced away. If slicing loses one of the racy paths, the RQ2 table's +// Preserved column should expose the mismatch. +#include + +int shared_a; +int shared_b; +int shared_c; +int shared_array[4]; + +static int local_mix(int x) { + int v = x; + for (int i = 0; i < 12; i++) { + v = (v * 17 + i) ^ (v >> 1); + } + return v; +} + +static void local_only(int seed) { + volatile int sink = 0; + for (int i = 0; i < 8; i++) { + sink += local_mix(seed + i); + } +} + +static void write_indirect(int *p, int v) { + *p = v; +} + +static void write_chain3(int v) { + shared_c = v; +} + +static void write_chain2(int v) { + write_chain3(v + 11); +} + +static void write_chain1(int v) { + write_chain2(v * 3); +} + +static void touch_array(int idx, int v) { + shared_array[idx & 3] = v; +} + +void *worker_direct(void *arg) { + long id = (long)arg; + local_only((int)id); + shared_a = (int)id; + shared_b = shared_a + 1; + return 0; +} + +void *worker_indirect(void *arg) { + long id = (long)arg; + local_only((int)id + 20); + write_indirect(&shared_b, (int)id); + write_chain1((int)id); + return 0; +} + +void *worker_array(void *arg) { + long id = (long)arg; + local_only((int)id + 40); + touch_array((int)id, (int)id * 5); + touch_array(1, (int)id * 7); + return 0; +} + +int main(void) { + pthread_t t1, t2, t3, t4; + local_only(100); + pthread_create(&t1, 0, worker_direct, (void *)1); + pthread_create(&t2, 0, worker_indirect, (void *)2); + pthread_create(&t3, 0, worker_array, (void *)3); + pthread_create(&t4, 0, worker_array, (void *)5); + shared_a = 9; + write_indirect(&shared_b, 10); + write_chain1(11); + shared_array[1] = shared_c; + pthread_join(t1, 0); + pthread_join(t2, 0); + pthread_join(t3, 0); + pthread_join(t4, 0); + return 0; +} diff --git a/src/sliced_mta/smoke4_pointer_noise.c b/src/sliced_mta/smoke4_pointer_noise.c new file mode 100644 index 000000000..ec2bf2b4c --- /dev/null +++ b/src/sliced_mta/smoke4_pointer_noise.c @@ -0,0 +1,75 @@ +// smoke4_pointer_noise.c -- pthread races with unrelated pointer-heavy code. +#include + +typedef struct Node { + int value; + struct Node *next; +} Node; + +int hot_a; +int hot_b; +Node pool[32]; + +#define TOUCH_NODE(i, seed) \ + do { \ + pool[(i)].value = (seed) + (i); \ + pool[(i)].next = &pool[((i) + 1) & 31]; \ + } while (0) + +#define TOUCH_8(base, seed) \ + TOUCH_NODE((base) + 0, seed); \ + TOUCH_NODE((base) + 1, seed); \ + TOUCH_NODE((base) + 2, seed); \ + TOUCH_NODE((base) + 3, seed); \ + TOUCH_NODE((base) + 4, seed); \ + TOUCH_NODE((base) + 5, seed); \ + TOUCH_NODE((base) + 6, seed); \ + TOUCH_NODE((base) + 7, seed) + +static int pointer_noise(int seed) { + TOUCH_8(0, seed); + TOUCH_8(8, seed); + TOUCH_8(16, seed); + TOUCH_8(24, seed); + Node *p = &pool[seed & 31]; + int sum = 0; + for (int i = 0; i < 16; i++) { + sum += p->value; + p = p->next; + } + return sum; +} + +static void write_hot(int v) { + hot_a = v; + hot_b = hot_a + 1; +} + +void *worker_a(void *arg) { + int v = (int)(long)arg; + pointer_noise(v); + write_hot(v); + return 0; +} + +void *worker_b(void *arg) { + int v = (int)(long)arg; + pointer_noise(v + 10); + hot_b = v * 3; + hot_a = hot_b + 1; + return 0; +} + +int main(void) { + pthread_t t1, t2, t3; + pointer_noise(100); + pthread_create(&t1, 0, worker_a, (void *)1); + pthread_create(&t2, 0, worker_b, (void *)2); + pthread_create(&t3, 0, worker_a, (void *)3); + hot_a = 7; + hot_b = hot_a; + pthread_join(t1, 0); + pthread_join(t2, 0); + pthread_join(t3, 0); + return 0; +} diff --git a/src/sliced_mta/smoke5_workqueue_stats.c b/src/sliced_mta/smoke5_workqueue_stats.c new file mode 100644 index 000000000..e3acd5b65 --- /dev/null +++ b/src/sliced_mta/smoke5_workqueue_stats.c @@ -0,0 +1,358 @@ +// smoke5_workqueue_stats.c -- a small request-processing workload. +// +// Worker threads run a local request pipeline and then update shared statistics +// without locks. Most request parsing, routing, checksum, and serialization code +// is local to each request; the raced statements are the final statistics +// updates. +#include + +typedef struct Request { + int id; + int user; + int route; + int payload[24]; + int scratch[24]; +} Request; + +typedef struct Response { + int status; + int cost; + int bytes; + int tags[12]; +} Response; + +int requests_done; +int error_count; +int route_hits[4]; + +static int mix32(int x) { + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return x; +} + +static int parse_header(Request *req, int seed) { + req->id = mix32(seed) & 0x7fff; + req->user = mix32(seed + 17) & 0xff; + req->route = (req->id ^ req->user) & 3; + return req->route; +} + +static int parse_payload(Request *req, int seed) { + int total = 0; + for (int i = 0; i < 24; i++) { + req->payload[i] = mix32(seed + i * 19) & 0x3ff; + total += req->payload[i]; + } + return total; +} + +static int normalize_payload(Request *req) { + int total = 0; + for (int i = 0; i < 24; i++) { + int v = req->payload[i]; + req->scratch[i] = (v < 128) ? (v + 31) : (v - 7); + total += req->scratch[i]; + } + return total; +} + +static int apply_route_a(Request *req) { + int score = 0; + for (int i = 0; i < 12; i++) { + score += req->scratch[i] * (i + 1); + } + return score; +} + +static int apply_route_b(Request *req) { + int score = 1; + for (int i = 12; i < 24; i++) { + score ^= req->scratch[i] + i * 3; + } + return score; +} + +static int apply_route_c(Request *req) { + int score = 0; + for (int i = 0; i < 24; i += 2) { + score += req->scratch[i] ^ req->scratch[i + 1]; + } + return score; +} + +static int route_request(Request *req) { + if (req->route == 0) return apply_route_a(req); + if (req->route == 1) return apply_route_b(req); + if (req->route == 2) return apply_route_c(req); + return apply_route_a(req) + apply_route_c(req); +} + +static int authorize_request(Request *req, int score) { + int token = mix32(req->user + score); + int class_id = (token ^ req->id) & 7; + return class_id != 6; +} + +static int compute_checksum(Request *req) { + int h = 216613626; + for (int i = 0; i < 24; i++) { + h = mix32(h ^ req->payload[i]); + h = mix32(h + req->scratch[i]); + } + return h; +} + +static int classify_request(Request *req, int checksum) { + int c0 = (checksum ^ req->id) & 15; + int c1 = (checksum >> 4) & 15; + int c2 = (req->user + req->route) & 15; + return (c0 + c1 + c2) & 15; +} + +static void build_response(Response *resp, Request *req, int score, int checksum) { + resp->status = authorize_request(req, score) ? 200 : 403; + resp->cost = (score ^ checksum) & 0x3fff; + resp->bytes = 64 + (resp->cost & 127); + for (int i = 0; i < 12; i++) { + resp->tags[i] = mix32(resp->cost + req->scratch[i]) & 0xff; + } +} + +static int serialize_response(Response *resp) { + int bytes = resp->bytes; + for (int i = 0; i < 12; i++) { + bytes += (resp->tags[i] & 7); + } + return bytes; +} + +static int endpoint_search(Request *req, Response *resp) { + int score = req->id + resp->cost; + score += req->payload[0] * 3; + score ^= req->scratch[3] + req->payload[5]; + score += mix32(req->scratch[7] + score); + score ^= req->payload[11] + req->scratch[13]; + resp->tags[0] = score & 0xff; + resp->tags[1] = (score >> 3) & 0xff; + return score; +} + +static int endpoint_profile(Request *req, Response *resp) { + int score = req->user * 17; + score += req->payload[2] + req->payload[4]; + score ^= mix32(req->scratch[6] + req->scratch[8]); + score += req->payload[10] * 5; + score ^= req->scratch[12] + req->payload[14]; + resp->tags[2] = score & 0xff; + resp->tags[3] = (score >> 2) & 0xff; + return score; +} + +static int endpoint_checkout(Request *req, Response *resp) { + int score = resp->bytes; + score += req->payload[1] * req->scratch[1]; + score ^= req->payload[3] + req->scratch[9]; + score += mix32(req->payload[15] + score); + score ^= req->scratch[17] + req->payload[19]; + resp->tags[4] = score & 0xff; + resp->tags[5] = (score >> 4) & 0xff; + return score; +} + +static int endpoint_inventory(Request *req, Response *resp) { + int score = req->route + 31; + score += req->scratch[0] + req->scratch[2]; + score ^= mix32(req->payload[6] + req->payload[8]); + score += req->scratch[16] * 7; + score ^= req->payload[20] + req->scratch[22]; + resp->tags[6] = score & 0xff; + resp->tags[7] = (score >> 5) & 0xff; + return score; +} + +static int endpoint_recommend(Request *req, Response *resp) { + int score = req->id ^ req->user; + score += mix32(req->payload[7] + req->scratch[4]); + score ^= req->payload[9] * 11; + score += req->scratch[18] + req->payload[21]; + score ^= mix32(score + req->scratch[23]); + resp->tags[8] = score & 0xff; + resp->tags[9] = (score >> 6) & 0xff; + return score; +} + +static int endpoint_audit(Request *req, Response *resp) { + int score = resp->status; + score += req->payload[12] + req->payload[13]; + score ^= req->scratch[5] * 13; + score += mix32(req->scratch[10] + req->payload[16]); + score ^= req->scratch[21] + resp->cost; + resp->tags[10] = score & 0xff; + resp->tags[11] = (score >> 7) & 0xff; + return score; +} + +static int endpoint_local_report(Request *req, Response *resp) { + int score = req->payload[0] + req->payload[23]; + score ^= req->scratch[1] + req->scratch[22]; + score += mix32(score + req->id); + score ^= resp->bytes + req->route; + score += req->user * 19; + return score; +} + +static int endpoint_local_cache(Request *req, Response *resp) { + int score = req->scratch[2] + req->scratch[20]; + score += mix32(req->payload[5] + req->payload[18]); + score ^= resp->cost + req->payload[6]; + score += req->scratch[14] * 23; + score ^= mix32(score + resp->status); + return score; +} + +static int endpoint_billing(Request *req, Response *resp) { + int score = req->user + resp->bytes; + score += req->payload[4] * 29; + score ^= req->scratch[6] + req->payload[17]; + score += mix32(resp->cost + req->scratch[19]); + score ^= req->payload[22] + req->id; + resp->tags[0] ^= score & 0xff; + return score; +} + +static int endpoint_shipping(Request *req, Response *resp) { + int score = req->route * 41; + score += req->scratch[8] + req->scratch[15]; + score ^= mix32(req->payload[1] + req->payload[21]); + score += resp->bytes * 3; + score ^= req->scratch[11] + req->payload[13]; + resp->tags[1] ^= (score >> 1) & 0xff; + return score; +} + +static int endpoint_fraud_check(Request *req, Response *resp) { + int score = req->id ^ resp->status; + score += mix32(req->user + req->payload[2]); + score ^= req->scratch[7] * 31; + score += req->payload[18] + req->scratch[20]; + score ^= mix32(score + resp->cost); + resp->tags[2] ^= (score >> 2) & 0xff; + return score; +} + +static int endpoint_notification(Request *req, Response *resp) { + int score = resp->bytes + 97; + score += req->payload[3] + req->scratch[4]; + score ^= mix32(req->payload[12] + req->scratch[16]); + score += req->user * 37; + score ^= resp->status + req->route; + resp->tags[3] ^= (score >> 3) & 0xff; + return score; +} + +static int endpoint_session(Request *req, Response *resp) { + int score = req->id + req->user; + score ^= req->payload[9] + req->scratch[9]; + score += mix32(req->payload[10] + req->scratch[10]); + score ^= resp->cost * 5; + score += req->payload[23] + resp->bytes; + resp->tags[4] ^= (score >> 4) & 0xff; + return score; +} + +static int endpoint_localization(Request *req, Response *resp) { + int score = req->route + req->payload[6]; + score += req->scratch[12] * 43; + score ^= mix32(req->payload[14] + req->scratch[18]); + score += resp->status + req->user; + score ^= req->payload[20] + resp->cost; + resp->tags[5] ^= (score >> 5) & 0xff; + return score; +} + +static int endpoint_ab_test(Request *req, Response *resp) { + int score = req->id & 255; + score += req->payload[7] + req->scratch[13]; + score ^= mix32(req->payload[15] + resp->bytes); + score += req->scratch[21] * 47; + score ^= req->user + resp->status; + resp->tags[6] ^= (score >> 6) & 0xff; + return score; +} + +static int endpoint_local_metrics(Request *req, Response *resp) { + int score = resp->cost + resp->bytes; + score += req->payload[8] + req->scratch[0]; + score ^= mix32(req->payload[16] + req->scratch[23]); + score += req->route * 53; + score ^= req->id + req->payload[19]; + resp->tags[7] ^= (score >> 7) & 0xff; + return score; +} + +static int dispatch_endpoint(Request *req, Response *resp, int cls) { + switch (cls & 15) { + case 0: return endpoint_search(req, resp); + case 1: return endpoint_profile(req, resp); + case 2: return endpoint_checkout(req, resp); + case 3: return endpoint_inventory(req, resp); + case 4: return endpoint_recommend(req, resp); + case 5: return endpoint_audit(req, resp); + case 6: return endpoint_local_report(req, resp); + case 7: return endpoint_local_cache(req, resp); + case 8: return endpoint_billing(req, resp); + case 9: return endpoint_shipping(req, resp); + case 10: return endpoint_fraud_check(req, resp); + case 11: return endpoint_notification(req, resp); + case 12: return endpoint_session(req, resp); + case 13: return endpoint_localization(req, resp); + case 14: return endpoint_ab_test(req, resp); + default: return endpoint_local_metrics(req, resp); + } +} + +static int process_request(int seed) { + Request req; + Response resp; + parse_header(&req, seed); + parse_payload(&req, seed + 100); + normalize_payload(&req); + int score = route_request(&req); + int checksum = compute_checksum(&req); + int cls = classify_request(&req, checksum); + build_response(&resp, &req, score + cls, checksum); + resp.cost ^= dispatch_endpoint(&req, &resp, cls); + return serialize_response(&resp); +} + +static void record_stats(int route, int bytes) { + requests_done = requests_done + 1; + route_hits[route & 3] = route_hits[route & 3] + 1; + if (bytes & 1) { + error_count = error_count + 1; + } +} + +void *worker(void *arg) { + int seed = (int)(long)arg; + int bytes = process_request(seed); + record_stats(seed, bytes); + return 0; +} + +int main(void) { + pthread_t t1, t2, t3, t4; + pthread_create(&t1, 0, worker, (void *)11); + pthread_create(&t2, 0, worker, (void *)23); + pthread_create(&t3, 0, worker, (void *)37); + pthread_create(&t4, 0, worker, (void *)41); + record_stats(1, process_request(5)); + record_stats(2, process_request(7)); + pthread_join(t1, 0); + pthread_join(t2, 0); + pthread_join(t3, 0); + pthread_join(t4, 0); + return requests_done + error_count; +} diff --git a/test_cases_bc/sliced_mta/smoke1_basic.c.bc b/test_cases_bc/sliced_mta/smoke1_basic.c.bc new file mode 100644 index 000000000..088c950f1 --- /dev/null +++ b/test_cases_bc/sliced_mta/smoke1_basic.c.bc @@ -0,0 +1,192 @@ +; ModuleID = 'test_cases_bc/sliced_mta/smoke1_basic.c.bc' +source_filename = "src/sliced_mta/smoke1_basic.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@counter = dso_local global i32 0, align 4 +@flag = dso_local global i32 0, align 4 +@done_local = dso_local global i32 0, align 4 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + %conv = trunc i64 %1 to i32 + call void @busy_work(i32 noundef %conv) + %2 = load i32, ptr @counter, align 4 + %add = add nsw i32 %2, 1 + store i32 %add, ptr @counter, align 4 + store i32 1, ptr @flag, align 4 + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @busy_work(i32 noundef %seed) #0 { +entry: + %seed.addr = alloca i32, align 4 + %sink = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 %seed, ptr %seed.addr, align 4 + store volatile i32 0, ptr %sink, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 4 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, ptr %seed.addr, align 4 + %2 = load i32, ptr %i, align 4 + %add = add nsw i32 %1, %2 + %call = call i32 @compute_c(i32 noundef %add) + %3 = load volatile i32, ptr %sink, align 4 + %add1 = add nsw i32 %3, %call + store volatile i32 %add1, ptr %sink, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %4 = load i32, ptr %i, align 4 + %inc = add nsw i32 %4, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !6 + +for.end: ; preds = %for.cond + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %t1 = alloca i64, align 8 + %t2 = alloca i64, align 8 + %r = alloca i32, align 4 + store i32 0, ptr %retval, align 4 + call void @busy_work(i32 noundef 42) + %call = call i32 @pthread_create(ptr noundef %t1, ptr noundef null, ptr noundef @worker, ptr noundef inttoptr (i64 1 to ptr)) #3 + %call1 = call i32 @pthread_create(ptr noundef %t2, ptr noundef null, ptr noundef @worker, ptr noundef inttoptr (i64 2 to ptr)) #3 + %0 = load i32, ptr @flag, align 4 + store i32 %0, ptr %r, align 4 + %1 = load i32, ptr %r, align 4 + store i32 %1, ptr @counter, align 4 + %2 = load i64, ptr %t1, align 8 + %call2 = call i32 @pthread_join(i64 noundef %2, ptr noundef null) + %3 = load i64, ptr %t2, align 8 + %call3 = call i32 @pthread_join(i64 noundef %3, ptr noundef null) + ret i32 0 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #1 + +declare i32 @pthread_join(i64 noundef, ptr noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @compute_c(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + %s = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + store i32 0, ptr %s, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 8 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, ptr %x.addr, align 4 + %2 = load i32, ptr %i, align 4 + %add = add nsw i32 %1, %2 + %call = call i32 @compute_b(i32 noundef %add) + %3 = load i32, ptr %s, align 4 + %add1 = add nsw i32 %3, %call + store i32 %add1, ptr %s, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %4 = load i32, ptr %i, align 4 + %inc = add nsw i32 %4, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !8 + +for.end: ; preds = %for.cond + %5 = load i32, ptr %s, align 4 + ret i32 %5 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @compute_b(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %call = call i32 @compute_a(i32 noundef %0) + %1 = load i32, ptr %x.addr, align 4 + %shl = shl i32 %1, 2 + %xor = xor i32 %call, %shl + ret i32 %xor +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @compute_a(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + %s = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + store i32 %0, ptr %s, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %1 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %1, 10 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %2 = load i32, ptr %s, align 4 + %mul = mul nsw i32 %2, 3 + %3 = load i32, ptr %i, align 4 + %add = add nsw i32 %mul, %3 + store i32 %add, ptr %s, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %4 = load i32, ptr %i, align 4 + %inc = add nsw i32 %4, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !9 + +for.end: ; preds = %for.cond + %5 = load i32, ptr %s, align 4 + ret i32 %5 +} + +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"="+cmov,+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"="+cmov,+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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} +!9 = distinct !{!9, !7} diff --git a/test_cases_bc/sliced_mta/smoke2_interproc.c.bc b/test_cases_bc/sliced_mta/smoke2_interproc.c.bc new file mode 100644 index 000000000..c5efeaa9b --- /dev/null +++ b/test_cases_bc/sliced_mta/smoke2_interproc.c.bc @@ -0,0 +1,272 @@ +; ModuleID = 'test_cases_bc/sliced_mta/smoke2_interproc.c.bc' +source_filename = "src/sliced_mta/smoke2_interproc.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@shared = dso_local global i32 0, align 4 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + %conv = trunc i64 %1 to i32 + call void @local_only(i32 noundef %conv) + %2 = load ptr, ptr %arg.addr, align 8 + %3 = ptrtoint ptr %2 to i64 + %conv1 = trunc i64 %3 to i32 + call void @entry_layer(i32 noundef %conv1) + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @local_only(i32 noundef %seed) #0 { +entry: + %seed.addr = alloca i32, align 4 + %sink = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 %seed, ptr %seed.addr, align 4 + store volatile i32 0, ptr %sink, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 6 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, ptr %seed.addr, align 4 + %2 = load i32, ptr %i, align 4 + %add = add nsw i32 %1, %2 + %call = call i32 @helper_7(i32 noundef %add) + %3 = load volatile i32, ptr %sink, align 4 + %add1 = add nsw i32 %3, %call + store volatile i32 %add1, ptr %sink, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %4 = load i32, ptr %i, align 4 + %inc = add nsw i32 %4, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !6 + +for.end: ; preds = %for.cond + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @entry_layer(i32 noundef %v) #0 { +entry: + %v.addr = alloca i32, align 4 + store i32 %v, ptr %v.addr, align 4 + %0 = load i32, ptr %v.addr, align 4 + %mul = mul nsw i32 %0, 2 + call void @mid_layer(i32 noundef %mul) + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %pool = alloca [3 x i64], align 16 + %i = alloca i32, align 4 + %i1 = alloca i32, align 4 + store i32 0, ptr %retval, align 4 + call void @local_only(i32 noundef 99) + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 3 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, ptr %i, align 4 + %idxprom = sext i32 %1 to i64 + %arrayidx = getelementptr inbounds [3 x i64], ptr %pool, i64 0, i64 %idxprom + %2 = load i32, ptr %i, align 4 + %conv = sext i32 %2 to i64 + %3 = inttoptr i64 %conv to ptr + %call = call i32 @pthread_create(ptr noundef %arrayidx, ptr noundef null, ptr noundef @worker, ptr noundef %3) #3 + br label %for.inc + +for.inc: ; preds = %for.body + %4 = load i32, ptr %i, align 4 + %inc = add nsw i32 %4, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !8 + +for.end: ; preds = %for.cond + store i32 100, ptr @shared, align 4 + store i32 0, ptr %i1, align 4 + br label %for.cond2 + +for.cond2: ; preds = %for.inc9, %for.end + %5 = load i32, ptr %i1, align 4 + %cmp3 = icmp slt i32 %5, 3 + br i1 %cmp3, label %for.body5, label %for.end11 + +for.body5: ; preds = %for.cond2 + %6 = load i32, ptr %i1, align 4 + %idxprom6 = sext i32 %6 to i64 + %arrayidx7 = getelementptr inbounds [3 x i64], ptr %pool, i64 0, i64 %idxprom6 + %7 = load i64, ptr %arrayidx7, align 8 + %call8 = call i32 @pthread_join(i64 noundef %7, ptr noundef null) + br label %for.inc9 + +for.inc9: ; preds = %for.body5 + %8 = load i32, ptr %i1, align 4 + %inc10 = add nsw i32 %8, 1 + store i32 %inc10, ptr %i1, align 4 + br label %for.cond2, !llvm.loop !9 + +for.end11: ; preds = %for.cond2 + ret i32 0 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #1 + +declare i32 @pthread_join(i64 noundef, ptr noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @helper_7(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %call = call i32 @helper_6(i32 noundef %0) + %1 = load i32, ptr %x.addr, align 4 + %call1 = call i32 @helper_3(i32 noundef %1) + %xor = xor i32 %call, %call1 + ret i32 %xor +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @helper_6(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %call = call i32 @helper_5(i32 noundef %0) + %1 = load i32, ptr %x.addr, align 4 + %call1 = call i32 @helper_2(i32 noundef %1) + %add = add nsw i32 %call, %call1 + ret i32 %add +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @helper_3(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %call = call i32 @helper_2(i32 noundef %0) + %1 = load i32, ptr %x.addr, align 4 + %call1 = call i32 @helper_0(i32 noundef %1) + %add = add nsw i32 %call, %call1 + ret i32 %add +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @helper_5(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %call = call i32 @helper_4(i32 noundef %0) + %1 = load i32, ptr %x.addr, align 4 + %call1 = call i32 @helper_1(i32 noundef %1) + %sub = sub nsw i32 %call, %call1 + ret i32 %sub +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @helper_2(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %call = call i32 @helper_1(i32 noundef %0) + %1 = load i32, ptr %x.addr, align 4 + %xor = xor i32 %call, %1 + ret i32 %xor +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @helper_4(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %call = call i32 @helper_3(i32 noundef %0) + %mul = mul nsw i32 %call, 2 + ret i32 %mul +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @helper_1(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %call = call i32 @helper_0(i32 noundef %0) + %sub = sub nsw i32 %call, 3 + ret i32 %sub +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @helper_0(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %mul = mul nsw i32 %0, 7 + %add = add nsw i32 %mul, 1 + ret i32 %add +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @mid_layer(i32 noundef %v) #0 { +entry: + %v.addr = alloca i32, align 4 + store i32 %v, ptr %v.addr, align 4 + %0 = load i32, ptr %v.addr, align 4 + %add = add nsw i32 %0, 1 + call void @write_shared(i32 noundef %add) + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @write_shared(i32 noundef %v) #0 { +entry: + %v.addr = alloca i32, align 4 + store i32 %v, ptr %v.addr, align 4 + %0 = load i32, ptr %v.addr, align 4 + store i32 %0, ptr @shared, align 4 + ret void +} + +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"="+cmov,+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"="+cmov,+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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} +!9 = distinct !{!9, !7} diff --git a/test_cases_bc/sliced_mta/smoke3_rich_races.c.bc b/test_cases_bc/sliced_mta/smoke3_rich_races.c.bc new file mode 100644 index 000000000..18fe81d5e --- /dev/null +++ b/test_cases_bc/sliced_mta/smoke3_rich_races.c.bc @@ -0,0 +1,267 @@ +; ModuleID = 'test_cases_bc/sliced_mta/smoke3_rich_races.c.bc' +source_filename = "src/sliced_mta/smoke3_rich_races.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@shared_a = dso_local global i32 0, align 4 +@shared_b = dso_local global i32 0, align 4 +@shared_c = dso_local global i32 0, align 4 +@shared_array = dso_local global [4 x i32] zeroinitializer, align 16 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker_direct(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %id = alloca i64, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + store i64 %1, ptr %id, align 8 + %2 = load i64, ptr %id, align 8 + %conv = trunc i64 %2 to i32 + call void @local_only(i32 noundef %conv) + %3 = load i64, ptr %id, align 8 + %conv1 = trunc i64 %3 to i32 + store i32 %conv1, ptr @shared_a, align 4 + %4 = load i32, ptr @shared_a, align 4 + %add = add nsw i32 %4, 1 + store i32 %add, ptr @shared_b, align 4 + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @local_only(i32 noundef %seed) #0 { +entry: + %seed.addr = alloca i32, align 4 + %sink = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 %seed, ptr %seed.addr, align 4 + store volatile i32 0, ptr %sink, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 8 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, ptr %seed.addr, align 4 + %2 = load i32, ptr %i, align 4 + %add = add nsw i32 %1, %2 + %call = call i32 @local_mix(i32 noundef %add) + %3 = load volatile i32, ptr %sink, align 4 + %add1 = add nsw i32 %3, %call + store volatile i32 %add1, ptr %sink, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %4 = load i32, ptr %i, align 4 + %inc = add nsw i32 %4, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !6 + +for.end: ; preds = %for.cond + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker_indirect(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %id = alloca i64, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + store i64 %1, ptr %id, align 8 + %2 = load i64, ptr %id, align 8 + %conv = trunc i64 %2 to i32 + %add = add nsw i32 %conv, 20 + call void @local_only(i32 noundef %add) + %3 = load i64, ptr %id, align 8 + %conv1 = trunc i64 %3 to i32 + call void @write_indirect(ptr noundef @shared_b, i32 noundef %conv1) + %4 = load i64, ptr %id, align 8 + %conv2 = trunc i64 %4 to i32 + call void @write_chain1(i32 noundef %conv2) + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @write_indirect(ptr noundef %p, i32 noundef %v) #0 { +entry: + %p.addr = alloca ptr, align 8 + %v.addr = alloca i32, align 4 + store ptr %p, ptr %p.addr, align 8 + store i32 %v, ptr %v.addr, align 4 + %0 = load i32, ptr %v.addr, align 4 + %1 = load ptr, ptr %p.addr, align 8 + store i32 %0, ptr %1, align 4 + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @write_chain1(i32 noundef %v) #0 { +entry: + %v.addr = alloca i32, align 4 + store i32 %v, ptr %v.addr, align 4 + %0 = load i32, ptr %v.addr, align 4 + %mul = mul nsw i32 %0, 3 + call void @write_chain2(i32 noundef %mul) + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker_array(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %id = alloca i64, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + store i64 %1, ptr %id, align 8 + %2 = load i64, ptr %id, align 8 + %conv = trunc i64 %2 to i32 + %add = add nsw i32 %conv, 40 + call void @local_only(i32 noundef %add) + %3 = load i64, ptr %id, align 8 + %conv1 = trunc i64 %3 to i32 + %4 = load i64, ptr %id, align 8 + %conv2 = trunc i64 %4 to i32 + %mul = mul nsw i32 %conv2, 5 + call void @touch_array(i32 noundef %conv1, i32 noundef %mul) + %5 = load i64, ptr %id, align 8 + %conv3 = trunc i64 %5 to i32 + %mul4 = mul nsw i32 %conv3, 7 + call void @touch_array(i32 noundef 1, i32 noundef %mul4) + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @touch_array(i32 noundef %idx, i32 noundef %v) #0 { +entry: + %idx.addr = alloca i32, align 4 + %v.addr = alloca i32, align 4 + store i32 %idx, ptr %idx.addr, align 4 + store i32 %v, ptr %v.addr, align 4 + %0 = load i32, ptr %v.addr, align 4 + %1 = load i32, ptr %idx.addr, align 4 + %and = and i32 %1, 3 + %idxprom = sext i32 %and to i64 + %arrayidx = getelementptr inbounds [4 x i32], ptr @shared_array, i64 0, i64 %idxprom + store i32 %0, ptr %arrayidx, align 4 + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %t1 = alloca i64, align 8 + %t2 = alloca i64, align 8 + %t3 = alloca i64, align 8 + %t4 = alloca i64, align 8 + store i32 0, ptr %retval, align 4 + call void @local_only(i32 noundef 100) + %call = call i32 @pthread_create(ptr noundef %t1, ptr noundef null, ptr noundef @worker_direct, ptr noundef inttoptr (i64 1 to ptr)) #3 + %call1 = call i32 @pthread_create(ptr noundef %t2, ptr noundef null, ptr noundef @worker_indirect, ptr noundef inttoptr (i64 2 to ptr)) #3 + %call2 = call i32 @pthread_create(ptr noundef %t3, ptr noundef null, ptr noundef @worker_array, ptr noundef inttoptr (i64 3 to ptr)) #3 + %call3 = call i32 @pthread_create(ptr noundef %t4, ptr noundef null, ptr noundef @worker_array, ptr noundef inttoptr (i64 5 to ptr)) #3 + store i32 9, ptr @shared_a, align 4 + call void @write_indirect(ptr noundef @shared_b, i32 noundef 10) + call void @write_chain1(i32 noundef 11) + %0 = load i32, ptr @shared_c, align 4 + store i32 %0, ptr getelementptr inbounds ([4 x i32], ptr @shared_array, i64 0, i64 1), align 4 + %1 = load i64, ptr %t1, align 8 + %call4 = call i32 @pthread_join(i64 noundef %1, ptr noundef null) + %2 = load i64, ptr %t2, align 8 + %call5 = call i32 @pthread_join(i64 noundef %2, ptr noundef null) + %3 = load i64, ptr %t3, align 8 + %call6 = call i32 @pthread_join(i64 noundef %3, ptr noundef null) + %4 = load i64, ptr %t4, align 8 + %call7 = call i32 @pthread_join(i64 noundef %4, ptr noundef null) + ret i32 0 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #1 + +declare i32 @pthread_join(i64 noundef, ptr noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @local_mix(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + %v = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + store i32 %0, ptr %v, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %1 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %1, 12 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %2 = load i32, ptr %v, align 4 + %mul = mul nsw i32 %2, 17 + %3 = load i32, ptr %i, align 4 + %add = add nsw i32 %mul, %3 + %4 = load i32, ptr %v, align 4 + %shr = ashr i32 %4, 1 + %xor = xor i32 %add, %shr + store i32 %xor, ptr %v, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %5 = load i32, ptr %i, align 4 + %inc = add nsw i32 %5, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !8 + +for.end: ; preds = %for.cond + %6 = load i32, ptr %v, align 4 + ret i32 %6 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @write_chain2(i32 noundef %v) #0 { +entry: + %v.addr = alloca i32, align 4 + store i32 %v, ptr %v.addr, align 4 + %0 = load i32, ptr %v.addr, align 4 + %add = add nsw i32 %0, 11 + call void @write_chain3(i32 noundef %add) + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @write_chain3(i32 noundef %v) #0 { +entry: + %v.addr = alloca i32, align 4 + store i32 %v, ptr %v.addr, align 4 + %0 = load i32, ptr %v.addr, align 4 + store i32 %0, ptr @shared_c, align 4 + ret void +} + +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"="+cmov,+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"="+cmov,+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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} diff --git a/test_cases_bc/sliced_mta/smoke4_pointer_noise.c.bc b/test_cases_bc/sliced_mta/smoke4_pointer_noise.c.bc new file mode 100644 index 000000000..fa34381db --- /dev/null +++ b/test_cases_bc/sliced_mta/smoke4_pointer_noise.c.bc @@ -0,0 +1,474 @@ +; ModuleID = 'test_cases_bc/sliced_mta/smoke4_pointer_noise.c.bc' +source_filename = "src/sliced_mta/smoke4_pointer_noise.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.Node = type { i32, ptr } + +@hot_b = dso_local global i32 0, align 4 +@hot_a = dso_local global i32 0, align 4 +@pool = dso_local global [32 x %struct.Node] zeroinitializer, align 16 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker_a(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %v = alloca i32, align 4 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + %conv = trunc i64 %1 to i32 + store i32 %conv, ptr %v, align 4 + %2 = load i32, ptr %v, align 4 + %call = call i32 @pointer_noise(i32 noundef %2) + %3 = load i32, ptr %v, align 4 + call void @write_hot(i32 noundef %3) + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @pointer_noise(i32 noundef %seed) #0 { +entry: + %seed.addr = alloca i32, align 4 + %p = alloca ptr, align 8 + %sum = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 %seed, ptr %seed.addr, align 4 + br label %do.body + +do.body: ; preds = %entry + %0 = load i32, ptr %seed.addr, align 4 + %add = add nsw i32 %0, 0 + store i32 %add, ptr @pool, align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 1), ptr getelementptr inbounds nuw (%struct.Node, ptr @pool, i32 0, i32 1), align 8 + br label %do.end + +do.end: ; preds = %do.body + br label %do.body1 + +do.body1: ; preds = %do.end + %1 = load i32, ptr %seed.addr, align 4 + %add2 = add nsw i32 %1, 1 + store i32 %add2, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 1), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 2), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 1), i32 0, i32 1), align 8 + br label %do.end3 + +do.end3: ; preds = %do.body1 + br label %do.body4 + +do.body4: ; preds = %do.end3 + %2 = load i32, ptr %seed.addr, align 4 + %add5 = add nsw i32 %2, 2 + store i32 %add5, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 2), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 3), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 2), i32 0, i32 1), align 8 + br label %do.end6 + +do.end6: ; preds = %do.body4 + br label %do.body7 + +do.body7: ; preds = %do.end6 + %3 = load i32, ptr %seed.addr, align 4 + %add8 = add nsw i32 %3, 3 + store i32 %add8, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 3), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 4), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 3), i32 0, i32 1), align 8 + br label %do.end9 + +do.end9: ; preds = %do.body7 + br label %do.body10 + +do.body10: ; preds = %do.end9 + %4 = load i32, ptr %seed.addr, align 4 + %add11 = add nsw i32 %4, 4 + store i32 %add11, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 4), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 5), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 4), i32 0, i32 1), align 8 + br label %do.end12 + +do.end12: ; preds = %do.body10 + br label %do.body13 + +do.body13: ; preds = %do.end12 + %5 = load i32, ptr %seed.addr, align 4 + %add14 = add nsw i32 %5, 5 + store i32 %add14, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 5), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 6), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 5), i32 0, i32 1), align 8 + br label %do.end15 + +do.end15: ; preds = %do.body13 + br label %do.body16 + +do.body16: ; preds = %do.end15 + %6 = load i32, ptr %seed.addr, align 4 + %add17 = add nsw i32 %6, 6 + store i32 %add17, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 6), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 7), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 6), i32 0, i32 1), align 8 + br label %do.end18 + +do.end18: ; preds = %do.body16 + br label %do.body19 + +do.body19: ; preds = %do.end18 + %7 = load i32, ptr %seed.addr, align 4 + %add20 = add nsw i32 %7, 7 + store i32 %add20, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 7), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 8), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 7), i32 0, i32 1), align 8 + br label %do.end21 + +do.end21: ; preds = %do.body19 + br label %do.body22 + +do.body22: ; preds = %do.end21 + %8 = load i32, ptr %seed.addr, align 4 + %add23 = add nsw i32 %8, 8 + store i32 %add23, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 8), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 9), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 8), i32 0, i32 1), align 8 + br label %do.end24 + +do.end24: ; preds = %do.body22 + br label %do.body25 + +do.body25: ; preds = %do.end24 + %9 = load i32, ptr %seed.addr, align 4 + %add26 = add nsw i32 %9, 9 + store i32 %add26, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 9), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 10), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 9), i32 0, i32 1), align 8 + br label %do.end27 + +do.end27: ; preds = %do.body25 + br label %do.body28 + +do.body28: ; preds = %do.end27 + %10 = load i32, ptr %seed.addr, align 4 + %add29 = add nsw i32 %10, 10 + store i32 %add29, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 10), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 11), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 10), i32 0, i32 1), align 8 + br label %do.end30 + +do.end30: ; preds = %do.body28 + br label %do.body31 + +do.body31: ; preds = %do.end30 + %11 = load i32, ptr %seed.addr, align 4 + %add32 = add nsw i32 %11, 11 + store i32 %add32, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 11), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 12), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 11), i32 0, i32 1), align 8 + br label %do.end33 + +do.end33: ; preds = %do.body31 + br label %do.body34 + +do.body34: ; preds = %do.end33 + %12 = load i32, ptr %seed.addr, align 4 + %add35 = add nsw i32 %12, 12 + store i32 %add35, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 12), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 13), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 12), i32 0, i32 1), align 8 + br label %do.end36 + +do.end36: ; preds = %do.body34 + br label %do.body37 + +do.body37: ; preds = %do.end36 + %13 = load i32, ptr %seed.addr, align 4 + %add38 = add nsw i32 %13, 13 + store i32 %add38, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 13), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 14), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 13), i32 0, i32 1), align 8 + br label %do.end39 + +do.end39: ; preds = %do.body37 + br label %do.body40 + +do.body40: ; preds = %do.end39 + %14 = load i32, ptr %seed.addr, align 4 + %add41 = add nsw i32 %14, 14 + store i32 %add41, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 14), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 15), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 14), i32 0, i32 1), align 8 + br label %do.end42 + +do.end42: ; preds = %do.body40 + br label %do.body43 + +do.body43: ; preds = %do.end42 + %15 = load i32, ptr %seed.addr, align 4 + %add44 = add nsw i32 %15, 15 + store i32 %add44, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 15), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 16), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 15), i32 0, i32 1), align 8 + br label %do.end45 + +do.end45: ; preds = %do.body43 + br label %do.body46 + +do.body46: ; preds = %do.end45 + %16 = load i32, ptr %seed.addr, align 4 + %add47 = add nsw i32 %16, 16 + store i32 %add47, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 16), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 17), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 16), i32 0, i32 1), align 8 + br label %do.end48 + +do.end48: ; preds = %do.body46 + br label %do.body49 + +do.body49: ; preds = %do.end48 + %17 = load i32, ptr %seed.addr, align 4 + %add50 = add nsw i32 %17, 17 + store i32 %add50, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 17), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 18), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 17), i32 0, i32 1), align 8 + br label %do.end51 + +do.end51: ; preds = %do.body49 + br label %do.body52 + +do.body52: ; preds = %do.end51 + %18 = load i32, ptr %seed.addr, align 4 + %add53 = add nsw i32 %18, 18 + store i32 %add53, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 18), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 19), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 18), i32 0, i32 1), align 8 + br label %do.end54 + +do.end54: ; preds = %do.body52 + br label %do.body55 + +do.body55: ; preds = %do.end54 + %19 = load i32, ptr %seed.addr, align 4 + %add56 = add nsw i32 %19, 19 + store i32 %add56, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 19), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 20), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 19), i32 0, i32 1), align 8 + br label %do.end57 + +do.end57: ; preds = %do.body55 + br label %do.body58 + +do.body58: ; preds = %do.end57 + %20 = load i32, ptr %seed.addr, align 4 + %add59 = add nsw i32 %20, 20 + store i32 %add59, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 20), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 21), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 20), i32 0, i32 1), align 8 + br label %do.end60 + +do.end60: ; preds = %do.body58 + br label %do.body61 + +do.body61: ; preds = %do.end60 + %21 = load i32, ptr %seed.addr, align 4 + %add62 = add nsw i32 %21, 21 + store i32 %add62, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 21), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 22), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 21), i32 0, i32 1), align 8 + br label %do.end63 + +do.end63: ; preds = %do.body61 + br label %do.body64 + +do.body64: ; preds = %do.end63 + %22 = load i32, ptr %seed.addr, align 4 + %add65 = add nsw i32 %22, 22 + store i32 %add65, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 22), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 23), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 22), i32 0, i32 1), align 8 + br label %do.end66 + +do.end66: ; preds = %do.body64 + br label %do.body67 + +do.body67: ; preds = %do.end66 + %23 = load i32, ptr %seed.addr, align 4 + %add68 = add nsw i32 %23, 23 + store i32 %add68, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 23), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 24), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 23), i32 0, i32 1), align 8 + br label %do.end69 + +do.end69: ; preds = %do.body67 + br label %do.body70 + +do.body70: ; preds = %do.end69 + %24 = load i32, ptr %seed.addr, align 4 + %add71 = add nsw i32 %24, 24 + store i32 %add71, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 24), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 25), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 24), i32 0, i32 1), align 8 + br label %do.end72 + +do.end72: ; preds = %do.body70 + br label %do.body73 + +do.body73: ; preds = %do.end72 + %25 = load i32, ptr %seed.addr, align 4 + %add74 = add nsw i32 %25, 25 + store i32 %add74, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 25), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 26), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 25), i32 0, i32 1), align 8 + br label %do.end75 + +do.end75: ; preds = %do.body73 + br label %do.body76 + +do.body76: ; preds = %do.end75 + %26 = load i32, ptr %seed.addr, align 4 + %add77 = add nsw i32 %26, 26 + store i32 %add77, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 26), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 27), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 26), i32 0, i32 1), align 8 + br label %do.end78 + +do.end78: ; preds = %do.body76 + br label %do.body79 + +do.body79: ; preds = %do.end78 + %27 = load i32, ptr %seed.addr, align 4 + %add80 = add nsw i32 %27, 27 + store i32 %add80, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 27), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 28), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 27), i32 0, i32 1), align 8 + br label %do.end81 + +do.end81: ; preds = %do.body79 + br label %do.body82 + +do.body82: ; preds = %do.end81 + %28 = load i32, ptr %seed.addr, align 4 + %add83 = add nsw i32 %28, 28 + store i32 %add83, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 28), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 29), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 28), i32 0, i32 1), align 8 + br label %do.end84 + +do.end84: ; preds = %do.body82 + br label %do.body85 + +do.body85: ; preds = %do.end84 + %29 = load i32, ptr %seed.addr, align 4 + %add86 = add nsw i32 %29, 29 + store i32 %add86, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 29), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 30), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 29), i32 0, i32 1), align 8 + br label %do.end87 + +do.end87: ; preds = %do.body85 + br label %do.body88 + +do.body88: ; preds = %do.end87 + %30 = load i32, ptr %seed.addr, align 4 + %add89 = add nsw i32 %30, 30 + store i32 %add89, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 30), align 16 + store ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 31), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 30), i32 0, i32 1), align 8 + br label %do.end90 + +do.end90: ; preds = %do.body88 + br label %do.body91 + +do.body91: ; preds = %do.end90 + %31 = load i32, ptr %seed.addr, align 4 + %add92 = add nsw i32 %31, 31 + store i32 %add92, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 31), align 16 + store ptr @pool, ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([32 x %struct.Node], ptr @pool, i64 0, i64 31), i32 0, i32 1), align 8 + br label %do.end93 + +do.end93: ; preds = %do.body91 + %32 = load i32, ptr %seed.addr, align 4 + %and = and i32 %32, 31 + %idxprom = sext i32 %and to i64 + %arrayidx = getelementptr inbounds [32 x %struct.Node], ptr @pool, i64 0, i64 %idxprom + store ptr %arrayidx, ptr %p, align 8 + store i32 0, ptr %sum, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %do.end93 + %33 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %33, 16 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %34 = load ptr, ptr %p, align 8 + %value = getelementptr inbounds nuw %struct.Node, ptr %34, i32 0, i32 0 + %35 = load i32, ptr %value, align 8 + %36 = load i32, ptr %sum, align 4 + %add94 = add nsw i32 %36, %35 + store i32 %add94, ptr %sum, align 4 + %37 = load ptr, ptr %p, align 8 + %next = getelementptr inbounds nuw %struct.Node, ptr %37, i32 0, i32 1 + %38 = load ptr, ptr %next, align 8 + store ptr %38, ptr %p, align 8 + br label %for.inc + +for.inc: ; preds = %for.body + %39 = load i32, ptr %i, align 4 + %inc = add nsw i32 %39, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !6 + +for.end: ; preds = %for.cond + %40 = load i32, ptr %sum, align 4 + ret i32 %40 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @write_hot(i32 noundef %v) #0 { +entry: + %v.addr = alloca i32, align 4 + store i32 %v, ptr %v.addr, align 4 + %0 = load i32, ptr %v.addr, align 4 + store i32 %0, ptr @hot_a, align 4 + %1 = load i32, ptr @hot_a, align 4 + %add = add nsw i32 %1, 1 + store i32 %add, ptr @hot_b, align 4 + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker_b(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %v = alloca i32, align 4 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + %conv = trunc i64 %1 to i32 + store i32 %conv, ptr %v, align 4 + %2 = load i32, ptr %v, align 4 + %add = add nsw i32 %2, 10 + %call = call i32 @pointer_noise(i32 noundef %add) + %3 = load i32, ptr %v, align 4 + %mul = mul nsw i32 %3, 3 + store i32 %mul, ptr @hot_b, align 4 + %4 = load i32, ptr @hot_b, align 4 + %add1 = add nsw i32 %4, 1 + store i32 %add1, ptr @hot_a, align 4 + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %t1 = alloca i64, align 8 + %t2 = alloca i64, align 8 + %t3 = alloca i64, align 8 + store i32 0, ptr %retval, align 4 + %call = call i32 @pointer_noise(i32 noundef 100) + %call1 = call i32 @pthread_create(ptr noundef %t1, ptr noundef null, ptr noundef @worker_a, ptr noundef inttoptr (i64 1 to ptr)) #3 + %call2 = call i32 @pthread_create(ptr noundef %t2, ptr noundef null, ptr noundef @worker_b, ptr noundef inttoptr (i64 2 to ptr)) #3 + %call3 = call i32 @pthread_create(ptr noundef %t3, ptr noundef null, ptr noundef @worker_a, ptr noundef inttoptr (i64 3 to ptr)) #3 + store i32 7, ptr @hot_a, align 4 + %0 = load i32, ptr @hot_a, align 4 + store i32 %0, ptr @hot_b, align 4 + %1 = load i64, ptr %t1, align 8 + %call4 = call i32 @pthread_join(i64 noundef %1, ptr noundef null) + %2 = load i64, ptr %t2, align 8 + %call5 = call i32 @pthread_join(i64 noundef %2, ptr noundef null) + %3 = load i64, ptr %t3, align 8 + %call6 = call i32 @pthread_join(i64 noundef %3, ptr noundef null) + ret i32 0 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #1 + +declare i32 @pthread_join(i64 noundef, ptr 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"="+cmov,+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"="+cmov,+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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} diff --git a/test_cases_bc/sliced_mta/smoke5_workqueue_stats.c.bc b/test_cases_bc/sliced_mta/smoke5_workqueue_stats.c.bc new file mode 100644 index 000000000..3a3f06f41 --- /dev/null +++ b/test_cases_bc/sliced_mta/smoke5_workqueue_stats.c.bc @@ -0,0 +1,2055 @@ +; ModuleID = 'test_cases_bc/sliced_mta/smoke5_workqueue_stats.c.bc' +source_filename = "src/sliced_mta/smoke5_workqueue_stats.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.Request = type { i32, i32, i32, [24 x i32], [24 x i32] } +%struct.Response = type { i32, i32, i32, [12 x i32] } + +@requests_done = dso_local global i32 0, align 4 +@error_count = dso_local global i32 0, align 4 +@route_hits = dso_local global [4 x i32] zeroinitializer, align 16 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %seed = alloca i32, align 4 + %bytes = alloca i32, align 4 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + %conv = trunc i64 %1 to i32 + store i32 %conv, ptr %seed, align 4 + %2 = load i32, ptr %seed, align 4 + %call = call i32 @process_request(i32 noundef %2) + store i32 %call, ptr %bytes, align 4 + %3 = load i32, ptr %seed, align 4 + %4 = load i32, ptr %bytes, align 4 + call void @record_stats(i32 noundef %3, i32 noundef %4) + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @process_request(i32 noundef %seed) #0 { +entry: + %seed.addr = alloca i32, align 4 + %req = alloca %struct.Request, align 4 + %resp = alloca %struct.Response, align 4 + %score = alloca i32, align 4 + %checksum = alloca i32, align 4 + %cls = alloca i32, align 4 + store i32 %seed, ptr %seed.addr, align 4 + %0 = load i32, ptr %seed.addr, align 4 + %call = call i32 @parse_header(ptr noundef %req, i32 noundef %0) + %1 = load i32, ptr %seed.addr, align 4 + %add = add nsw i32 %1, 100 + %call1 = call i32 @parse_payload(ptr noundef %req, i32 noundef %add) + %call2 = call i32 @normalize_payload(ptr noundef %req) + %call3 = call i32 @route_request(ptr noundef %req) + store i32 %call3, ptr %score, align 4 + %call4 = call i32 @compute_checksum(ptr noundef %req) + store i32 %call4, ptr %checksum, align 4 + %2 = load i32, ptr %checksum, align 4 + %call5 = call i32 @classify_request(ptr noundef %req, i32 noundef %2) + store i32 %call5, ptr %cls, align 4 + %3 = load i32, ptr %score, align 4 + %4 = load i32, ptr %cls, align 4 + %add6 = add nsw i32 %3, %4 + %5 = load i32, ptr %checksum, align 4 + call void @build_response(ptr noundef %resp, ptr noundef %req, i32 noundef %add6, i32 noundef %5) + %6 = load i32, ptr %cls, align 4 + %call7 = call i32 @dispatch_endpoint(ptr noundef %req, ptr noundef %resp, i32 noundef %6) + %cost = getelementptr inbounds nuw %struct.Response, ptr %resp, i32 0, i32 1 + %7 = load i32, ptr %cost, align 4 + %xor = xor i32 %7, %call7 + store i32 %xor, ptr %cost, align 4 + %call8 = call i32 @serialize_response(ptr noundef %resp) + ret i32 %call8 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @record_stats(i32 noundef %route, i32 noundef %bytes) #0 { +entry: + %route.addr = alloca i32, align 4 + %bytes.addr = alloca i32, align 4 + store i32 %route, ptr %route.addr, align 4 + store i32 %bytes, ptr %bytes.addr, align 4 + %0 = load i32, ptr @requests_done, align 4 + %add = add nsw i32 %0, 1 + store i32 %add, ptr @requests_done, align 4 + %1 = load i32, ptr %route.addr, align 4 + %and = and i32 %1, 3 + %idxprom = sext i32 %and to i64 + %arrayidx = getelementptr inbounds [4 x i32], ptr @route_hits, i64 0, i64 %idxprom + %2 = load i32, ptr %arrayidx, align 4 + %add1 = add nsw i32 %2, 1 + %3 = load i32, ptr %route.addr, align 4 + %and2 = and i32 %3, 3 + %idxprom3 = sext i32 %and2 to i64 + %arrayidx4 = getelementptr inbounds [4 x i32], ptr @route_hits, i64 0, i64 %idxprom3 + store i32 %add1, ptr %arrayidx4, align 4 + %4 = load i32, ptr %bytes.addr, align 4 + %and5 = and i32 %4, 1 + %tobool = icmp ne i32 %and5, 0 + br i1 %tobool, label %if.then, label %if.end + +if.then: ; preds = %entry + %5 = load i32, ptr @error_count, align 4 + %add6 = add nsw i32 %5, 1 + store i32 %add6, ptr @error_count, align 4 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %t1 = alloca i64, align 8 + %t2 = alloca i64, align 8 + %t3 = alloca i64, align 8 + %t4 = alloca i64, align 8 + store i32 0, ptr %retval, align 4 + %call = call i32 @pthread_create(ptr noundef %t1, ptr noundef null, ptr noundef @worker, ptr noundef inttoptr (i64 11 to ptr)) #3 + %call1 = call i32 @pthread_create(ptr noundef %t2, ptr noundef null, ptr noundef @worker, ptr noundef inttoptr (i64 23 to ptr)) #3 + %call2 = call i32 @pthread_create(ptr noundef %t3, ptr noundef null, ptr noundef @worker, ptr noundef inttoptr (i64 37 to ptr)) #3 + %call3 = call i32 @pthread_create(ptr noundef %t4, ptr noundef null, ptr noundef @worker, ptr noundef inttoptr (i64 41 to ptr)) #3 + %call4 = call i32 @process_request(i32 noundef 5) + call void @record_stats(i32 noundef 1, i32 noundef %call4) + %call5 = call i32 @process_request(i32 noundef 7) + call void @record_stats(i32 noundef 2, i32 noundef %call5) + %0 = load i64, ptr %t1, align 8 + %call6 = call i32 @pthread_join(i64 noundef %0, ptr noundef null) + %1 = load i64, ptr %t2, align 8 + %call7 = call i32 @pthread_join(i64 noundef %1, ptr noundef null) + %2 = load i64, ptr %t3, align 8 + %call8 = call i32 @pthread_join(i64 noundef %2, ptr noundef null) + %3 = load i64, ptr %t4, align 8 + %call9 = call i32 @pthread_join(i64 noundef %3, ptr noundef null) + %4 = load i32, ptr @requests_done, align 4 + %5 = load i32, ptr @error_count, align 4 + %add = add nsw i32 %4, %5 + ret i32 %add +} + +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #1 + +declare i32 @pthread_join(i64 noundef, ptr noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @parse_header(ptr noundef %req, i32 noundef %seed) #0 { +entry: + %req.addr = alloca ptr, align 8 + %seed.addr = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store i32 %seed, ptr %seed.addr, align 4 + %0 = load i32, ptr %seed.addr, align 4 + %call = call i32 @mix32(i32 noundef %0) + %and = and i32 %call, 32767 + %1 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %1, i32 0, i32 0 + store i32 %and, ptr %id, align 4 + %2 = load i32, ptr %seed.addr, align 4 + %add = add nsw i32 %2, 17 + %call1 = call i32 @mix32(i32 noundef %add) + %and2 = and i32 %call1, 255 + %3 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %3, i32 0, i32 1 + store i32 %and2, ptr %user, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %id3 = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 0 + %5 = load i32, ptr %id3, align 4 + %6 = load ptr, ptr %req.addr, align 8 + %user4 = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 1 + %7 = load i32, ptr %user4, align 4 + %xor = xor i32 %5, %7 + %and5 = and i32 %xor, 3 + %8 = load ptr, ptr %req.addr, align 8 + %route = getelementptr inbounds nuw %struct.Request, ptr %8, i32 0, i32 2 + store i32 %and5, ptr %route, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %route6 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 2 + %10 = load i32, ptr %route6, align 4 + ret i32 %10 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @parse_payload(ptr noundef %req, i32 noundef %seed) #0 { +entry: + %req.addr = alloca ptr, align 8 + %seed.addr = alloca i32, align 4 + %total = alloca i32, align 4 + %i = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store i32 %seed, ptr %seed.addr, align 4 + store i32 0, ptr %total, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 24 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, ptr %seed.addr, align 4 + %2 = load i32, ptr %i, align 4 + %mul = mul nsw i32 %2, 19 + %add = add nsw i32 %1, %mul + %call = call i32 @mix32(i32 noundef %add) + %and = and i32 %call, 1023 + %3 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %3, i32 0, i32 3 + %4 = load i32, ptr %i, align 4 + %idxprom = sext i32 %4 to i64 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 %idxprom + store i32 %and, ptr %arrayidx, align 4 + %5 = load ptr, ptr %req.addr, align 8 + %payload1 = getelementptr inbounds nuw %struct.Request, ptr %5, i32 0, i32 3 + %6 = load i32, ptr %i, align 4 + %idxprom2 = sext i32 %6 to i64 + %arrayidx3 = getelementptr inbounds [24 x i32], ptr %payload1, i64 0, i64 %idxprom2 + %7 = load i32, ptr %arrayidx3, align 4 + %8 = load i32, ptr %total, align 4 + %add4 = add nsw i32 %8, %7 + store i32 %add4, ptr %total, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %9 = load i32, ptr %i, align 4 + %inc = add nsw i32 %9, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !6 + +for.end: ; preds = %for.cond + %10 = load i32, ptr %total, align 4 + ret i32 %10 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @normalize_payload(ptr noundef %req) #0 { +entry: + %req.addr = alloca ptr, align 8 + %total = alloca i32, align 4 + %i = alloca i32, align 4 + %v = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store i32 0, ptr %total, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 24 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %1, i32 0, i32 3 + %2 = load i32, ptr %i, align 4 + %idxprom = sext i32 %2 to i64 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 %idxprom + %3 = load i32, ptr %arrayidx, align 4 + store i32 %3, ptr %v, align 4 + %4 = load i32, ptr %v, align 4 + %cmp1 = icmp slt i32 %4, 128 + br i1 %cmp1, label %cond.true, label %cond.false + +cond.true: ; preds = %for.body + %5 = load i32, ptr %v, align 4 + %add = add nsw i32 %5, 31 + br label %cond.end + +cond.false: ; preds = %for.body + %6 = load i32, ptr %v, align 4 + %sub = sub nsw i32 %6, 7 + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32 [ %add, %cond.true ], [ %sub, %cond.false ] + %7 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 4 + %8 = load i32, ptr %i, align 4 + %idxprom2 = sext i32 %8 to i64 + %arrayidx3 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 %idxprom2 + store i32 %cond, ptr %arrayidx3, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %scratch4 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 4 + %10 = load i32, ptr %i, align 4 + %idxprom5 = sext i32 %10 to i64 + %arrayidx6 = getelementptr inbounds [24 x i32], ptr %scratch4, i64 0, i64 %idxprom5 + %11 = load i32, ptr %arrayidx6, align 4 + %12 = load i32, ptr %total, align 4 + %add7 = add nsw i32 %12, %11 + store i32 %add7, ptr %total, align 4 + br label %for.inc + +for.inc: ; preds = %cond.end + %13 = load i32, ptr %i, align 4 + %inc = add nsw i32 %13, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !8 + +for.end: ; preds = %for.cond + %14 = load i32, ptr %total, align 4 + ret i32 %14 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @route_request(ptr noundef %req) #0 { +entry: + %retval = alloca i32, align 4 + %req.addr = alloca ptr, align 8 + store ptr %req, ptr %req.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %route = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 2 + %1 = load i32, ptr %route, align 4 + %cmp = icmp eq i32 %1, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + %2 = load ptr, ptr %req.addr, align 8 + %call = call i32 @apply_route_a(ptr noundef %2) + store i32 %call, ptr %retval, align 4 + br label %return + +if.end: ; preds = %entry + %3 = load ptr, ptr %req.addr, align 8 + %route1 = getelementptr inbounds nuw %struct.Request, ptr %3, i32 0, i32 2 + %4 = load i32, ptr %route1, align 4 + %cmp2 = icmp eq i32 %4, 1 + br i1 %cmp2, label %if.then3, label %if.end5 + +if.then3: ; preds = %if.end + %5 = load ptr, ptr %req.addr, align 8 + %call4 = call i32 @apply_route_b(ptr noundef %5) + store i32 %call4, ptr %retval, align 4 + br label %return + +if.end5: ; preds = %if.end + %6 = load ptr, ptr %req.addr, align 8 + %route6 = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 2 + %7 = load i32, ptr %route6, align 4 + %cmp7 = icmp eq i32 %7, 2 + br i1 %cmp7, label %if.then8, label %if.end10 + +if.then8: ; preds = %if.end5 + %8 = load ptr, ptr %req.addr, align 8 + %call9 = call i32 @apply_route_c(ptr noundef %8) + store i32 %call9, ptr %retval, align 4 + br label %return + +if.end10: ; preds = %if.end5 + %9 = load ptr, ptr %req.addr, align 8 + %call11 = call i32 @apply_route_a(ptr noundef %9) + %10 = load ptr, ptr %req.addr, align 8 + %call12 = call i32 @apply_route_c(ptr noundef %10) + %add = add nsw i32 %call11, %call12 + store i32 %add, ptr %retval, align 4 + br label %return + +return: ; preds = %if.end10, %if.then8, %if.then3, %if.then + %11 = load i32, ptr %retval, align 4 + ret i32 %11 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @compute_checksum(ptr noundef %req) #0 { +entry: + %req.addr = alloca ptr, align 8 + %h = alloca i32, align 4 + %i = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store i32 216613626, ptr %h, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 24 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, ptr %h, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 3 + %3 = load i32, ptr %i, align 4 + %idxprom = sext i32 %3 to i64 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 %idxprom + %4 = load i32, ptr %arrayidx, align 4 + %xor = xor i32 %1, %4 + %call = call i32 @mix32(i32 noundef %xor) + store i32 %call, ptr %h, align 4 + %5 = load i32, ptr %h, align 4 + %6 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 4 + %7 = load i32, ptr %i, align 4 + %idxprom1 = sext i32 %7 to i64 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 %idxprom1 + %8 = load i32, ptr %arrayidx2, align 4 + %add = add nsw i32 %5, %8 + %call3 = call i32 @mix32(i32 noundef %add) + store i32 %call3, ptr %h, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %9 = load i32, ptr %i, align 4 + %inc = add nsw i32 %9, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !9 + +for.end: ; preds = %for.cond + %10 = load i32, ptr %h, align 4 + ret i32 %10 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @classify_request(ptr noundef %req, i32 noundef %checksum) #0 { +entry: + %req.addr = alloca ptr, align 8 + %checksum.addr = alloca i32, align 4 + %c0 = alloca i32, align 4 + %c1 = alloca i32, align 4 + %c2 = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store i32 %checksum, ptr %checksum.addr, align 4 + %0 = load i32, ptr %checksum.addr, align 4 + %1 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %1, i32 0, i32 0 + %2 = load i32, ptr %id, align 4 + %xor = xor i32 %0, %2 + %and = and i32 %xor, 15 + store i32 %and, ptr %c0, align 4 + %3 = load i32, ptr %checksum.addr, align 4 + %shr = ashr i32 %3, 4 + %and1 = and i32 %shr, 15 + store i32 %and1, ptr %c1, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 1 + %5 = load i32, ptr %user, align 4 + %6 = load ptr, ptr %req.addr, align 8 + %route = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 2 + %7 = load i32, ptr %route, align 4 + %add = add nsw i32 %5, %7 + %and2 = and i32 %add, 15 + store i32 %and2, ptr %c2, align 4 + %8 = load i32, ptr %c0, align 4 + %9 = load i32, ptr %c1, align 4 + %add3 = add nsw i32 %8, %9 + %10 = load i32, ptr %c2, align 4 + %add4 = add nsw i32 %add3, %10 + %and5 = and i32 %add4, 15 + ret i32 %and5 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @build_response(ptr noundef %resp, ptr noundef %req, i32 noundef %score, i32 noundef %checksum) #0 { +entry: + %resp.addr = alloca ptr, align 8 + %req.addr = alloca ptr, align 8 + %score.addr = alloca i32, align 4 + %checksum.addr = alloca i32, align 4 + %i = alloca i32, align 4 + store ptr %resp, ptr %resp.addr, align 8 + store ptr %req, ptr %req.addr, align 8 + store i32 %score, ptr %score.addr, align 4 + store i32 %checksum, ptr %checksum.addr, align 4 + %0 = load ptr, ptr %req.addr, align 8 + %1 = load i32, ptr %score.addr, align 4 + %call = call i32 @authorize_request(ptr noundef %0, i32 noundef %1) + %tobool = icmp ne i32 %call, 0 + %2 = zext i1 %tobool to i64 + %cond = select i1 %tobool, i32 200, i32 403 + %3 = load ptr, ptr %resp.addr, align 8 + %status = getelementptr inbounds nuw %struct.Response, ptr %3, i32 0, i32 0 + store i32 %cond, ptr %status, align 4 + %4 = load i32, ptr %score.addr, align 4 + %5 = load i32, ptr %checksum.addr, align 4 + %xor = xor i32 %4, %5 + %and = and i32 %xor, 16383 + %6 = load ptr, ptr %resp.addr, align 8 + %cost = getelementptr inbounds nuw %struct.Response, ptr %6, i32 0, i32 1 + store i32 %and, ptr %cost, align 4 + %7 = load ptr, ptr %resp.addr, align 8 + %cost1 = getelementptr inbounds nuw %struct.Response, ptr %7, i32 0, i32 1 + %8 = load i32, ptr %cost1, align 4 + %and2 = and i32 %8, 127 + %add = add nsw i32 64, %and2 + %9 = load ptr, ptr %resp.addr, align 8 + %bytes = getelementptr inbounds nuw %struct.Response, ptr %9, i32 0, i32 2 + store i32 %add, ptr %bytes, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %10 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %10, 12 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %11 = load ptr, ptr %resp.addr, align 8 + %cost3 = getelementptr inbounds nuw %struct.Response, ptr %11, i32 0, i32 1 + %12 = load i32, ptr %cost3, align 4 + %13 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %13, i32 0, i32 4 + %14 = load i32, ptr %i, align 4 + %idxprom = sext i32 %14 to i64 + %arrayidx = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 %idxprom + %15 = load i32, ptr %arrayidx, align 4 + %add4 = add nsw i32 %12, %15 + %call5 = call i32 @mix32(i32 noundef %add4) + %and6 = and i32 %call5, 255 + %16 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %16, i32 0, i32 3 + %17 = load i32, ptr %i, align 4 + %idxprom7 = sext i32 %17 to i64 + %arrayidx8 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 %idxprom7 + store i32 %and6, ptr %arrayidx8, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %18 = load i32, ptr %i, align 4 + %inc = add nsw i32 %18, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !10 + +for.end: ; preds = %for.cond + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @dispatch_endpoint(ptr noundef %req, ptr noundef %resp, i32 noundef %cls) #0 { +entry: + %retval = alloca i32, align 4 + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %cls.addr = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + store i32 %cls, ptr %cls.addr, align 4 + %0 = load i32, ptr %cls.addr, align 4 + %and = and i32 %0, 15 + switch i32 %and, label %sw.default [ + i32 0, label %sw.bb + i32 1, label %sw.bb1 + i32 2, label %sw.bb3 + i32 3, label %sw.bb5 + i32 4, label %sw.bb7 + i32 5, label %sw.bb9 + i32 6, label %sw.bb11 + i32 7, label %sw.bb13 + i32 8, label %sw.bb15 + i32 9, label %sw.bb17 + i32 10, label %sw.bb19 + i32 11, label %sw.bb21 + i32 12, label %sw.bb23 + i32 13, label %sw.bb25 + i32 14, label %sw.bb27 + ] + +sw.bb: ; preds = %entry + %1 = load ptr, ptr %req.addr, align 8 + %2 = load ptr, ptr %resp.addr, align 8 + %call = call i32 @endpoint_search(ptr noundef %1, ptr noundef %2) + store i32 %call, ptr %retval, align 4 + br label %return + +sw.bb1: ; preds = %entry + %3 = load ptr, ptr %req.addr, align 8 + %4 = load ptr, ptr %resp.addr, align 8 + %call2 = call i32 @endpoint_profile(ptr noundef %3, ptr noundef %4) + store i32 %call2, ptr %retval, align 4 + br label %return + +sw.bb3: ; preds = %entry + %5 = load ptr, ptr %req.addr, align 8 + %6 = load ptr, ptr %resp.addr, align 8 + %call4 = call i32 @endpoint_checkout(ptr noundef %5, ptr noundef %6) + store i32 %call4, ptr %retval, align 4 + br label %return + +sw.bb5: ; preds = %entry + %7 = load ptr, ptr %req.addr, align 8 + %8 = load ptr, ptr %resp.addr, align 8 + %call6 = call i32 @endpoint_inventory(ptr noundef %7, ptr noundef %8) + store i32 %call6, ptr %retval, align 4 + br label %return + +sw.bb7: ; preds = %entry + %9 = load ptr, ptr %req.addr, align 8 + %10 = load ptr, ptr %resp.addr, align 8 + %call8 = call i32 @endpoint_recommend(ptr noundef %9, ptr noundef %10) + store i32 %call8, ptr %retval, align 4 + br label %return + +sw.bb9: ; preds = %entry + %11 = load ptr, ptr %req.addr, align 8 + %12 = load ptr, ptr %resp.addr, align 8 + %call10 = call i32 @endpoint_audit(ptr noundef %11, ptr noundef %12) + store i32 %call10, ptr %retval, align 4 + br label %return + +sw.bb11: ; preds = %entry + %13 = load ptr, ptr %req.addr, align 8 + %14 = load ptr, ptr %resp.addr, align 8 + %call12 = call i32 @endpoint_local_report(ptr noundef %13, ptr noundef %14) + store i32 %call12, ptr %retval, align 4 + br label %return + +sw.bb13: ; preds = %entry + %15 = load ptr, ptr %req.addr, align 8 + %16 = load ptr, ptr %resp.addr, align 8 + %call14 = call i32 @endpoint_local_cache(ptr noundef %15, ptr noundef %16) + store i32 %call14, ptr %retval, align 4 + br label %return + +sw.bb15: ; preds = %entry + %17 = load ptr, ptr %req.addr, align 8 + %18 = load ptr, ptr %resp.addr, align 8 + %call16 = call i32 @endpoint_billing(ptr noundef %17, ptr noundef %18) + store i32 %call16, ptr %retval, align 4 + br label %return + +sw.bb17: ; preds = %entry + %19 = load ptr, ptr %req.addr, align 8 + %20 = load ptr, ptr %resp.addr, align 8 + %call18 = call i32 @endpoint_shipping(ptr noundef %19, ptr noundef %20) + store i32 %call18, ptr %retval, align 4 + br label %return + +sw.bb19: ; preds = %entry + %21 = load ptr, ptr %req.addr, align 8 + %22 = load ptr, ptr %resp.addr, align 8 + %call20 = call i32 @endpoint_fraud_check(ptr noundef %21, ptr noundef %22) + store i32 %call20, ptr %retval, align 4 + br label %return + +sw.bb21: ; preds = %entry + %23 = load ptr, ptr %req.addr, align 8 + %24 = load ptr, ptr %resp.addr, align 8 + %call22 = call i32 @endpoint_notification(ptr noundef %23, ptr noundef %24) + store i32 %call22, ptr %retval, align 4 + br label %return + +sw.bb23: ; preds = %entry + %25 = load ptr, ptr %req.addr, align 8 + %26 = load ptr, ptr %resp.addr, align 8 + %call24 = call i32 @endpoint_session(ptr noundef %25, ptr noundef %26) + store i32 %call24, ptr %retval, align 4 + br label %return + +sw.bb25: ; preds = %entry + %27 = load ptr, ptr %req.addr, align 8 + %28 = load ptr, ptr %resp.addr, align 8 + %call26 = call i32 @endpoint_localization(ptr noundef %27, ptr noundef %28) + store i32 %call26, ptr %retval, align 4 + br label %return + +sw.bb27: ; preds = %entry + %29 = load ptr, ptr %req.addr, align 8 + %30 = load ptr, ptr %resp.addr, align 8 + %call28 = call i32 @endpoint_ab_test(ptr noundef %29, ptr noundef %30) + store i32 %call28, ptr %retval, align 4 + br label %return + +sw.default: ; preds = %entry + %31 = load ptr, ptr %req.addr, align 8 + %32 = load ptr, ptr %resp.addr, align 8 + %call29 = call i32 @endpoint_local_metrics(ptr noundef %31, ptr noundef %32) + store i32 %call29, ptr %retval, align 4 + br label %return + +return: ; preds = %sw.default, %sw.bb27, %sw.bb25, %sw.bb23, %sw.bb21, %sw.bb19, %sw.bb17, %sw.bb15, %sw.bb13, %sw.bb11, %sw.bb9, %sw.bb7, %sw.bb5, %sw.bb3, %sw.bb1, %sw.bb + %33 = load i32, ptr %retval, align 4 + ret i32 %33 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @serialize_response(ptr noundef %resp) #0 { +entry: + %resp.addr = alloca ptr, align 8 + %bytes = alloca i32, align 4 + %i = alloca i32, align 4 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %resp.addr, align 8 + %bytes1 = getelementptr inbounds nuw %struct.Response, ptr %0, i32 0, i32 2 + %1 = load i32, ptr %bytes1, align 4 + store i32 %1, ptr %bytes, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %2 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %2, 12 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %3 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %3, i32 0, i32 3 + %4 = load i32, ptr %i, align 4 + %idxprom = sext i32 %4 to i64 + %arrayidx = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 %idxprom + %5 = load i32, ptr %arrayidx, align 4 + %and = and i32 %5, 7 + %6 = load i32, ptr %bytes, align 4 + %add = add nsw i32 %6, %and + store i32 %add, ptr %bytes, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %7 = load i32, ptr %i, align 4 + %inc = add nsw i32 %7, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !11 + +for.end: ; preds = %for.cond + %8 = load i32, ptr %bytes, align 4 + ret i32 %8 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @mix32(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + %shl = shl i32 %0, 13 + %1 = load i32, ptr %x.addr, align 4 + %xor = xor i32 %1, %shl + store i32 %xor, ptr %x.addr, align 4 + %2 = load i32, ptr %x.addr, align 4 + %shr = ashr i32 %2, 17 + %3 = load i32, ptr %x.addr, align 4 + %xor1 = xor i32 %3, %shr + store i32 %xor1, ptr %x.addr, align 4 + %4 = load i32, ptr %x.addr, align 4 + %shl2 = shl i32 %4, 5 + %5 = load i32, ptr %x.addr, align 4 + %xor3 = xor i32 %5, %shl2 + store i32 %xor3, ptr %x.addr, align 4 + %6 = load i32, ptr %x.addr, align 4 + ret i32 %6 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @apply_route_a(ptr noundef %req) #0 { +entry: + %req.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + %i = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store i32 0, ptr %score, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 12 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %1, i32 0, i32 4 + %2 = load i32, ptr %i, align 4 + %idxprom = sext i32 %2 to i64 + %arrayidx = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 %idxprom + %3 = load i32, ptr %arrayidx, align 4 + %4 = load i32, ptr %i, align 4 + %add = add nsw i32 %4, 1 + %mul = mul nsw i32 %3, %add + %5 = load i32, ptr %score, align 4 + %add1 = add nsw i32 %5, %mul + store i32 %add1, ptr %score, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %6 = load i32, ptr %i, align 4 + %inc = add nsw i32 %6, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !12 + +for.end: ; preds = %for.cond + %7 = load i32, ptr %score, align 4 + ret i32 %7 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @apply_route_b(ptr noundef %req) #0 { +entry: + %req.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + %i = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store i32 1, ptr %score, align 4 + store i32 12, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 24 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %1, i32 0, i32 4 + %2 = load i32, ptr %i, align 4 + %idxprom = sext i32 %2 to i64 + %arrayidx = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 %idxprom + %3 = load i32, ptr %arrayidx, align 4 + %4 = load i32, ptr %i, align 4 + %mul = mul nsw i32 %4, 3 + %add = add nsw i32 %3, %mul + %5 = load i32, ptr %score, align 4 + %xor = xor i32 %5, %add + store i32 %xor, ptr %score, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %6 = load i32, ptr %i, align 4 + %inc = add nsw i32 %6, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !13 + +for.end: ; preds = %for.cond + %7 = load i32, ptr %score, align 4 + ret i32 %7 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @apply_route_c(ptr noundef %req) #0 { +entry: + %req.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + %i = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store i32 0, ptr %score, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 24 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %1, i32 0, i32 4 + %2 = load i32, ptr %i, align 4 + %idxprom = sext i32 %2 to i64 + %arrayidx = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 %idxprom + %3 = load i32, ptr %arrayidx, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %scratch1 = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 4 + %5 = load i32, ptr %i, align 4 + %add = add nsw i32 %5, 1 + %idxprom2 = sext i32 %add to i64 + %arrayidx3 = getelementptr inbounds [24 x i32], ptr %scratch1, i64 0, i64 %idxprom2 + %6 = load i32, ptr %arrayidx3, align 4 + %xor = xor i32 %3, %6 + %7 = load i32, ptr %score, align 4 + %add4 = add nsw i32 %7, %xor + store i32 %add4, ptr %score, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %8 = load i32, ptr %i, align 4 + %add5 = add nsw i32 %8, 2 + store i32 %add5, ptr %i, align 4 + br label %for.cond, !llvm.loop !14 + +for.end: ; preds = %for.cond + %9 = load i32, ptr %score, align 4 + ret i32 %9 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @authorize_request(ptr noundef %req, i32 noundef %score) #0 { +entry: + %req.addr = alloca ptr, align 8 + %score.addr = alloca i32, align 4 + %token = alloca i32, align 4 + %class_id = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store i32 %score, ptr %score.addr, align 4 + %0 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 1 + %1 = load i32, ptr %user, align 4 + %2 = load i32, ptr %score.addr, align 4 + %add = add nsw i32 %1, %2 + %call = call i32 @mix32(i32 noundef %add) + store i32 %call, ptr %token, align 4 + %3 = load i32, ptr %token, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 0 + %5 = load i32, ptr %id, align 4 + %xor = xor i32 %3, %5 + %and = and i32 %xor, 7 + store i32 %and, ptr %class_id, align 4 + %6 = load i32, ptr %class_id, align 4 + %cmp = icmp ne i32 %6, 6 + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_search(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 0 + %1 = load i32, ptr %id, align 4 + %2 = load ptr, ptr %resp.addr, align 8 + %cost = getelementptr inbounds nuw %struct.Response, ptr %2, i32 0, i32 1 + %3 = load i32, ptr %cost, align 4 + %add = add nsw i32 %1, %3 + store i32 %add, ptr %score, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 0 + %5 = load i32, ptr %arrayidx, align 4 + %mul = mul nsw i32 %5, 3 + %6 = load i32, ptr %score, align 4 + %add1 = add nsw i32 %6, %mul + store i32 %add1, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 4 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 3 + %8 = load i32, ptr %arrayidx2, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %payload3 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 3 + %arrayidx4 = getelementptr inbounds [24 x i32], ptr %payload3, i64 0, i64 5 + %10 = load i32, ptr %arrayidx4, align 4 + %add5 = add nsw i32 %8, %10 + %11 = load i32, ptr %score, align 4 + %xor = xor i32 %11, %add5 + store i32 %xor, ptr %score, align 4 + %12 = load ptr, ptr %req.addr, align 8 + %scratch6 = getelementptr inbounds nuw %struct.Request, ptr %12, i32 0, i32 4 + %arrayidx7 = getelementptr inbounds [24 x i32], ptr %scratch6, i64 0, i64 7 + %13 = load i32, ptr %arrayidx7, align 4 + %14 = load i32, ptr %score, align 4 + %add8 = add nsw i32 %13, %14 + %call = call i32 @mix32(i32 noundef %add8) + %15 = load i32, ptr %score, align 4 + %add9 = add nsw i32 %15, %call + store i32 %add9, ptr %score, align 4 + %16 = load ptr, ptr %req.addr, align 8 + %payload10 = getelementptr inbounds nuw %struct.Request, ptr %16, i32 0, i32 3 + %arrayidx11 = getelementptr inbounds [24 x i32], ptr %payload10, i64 0, i64 11 + %17 = load i32, ptr %arrayidx11, align 4 + %18 = load ptr, ptr %req.addr, align 8 + %scratch12 = getelementptr inbounds nuw %struct.Request, ptr %18, i32 0, i32 4 + %arrayidx13 = getelementptr inbounds [24 x i32], ptr %scratch12, i64 0, i64 13 + %19 = load i32, ptr %arrayidx13, align 4 + %add14 = add nsw i32 %17, %19 + %20 = load i32, ptr %score, align 4 + %xor15 = xor i32 %20, %add14 + store i32 %xor15, ptr %score, align 4 + %21 = load i32, ptr %score, align 4 + %and = and i32 %21, 255 + %22 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %22, i32 0, i32 3 + %arrayidx16 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 0 + store i32 %and, ptr %arrayidx16, align 4 + %23 = load i32, ptr %score, align 4 + %shr = ashr i32 %23, 3 + %and17 = and i32 %shr, 255 + %24 = load ptr, ptr %resp.addr, align 8 + %tags18 = getelementptr inbounds nuw %struct.Response, ptr %24, i32 0, i32 3 + %arrayidx19 = getelementptr inbounds [12 x i32], ptr %tags18, i64 0, i64 1 + store i32 %and17, ptr %arrayidx19, align 4 + %25 = load i32, ptr %score, align 4 + ret i32 %25 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_profile(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 1 + %1 = load i32, ptr %user, align 4 + %mul = mul nsw i32 %1, 17 + store i32 %mul, ptr %score, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 2 + %3 = load i32, ptr %arrayidx, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %payload1 = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 3 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %payload1, i64 0, i64 4 + %5 = load i32, ptr %arrayidx2, align 4 + %add = add nsw i32 %3, %5 + %6 = load i32, ptr %score, align 4 + %add3 = add nsw i32 %6, %add + store i32 %add3, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 4 + %arrayidx4 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 6 + %8 = load i32, ptr %arrayidx4, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %scratch5 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 4 + %arrayidx6 = getelementptr inbounds [24 x i32], ptr %scratch5, i64 0, i64 8 + %10 = load i32, ptr %arrayidx6, align 4 + %add7 = add nsw i32 %8, %10 + %call = call i32 @mix32(i32 noundef %add7) + %11 = load i32, ptr %score, align 4 + %xor = xor i32 %11, %call + store i32 %xor, ptr %score, align 4 + %12 = load ptr, ptr %req.addr, align 8 + %payload8 = getelementptr inbounds nuw %struct.Request, ptr %12, i32 0, i32 3 + %arrayidx9 = getelementptr inbounds [24 x i32], ptr %payload8, i64 0, i64 10 + %13 = load i32, ptr %arrayidx9, align 4 + %mul10 = mul nsw i32 %13, 5 + %14 = load i32, ptr %score, align 4 + %add11 = add nsw i32 %14, %mul10 + store i32 %add11, ptr %score, align 4 + %15 = load ptr, ptr %req.addr, align 8 + %scratch12 = getelementptr inbounds nuw %struct.Request, ptr %15, i32 0, i32 4 + %arrayidx13 = getelementptr inbounds [24 x i32], ptr %scratch12, i64 0, i64 12 + %16 = load i32, ptr %arrayidx13, align 4 + %17 = load ptr, ptr %req.addr, align 8 + %payload14 = getelementptr inbounds nuw %struct.Request, ptr %17, i32 0, i32 3 + %arrayidx15 = getelementptr inbounds [24 x i32], ptr %payload14, i64 0, i64 14 + %18 = load i32, ptr %arrayidx15, align 4 + %add16 = add nsw i32 %16, %18 + %19 = load i32, ptr %score, align 4 + %xor17 = xor i32 %19, %add16 + store i32 %xor17, ptr %score, align 4 + %20 = load i32, ptr %score, align 4 + %and = and i32 %20, 255 + %21 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %21, i32 0, i32 3 + %arrayidx18 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 2 + store i32 %and, ptr %arrayidx18, align 4 + %22 = load i32, ptr %score, align 4 + %shr = ashr i32 %22, 2 + %and19 = and i32 %shr, 255 + %23 = load ptr, ptr %resp.addr, align 8 + %tags20 = getelementptr inbounds nuw %struct.Response, ptr %23, i32 0, i32 3 + %arrayidx21 = getelementptr inbounds [12 x i32], ptr %tags20, i64 0, i64 3 + store i32 %and19, ptr %arrayidx21, align 4 + %24 = load i32, ptr %score, align 4 + ret i32 %24 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_checkout(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %resp.addr, align 8 + %bytes = getelementptr inbounds nuw %struct.Response, ptr %0, i32 0, i32 2 + %1 = load i32, ptr %bytes, align 4 + store i32 %1, ptr %score, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 1 + %3 = load i32, ptr %arrayidx, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 4 + %arrayidx1 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 1 + %5 = load i32, ptr %arrayidx1, align 4 + %mul = mul nsw i32 %3, %5 + %6 = load i32, ptr %score, align 4 + %add = add nsw i32 %6, %mul + store i32 %add, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %payload2 = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 3 + %arrayidx3 = getelementptr inbounds [24 x i32], ptr %payload2, i64 0, i64 3 + %8 = load i32, ptr %arrayidx3, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %scratch4 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 4 + %arrayidx5 = getelementptr inbounds [24 x i32], ptr %scratch4, i64 0, i64 9 + %10 = load i32, ptr %arrayidx5, align 4 + %add6 = add nsw i32 %8, %10 + %11 = load i32, ptr %score, align 4 + %xor = xor i32 %11, %add6 + store i32 %xor, ptr %score, align 4 + %12 = load ptr, ptr %req.addr, align 8 + %payload7 = getelementptr inbounds nuw %struct.Request, ptr %12, i32 0, i32 3 + %arrayidx8 = getelementptr inbounds [24 x i32], ptr %payload7, i64 0, i64 15 + %13 = load i32, ptr %arrayidx8, align 4 + %14 = load i32, ptr %score, align 4 + %add9 = add nsw i32 %13, %14 + %call = call i32 @mix32(i32 noundef %add9) + %15 = load i32, ptr %score, align 4 + %add10 = add nsw i32 %15, %call + store i32 %add10, ptr %score, align 4 + %16 = load ptr, ptr %req.addr, align 8 + %scratch11 = getelementptr inbounds nuw %struct.Request, ptr %16, i32 0, i32 4 + %arrayidx12 = getelementptr inbounds [24 x i32], ptr %scratch11, i64 0, i64 17 + %17 = load i32, ptr %arrayidx12, align 4 + %18 = load ptr, ptr %req.addr, align 8 + %payload13 = getelementptr inbounds nuw %struct.Request, ptr %18, i32 0, i32 3 + %arrayidx14 = getelementptr inbounds [24 x i32], ptr %payload13, i64 0, i64 19 + %19 = load i32, ptr %arrayidx14, align 4 + %add15 = add nsw i32 %17, %19 + %20 = load i32, ptr %score, align 4 + %xor16 = xor i32 %20, %add15 + store i32 %xor16, ptr %score, align 4 + %21 = load i32, ptr %score, align 4 + %and = and i32 %21, 255 + %22 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %22, i32 0, i32 3 + %arrayidx17 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 4 + store i32 %and, ptr %arrayidx17, align 4 + %23 = load i32, ptr %score, align 4 + %shr = ashr i32 %23, 4 + %and18 = and i32 %shr, 255 + %24 = load ptr, ptr %resp.addr, align 8 + %tags19 = getelementptr inbounds nuw %struct.Response, ptr %24, i32 0, i32 3 + %arrayidx20 = getelementptr inbounds [12 x i32], ptr %tags19, i64 0, i64 5 + store i32 %and18, ptr %arrayidx20, align 4 + %25 = load i32, ptr %score, align 4 + ret i32 %25 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_inventory(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %route = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 2 + %1 = load i32, ptr %route, align 4 + %add = add nsw i32 %1, 31 + store i32 %add, ptr %score, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 4 + %arrayidx = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 0 + %3 = load i32, ptr %arrayidx, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %scratch1 = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 4 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %scratch1, i64 0, i64 2 + %5 = load i32, ptr %arrayidx2, align 4 + %add3 = add nsw i32 %3, %5 + %6 = load i32, ptr %score, align 4 + %add4 = add nsw i32 %6, %add3 + store i32 %add4, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 3 + %arrayidx5 = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 6 + %8 = load i32, ptr %arrayidx5, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %payload6 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 3 + %arrayidx7 = getelementptr inbounds [24 x i32], ptr %payload6, i64 0, i64 8 + %10 = load i32, ptr %arrayidx7, align 4 + %add8 = add nsw i32 %8, %10 + %call = call i32 @mix32(i32 noundef %add8) + %11 = load i32, ptr %score, align 4 + %xor = xor i32 %11, %call + store i32 %xor, ptr %score, align 4 + %12 = load ptr, ptr %req.addr, align 8 + %scratch9 = getelementptr inbounds nuw %struct.Request, ptr %12, i32 0, i32 4 + %arrayidx10 = getelementptr inbounds [24 x i32], ptr %scratch9, i64 0, i64 16 + %13 = load i32, ptr %arrayidx10, align 4 + %mul = mul nsw i32 %13, 7 + %14 = load i32, ptr %score, align 4 + %add11 = add nsw i32 %14, %mul + store i32 %add11, ptr %score, align 4 + %15 = load ptr, ptr %req.addr, align 8 + %payload12 = getelementptr inbounds nuw %struct.Request, ptr %15, i32 0, i32 3 + %arrayidx13 = getelementptr inbounds [24 x i32], ptr %payload12, i64 0, i64 20 + %16 = load i32, ptr %arrayidx13, align 4 + %17 = load ptr, ptr %req.addr, align 8 + %scratch14 = getelementptr inbounds nuw %struct.Request, ptr %17, i32 0, i32 4 + %arrayidx15 = getelementptr inbounds [24 x i32], ptr %scratch14, i64 0, i64 22 + %18 = load i32, ptr %arrayidx15, align 4 + %add16 = add nsw i32 %16, %18 + %19 = load i32, ptr %score, align 4 + %xor17 = xor i32 %19, %add16 + store i32 %xor17, ptr %score, align 4 + %20 = load i32, ptr %score, align 4 + %and = and i32 %20, 255 + %21 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %21, i32 0, i32 3 + %arrayidx18 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 6 + store i32 %and, ptr %arrayidx18, align 4 + %22 = load i32, ptr %score, align 4 + %shr = ashr i32 %22, 5 + %and19 = and i32 %shr, 255 + %23 = load ptr, ptr %resp.addr, align 8 + %tags20 = getelementptr inbounds nuw %struct.Response, ptr %23, i32 0, i32 3 + %arrayidx21 = getelementptr inbounds [12 x i32], ptr %tags20, i64 0, i64 7 + store i32 %and19, ptr %arrayidx21, align 4 + %24 = load i32, ptr %score, align 4 + ret i32 %24 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_recommend(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 0 + %1 = load i32, ptr %id, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 1 + %3 = load i32, ptr %user, align 4 + %xor = xor i32 %1, %3 + store i32 %xor, ptr %score, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 7 + %5 = load i32, ptr %arrayidx, align 4 + %6 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 4 + %arrayidx1 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 4 + %7 = load i32, ptr %arrayidx1, align 4 + %add = add nsw i32 %5, %7 + %call = call i32 @mix32(i32 noundef %add) + %8 = load i32, ptr %score, align 4 + %add2 = add nsw i32 %8, %call + store i32 %add2, ptr %score, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %payload3 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 3 + %arrayidx4 = getelementptr inbounds [24 x i32], ptr %payload3, i64 0, i64 9 + %10 = load i32, ptr %arrayidx4, align 4 + %mul = mul nsw i32 %10, 11 + %11 = load i32, ptr %score, align 4 + %xor5 = xor i32 %11, %mul + store i32 %xor5, ptr %score, align 4 + %12 = load ptr, ptr %req.addr, align 8 + %scratch6 = getelementptr inbounds nuw %struct.Request, ptr %12, i32 0, i32 4 + %arrayidx7 = getelementptr inbounds [24 x i32], ptr %scratch6, i64 0, i64 18 + %13 = load i32, ptr %arrayidx7, align 4 + %14 = load ptr, ptr %req.addr, align 8 + %payload8 = getelementptr inbounds nuw %struct.Request, ptr %14, i32 0, i32 3 + %arrayidx9 = getelementptr inbounds [24 x i32], ptr %payload8, i64 0, i64 21 + %15 = load i32, ptr %arrayidx9, align 4 + %add10 = add nsw i32 %13, %15 + %16 = load i32, ptr %score, align 4 + %add11 = add nsw i32 %16, %add10 + store i32 %add11, ptr %score, align 4 + %17 = load i32, ptr %score, align 4 + %18 = load ptr, ptr %req.addr, align 8 + %scratch12 = getelementptr inbounds nuw %struct.Request, ptr %18, i32 0, i32 4 + %arrayidx13 = getelementptr inbounds [24 x i32], ptr %scratch12, i64 0, i64 23 + %19 = load i32, ptr %arrayidx13, align 4 + %add14 = add nsw i32 %17, %19 + %call15 = call i32 @mix32(i32 noundef %add14) + %20 = load i32, ptr %score, align 4 + %xor16 = xor i32 %20, %call15 + store i32 %xor16, ptr %score, align 4 + %21 = load i32, ptr %score, align 4 + %and = and i32 %21, 255 + %22 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %22, i32 0, i32 3 + %arrayidx17 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 8 + store i32 %and, ptr %arrayidx17, align 4 + %23 = load i32, ptr %score, align 4 + %shr = ashr i32 %23, 6 + %and18 = and i32 %shr, 255 + %24 = load ptr, ptr %resp.addr, align 8 + %tags19 = getelementptr inbounds nuw %struct.Response, ptr %24, i32 0, i32 3 + %arrayidx20 = getelementptr inbounds [12 x i32], ptr %tags19, i64 0, i64 9 + store i32 %and18, ptr %arrayidx20, align 4 + %25 = load i32, ptr %score, align 4 + ret i32 %25 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_audit(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %resp.addr, align 8 + %status = getelementptr inbounds nuw %struct.Response, ptr %0, i32 0, i32 0 + %1 = load i32, ptr %status, align 4 + store i32 %1, ptr %score, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 12 + %3 = load i32, ptr %arrayidx, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %payload1 = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 3 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %payload1, i64 0, i64 13 + %5 = load i32, ptr %arrayidx2, align 4 + %add = add nsw i32 %3, %5 + %6 = load i32, ptr %score, align 4 + %add3 = add nsw i32 %6, %add + store i32 %add3, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 4 + %arrayidx4 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 5 + %8 = load i32, ptr %arrayidx4, align 4 + %mul = mul nsw i32 %8, 13 + %9 = load i32, ptr %score, align 4 + %xor = xor i32 %9, %mul + store i32 %xor, ptr %score, align 4 + %10 = load ptr, ptr %req.addr, align 8 + %scratch5 = getelementptr inbounds nuw %struct.Request, ptr %10, i32 0, i32 4 + %arrayidx6 = getelementptr inbounds [24 x i32], ptr %scratch5, i64 0, i64 10 + %11 = load i32, ptr %arrayidx6, align 4 + %12 = load ptr, ptr %req.addr, align 8 + %payload7 = getelementptr inbounds nuw %struct.Request, ptr %12, i32 0, i32 3 + %arrayidx8 = getelementptr inbounds [24 x i32], ptr %payload7, i64 0, i64 16 + %13 = load i32, ptr %arrayidx8, align 4 + %add9 = add nsw i32 %11, %13 + %call = call i32 @mix32(i32 noundef %add9) + %14 = load i32, ptr %score, align 4 + %add10 = add nsw i32 %14, %call + store i32 %add10, ptr %score, align 4 + %15 = load ptr, ptr %req.addr, align 8 + %scratch11 = getelementptr inbounds nuw %struct.Request, ptr %15, i32 0, i32 4 + %arrayidx12 = getelementptr inbounds [24 x i32], ptr %scratch11, i64 0, i64 21 + %16 = load i32, ptr %arrayidx12, align 4 + %17 = load ptr, ptr %resp.addr, align 8 + %cost = getelementptr inbounds nuw %struct.Response, ptr %17, i32 0, i32 1 + %18 = load i32, ptr %cost, align 4 + %add13 = add nsw i32 %16, %18 + %19 = load i32, ptr %score, align 4 + %xor14 = xor i32 %19, %add13 + store i32 %xor14, ptr %score, align 4 + %20 = load i32, ptr %score, align 4 + %and = and i32 %20, 255 + %21 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %21, i32 0, i32 3 + %arrayidx15 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 10 + store i32 %and, ptr %arrayidx15, align 4 + %22 = load i32, ptr %score, align 4 + %shr = ashr i32 %22, 7 + %and16 = and i32 %shr, 255 + %23 = load ptr, ptr %resp.addr, align 8 + %tags17 = getelementptr inbounds nuw %struct.Response, ptr %23, i32 0, i32 3 + %arrayidx18 = getelementptr inbounds [12 x i32], ptr %tags17, i64 0, i64 11 + store i32 %and16, ptr %arrayidx18, align 4 + %24 = load i32, ptr %score, align 4 + ret i32 %24 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_local_report(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 0 + %1 = load i32, ptr %arrayidx, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %payload1 = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 3 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %payload1, i64 0, i64 23 + %3 = load i32, ptr %arrayidx2, align 4 + %add = add nsw i32 %1, %3 + store i32 %add, ptr %score, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 4 + %arrayidx3 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 1 + %5 = load i32, ptr %arrayidx3, align 4 + %6 = load ptr, ptr %req.addr, align 8 + %scratch4 = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 4 + %arrayidx5 = getelementptr inbounds [24 x i32], ptr %scratch4, i64 0, i64 22 + %7 = load i32, ptr %arrayidx5, align 4 + %add6 = add nsw i32 %5, %7 + %8 = load i32, ptr %score, align 4 + %xor = xor i32 %8, %add6 + store i32 %xor, ptr %score, align 4 + %9 = load i32, ptr %score, align 4 + %10 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %10, i32 0, i32 0 + %11 = load i32, ptr %id, align 4 + %add7 = add nsw i32 %9, %11 + %call = call i32 @mix32(i32 noundef %add7) + %12 = load i32, ptr %score, align 4 + %add8 = add nsw i32 %12, %call + store i32 %add8, ptr %score, align 4 + %13 = load ptr, ptr %resp.addr, align 8 + %bytes = getelementptr inbounds nuw %struct.Response, ptr %13, i32 0, i32 2 + %14 = load i32, ptr %bytes, align 4 + %15 = load ptr, ptr %req.addr, align 8 + %route = getelementptr inbounds nuw %struct.Request, ptr %15, i32 0, i32 2 + %16 = load i32, ptr %route, align 4 + %add9 = add nsw i32 %14, %16 + %17 = load i32, ptr %score, align 4 + %xor10 = xor i32 %17, %add9 + store i32 %xor10, ptr %score, align 4 + %18 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %18, i32 0, i32 1 + %19 = load i32, ptr %user, align 4 + %mul = mul nsw i32 %19, 19 + %20 = load i32, ptr %score, align 4 + %add11 = add nsw i32 %20, %mul + store i32 %add11, ptr %score, align 4 + %21 = load i32, ptr %score, align 4 + ret i32 %21 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_local_cache(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 4 + %arrayidx = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 2 + %1 = load i32, ptr %arrayidx, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %scratch1 = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 4 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %scratch1, i64 0, i64 20 + %3 = load i32, ptr %arrayidx2, align 4 + %add = add nsw i32 %1, %3 + store i32 %add, ptr %score, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 3 + %arrayidx3 = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 5 + %5 = load i32, ptr %arrayidx3, align 4 + %6 = load ptr, ptr %req.addr, align 8 + %payload4 = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 3 + %arrayidx5 = getelementptr inbounds [24 x i32], ptr %payload4, i64 0, i64 18 + %7 = load i32, ptr %arrayidx5, align 4 + %add6 = add nsw i32 %5, %7 + %call = call i32 @mix32(i32 noundef %add6) + %8 = load i32, ptr %score, align 4 + %add7 = add nsw i32 %8, %call + store i32 %add7, ptr %score, align 4 + %9 = load ptr, ptr %resp.addr, align 8 + %cost = getelementptr inbounds nuw %struct.Response, ptr %9, i32 0, i32 1 + %10 = load i32, ptr %cost, align 4 + %11 = load ptr, ptr %req.addr, align 8 + %payload8 = getelementptr inbounds nuw %struct.Request, ptr %11, i32 0, i32 3 + %arrayidx9 = getelementptr inbounds [24 x i32], ptr %payload8, i64 0, i64 6 + %12 = load i32, ptr %arrayidx9, align 4 + %add10 = add nsw i32 %10, %12 + %13 = load i32, ptr %score, align 4 + %xor = xor i32 %13, %add10 + store i32 %xor, ptr %score, align 4 + %14 = load ptr, ptr %req.addr, align 8 + %scratch11 = getelementptr inbounds nuw %struct.Request, ptr %14, i32 0, i32 4 + %arrayidx12 = getelementptr inbounds [24 x i32], ptr %scratch11, i64 0, i64 14 + %15 = load i32, ptr %arrayidx12, align 4 + %mul = mul nsw i32 %15, 23 + %16 = load i32, ptr %score, align 4 + %add13 = add nsw i32 %16, %mul + store i32 %add13, ptr %score, align 4 + %17 = load i32, ptr %score, align 4 + %18 = load ptr, ptr %resp.addr, align 8 + %status = getelementptr inbounds nuw %struct.Response, ptr %18, i32 0, i32 0 + %19 = load i32, ptr %status, align 4 + %add14 = add nsw i32 %17, %19 + %call15 = call i32 @mix32(i32 noundef %add14) + %20 = load i32, ptr %score, align 4 + %xor16 = xor i32 %20, %call15 + store i32 %xor16, ptr %score, align 4 + %21 = load i32, ptr %score, align 4 + ret i32 %21 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_billing(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 1 + %1 = load i32, ptr %user, align 4 + %2 = load ptr, ptr %resp.addr, align 8 + %bytes = getelementptr inbounds nuw %struct.Response, ptr %2, i32 0, i32 2 + %3 = load i32, ptr %bytes, align 4 + %add = add nsw i32 %1, %3 + store i32 %add, ptr %score, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 4 + %5 = load i32, ptr %arrayidx, align 4 + %mul = mul nsw i32 %5, 29 + %6 = load i32, ptr %score, align 4 + %add1 = add nsw i32 %6, %mul + store i32 %add1, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 4 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 6 + %8 = load i32, ptr %arrayidx2, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %payload3 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 3 + %arrayidx4 = getelementptr inbounds [24 x i32], ptr %payload3, i64 0, i64 17 + %10 = load i32, ptr %arrayidx4, align 4 + %add5 = add nsw i32 %8, %10 + %11 = load i32, ptr %score, align 4 + %xor = xor i32 %11, %add5 + store i32 %xor, ptr %score, align 4 + %12 = load ptr, ptr %resp.addr, align 8 + %cost = getelementptr inbounds nuw %struct.Response, ptr %12, i32 0, i32 1 + %13 = load i32, ptr %cost, align 4 + %14 = load ptr, ptr %req.addr, align 8 + %scratch6 = getelementptr inbounds nuw %struct.Request, ptr %14, i32 0, i32 4 + %arrayidx7 = getelementptr inbounds [24 x i32], ptr %scratch6, i64 0, i64 19 + %15 = load i32, ptr %arrayidx7, align 4 + %add8 = add nsw i32 %13, %15 + %call = call i32 @mix32(i32 noundef %add8) + %16 = load i32, ptr %score, align 4 + %add9 = add nsw i32 %16, %call + store i32 %add9, ptr %score, align 4 + %17 = load ptr, ptr %req.addr, align 8 + %payload10 = getelementptr inbounds nuw %struct.Request, ptr %17, i32 0, i32 3 + %arrayidx11 = getelementptr inbounds [24 x i32], ptr %payload10, i64 0, i64 22 + %18 = load i32, ptr %arrayidx11, align 4 + %19 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %19, i32 0, i32 0 + %20 = load i32, ptr %id, align 4 + %add12 = add nsw i32 %18, %20 + %21 = load i32, ptr %score, align 4 + %xor13 = xor i32 %21, %add12 + store i32 %xor13, ptr %score, align 4 + %22 = load i32, ptr %score, align 4 + %and = and i32 %22, 255 + %23 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %23, i32 0, i32 3 + %arrayidx14 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 0 + %24 = load i32, ptr %arrayidx14, align 4 + %xor15 = xor i32 %24, %and + store i32 %xor15, ptr %arrayidx14, align 4 + %25 = load i32, ptr %score, align 4 + ret i32 %25 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_shipping(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %route = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 2 + %1 = load i32, ptr %route, align 4 + %mul = mul nsw i32 %1, 41 + store i32 %mul, ptr %score, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 4 + %arrayidx = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 8 + %3 = load i32, ptr %arrayidx, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %scratch1 = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 4 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %scratch1, i64 0, i64 15 + %5 = load i32, ptr %arrayidx2, align 4 + %add = add nsw i32 %3, %5 + %6 = load i32, ptr %score, align 4 + %add3 = add nsw i32 %6, %add + store i32 %add3, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 3 + %arrayidx4 = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 1 + %8 = load i32, ptr %arrayidx4, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %payload5 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 3 + %arrayidx6 = getelementptr inbounds [24 x i32], ptr %payload5, i64 0, i64 21 + %10 = load i32, ptr %arrayidx6, align 4 + %add7 = add nsw i32 %8, %10 + %call = call i32 @mix32(i32 noundef %add7) + %11 = load i32, ptr %score, align 4 + %xor = xor i32 %11, %call + store i32 %xor, ptr %score, align 4 + %12 = load ptr, ptr %resp.addr, align 8 + %bytes = getelementptr inbounds nuw %struct.Response, ptr %12, i32 0, i32 2 + %13 = load i32, ptr %bytes, align 4 + %mul8 = mul nsw i32 %13, 3 + %14 = load i32, ptr %score, align 4 + %add9 = add nsw i32 %14, %mul8 + store i32 %add9, ptr %score, align 4 + %15 = load ptr, ptr %req.addr, align 8 + %scratch10 = getelementptr inbounds nuw %struct.Request, ptr %15, i32 0, i32 4 + %arrayidx11 = getelementptr inbounds [24 x i32], ptr %scratch10, i64 0, i64 11 + %16 = load i32, ptr %arrayidx11, align 4 + %17 = load ptr, ptr %req.addr, align 8 + %payload12 = getelementptr inbounds nuw %struct.Request, ptr %17, i32 0, i32 3 + %arrayidx13 = getelementptr inbounds [24 x i32], ptr %payload12, i64 0, i64 13 + %18 = load i32, ptr %arrayidx13, align 4 + %add14 = add nsw i32 %16, %18 + %19 = load i32, ptr %score, align 4 + %xor15 = xor i32 %19, %add14 + store i32 %xor15, ptr %score, align 4 + %20 = load i32, ptr %score, align 4 + %shr = ashr i32 %20, 1 + %and = and i32 %shr, 255 + %21 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %21, i32 0, i32 3 + %arrayidx16 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 1 + %22 = load i32, ptr %arrayidx16, align 4 + %xor17 = xor i32 %22, %and + store i32 %xor17, ptr %arrayidx16, align 4 + %23 = load i32, ptr %score, align 4 + ret i32 %23 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_fraud_check(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 0 + %1 = load i32, ptr %id, align 4 + %2 = load ptr, ptr %resp.addr, align 8 + %status = getelementptr inbounds nuw %struct.Response, ptr %2, i32 0, i32 0 + %3 = load i32, ptr %status, align 4 + %xor = xor i32 %1, %3 + store i32 %xor, ptr %score, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 1 + %5 = load i32, ptr %user, align 4 + %6 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 2 + %7 = load i32, ptr %arrayidx, align 4 + %add = add nsw i32 %5, %7 + %call = call i32 @mix32(i32 noundef %add) + %8 = load i32, ptr %score, align 4 + %add1 = add nsw i32 %8, %call + store i32 %add1, ptr %score, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 4 + %arrayidx2 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 7 + %10 = load i32, ptr %arrayidx2, align 4 + %mul = mul nsw i32 %10, 31 + %11 = load i32, ptr %score, align 4 + %xor3 = xor i32 %11, %mul + store i32 %xor3, ptr %score, align 4 + %12 = load ptr, ptr %req.addr, align 8 + %payload4 = getelementptr inbounds nuw %struct.Request, ptr %12, i32 0, i32 3 + %arrayidx5 = getelementptr inbounds [24 x i32], ptr %payload4, i64 0, i64 18 + %13 = load i32, ptr %arrayidx5, align 4 + %14 = load ptr, ptr %req.addr, align 8 + %scratch6 = getelementptr inbounds nuw %struct.Request, ptr %14, i32 0, i32 4 + %arrayidx7 = getelementptr inbounds [24 x i32], ptr %scratch6, i64 0, i64 20 + %15 = load i32, ptr %arrayidx7, align 4 + %add8 = add nsw i32 %13, %15 + %16 = load i32, ptr %score, align 4 + %add9 = add nsw i32 %16, %add8 + store i32 %add9, ptr %score, align 4 + %17 = load i32, ptr %score, align 4 + %18 = load ptr, ptr %resp.addr, align 8 + %cost = getelementptr inbounds nuw %struct.Response, ptr %18, i32 0, i32 1 + %19 = load i32, ptr %cost, align 4 + %add10 = add nsw i32 %17, %19 + %call11 = call i32 @mix32(i32 noundef %add10) + %20 = load i32, ptr %score, align 4 + %xor12 = xor i32 %20, %call11 + store i32 %xor12, ptr %score, align 4 + %21 = load i32, ptr %score, align 4 + %shr = ashr i32 %21, 2 + %and = and i32 %shr, 255 + %22 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %22, i32 0, i32 3 + %arrayidx13 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 2 + %23 = load i32, ptr %arrayidx13, align 4 + %xor14 = xor i32 %23, %and + store i32 %xor14, ptr %arrayidx13, align 4 + %24 = load i32, ptr %score, align 4 + ret i32 %24 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_notification(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %resp.addr, align 8 + %bytes = getelementptr inbounds nuw %struct.Response, ptr %0, i32 0, i32 2 + %1 = load i32, ptr %bytes, align 4 + %add = add nsw i32 %1, 97 + store i32 %add, ptr %score, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 3 + %3 = load i32, ptr %arrayidx, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 4 + %arrayidx1 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 4 + %5 = load i32, ptr %arrayidx1, align 4 + %add2 = add nsw i32 %3, %5 + %6 = load i32, ptr %score, align 4 + %add3 = add nsw i32 %6, %add2 + store i32 %add3, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %payload4 = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 3 + %arrayidx5 = getelementptr inbounds [24 x i32], ptr %payload4, i64 0, i64 12 + %8 = load i32, ptr %arrayidx5, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %scratch6 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 4 + %arrayidx7 = getelementptr inbounds [24 x i32], ptr %scratch6, i64 0, i64 16 + %10 = load i32, ptr %arrayidx7, align 4 + %add8 = add nsw i32 %8, %10 + %call = call i32 @mix32(i32 noundef %add8) + %11 = load i32, ptr %score, align 4 + %xor = xor i32 %11, %call + store i32 %xor, ptr %score, align 4 + %12 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %12, i32 0, i32 1 + %13 = load i32, ptr %user, align 4 + %mul = mul nsw i32 %13, 37 + %14 = load i32, ptr %score, align 4 + %add9 = add nsw i32 %14, %mul + store i32 %add9, ptr %score, align 4 + %15 = load ptr, ptr %resp.addr, align 8 + %status = getelementptr inbounds nuw %struct.Response, ptr %15, i32 0, i32 0 + %16 = load i32, ptr %status, align 4 + %17 = load ptr, ptr %req.addr, align 8 + %route = getelementptr inbounds nuw %struct.Request, ptr %17, i32 0, i32 2 + %18 = load i32, ptr %route, align 4 + %add10 = add nsw i32 %16, %18 + %19 = load i32, ptr %score, align 4 + %xor11 = xor i32 %19, %add10 + store i32 %xor11, ptr %score, align 4 + %20 = load i32, ptr %score, align 4 + %shr = ashr i32 %20, 3 + %and = and i32 %shr, 255 + %21 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %21, i32 0, i32 3 + %arrayidx12 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 3 + %22 = load i32, ptr %arrayidx12, align 4 + %xor13 = xor i32 %22, %and + store i32 %xor13, ptr %arrayidx12, align 4 + %23 = load i32, ptr %score, align 4 + ret i32 %23 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_session(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 0 + %1 = load i32, ptr %id, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 1 + %3 = load i32, ptr %user, align 4 + %add = add nsw i32 %1, %3 + store i32 %add, ptr %score, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 9 + %5 = load i32, ptr %arrayidx, align 4 + %6 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 4 + %arrayidx1 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 9 + %7 = load i32, ptr %arrayidx1, align 4 + %add2 = add nsw i32 %5, %7 + %8 = load i32, ptr %score, align 4 + %xor = xor i32 %8, %add2 + store i32 %xor, ptr %score, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %payload3 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 3 + %arrayidx4 = getelementptr inbounds [24 x i32], ptr %payload3, i64 0, i64 10 + %10 = load i32, ptr %arrayidx4, align 4 + %11 = load ptr, ptr %req.addr, align 8 + %scratch5 = getelementptr inbounds nuw %struct.Request, ptr %11, i32 0, i32 4 + %arrayidx6 = getelementptr inbounds [24 x i32], ptr %scratch5, i64 0, i64 10 + %12 = load i32, ptr %arrayidx6, align 4 + %add7 = add nsw i32 %10, %12 + %call = call i32 @mix32(i32 noundef %add7) + %13 = load i32, ptr %score, align 4 + %add8 = add nsw i32 %13, %call + store i32 %add8, ptr %score, align 4 + %14 = load ptr, ptr %resp.addr, align 8 + %cost = getelementptr inbounds nuw %struct.Response, ptr %14, i32 0, i32 1 + %15 = load i32, ptr %cost, align 4 + %mul = mul nsw i32 %15, 5 + %16 = load i32, ptr %score, align 4 + %xor9 = xor i32 %16, %mul + store i32 %xor9, ptr %score, align 4 + %17 = load ptr, ptr %req.addr, align 8 + %payload10 = getelementptr inbounds nuw %struct.Request, ptr %17, i32 0, i32 3 + %arrayidx11 = getelementptr inbounds [24 x i32], ptr %payload10, i64 0, i64 23 + %18 = load i32, ptr %arrayidx11, align 4 + %19 = load ptr, ptr %resp.addr, align 8 + %bytes = getelementptr inbounds nuw %struct.Response, ptr %19, i32 0, i32 2 + %20 = load i32, ptr %bytes, align 4 + %add12 = add nsw i32 %18, %20 + %21 = load i32, ptr %score, align 4 + %add13 = add nsw i32 %21, %add12 + store i32 %add13, ptr %score, align 4 + %22 = load i32, ptr %score, align 4 + %shr = ashr i32 %22, 4 + %and = and i32 %shr, 255 + %23 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %23, i32 0, i32 3 + %arrayidx14 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 4 + %24 = load i32, ptr %arrayidx14, align 4 + %xor15 = xor i32 %24, %and + store i32 %xor15, ptr %arrayidx14, align 4 + %25 = load i32, ptr %score, align 4 + ret i32 %25 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_localization(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %route = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 2 + %1 = load i32, ptr %route, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 6 + %3 = load i32, ptr %arrayidx, align 4 + %add = add nsw i32 %1, %3 + store i32 %add, ptr %score, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 4 + %arrayidx1 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 12 + %5 = load i32, ptr %arrayidx1, align 4 + %mul = mul nsw i32 %5, 43 + %6 = load i32, ptr %score, align 4 + %add2 = add nsw i32 %6, %mul + store i32 %add2, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %payload3 = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 3 + %arrayidx4 = getelementptr inbounds [24 x i32], ptr %payload3, i64 0, i64 14 + %8 = load i32, ptr %arrayidx4, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %scratch5 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 4 + %arrayidx6 = getelementptr inbounds [24 x i32], ptr %scratch5, i64 0, i64 18 + %10 = load i32, ptr %arrayidx6, align 4 + %add7 = add nsw i32 %8, %10 + %call = call i32 @mix32(i32 noundef %add7) + %11 = load i32, ptr %score, align 4 + %xor = xor i32 %11, %call + store i32 %xor, ptr %score, align 4 + %12 = load ptr, ptr %resp.addr, align 8 + %status = getelementptr inbounds nuw %struct.Response, ptr %12, i32 0, i32 0 + %13 = load i32, ptr %status, align 4 + %14 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %14, i32 0, i32 1 + %15 = load i32, ptr %user, align 4 + %add8 = add nsw i32 %13, %15 + %16 = load i32, ptr %score, align 4 + %add9 = add nsw i32 %16, %add8 + store i32 %add9, ptr %score, align 4 + %17 = load ptr, ptr %req.addr, align 8 + %payload10 = getelementptr inbounds nuw %struct.Request, ptr %17, i32 0, i32 3 + %arrayidx11 = getelementptr inbounds [24 x i32], ptr %payload10, i64 0, i64 20 + %18 = load i32, ptr %arrayidx11, align 4 + %19 = load ptr, ptr %resp.addr, align 8 + %cost = getelementptr inbounds nuw %struct.Response, ptr %19, i32 0, i32 1 + %20 = load i32, ptr %cost, align 4 + %add12 = add nsw i32 %18, %20 + %21 = load i32, ptr %score, align 4 + %xor13 = xor i32 %21, %add12 + store i32 %xor13, ptr %score, align 4 + %22 = load i32, ptr %score, align 4 + %shr = ashr i32 %22, 5 + %and = and i32 %shr, 255 + %23 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %23, i32 0, i32 3 + %arrayidx14 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 5 + %24 = load i32, ptr %arrayidx14, align 4 + %xor15 = xor i32 %24, %and + store i32 %xor15, ptr %arrayidx14, align 4 + %25 = load i32, ptr %score, align 4 + ret i32 %25 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_ab_test(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %0, i32 0, i32 0 + %1 = load i32, ptr %id, align 4 + %and = and i32 %1, 255 + store i32 %and, ptr %score, align 4 + %2 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %2, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 7 + %3 = load i32, ptr %arrayidx, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 4 + %arrayidx1 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 13 + %5 = load i32, ptr %arrayidx1, align 4 + %add = add nsw i32 %3, %5 + %6 = load i32, ptr %score, align 4 + %add2 = add nsw i32 %6, %add + store i32 %add2, ptr %score, align 4 + %7 = load ptr, ptr %req.addr, align 8 + %payload3 = getelementptr inbounds nuw %struct.Request, ptr %7, i32 0, i32 3 + %arrayidx4 = getelementptr inbounds [24 x i32], ptr %payload3, i64 0, i64 15 + %8 = load i32, ptr %arrayidx4, align 4 + %9 = load ptr, ptr %resp.addr, align 8 + %bytes = getelementptr inbounds nuw %struct.Response, ptr %9, i32 0, i32 2 + %10 = load i32, ptr %bytes, align 4 + %add5 = add nsw i32 %8, %10 + %call = call i32 @mix32(i32 noundef %add5) + %11 = load i32, ptr %score, align 4 + %xor = xor i32 %11, %call + store i32 %xor, ptr %score, align 4 + %12 = load ptr, ptr %req.addr, align 8 + %scratch6 = getelementptr inbounds nuw %struct.Request, ptr %12, i32 0, i32 4 + %arrayidx7 = getelementptr inbounds [24 x i32], ptr %scratch6, i64 0, i64 21 + %13 = load i32, ptr %arrayidx7, align 4 + %mul = mul nsw i32 %13, 47 + %14 = load i32, ptr %score, align 4 + %add8 = add nsw i32 %14, %mul + store i32 %add8, ptr %score, align 4 + %15 = load ptr, ptr %req.addr, align 8 + %user = getelementptr inbounds nuw %struct.Request, ptr %15, i32 0, i32 1 + %16 = load i32, ptr %user, align 4 + %17 = load ptr, ptr %resp.addr, align 8 + %status = getelementptr inbounds nuw %struct.Response, ptr %17, i32 0, i32 0 + %18 = load i32, ptr %status, align 4 + %add9 = add nsw i32 %16, %18 + %19 = load i32, ptr %score, align 4 + %xor10 = xor i32 %19, %add9 + store i32 %xor10, ptr %score, align 4 + %20 = load i32, ptr %score, align 4 + %shr = ashr i32 %20, 6 + %and11 = and i32 %shr, 255 + %21 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %21, i32 0, i32 3 + %arrayidx12 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 6 + %22 = load i32, ptr %arrayidx12, align 4 + %xor13 = xor i32 %22, %and11 + store i32 %xor13, ptr %arrayidx12, align 4 + %23 = load i32, ptr %score, align 4 + ret i32 %23 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @endpoint_local_metrics(ptr noundef %req, ptr noundef %resp) #0 { +entry: + %req.addr = alloca ptr, align 8 + %resp.addr = alloca ptr, align 8 + %score = alloca i32, align 4 + store ptr %req, ptr %req.addr, align 8 + store ptr %resp, ptr %resp.addr, align 8 + %0 = load ptr, ptr %resp.addr, align 8 + %cost = getelementptr inbounds nuw %struct.Response, ptr %0, i32 0, i32 1 + %1 = load i32, ptr %cost, align 4 + %2 = load ptr, ptr %resp.addr, align 8 + %bytes = getelementptr inbounds nuw %struct.Response, ptr %2, i32 0, i32 2 + %3 = load i32, ptr %bytes, align 4 + %add = add nsw i32 %1, %3 + store i32 %add, ptr %score, align 4 + %4 = load ptr, ptr %req.addr, align 8 + %payload = getelementptr inbounds nuw %struct.Request, ptr %4, i32 0, i32 3 + %arrayidx = getelementptr inbounds [24 x i32], ptr %payload, i64 0, i64 8 + %5 = load i32, ptr %arrayidx, align 4 + %6 = load ptr, ptr %req.addr, align 8 + %scratch = getelementptr inbounds nuw %struct.Request, ptr %6, i32 0, i32 4 + %arrayidx1 = getelementptr inbounds [24 x i32], ptr %scratch, i64 0, i64 0 + %7 = load i32, ptr %arrayidx1, align 4 + %add2 = add nsw i32 %5, %7 + %8 = load i32, ptr %score, align 4 + %add3 = add nsw i32 %8, %add2 + store i32 %add3, ptr %score, align 4 + %9 = load ptr, ptr %req.addr, align 8 + %payload4 = getelementptr inbounds nuw %struct.Request, ptr %9, i32 0, i32 3 + %arrayidx5 = getelementptr inbounds [24 x i32], ptr %payload4, i64 0, i64 16 + %10 = load i32, ptr %arrayidx5, align 4 + %11 = load ptr, ptr %req.addr, align 8 + %scratch6 = getelementptr inbounds nuw %struct.Request, ptr %11, i32 0, i32 4 + %arrayidx7 = getelementptr inbounds [24 x i32], ptr %scratch6, i64 0, i64 23 + %12 = load i32, ptr %arrayidx7, align 4 + %add8 = add nsw i32 %10, %12 + %call = call i32 @mix32(i32 noundef %add8) + %13 = load i32, ptr %score, align 4 + %xor = xor i32 %13, %call + store i32 %xor, ptr %score, align 4 + %14 = load ptr, ptr %req.addr, align 8 + %route = getelementptr inbounds nuw %struct.Request, ptr %14, i32 0, i32 2 + %15 = load i32, ptr %route, align 4 + %mul = mul nsw i32 %15, 53 + %16 = load i32, ptr %score, align 4 + %add9 = add nsw i32 %16, %mul + store i32 %add9, ptr %score, align 4 + %17 = load ptr, ptr %req.addr, align 8 + %id = getelementptr inbounds nuw %struct.Request, ptr %17, i32 0, i32 0 + %18 = load i32, ptr %id, align 4 + %19 = load ptr, ptr %req.addr, align 8 + %payload10 = getelementptr inbounds nuw %struct.Request, ptr %19, i32 0, i32 3 + %arrayidx11 = getelementptr inbounds [24 x i32], ptr %payload10, i64 0, i64 19 + %20 = load i32, ptr %arrayidx11, align 4 + %add12 = add nsw i32 %18, %20 + %21 = load i32, ptr %score, align 4 + %xor13 = xor i32 %21, %add12 + store i32 %xor13, ptr %score, align 4 + %22 = load i32, ptr %score, align 4 + %shr = ashr i32 %22, 7 + %and = and i32 %shr, 255 + %23 = load ptr, ptr %resp.addr, align 8 + %tags = getelementptr inbounds nuw %struct.Response, ptr %23, i32 0, i32 3 + %arrayidx14 = getelementptr inbounds [12 x i32], ptr %tags, i64 0, i64 7 + %24 = load i32, ptr %arrayidx14, align 4 + %xor15 = xor i32 %24, %and + store i32 %xor15, ptr %arrayidx14, align 4 + %25 = load i32, ptr %score, align 4 + ret i32 %25 +} + +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"="+cmov,+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"="+cmov,+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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} +!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} +!14 = distinct !{!14, !7} From 40ae61220b180bb39f4209c53b166ee0ce3c9207 Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Thu, 2 Jul 2026 17:14:16 +1000 Subject: [PATCH 2/8] Expand sliced MTA coverage tests --- CMakeLists.txt | 18 +- src/sliced_mta/smoke6_lock_paths.c | 66 ++++++ src/sliced_mta/smoke7_indirect_fork_join.c | 50 +++++ src/sliced_mta/smoke8_pointer_field_flows.c | 64 ++++++ .../sliced_mta/smoke6_lock_paths.c.bc | 193 +++++++++++++++++ .../sliced_mta/smoke7_indirect_fork_join.c.bc | 182 ++++++++++++++++ .../smoke8_pointer_field_flows.c.bc | 195 ++++++++++++++++++ 7 files changed, 767 insertions(+), 1 deletion(-) create mode 100644 src/sliced_mta/smoke6_lock_paths.c create mode 100644 src/sliced_mta/smoke7_indirect_fork_join.c create mode 100644 src/sliced_mta/smoke8_pointer_field_flows.c create mode 100644 test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc create mode 100644 test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc create mode 100644 test_cases_bc/sliced_mta/smoke8_pointer_field_flows.c.bc diff --git a/CMakeLists.txt b/CMakeLists.txt index a7f4ac4de..f4594a095 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,7 +176,7 @@ foreach(i RANGE ${dvf_len2}) endforeach() # sliced mta tests (ctest -R sliced_mta_tests -VV) -set(sliced_mta_cmd "mta -enable-slicing=true") +set(sliced_mta_cmd "mta -enable-slicing=true -stat=true") file(GLOB sliced_mta_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/sliced_mta/*.bc*") string(REPLACE " " ";" commandtemp ${sliced_mta_cmd}) set(command ${commandtemp}) @@ -191,6 +191,22 @@ foreach(filename ${sliced_mta_files}) ) endforeach() +# mta statistic tests (ctest -R mta_stat_tests -VV) +set(mta_stat_cmd "mta -flow-sensitive=false -stat=true") +set(mta_stat_files + test_cases_bc/sliced_mta/smoke1_basic.c.bc + test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc +) +string(REPLACE " " ";" commandtemp ${mta_stat_cmd}) +set(command ${commandtemp}) +foreach(filename ${mta_stat_files}) + add_test( + NAME mta_stat_tests/${filename} + COMMAND ${command} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endforeach() + # graphdb dvf and mta tests (write + read) # Usage: ctest -R graphdb-dvf_tests -VV list(APPEND graphdb_dvf_folders diff --git a/src/sliced_mta/smoke6_lock_paths.c b/src/sliced_mta/smoke6_lock_paths.c new file mode 100644 index 000000000..5fec0dedf --- /dev/null +++ b/src/sliced_mta/smoke6_lock_paths.c @@ -0,0 +1,66 @@ +#include + +typedef struct Item { + int count; + int shadow; +} Item; + +pthread_mutex_t primary_lock; +pthread_mutex_t secondary_lock; +Item global_item; +int unlocked_total; + +static void lock_primary(void) { + pthread_mutex_lock(&primary_lock); +} + +static void unlock_primary(void) { + pthread_mutex_unlock(&primary_lock); +} + +static void locked_increment(Item *item, int delta) { + lock_primary(); + item->count += delta; + item->shadow = item->count + delta; + unlock_primary(); +} + +static void nested_locked_update(Item *item, int delta) { + pthread_mutex_lock(&primary_lock); + item->count += delta; + pthread_mutex_lock(&secondary_lock); + item->shadow += item->count; + pthread_mutex_unlock(&secondary_lock); + pthread_mutex_unlock(&primary_lock); +} + +static void conditional_update(Item *item, int delta) { + if (delta & 1) { + pthread_mutex_lock(&primary_lock); + item->count += delta; + pthread_mutex_unlock(&primary_lock); + } else { + item->count += delta; + } +} + +static void *locked_worker(void *arg) { + long id = (long)arg; + locked_increment(&global_item, (int)id); + nested_locked_update(&global_item, (int)id + 3); + conditional_update(&global_item, (int)id + 4); + unlocked_total += global_item.count; + return 0; +} + +int main(void) { + pthread_t t1; + pthread_t t2; + pthread_create(&t1, 0, locked_worker, (void *)1); + pthread_create(&t2, 0, locked_worker, (void *)2); + conditional_update(&global_item, 8); + unlocked_total += global_item.shadow; + pthread_join(t1, 0); + pthread_join(t2, 0); + return unlocked_total; +} diff --git a/src/sliced_mta/smoke7_indirect_fork_join.c b/src/sliced_mta/smoke7_indirect_fork_join.c new file mode 100644 index 000000000..2ec96378e --- /dev/null +++ b/src/sliced_mta/smoke7_indirect_fork_join.c @@ -0,0 +1,50 @@ +#include + +typedef void *(*entry_fn)(void *); + +pthread_t workers[4]; +int shared_slots[4]; +int shared_sum; + +static void update_slot(int idx, int value) { + shared_slots[idx & 3] = value; + shared_sum += shared_slots[idx & 3]; +} + +static void *worker_a(void *arg) { + long id = (long)arg; + update_slot((int)id, (int)id + 10); + shared_sum += (int)id; + return 0; +} + +static void *worker_b(void *arg) { + long id = (long)arg; + update_slot((int)id + 1, (int)id + 20); + shared_slots[1] += shared_sum; + return 0; +} + +static entry_fn pick_worker(int flag) { + if (flag) + return worker_a; + return worker_b; +} + +static void spawn_pair(int base) { + entry_fn first = pick_worker(base & 1); + entry_fn second = pick_worker((base + 1) & 1); + pthread_create(&workers[base], 0, first, (void *)(long)(base + 1)); + pthread_create(&workers[base + 1], 0, second, (void *)(long)(base + 2)); +} + +int main(void) { + spawn_pair(0); + spawn_pair(2); + shared_slots[2] = shared_sum; + pthread_join(workers[0], 0); + pthread_join(workers[1], 0); + pthread_join(workers[2], 0); + pthread_join(workers[3], 0); + return shared_slots[0] + shared_sum; +} diff --git a/src/sliced_mta/smoke8_pointer_field_flows.c b/src/sliced_mta/smoke8_pointer_field_flows.c new file mode 100644 index 000000000..d656e7df4 --- /dev/null +++ b/src/sliced_mta/smoke8_pointer_field_flows.c @@ -0,0 +1,64 @@ +#include + +typedef struct Node { + int value; + int aux; + struct Node *next; +} Node; + +pthread_mutex_t node_lock; +Node nodes[3]; +Node *shared_head; +int global_sink; + +static Node *select_node(int idx) { + return &nodes[idx % 3]; +} + +static void init_nodes(void) { + nodes[0].next = &nodes[1]; + nodes[1].next = &nodes[2]; + nodes[2].next = &nodes[0]; + shared_head = &nodes[0]; +} + +static void write_chain(Node *node, int value) { + node->value = value; + node->next->aux = value + node->value; +} + +static void locked_chain(Node *node, int value) { + pthread_mutex_lock(&node_lock); + node->value += value; + node->next->aux += node->value; + pthread_mutex_unlock(&node_lock); +} + +static int read_chain(Node *node) { + return node->value + node->next->aux; +} + +static void *field_worker(void *arg) { + long id = (long)arg; + Node *node = select_node((int)id); + write_chain(node, (int)id + 5); + locked_chain(shared_head->next, (int)id); + global_sink += read_chain(node->next); + return 0; +} + +int main(void) { + pthread_t t1; + pthread_t t2; + pthread_t t3; + init_nodes(); + pthread_create(&t1, 0, field_worker, (void *)1); + pthread_create(&t2, 0, field_worker, (void *)2); + pthread_create(&t3, 0, field_worker, (void *)3); + write_chain(shared_head, 11); + global_sink += read_chain(shared_head); + pthread_join(t1, 0); + pthread_join(t2, 0); + pthread_join(t3, 0); + return global_sink; +} diff --git a/test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc b/test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc new file mode 100644 index 000000000..14e0e0578 --- /dev/null +++ b/test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc @@ -0,0 +1,193 @@ +; ModuleID = 'test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc' +source_filename = "src/sliced_mta/smoke6_lock_paths.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.Item = type { i32, i32 } +%union.pthread_mutex_t = type { %struct.__pthread_mutex_s } +%struct.__pthread_mutex_s = type { i32, i32, i32, i32, i32, i16, i16, %struct.__pthread_internal_list } +%struct.__pthread_internal_list = type { ptr, ptr } + +@global_item = dso_local global %struct.Item zeroinitializer, align 4 +@unlocked_total = dso_local global i32 0, align 4 +@primary_lock = dso_local global %union.pthread_mutex_t zeroinitializer, align 8 +@secondary_lock = dso_local global %union.pthread_mutex_t zeroinitializer, align 8 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %t1 = alloca i64, align 8 + %t2 = alloca i64, align 8 + store i32 0, ptr %retval, align 4 + %call = call i32 @pthread_create(ptr noundef %t1, ptr noundef null, ptr noundef @locked_worker, ptr noundef inttoptr (i64 1 to ptr)) #3 + %call1 = call i32 @pthread_create(ptr noundef %t2, ptr noundef null, ptr noundef @locked_worker, ptr noundef inttoptr (i64 2 to ptr)) #3 + call void @conditional_update(ptr noundef @global_item, i32 noundef 8) + %0 = load i32, ptr getelementptr inbounds nuw (%struct.Item, ptr @global_item, i32 0, i32 1), align 4 + %1 = load i32, ptr @unlocked_total, align 4 + %add = add nsw i32 %1, %0 + store i32 %add, ptr @unlocked_total, align 4 + %2 = load i64, ptr %t1, align 8 + %call2 = call i32 @pthread_join(i64 noundef %2, ptr noundef null) + %3 = load i64, ptr %t2, align 8 + %call3 = call i32 @pthread_join(i64 noundef %3, ptr noundef null) + %4 = load i32, ptr @unlocked_total, align 4 + ret i32 %4 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define internal ptr @locked_worker(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %id = alloca i64, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + store i64 %1, ptr %id, align 8 + %2 = load i64, ptr %id, align 8 + %conv = trunc i64 %2 to i32 + call void @locked_increment(ptr noundef @global_item, i32 noundef %conv) + %3 = load i64, ptr %id, align 8 + %conv1 = trunc i64 %3 to i32 + %add = add nsw i32 %conv1, 3 + call void @nested_locked_update(ptr noundef @global_item, i32 noundef %add) + %4 = load i64, ptr %id, align 8 + %conv2 = trunc i64 %4 to i32 + %add3 = add nsw i32 %conv2, 4 + call void @conditional_update(ptr noundef @global_item, i32 noundef %add3) + %5 = load i32, ptr @global_item, align 4 + %6 = load i32, ptr @unlocked_total, align 4 + %add4 = add nsw i32 %6, %5 + store i32 %add4, ptr @unlocked_total, align 4 + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @conditional_update(ptr noundef %item, i32 noundef %delta) #0 { +entry: + %item.addr = alloca ptr, align 8 + %delta.addr = alloca i32, align 4 + store ptr %item, ptr %item.addr, align 8 + store i32 %delta, ptr %delta.addr, align 4 + %0 = load i32, ptr %delta.addr, align 4 + %and = and i32 %0, 1 + %tobool = icmp ne i32 %and, 0 + br i1 %tobool, label %if.then, label %if.else + +if.then: ; preds = %entry + %call = call i32 @pthread_mutex_lock(ptr noundef @primary_lock) #3 + %1 = load i32, ptr %delta.addr, align 4 + %2 = load ptr, ptr %item.addr, align 8 + %count = getelementptr inbounds nuw %struct.Item, ptr %2, i32 0, i32 0 + %3 = load i32, ptr %count, align 4 + %add = add nsw i32 %3, %1 + store i32 %add, ptr %count, align 4 + %call1 = call i32 @pthread_mutex_unlock(ptr noundef @primary_lock) #3 + br label %if.end + +if.else: ; preds = %entry + %4 = load i32, ptr %delta.addr, align 4 + %5 = load ptr, ptr %item.addr, align 8 + %count2 = getelementptr inbounds nuw %struct.Item, ptr %5, i32 0, i32 0 + %6 = load i32, ptr %count2, align 4 + %add3 = add nsw i32 %6, %4 + store i32 %add3, ptr %count2, align 4 + br label %if.end + +if.end: ; preds = %if.else, %if.then + ret void +} + +declare i32 @pthread_join(i64 noundef, ptr noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @locked_increment(ptr noundef %item, i32 noundef %delta) #0 { +entry: + %item.addr = alloca ptr, align 8 + %delta.addr = alloca i32, align 4 + store ptr %item, ptr %item.addr, align 8 + store i32 %delta, ptr %delta.addr, align 4 + call void @lock_primary() + %0 = load i32, ptr %delta.addr, align 4 + %1 = load ptr, ptr %item.addr, align 8 + %count = getelementptr inbounds nuw %struct.Item, ptr %1, i32 0, i32 0 + %2 = load i32, ptr %count, align 4 + %add = add nsw i32 %2, %0 + store i32 %add, ptr %count, align 4 + %3 = load ptr, ptr %item.addr, align 8 + %count1 = getelementptr inbounds nuw %struct.Item, ptr %3, i32 0, i32 0 + %4 = load i32, ptr %count1, align 4 + %5 = load i32, ptr %delta.addr, align 4 + %add2 = add nsw i32 %4, %5 + %6 = load ptr, ptr %item.addr, align 8 + %shadow = getelementptr inbounds nuw %struct.Item, ptr %6, i32 0, i32 1 + store i32 %add2, ptr %shadow, align 4 + call void @unlock_primary() + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @nested_locked_update(ptr noundef %item, i32 noundef %delta) #0 { +entry: + %item.addr = alloca ptr, align 8 + %delta.addr = alloca i32, align 4 + store ptr %item, ptr %item.addr, align 8 + store i32 %delta, ptr %delta.addr, align 4 + %call = call i32 @pthread_mutex_lock(ptr noundef @primary_lock) #3 + %0 = load i32, ptr %delta.addr, align 4 + %1 = load ptr, ptr %item.addr, align 8 + %count = getelementptr inbounds nuw %struct.Item, ptr %1, i32 0, i32 0 + %2 = load i32, ptr %count, align 4 + %add = add nsw i32 %2, %0 + store i32 %add, ptr %count, align 4 + %call1 = call i32 @pthread_mutex_lock(ptr noundef @secondary_lock) #3 + %3 = load ptr, ptr %item.addr, align 8 + %count2 = getelementptr inbounds nuw %struct.Item, ptr %3, i32 0, i32 0 + %4 = load i32, ptr %count2, align 4 + %5 = load ptr, ptr %item.addr, align 8 + %shadow = getelementptr inbounds nuw %struct.Item, ptr %5, i32 0, i32 1 + %6 = load i32, ptr %shadow, align 4 + %add3 = add nsw i32 %6, %4 + store i32 %add3, ptr %shadow, align 4 + %call4 = call i32 @pthread_mutex_unlock(ptr noundef @secondary_lock) #3 + %call5 = call i32 @pthread_mutex_unlock(ptr noundef @primary_lock) #3 + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @lock_primary() #0 { +entry: + %call = call i32 @pthread_mutex_lock(ptr noundef @primary_lock) #3 + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @unlock_primary() #0 { +entry: + %call = call i32 @pthread_mutex_unlock(ptr noundef @primary_lock) #3 + ret void +} + +; Function Attrs: nounwind +declare i32 @pthread_mutex_lock(ptr noundef) #1 + +; Function Attrs: nounwind +declare i32 @pthread_mutex_unlock(ptr 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"="+cmov,+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"="+cmov,+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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} diff --git a/test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc b/test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc new file mode 100644 index 000000000..f520c2ed4 --- /dev/null +++ b/test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc @@ -0,0 +1,182 @@ +; ModuleID = 'test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc' +source_filename = "src/sliced_mta/smoke7_indirect_fork_join.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@shared_sum = dso_local global i32 0, align 4 +@shared_slots = dso_local global [4 x i32] zeroinitializer, align 16 +@workers = dso_local global [4 x i64] zeroinitializer, align 16 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + store i32 0, ptr %retval, align 4 + call void @spawn_pair(i32 noundef 0) + call void @spawn_pair(i32 noundef 2) + %0 = load i32, ptr @shared_sum, align 4 + store i32 %0, ptr getelementptr inbounds ([4 x i32], ptr @shared_slots, i64 0, i64 2), align 8 + %1 = load i64, ptr @workers, align 16 + %call = call i32 @pthread_join(i64 noundef %1, ptr noundef null) + %2 = load i64, ptr getelementptr inbounds ([4 x i64], ptr @workers, i64 0, i64 1), align 8 + %call1 = call i32 @pthread_join(i64 noundef %2, ptr noundef null) + %3 = load i64, ptr getelementptr inbounds ([4 x i64], ptr @workers, i64 0, i64 2), align 16 + %call2 = call i32 @pthread_join(i64 noundef %3, ptr noundef null) + %4 = load i64, ptr getelementptr inbounds ([4 x i64], ptr @workers, i64 0, i64 3), align 8 + %call3 = call i32 @pthread_join(i64 noundef %4, ptr noundef null) + %5 = load i32, ptr @shared_slots, align 16 + %6 = load i32, ptr @shared_sum, align 4 + %add = add nsw i32 %5, %6 + ret i32 %add +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @spawn_pair(i32 noundef %base) #0 { +entry: + %base.addr = alloca i32, align 4 + %first = alloca ptr, align 8 + %second = alloca ptr, align 8 + store i32 %base, ptr %base.addr, align 4 + %0 = load i32, ptr %base.addr, align 4 + %and = and i32 %0, 1 + %call = call ptr @pick_worker(i32 noundef %and) + store ptr %call, ptr %first, align 8 + %1 = load i32, ptr %base.addr, align 4 + %add = add nsw i32 %1, 1 + %and1 = and i32 %add, 1 + %call2 = call ptr @pick_worker(i32 noundef %and1) + store ptr %call2, ptr %second, align 8 + %2 = load i32, ptr %base.addr, align 4 + %idxprom = sext i32 %2 to i64 + %arrayidx = getelementptr inbounds [4 x i64], ptr @workers, i64 0, i64 %idxprom + %3 = load ptr, ptr %first, align 8 + %4 = load i32, ptr %base.addr, align 4 + %add3 = add nsw i32 %4, 1 + %conv = sext i32 %add3 to i64 + %5 = inttoptr i64 %conv to ptr + %call4 = call i32 @pthread_create(ptr noundef %arrayidx, ptr noundef null, ptr noundef %3, ptr noundef %5) #3 + %6 = load i32, ptr %base.addr, align 4 + %add5 = add nsw i32 %6, 1 + %idxprom6 = sext i32 %add5 to i64 + %arrayidx7 = getelementptr inbounds [4 x i64], ptr @workers, i64 0, i64 %idxprom6 + %7 = load ptr, ptr %second, align 8 + %8 = load i32, ptr %base.addr, align 4 + %add8 = add nsw i32 %8, 2 + %conv9 = sext i32 %add8 to i64 + %9 = inttoptr i64 %conv9 to ptr + %call10 = call i32 @pthread_create(ptr noundef %arrayidx7, ptr noundef null, ptr noundef %7, ptr noundef %9) #3 + ret void +} + +declare i32 @pthread_join(i64 noundef, ptr noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define internal ptr @pick_worker(i32 noundef %flag) #0 { +entry: + %retval = alloca ptr, align 8 + %flag.addr = alloca i32, align 4 + store i32 %flag, ptr %flag.addr, align 4 + %0 = load i32, ptr %flag.addr, align 4 + %tobool = icmp ne i32 %0, 0 + br i1 %tobool, label %if.then, label %if.end + +if.then: ; preds = %entry + store ptr @worker_a, ptr %retval, align 8 + br label %return + +if.end: ; preds = %entry + store ptr @worker_b, ptr %retval, align 8 + br label %return + +return: ; preds = %if.end, %if.then + %1 = load ptr, ptr %retval, align 8 + ret ptr %1 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define internal ptr @worker_a(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %id = alloca i64, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + store i64 %1, ptr %id, align 8 + %2 = load i64, ptr %id, align 8 + %conv = trunc i64 %2 to i32 + %3 = load i64, ptr %id, align 8 + %conv1 = trunc i64 %3 to i32 + %add = add nsw i32 %conv1, 10 + call void @update_slot(i32 noundef %conv, i32 noundef %add) + %4 = load i64, ptr %id, align 8 + %conv2 = trunc i64 %4 to i32 + %5 = load i32, ptr @shared_sum, align 4 + %add3 = add nsw i32 %5, %conv2 + store i32 %add3, ptr @shared_sum, align 4 + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal ptr @worker_b(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %id = alloca i64, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + store i64 %1, ptr %id, align 8 + %2 = load i64, ptr %id, align 8 + %conv = trunc i64 %2 to i32 + %add = add nsw i32 %conv, 1 + %3 = load i64, ptr %id, align 8 + %conv1 = trunc i64 %3 to i32 + %add2 = add nsw i32 %conv1, 20 + call void @update_slot(i32 noundef %add, i32 noundef %add2) + %4 = load i32, ptr @shared_sum, align 4 + %5 = load i32, ptr getelementptr inbounds ([4 x i32], ptr @shared_slots, i64 0, i64 1), align 4 + %add3 = add nsw i32 %5, %4 + store i32 %add3, ptr getelementptr inbounds ([4 x i32], ptr @shared_slots, i64 0, i64 1), align 4 + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @update_slot(i32 noundef %idx, i32 noundef %value) #0 { +entry: + %idx.addr = alloca i32, align 4 + %value.addr = alloca i32, align 4 + store i32 %idx, ptr %idx.addr, align 4 + store i32 %value, ptr %value.addr, align 4 + %0 = load i32, ptr %value.addr, align 4 + %1 = load i32, ptr %idx.addr, align 4 + %and = and i32 %1, 3 + %idxprom = sext i32 %and to i64 + %arrayidx = getelementptr inbounds [4 x i32], ptr @shared_slots, i64 0, i64 %idxprom + store i32 %0, ptr %arrayidx, align 4 + %2 = load i32, ptr %idx.addr, align 4 + %and1 = and i32 %2, 3 + %idxprom2 = sext i32 %and1 to i64 + %arrayidx3 = getelementptr inbounds [4 x i32], ptr @shared_slots, i64 0, i64 %idxprom2 + %3 = load i32, ptr %arrayidx3, align 4 + %4 = load i32, ptr @shared_sum, align 4 + %add = add nsw i32 %4, %3 + store i32 %add, ptr @shared_sum, align 4 + ret void +} + +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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #2 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} diff --git a/test_cases_bc/sliced_mta/smoke8_pointer_field_flows.c.bc b/test_cases_bc/sliced_mta/smoke8_pointer_field_flows.c.bc new file mode 100644 index 000000000..92044201e --- /dev/null +++ b/test_cases_bc/sliced_mta/smoke8_pointer_field_flows.c.bc @@ -0,0 +1,195 @@ +; ModuleID = 'test_cases_bc/sliced_mta/smoke8_pointer_field_flows.c.bc' +source_filename = "src/sliced_mta/smoke8_pointer_field_flows.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%union.pthread_mutex_t = type { %struct.__pthread_mutex_s } +%struct.__pthread_mutex_s = type { i32, i32, i32, i32, i32, i16, i16, %struct.__pthread_internal_list } +%struct.__pthread_internal_list = type { ptr, ptr } +%struct.Node = type { i32, i32, ptr } + +@shared_head = dso_local global ptr null, align 8 +@global_sink = dso_local global i32 0, align 4 +@node_lock = dso_local global %union.pthread_mutex_t zeroinitializer, align 8 +@nodes = dso_local global [3 x %struct.Node] zeroinitializer, align 16 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %t1 = alloca i64, align 8 + %t2 = alloca i64, align 8 + %t3 = alloca i64, align 8 + store i32 0, ptr %retval, align 4 + call void @init_nodes() + %call = call i32 @pthread_create(ptr noundef %t1, ptr noundef null, ptr noundef @field_worker, ptr noundef inttoptr (i64 1 to ptr)) #3 + %call1 = call i32 @pthread_create(ptr noundef %t2, ptr noundef null, ptr noundef @field_worker, ptr noundef inttoptr (i64 2 to ptr)) #3 + %call2 = call i32 @pthread_create(ptr noundef %t3, ptr noundef null, ptr noundef @field_worker, ptr noundef inttoptr (i64 3 to ptr)) #3 + %0 = load ptr, ptr @shared_head, align 8 + call void @write_chain(ptr noundef %0, i32 noundef 11) + %1 = load ptr, ptr @shared_head, align 8 + %call3 = call i32 @read_chain(ptr noundef %1) + %2 = load i32, ptr @global_sink, align 4 + %add = add nsw i32 %2, %call3 + store i32 %add, ptr @global_sink, align 4 + %3 = load i64, ptr %t1, align 8 + %call4 = call i32 @pthread_join(i64 noundef %3, ptr noundef null) + %4 = load i64, ptr %t2, align 8 + %call5 = call i32 @pthread_join(i64 noundef %4, ptr noundef null) + %5 = load i64, ptr %t3, align 8 + %call6 = call i32 @pthread_join(i64 noundef %5, ptr noundef null) + %6 = load i32, ptr @global_sink, align 4 + ret i32 %6 +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @init_nodes() #0 { +entry: + store ptr getelementptr inbounds ([3 x %struct.Node], ptr @nodes, i64 0, i64 1), ptr getelementptr inbounds nuw (%struct.Node, ptr @nodes, i32 0, i32 2), align 8 + store ptr getelementptr inbounds ([3 x %struct.Node], ptr @nodes, i64 0, i64 2), ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([3 x %struct.Node], ptr @nodes, i64 0, i64 1), i32 0, i32 2), align 8 + store ptr @nodes, ptr getelementptr inbounds nuw (%struct.Node, ptr getelementptr inbounds ([3 x %struct.Node], ptr @nodes, i64 0, i64 2), i32 0, i32 2), align 8 + store ptr @nodes, ptr @shared_head, align 8 + ret void +} + +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define internal ptr @field_worker(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + %id = alloca i64, align 8 + %node = alloca ptr, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + store i64 %1, ptr %id, align 8 + %2 = load i64, ptr %id, align 8 + %conv = trunc i64 %2 to i32 + %call = call ptr @select_node(i32 noundef %conv) + store ptr %call, ptr %node, align 8 + %3 = load ptr, ptr %node, align 8 + %4 = load i64, ptr %id, align 8 + %conv1 = trunc i64 %4 to i32 + %add = add nsw i32 %conv1, 5 + call void @write_chain(ptr noundef %3, i32 noundef %add) + %5 = load ptr, ptr @shared_head, align 8 + %next = getelementptr inbounds nuw %struct.Node, ptr %5, i32 0, i32 2 + %6 = load ptr, ptr %next, align 8 + %7 = load i64, ptr %id, align 8 + %conv2 = trunc i64 %7 to i32 + call void @locked_chain(ptr noundef %6, i32 noundef %conv2) + %8 = load ptr, ptr %node, align 8 + %next3 = getelementptr inbounds nuw %struct.Node, ptr %8, i32 0, i32 2 + %9 = load ptr, ptr %next3, align 8 + %call4 = call i32 @read_chain(ptr noundef %9) + %10 = load i32, ptr @global_sink, align 4 + %add5 = add nsw i32 %10, %call4 + store i32 %add5, ptr @global_sink, align 4 + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @write_chain(ptr noundef %node, i32 noundef %value) #0 { +entry: + %node.addr = alloca ptr, align 8 + %value.addr = alloca i32, align 4 + store ptr %node, ptr %node.addr, align 8 + store i32 %value, ptr %value.addr, align 4 + %0 = load i32, ptr %value.addr, align 4 + %1 = load ptr, ptr %node.addr, align 8 + %value1 = getelementptr inbounds nuw %struct.Node, ptr %1, i32 0, i32 0 + store i32 %0, ptr %value1, align 8 + %2 = load i32, ptr %value.addr, align 4 + %3 = load ptr, ptr %node.addr, align 8 + %value2 = getelementptr inbounds nuw %struct.Node, ptr %3, i32 0, i32 0 + %4 = load i32, ptr %value2, align 8 + %add = add nsw i32 %2, %4 + %5 = load ptr, ptr %node.addr, align 8 + %next = getelementptr inbounds nuw %struct.Node, ptr %5, i32 0, i32 2 + %6 = load ptr, ptr %next, align 8 + %aux = getelementptr inbounds nuw %struct.Node, ptr %6, i32 0, i32 1 + store i32 %add, ptr %aux, align 4 + ret void +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @read_chain(ptr noundef %node) #0 { +entry: + %node.addr = alloca ptr, align 8 + store ptr %node, ptr %node.addr, align 8 + %0 = load ptr, ptr %node.addr, align 8 + %value = getelementptr inbounds nuw %struct.Node, ptr %0, i32 0, i32 0 + %1 = load i32, ptr %value, align 8 + %2 = load ptr, ptr %node.addr, align 8 + %next = getelementptr inbounds nuw %struct.Node, ptr %2, i32 0, i32 2 + %3 = load ptr, ptr %next, align 8 + %aux = getelementptr inbounds nuw %struct.Node, ptr %3, i32 0, i32 1 + %4 = load i32, ptr %aux, align 4 + %add = add nsw i32 %1, %4 + ret i32 %add +} + +declare i32 @pthread_join(i64 noundef, ptr noundef) #2 + +; Function Attrs: noinline nounwind optnone uwtable +define internal ptr @select_node(i32 noundef %idx) #0 { +entry: + %idx.addr = alloca i32, align 4 + store i32 %idx, ptr %idx.addr, align 4 + %0 = load i32, ptr %idx.addr, align 4 + %rem = srem i32 %0, 3 + %idxprom = sext i32 %rem to i64 + %arrayidx = getelementptr inbounds [3 x %struct.Node], ptr @nodes, i64 0, i64 %idxprom + ret ptr %arrayidx +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal void @locked_chain(ptr noundef %node, i32 noundef %value) #0 { +entry: + %node.addr = alloca ptr, align 8 + %value.addr = alloca i32, align 4 + store ptr %node, ptr %node.addr, align 8 + store i32 %value, ptr %value.addr, align 4 + %call = call i32 @pthread_mutex_lock(ptr noundef @node_lock) #3 + %0 = load i32, ptr %value.addr, align 4 + %1 = load ptr, ptr %node.addr, align 8 + %value1 = getelementptr inbounds nuw %struct.Node, ptr %1, i32 0, i32 0 + %2 = load i32, ptr %value1, align 8 + %add = add nsw i32 %2, %0 + store i32 %add, ptr %value1, align 8 + %3 = load ptr, ptr %node.addr, align 8 + %value2 = getelementptr inbounds nuw %struct.Node, ptr %3, i32 0, i32 0 + %4 = load i32, ptr %value2, align 8 + %5 = load ptr, ptr %node.addr, align 8 + %next = getelementptr inbounds nuw %struct.Node, ptr %5, i32 0, i32 2 + %6 = load ptr, ptr %next, align 8 + %aux = getelementptr inbounds nuw %struct.Node, ptr %6, i32 0, i32 1 + %7 = load i32, ptr %aux, align 4 + %add3 = add nsw i32 %7, %4 + store i32 %add3, ptr %aux, align 4 + %call4 = call i32 @pthread_mutex_unlock(ptr noundef @node_lock) #3 + ret void +} + +; Function Attrs: nounwind +declare i32 @pthread_mutex_lock(ptr noundef) #1 + +; Function Attrs: nounwind +declare i32 @pthread_mutex_unlock(ptr 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"="+cmov,+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"="+cmov,+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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} From aa35c680a8cc8e7e33bed2f58ae343d1e268d8ef Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Thu, 2 Jul 2026 21:38:24 +1000 Subject: [PATCH 3/8] Update MTA statistic test option --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f4594a095..cf7ccfc3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,7 +192,7 @@ foreach(filename ${sliced_mta_files}) endforeach() # mta statistic tests (ctest -R mta_stat_tests -VV) -set(mta_stat_cmd "mta -flow-sensitive=false -stat=true") +set(mta_stat_cmd "mta -mt-flow-sensitive=false -stat=true") set(mta_stat_files test_cases_bc/sliced_mta/smoke1_basic.c.bc test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc From 2f52eaada7b176341d9b6124f21a20a0dd964039 Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Mon, 6 Jul 2026 21:07:48 +1000 Subject: [PATCH 4/8] MTA: add sliced-pipeline mode coverage tests New ctest suites (whole-program, single-slice, observe, main-ila, saber full-svfg) plus no_data_race and single_threaded cases covering the pipeline's guard paths. Co-Authored-By: Claude Opus 4.8 --- CMakeLists.txt | 94 +++++++++++++++ src/sliced_mta/no_data_race.c | 26 +++++ src/sliced_mta/single_threaded.c | 17 +++ test_cases_bc/sliced_mta/no_data_race.c.bc | 110 ++++++++++++++++++ test_cases_bc/sliced_mta/single_threaded.c.bc | 93 +++++++++++++++ 5 files changed, 340 insertions(+) create mode 100644 src/sliced_mta/no_data_race.c create mode 100644 src/sliced_mta/single_threaded.c create mode 100644 test_cases_bc/sliced_mta/no_data_race.c.bc create mode 100644 test_cases_bc/sliced_mta/single_threaded.c.bc diff --git a/CMakeLists.txt b/CMakeLists.txt index cf7ccfc3f..06436f488 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,6 +207,100 @@ foreach(filename ${mta_stat_files}) ) endforeach() +# whole-program (no-slicing) FSAM baseline (ctest -R mta_whole_tests -VV) +# Runs the SlicedMTA pipeline with slicing off, exercising runWholeProgramDetection +# (the A/B reference the sliced run is compared against). +set(mta_whole_cmd "mta -enable-slicing=false -stat=true") +file(GLOB mta_whole_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/sliced_mta/*.bc*") +string(REPLACE " " ";" commandtemp ${mta_whole_cmd}) +set(command ${commandtemp}) +foreach(filename ${mta_whole_files}) + if (${filename} MATCHES ".pre.bc" OR ${filename} MATCHES ".pre.svf.bc" OR ${filename} MATCHES ".svf.bc") + continue() + endif() + add_test( + NAME mta_whole_tests/${filename} + COMMAND ${command} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endforeach() + +# single unified slice, one slice for ILA + FSPTA (ctest -R mta_single_slice_tests -VV) +# Exercises the SingleSlicer (-slicing-single) single-pass baseline branch. +set(mta_single_cmd "mta -enable-slicing=true -slicing-single=true -stat=true") +file(GLOB mta_single_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/sliced_mta/*.bc*") +string(REPLACE " " ";" commandtemp ${mta_single_cmd}) +set(command ${commandtemp}) +foreach(filename ${mta_single_files}) + if (${filename} MATCHES ".pre.bc" OR ${filename} MATCHES ".pre.svf.bc" OR ${filename} MATCHES ".svf.bc") + continue() + endif() + add_test( + NAME mta_single_slice_tests/${filename} + COMMAND ${command} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endforeach() + +# main FSMPTA value flow rebuilt from the sliced ILA (ctest -R mta_main_ila_tests -VV) +# Exercises the -main-ila-sliced (fresh SVFG from the sliced ILA) branch. +set(mta_main_ila_cmd "mta -enable-slicing=true -main-ila-sliced=true -stat=true") +set(mta_main_ila_files + test_cases_bc/sliced_mta/smoke1_basic.c.bc + test_cases_bc/sliced_mta/smoke3_rich_races.c.bc +) +string(REPLACE " " ";" commandtemp ${mta_main_ila_cmd}) +set(command ${commandtemp}) +foreach(filename ${mta_main_ila_files}) + add_test( + NAME mta_main_ila_tests/${filename} + COMMAND ${command} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endforeach() + +# observe mode: dump FSAM points-to + ILA instead of detecting races +# (ctest -R mta_observe_tests -VV). Both slicing on/off variants are run so the +# sliced and whole-program observers (and the ILA dumper) are all exercised. +set(mta_observe_sliced_cmd "mta -observe=true -enable-slicing=true") +set(mta_observe_whole_cmd "mta -observe=true -enable-slicing=false") +set(mta_observe_files + test_cases_bc/sliced_mta/smoke1_basic.c.bc + test_cases_bc/sliced_mta/smoke3_rich_races.c.bc + test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc +) +foreach(filename ${mta_observe_files}) + string(REPLACE " " ";" cmd_sliced ${mta_observe_sliced_cmd}) + add_test( + NAME mta_observe_tests/sliced/${filename} + COMMAND ${cmd_sliced} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) + string(REPLACE " " ";" cmd_whole ${mta_observe_whole_cmd}) + add_test( + NAME mta_observe_tests/whole/${filename} + COMMAND ${cmd_whole} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endforeach() + +# saber with the full SVFG on top of the pointer-only one (ctest -R saber_full_svfg_tests -VV) +# Exercises SVFGBuilder::buildFullSVFG / SVFGOPT (plain saber uses the pointer-only SVFG). +set(saber_full_cmd "saber -leak -saber-full-svfg=true -valid-tests -stat=false") +file(GLOB saber_full_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/mem_leak/*.bc*") +string(REPLACE " " ";" commandtemp ${saber_full_cmd}) +set(command ${commandtemp}) +foreach(filename ${saber_full_files}) + if (${filename} MATCHES ".pre.bc" OR ${filename} MATCHES ".pre.svf.bc" OR ${filename} MATCHES ".svf.bc") + continue() + endif() + add_test( + NAME saber_full_svfg_tests/${filename} + COMMAND ${command} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endforeach() + # graphdb dvf and mta tests (write + read) # Usage: ctest -R graphdb-dvf_tests -VV list(APPEND graphdb_dvf_folders diff --git a/src/sliced_mta/no_data_race.c b/src/sliced_mta/no_data_race.c new file mode 100644 index 000000000..be437988c --- /dev/null +++ b/src/sliced_mta/no_data_race.c @@ -0,0 +1,26 @@ +// no_data_race.c -- a threaded program with NO data races. +// +// Two workers touch disjoint globals and main touches a third; no object is +// shared between concurrent threads, so both MSli and the whole-program FSAM +// report zero races. This exercises the pipeline's "no race pairs" paths (the +// slicing/PTA/final stages that early-out when the pre-analysis finds nothing). +#include + +int g_a; // written only by worker_a +int g_b; // written only by worker_b +int g_main; // touched only by main + +static int compute(int x) { int s = x; for (int i = 0; i < 10; i++) s = s * 3 + i; return s; } + +void* worker_a(void* arg) { g_a = compute((int)(long)arg); return 0; } +void* worker_b(void* arg) { g_b = compute((int)(long)arg) ^ 7; return 0; } + +int main(void) { + pthread_t ta, tb; + pthread_create(&ta, 0, worker_a, (void*)1); + pthread_create(&tb, 0, worker_b, (void*)2); + g_main = 5; // main-only, races nothing + pthread_join(ta, 0); + pthread_join(tb, 0); + return 0; +} diff --git a/src/sliced_mta/single_threaded.c b/src/sliced_mta/single_threaded.c new file mode 100644 index 000000000..2ef4fea0f --- /dev/null +++ b/src/sliced_mta/single_threaded.c @@ -0,0 +1,17 @@ +// single_threaded.c -- a program with NO thread-spawning calls. +// +// It never calls pthread_create, so the pre-analysis finds zero thread +// functions and the MSli pipeline takes its "no thread functions" early-out +// (nothing to slice / analyse). Keeps that guard path exercised. +#include + +int g_state; + +static int compute(int x) { int s = x; for (int i = 0; i < 10; i++) s = s * 3 + i; return s; } + +int main(void) { + g_state = compute(7); + for (int i = 0; i < 4; i++) + g_state += compute(i); + return g_state & 1; +} diff --git a/test_cases_bc/sliced_mta/no_data_race.c.bc b/test_cases_bc/sliced_mta/no_data_race.c.bc new file mode 100644 index 000000000..6d7398033 --- /dev/null +++ b/test_cases_bc/sliced_mta/no_data_race.c.bc @@ -0,0 +1,110 @@ +; ModuleID = '/mnt/scratch/PAG/yjw/projects/svf/Test-Suite/test_cases_bc/sliced_mta/no_data_race.c.bc' +source_filename = "/mnt/scratch/PAG/yjw/projects/svf/Test-Suite/src/sliced_mta/no_data_race.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@g_a = dso_local global i32 0, align 4 +@g_b = dso_local global i32 0, align 4 +@g_main = dso_local global i32 0, align 4 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker_a(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + %conv = trunc i64 %1 to i32 + %call = call i32 @compute(i32 noundef %conv) + store i32 %call, ptr @g_a, align 4 + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @compute(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + %s = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + store i32 %0, ptr %s, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %1 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %1, 10 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %2 = load i32, ptr %s, align 4 + %mul = mul nsw i32 %2, 3 + %3 = load i32, ptr %i, align 4 + %add = add nsw i32 %mul, %3 + store i32 %add, ptr %s, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %4 = load i32, ptr %i, align 4 + %inc = add nsw i32 %4, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !6 + +for.end: ; preds = %for.cond + %5 = load i32, ptr %s, align 4 + ret i32 %5 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local ptr @worker_b(ptr noundef %arg) #0 { +entry: + %arg.addr = alloca ptr, align 8 + store ptr %arg, ptr %arg.addr, align 8 + %0 = load ptr, ptr %arg.addr, align 8 + %1 = ptrtoint ptr %0 to i64 + %conv = trunc i64 %1 to i32 + %call = call i32 @compute(i32 noundef %conv) + %xor = xor i32 %call, 7 + store i32 %xor, ptr @g_b, align 4 + ret ptr null +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %ta = alloca i64, align 8 + %tb = alloca i64, align 8 + store i32 0, ptr %retval, align 4 + %call = call i32 @pthread_create(ptr noundef %ta, ptr noundef null, ptr noundef @worker_a, ptr noundef inttoptr (i64 1 to ptr)) #3 + %call1 = call i32 @pthread_create(ptr noundef %tb, ptr noundef null, ptr noundef @worker_b, ptr noundef inttoptr (i64 2 to ptr)) #3 + store i32 5, ptr @g_main, align 4 + %0 = load i64, ptr %ta, align 8 + %call2 = call i32 @pthread_join(i64 noundef %0, ptr noundef null) + %1 = load i64, ptr %tb, align 8 + %call3 = call i32 @pthread_join(i64 noundef %1, ptr noundef null) + ret i32 0 +} + +; Function Attrs: nounwind +declare i32 @pthread_create(ptr noundef, ptr noundef, ptr noundef, ptr noundef) #1 + +declare i32 @pthread_join(i64 noundef, ptr 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"="+cmov,+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"="+cmov,+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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} diff --git a/test_cases_bc/sliced_mta/single_threaded.c.bc b/test_cases_bc/sliced_mta/single_threaded.c.bc new file mode 100644 index 000000000..51be8c6e8 --- /dev/null +++ b/test_cases_bc/sliced_mta/single_threaded.c.bc @@ -0,0 +1,93 @@ +; ModuleID = '/mnt/scratch/PAG/yjw/projects/svf/Test-Suite/test_cases_bc/sliced_mta/single_threaded.c.bc' +source_filename = "/mnt/scratch/PAG/yjw/projects/svf/Test-Suite/src/sliced_mta/single_threaded.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@g_state = dso_local global i32 0, align 4 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @main() #0 { +entry: + %retval = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 0, ptr %retval, align 4 + %call = call i32 @compute(i32 noundef 7) + store i32 %call, ptr @g_state, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %0, 4 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %1 = load i32, ptr %i, align 4 + %call1 = call i32 @compute(i32 noundef %1) + %2 = load i32, ptr @g_state, align 4 + %add = add nsw i32 %2, %call1 + store i32 %add, ptr @g_state, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %3 = load i32, ptr %i, align 4 + %inc = add nsw i32 %3, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !6 + +for.end: ; preds = %for.cond + %4 = load i32, ptr @g_state, align 4 + %and = and i32 %4, 1 + ret i32 %and +} + +; Function Attrs: noinline nounwind optnone uwtable +define internal i32 @compute(i32 noundef %x) #0 { +entry: + %x.addr = alloca i32, align 4 + %s = alloca i32, align 4 + %i = alloca i32, align 4 + store i32 %x, ptr %x.addr, align 4 + %0 = load i32, ptr %x.addr, align 4 + store i32 %0, ptr %s, align 4 + store i32 0, ptr %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %1 = load i32, ptr %i, align 4 + %cmp = icmp slt i32 %1, 10 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %2 = load i32, ptr %s, align 4 + %mul = mul nsw i32 %2, 3 + %3 = load i32, ptr %i, align 4 + %add = add nsw i32 %mul, %3 + store i32 %add, ptr %s, align 4 + br label %for.inc + +for.inc: ; preds = %for.body + %4 = load i32, ptr %i, align 4 + %inc = add nsw i32 %4, 1 + store i32 %inc, ptr %i, align 4 + br label %for.cond, !llvm.loop !8 + +for.end: ; preds = %for.cond + %5 = load i32, ptr %s, align 4 + ret i32 %5 +} + +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"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } + +!llvm.module.flags = !{!0, !1, !2, !3, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 8, !"PIC Level", i32 2} +!2 = !{i32 7, !"PIE Level", i32 2} +!3 = !{i32 7, !"uwtable", i32 2} +!4 = !{i32 7, !"frame-pointer", i32 2} +!5 = !{!"clang version 21.1.0 (https://github.com/bjjwwang/LLVM-compile 4f7056e8ada487923d1c8f9bc38df6472008eda3)"} +!6 = distinct !{!6, !7} +!7 = !{!"llvm.loop.mustprogress"} +!8 = distinct !{!8, !7} From 77e64a7c76711c0708c222b254a7966f2f25573f Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Mon, 6 Jul 2026 21:39:36 +1000 Subject: [PATCH 5/8] MTA: rename sliced_mta test cases (drop smoke prefix) Use concise, descriptive names matching the suite's style. Co-Authored-By: Claude Opus 4.8 --- CMakeLists.txt | 14 +++++++------- src/sliced_mta/{smoke1_basic.c => basic.c} | 2 +- ...7_indirect_fork_join.c => indirect_fork_join.c} | 0 src/sliced_mta/{smoke2_interproc.c => interproc.c} | 2 +- .../{smoke6_lock_paths.c => lock_paths.c} | 0 ...pointer_field_flows.c => pointer_field_flows.c} | 0 .../{smoke4_pointer_noise.c => pointer_noise.c} | 2 +- .../{smoke3_rich_races.c => rich_races.c} | 2 +- ...{smoke5_workqueue_stats.c => workqueue_stats.c} | 2 +- .../sliced_mta/{smoke1_basic.c.bc => basic.c.bc} | 4 ++-- ...rect_fork_join.c.bc => indirect_fork_join.c.bc} | 4 ++-- .../{smoke2_interproc.c.bc => interproc.c.bc} | 4 ++-- .../{smoke6_lock_paths.c.bc => lock_paths.c.bc} | 4 ++-- ...r_field_flows.c.bc => pointer_field_flows.c.bc} | 4 ++-- ...moke4_pointer_noise.c.bc => pointer_noise.c.bc} | 4 ++-- .../{smoke3_rich_races.c.bc => rich_races.c.bc} | 4 ++-- ...5_workqueue_stats.c.bc => workqueue_stats.c.bc} | 4 ++-- 17 files changed, 28 insertions(+), 28 deletions(-) rename src/sliced_mta/{smoke1_basic.c => basic.c} (96%) rename src/sliced_mta/{smoke7_indirect_fork_join.c => indirect_fork_join.c} (100%) rename src/sliced_mta/{smoke2_interproc.c => interproc.c} (96%) rename src/sliced_mta/{smoke6_lock_paths.c => lock_paths.c} (100%) rename src/sliced_mta/{smoke8_pointer_field_flows.c => pointer_field_flows.c} (100%) rename src/sliced_mta/{smoke4_pointer_noise.c => pointer_noise.c} (95%) rename src/sliced_mta/{smoke3_rich_races.c => rich_races.c} (96%) rename src/sliced_mta/{smoke5_workqueue_stats.c => workqueue_stats.c} (99%) rename test_cases_bc/sliced_mta/{smoke1_basic.c.bc => basic.c.bc} (98%) rename test_cases_bc/sliced_mta/{smoke7_indirect_fork_join.c.bc => indirect_fork_join.c.bc} (98%) rename test_cases_bc/sliced_mta/{smoke2_interproc.c.bc => interproc.c.bc} (98%) rename test_cases_bc/sliced_mta/{smoke6_lock_paths.c.bc => lock_paths.c.bc} (98%) rename test_cases_bc/sliced_mta/{smoke8_pointer_field_flows.c.bc => pointer_field_flows.c.bc} (98%) rename test_cases_bc/sliced_mta/{smoke4_pointer_noise.c.bc => pointer_noise.c.bc} (99%) rename test_cases_bc/sliced_mta/{smoke3_rich_races.c.bc => rich_races.c.bc} (98%) rename test_cases_bc/sliced_mta/{smoke5_workqueue_stats.c.bc => workqueue_stats.c.bc} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06436f488..eff55c023 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,8 +194,8 @@ endforeach() # mta statistic tests (ctest -R mta_stat_tests -VV) set(mta_stat_cmd "mta -mt-flow-sensitive=false -stat=true") set(mta_stat_files - test_cases_bc/sliced_mta/smoke1_basic.c.bc - test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc + test_cases_bc/sliced_mta/basic.c.bc + test_cases_bc/sliced_mta/indirect_fork_join.c.bc ) string(REPLACE " " ";" commandtemp ${mta_stat_cmd}) set(command ${commandtemp}) @@ -246,8 +246,8 @@ endforeach() # Exercises the -main-ila-sliced (fresh SVFG from the sliced ILA) branch. set(mta_main_ila_cmd "mta -enable-slicing=true -main-ila-sliced=true -stat=true") set(mta_main_ila_files - test_cases_bc/sliced_mta/smoke1_basic.c.bc - test_cases_bc/sliced_mta/smoke3_rich_races.c.bc + test_cases_bc/sliced_mta/basic.c.bc + test_cases_bc/sliced_mta/rich_races.c.bc ) string(REPLACE " " ";" commandtemp ${mta_main_ila_cmd}) set(command ${commandtemp}) @@ -265,9 +265,9 @@ endforeach() set(mta_observe_sliced_cmd "mta -observe=true -enable-slicing=true") set(mta_observe_whole_cmd "mta -observe=true -enable-slicing=false") set(mta_observe_files - test_cases_bc/sliced_mta/smoke1_basic.c.bc - test_cases_bc/sliced_mta/smoke3_rich_races.c.bc - test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc + test_cases_bc/sliced_mta/basic.c.bc + test_cases_bc/sliced_mta/rich_races.c.bc + test_cases_bc/sliced_mta/lock_paths.c.bc ) foreach(filename ${mta_observe_files}) string(REPLACE " " ";" cmd_sliced ${mta_observe_sliced_cmd}) diff --git a/src/sliced_mta/smoke1_basic.c b/src/sliced_mta/basic.c similarity index 96% rename from src/sliced_mta/smoke1_basic.c rename to src/sliced_mta/basic.c index 264856842..8dcf85807 100644 --- a/src/sliced_mta/smoke1_basic.c +++ b/src/sliced_mta/basic.c @@ -1,4 +1,4 @@ -// smoke1_basic.c -- a minimal smoke test for the MSli artifact. +// basic.c -- a minimal test for the MSli artifact. // // Two worker threads share a counter and a flag; main also touches them. Most of // the program is independent local arithmetic (compute_*) that never touches the diff --git a/src/sliced_mta/smoke7_indirect_fork_join.c b/src/sliced_mta/indirect_fork_join.c similarity index 100% rename from src/sliced_mta/smoke7_indirect_fork_join.c rename to src/sliced_mta/indirect_fork_join.c diff --git a/src/sliced_mta/smoke2_interproc.c b/src/sliced_mta/interproc.c similarity index 96% rename from src/sliced_mta/smoke2_interproc.c rename to src/sliced_mta/interproc.c index 462c5d7f3..5e7667efe 100644 --- a/src/sliced_mta/smoke2_interproc.c +++ b/src/sliced_mta/interproc.c @@ -1,4 +1,4 @@ -// smoke2_interproc.c -- a second smoke test exercising interprocedural slicing. +// interproc.c -- a second test exercising interprocedural slicing. // // A pool of worker threads reaches a shared write through a chain of helper // calls, and main writes the same object concurrently. A separate, larger body diff --git a/src/sliced_mta/smoke6_lock_paths.c b/src/sliced_mta/lock_paths.c similarity index 100% rename from src/sliced_mta/smoke6_lock_paths.c rename to src/sliced_mta/lock_paths.c diff --git a/src/sliced_mta/smoke8_pointer_field_flows.c b/src/sliced_mta/pointer_field_flows.c similarity index 100% rename from src/sliced_mta/smoke8_pointer_field_flows.c rename to src/sliced_mta/pointer_field_flows.c diff --git a/src/sliced_mta/smoke4_pointer_noise.c b/src/sliced_mta/pointer_noise.c similarity index 95% rename from src/sliced_mta/smoke4_pointer_noise.c rename to src/sliced_mta/pointer_noise.c index ec2bf2b4c..1573634fc 100644 --- a/src/sliced_mta/smoke4_pointer_noise.c +++ b/src/sliced_mta/pointer_noise.c @@ -1,4 +1,4 @@ -// smoke4_pointer_noise.c -- pthread races with unrelated pointer-heavy code. +// pointer_noise.c -- pthread races with unrelated pointer-heavy code. #include typedef struct Node { diff --git a/src/sliced_mta/smoke3_rich_races.c b/src/sliced_mta/rich_races.c similarity index 96% rename from src/sliced_mta/smoke3_rich_races.c rename to src/sliced_mta/rich_races.c index 30a7776c3..7e12bc5e1 100644 --- a/src/sliced_mta/smoke3_rich_races.c +++ b/src/sliced_mta/rich_races.c @@ -1,4 +1,4 @@ -// smoke3_rich_races.c -- a denser smoke test for preservation checks. +// rich_races.c -- a denser test for preservation checks. // // This case has several independently reachable race statements: direct shared // writes, pointer-indirect writes, interprocedural writes, and array element diff --git a/src/sliced_mta/smoke5_workqueue_stats.c b/src/sliced_mta/workqueue_stats.c similarity index 99% rename from src/sliced_mta/smoke5_workqueue_stats.c rename to src/sliced_mta/workqueue_stats.c index e3acd5b65..c33a447cb 100644 --- a/src/sliced_mta/smoke5_workqueue_stats.c +++ b/src/sliced_mta/workqueue_stats.c @@ -1,4 +1,4 @@ -// smoke5_workqueue_stats.c -- a small request-processing workload. +// workqueue_stats.c -- a small request-processing workload. // // Worker threads run a local request pipeline and then update shared statistics // without locks. Most request parsing, routing, checksum, and serialization code diff --git a/test_cases_bc/sliced_mta/smoke1_basic.c.bc b/test_cases_bc/sliced_mta/basic.c.bc similarity index 98% rename from test_cases_bc/sliced_mta/smoke1_basic.c.bc rename to test_cases_bc/sliced_mta/basic.c.bc index 088c950f1..34133385a 100644 --- a/test_cases_bc/sliced_mta/smoke1_basic.c.bc +++ b/test_cases_bc/sliced_mta/basic.c.bc @@ -1,5 +1,5 @@ -; ModuleID = 'test_cases_bc/sliced_mta/smoke1_basic.c.bc' -source_filename = "src/sliced_mta/smoke1_basic.c" +; ModuleID = 'test_cases_bc/sliced_mta/basic.c.bc' +source_filename = "src/sliced_mta/basic.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc b/test_cases_bc/sliced_mta/indirect_fork_join.c.bc similarity index 98% rename from test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc rename to test_cases_bc/sliced_mta/indirect_fork_join.c.bc index f520c2ed4..7c6d35df2 100644 --- a/test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc +++ b/test_cases_bc/sliced_mta/indirect_fork_join.c.bc @@ -1,5 +1,5 @@ -; ModuleID = 'test_cases_bc/sliced_mta/smoke7_indirect_fork_join.c.bc' -source_filename = "src/sliced_mta/smoke7_indirect_fork_join.c" +; ModuleID = 'test_cases_bc/sliced_mta/indirect_fork_join.c.bc' +source_filename = "src/sliced_mta/indirect_fork_join.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test_cases_bc/sliced_mta/smoke2_interproc.c.bc b/test_cases_bc/sliced_mta/interproc.c.bc similarity index 98% rename from test_cases_bc/sliced_mta/smoke2_interproc.c.bc rename to test_cases_bc/sliced_mta/interproc.c.bc index c5efeaa9b..32a67ad83 100644 --- a/test_cases_bc/sliced_mta/smoke2_interproc.c.bc +++ b/test_cases_bc/sliced_mta/interproc.c.bc @@ -1,5 +1,5 @@ -; ModuleID = 'test_cases_bc/sliced_mta/smoke2_interproc.c.bc' -source_filename = "src/sliced_mta/smoke2_interproc.c" +; ModuleID = 'test_cases_bc/sliced_mta/interproc.c.bc' +source_filename = "src/sliced_mta/interproc.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc b/test_cases_bc/sliced_mta/lock_paths.c.bc similarity index 98% rename from test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc rename to test_cases_bc/sliced_mta/lock_paths.c.bc index 14e0e0578..9a63d7eb5 100644 --- a/test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc +++ b/test_cases_bc/sliced_mta/lock_paths.c.bc @@ -1,5 +1,5 @@ -; ModuleID = 'test_cases_bc/sliced_mta/smoke6_lock_paths.c.bc' -source_filename = "src/sliced_mta/smoke6_lock_paths.c" +; ModuleID = 'test_cases_bc/sliced_mta/lock_paths.c.bc' +source_filename = "src/sliced_mta/lock_paths.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test_cases_bc/sliced_mta/smoke8_pointer_field_flows.c.bc b/test_cases_bc/sliced_mta/pointer_field_flows.c.bc similarity index 98% rename from test_cases_bc/sliced_mta/smoke8_pointer_field_flows.c.bc rename to test_cases_bc/sliced_mta/pointer_field_flows.c.bc index 92044201e..06b246782 100644 --- a/test_cases_bc/sliced_mta/smoke8_pointer_field_flows.c.bc +++ b/test_cases_bc/sliced_mta/pointer_field_flows.c.bc @@ -1,5 +1,5 @@ -; ModuleID = 'test_cases_bc/sliced_mta/smoke8_pointer_field_flows.c.bc' -source_filename = "src/sliced_mta/smoke8_pointer_field_flows.c" +; ModuleID = 'test_cases_bc/sliced_mta/pointer_field_flows.c.bc' +source_filename = "src/sliced_mta/pointer_field_flows.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test_cases_bc/sliced_mta/smoke4_pointer_noise.c.bc b/test_cases_bc/sliced_mta/pointer_noise.c.bc similarity index 99% rename from test_cases_bc/sliced_mta/smoke4_pointer_noise.c.bc rename to test_cases_bc/sliced_mta/pointer_noise.c.bc index fa34381db..b7b883453 100644 --- a/test_cases_bc/sliced_mta/smoke4_pointer_noise.c.bc +++ b/test_cases_bc/sliced_mta/pointer_noise.c.bc @@ -1,5 +1,5 @@ -; ModuleID = 'test_cases_bc/sliced_mta/smoke4_pointer_noise.c.bc' -source_filename = "src/sliced_mta/smoke4_pointer_noise.c" +; ModuleID = 'test_cases_bc/sliced_mta/pointer_noise.c.bc' +source_filename = "src/sliced_mta/pointer_noise.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test_cases_bc/sliced_mta/smoke3_rich_races.c.bc b/test_cases_bc/sliced_mta/rich_races.c.bc similarity index 98% rename from test_cases_bc/sliced_mta/smoke3_rich_races.c.bc rename to test_cases_bc/sliced_mta/rich_races.c.bc index 18fe81d5e..da7067467 100644 --- a/test_cases_bc/sliced_mta/smoke3_rich_races.c.bc +++ b/test_cases_bc/sliced_mta/rich_races.c.bc @@ -1,5 +1,5 @@ -; ModuleID = 'test_cases_bc/sliced_mta/smoke3_rich_races.c.bc' -source_filename = "src/sliced_mta/smoke3_rich_races.c" +; ModuleID = 'test_cases_bc/sliced_mta/rich_races.c.bc' +source_filename = "src/sliced_mta/rich_races.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test_cases_bc/sliced_mta/smoke5_workqueue_stats.c.bc b/test_cases_bc/sliced_mta/workqueue_stats.c.bc similarity index 99% rename from test_cases_bc/sliced_mta/smoke5_workqueue_stats.c.bc rename to test_cases_bc/sliced_mta/workqueue_stats.c.bc index 3a3f06f41..f1accf887 100644 --- a/test_cases_bc/sliced_mta/smoke5_workqueue_stats.c.bc +++ b/test_cases_bc/sliced_mta/workqueue_stats.c.bc @@ -1,5 +1,5 @@ -; ModuleID = 'test_cases_bc/sliced_mta/smoke5_workqueue_stats.c.bc' -source_filename = "src/sliced_mta/smoke5_workqueue_stats.c" +; ModuleID = 'test_cases_bc/sliced_mta/workqueue_stats.c.bc' +source_filename = "src/sliced_mta/workqueue_stats.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" From ed0a9c0eb0f03713524a4c300edadfdc0320ebd5 Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Mon, 6 Jul 2026 21:56:51 +1000 Subject: [PATCH 6/8] MTA: assert race-statement counts (not just exit code) Add mta_race_count_tests: for each known program, assert the exact sliced (MSli) and whole-program (FSAM) race count, so a silent mis-detection or a sliced/whole divergence fails the suite. The other MTA suites only check that mta runs. Co-Authored-By: Claude Opus 4.8 --- CMakeLists.txt | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index eff55c023..ccc6eba32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -301,6 +301,42 @@ foreach(filename ${saber_full_files}) ) endforeach() +# MSli race-statement count assertions (ctest -R mta_race_count_tests -VV) +# The suites above only check that mta runs (exit 0); they pass even if race +# detection is silently broken. These assert the exact race-statement count for +# each known program, for BOTH the sliced (MSli) and whole-program (FSAM) runs -- +# so a wrong count, or a sliced/whole divergence (a query-preservation break), +# fails the test. Update the expected number when the analysis legitimately changes. +set(MTA_BIN "${CMAKE_BINARY_DIR}/bin/mta") +set(SLICED_MTA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/sliced_mta") +set(mta_race_counts + "basic=5" "interproc=2" "rich_races=9" "pointer_noise=75" + "workqueue_stats=6" "lock_paths=18" "indirect_fork_join=12" "pointer_field_flows=14" +) +foreach(entry ${mta_race_counts}) + string(REPLACE "=" ";" kv ${entry}) + list(GET kv 0 cname) + list(GET kv 1 ccount) + add_test( + NAME mta_race_count_tests/${cname} + COMMAND bash -c "${MTA_BIN} -enable-slicing=true '${SLICED_MTA_DIR}/${cname}.c.bc' | grep -Fxq '[MSLI-RQ] mode=MSli alarms=${ccount}' && ${MTA_BIN} -enable-slicing=false '${SLICED_MTA_DIR}/${cname}.c.bc' | grep -Fxq '[MSLI-RQ] mode=FSAM alarms=${ccount}'" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endforeach() + +# Guard-path assertions: a threaded but race-free program reports zero race +# pairs, and a non-threaded program reports no thread functions. +add_test( + NAME mta_race_count_tests/no_data_race + COMMAND bash -c "${MTA_BIN} -enable-slicing=true '${SLICED_MTA_DIR}/no_data_race.c.bc' | grep -Fxq 'Found 0 race pairs'" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) +add_test( + NAME mta_race_count_tests/single_threaded + COMMAND bash -c "${MTA_BIN} -enable-slicing=true '${SLICED_MTA_DIR}/single_threaded.c.bc' | grep -Fxq '[WARNING] No thread functions found'" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) + # graphdb dvf and mta tests (write + read) # Usage: ctest -R graphdb-dvf_tests -VV list(APPEND graphdb_dvf_folders From a97de564634dd47b476055f888a0c759255e30e5 Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Mon, 6 Jul 2026 22:08:30 +1000 Subject: [PATCH 7/8] MTA: drop the ad-hoc race-count assertion tests The in-tool MTA annotation validation was removed in the refactor, so these grep-based ctest assertions were inconsistent with the rest of the (exit-code) MTA suite. Co-Authored-By: Claude Opus 4.8 --- CMakeLists.txt | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ccc6eba32..eff55c023 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -301,42 +301,6 @@ foreach(filename ${saber_full_files}) ) endforeach() -# MSli race-statement count assertions (ctest -R mta_race_count_tests -VV) -# The suites above only check that mta runs (exit 0); they pass even if race -# detection is silently broken. These assert the exact race-statement count for -# each known program, for BOTH the sliced (MSli) and whole-program (FSAM) runs -- -# so a wrong count, or a sliced/whole divergence (a query-preservation break), -# fails the test. Update the expected number when the analysis legitimately changes. -set(MTA_BIN "${CMAKE_BINARY_DIR}/bin/mta") -set(SLICED_MTA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/sliced_mta") -set(mta_race_counts - "basic=5" "interproc=2" "rich_races=9" "pointer_noise=75" - "workqueue_stats=6" "lock_paths=18" "indirect_fork_join=12" "pointer_field_flows=14" -) -foreach(entry ${mta_race_counts}) - string(REPLACE "=" ";" kv ${entry}) - list(GET kv 0 cname) - list(GET kv 1 ccount) - add_test( - NAME mta_race_count_tests/${cname} - COMMAND bash -c "${MTA_BIN} -enable-slicing=true '${SLICED_MTA_DIR}/${cname}.c.bc' | grep -Fxq '[MSLI-RQ] mode=MSli alarms=${ccount}' && ${MTA_BIN} -enable-slicing=false '${SLICED_MTA_DIR}/${cname}.c.bc' | grep -Fxq '[MSLI-RQ] mode=FSAM alarms=${ccount}'" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) -endforeach() - -# Guard-path assertions: a threaded but race-free program reports zero race -# pairs, and a non-threaded program reports no thread functions. -add_test( - NAME mta_race_count_tests/no_data_race - COMMAND bash -c "${MTA_BIN} -enable-slicing=true '${SLICED_MTA_DIR}/no_data_race.c.bc' | grep -Fxq 'Found 0 race pairs'" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) -add_test( - NAME mta_race_count_tests/single_threaded - COMMAND bash -c "${MTA_BIN} -enable-slicing=true '${SLICED_MTA_DIR}/single_threaded.c.bc' | grep -Fxq '[WARNING] No thread functions found'" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) - # graphdb dvf and mta tests (write + read) # Usage: ctest -R graphdb-dvf_tests -VV list(APPEND graphdb_dvf_folders From bd3642e5433c12fceb9177d018be47ef00f87420 Mon Sep 17 00:00:00 2001 From: JoelYYoung <56264140+JoelYYoung@users.noreply.github.com> Date: Tue, 7 Jul 2026 16:15:33 +1000 Subject: [PATCH 8/8] MTA: rename sliced_mta test options to the -mta-* namespace Follow the SVF option rename: -enable-slicing -> -mta-enable-slicing, -mt-flow-sensitive -> -mta-flow-sensitive, -slicing-single -> -mta-slicing-single. Drop the main-ila-sliced and observe test blocks (those options were removed). --- CMakeLists.txt | 52 +++++--------------------------------------------- 1 file changed, 5 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eff55c023..4a2090614 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,7 +176,7 @@ foreach(i RANGE ${dvf_len2}) endforeach() # sliced mta tests (ctest -R sliced_mta_tests -VV) -set(sliced_mta_cmd "mta -enable-slicing=true -stat=true") +set(sliced_mta_cmd "mta -mta-enable-slicing=true -stat=true") file(GLOB sliced_mta_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/sliced_mta/*.bc*") string(REPLACE " " ";" commandtemp ${sliced_mta_cmd}) set(command ${commandtemp}) @@ -192,7 +192,7 @@ foreach(filename ${sliced_mta_files}) endforeach() # mta statistic tests (ctest -R mta_stat_tests -VV) -set(mta_stat_cmd "mta -mt-flow-sensitive=false -stat=true") +set(mta_stat_cmd "mta -mta-flow-sensitive=false -stat=true") set(mta_stat_files test_cases_bc/sliced_mta/basic.c.bc test_cases_bc/sliced_mta/indirect_fork_join.c.bc @@ -210,7 +210,7 @@ endforeach() # whole-program (no-slicing) FSAM baseline (ctest -R mta_whole_tests -VV) # Runs the SlicedMTA pipeline with slicing off, exercising runWholeProgramDetection # (the A/B reference the sliced run is compared against). -set(mta_whole_cmd "mta -enable-slicing=false -stat=true") +set(mta_whole_cmd "mta -mta-enable-slicing=false -stat=true") file(GLOB mta_whole_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/sliced_mta/*.bc*") string(REPLACE " " ";" commandtemp ${mta_whole_cmd}) set(command ${commandtemp}) @@ -226,8 +226,8 @@ foreach(filename ${mta_whole_files}) endforeach() # single unified slice, one slice for ILA + FSPTA (ctest -R mta_single_slice_tests -VV) -# Exercises the SingleSlicer (-slicing-single) single-pass baseline branch. -set(mta_single_cmd "mta -enable-slicing=true -slicing-single=true -stat=true") +# Exercises the SingleSlicer (-mta-slicing-single) single-pass baseline branch. +set(mta_single_cmd "mta -mta-enable-slicing=true -mta-slicing-single=true -stat=true") file(GLOB mta_single_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/sliced_mta/*.bc*") string(REPLACE " " ";" commandtemp ${mta_single_cmd}) set(command ${commandtemp}) @@ -242,48 +242,6 @@ foreach(filename ${mta_single_files}) ) endforeach() -# main FSMPTA value flow rebuilt from the sliced ILA (ctest -R mta_main_ila_tests -VV) -# Exercises the -main-ila-sliced (fresh SVFG from the sliced ILA) branch. -set(mta_main_ila_cmd "mta -enable-slicing=true -main-ila-sliced=true -stat=true") -set(mta_main_ila_files - test_cases_bc/sliced_mta/basic.c.bc - test_cases_bc/sliced_mta/rich_races.c.bc -) -string(REPLACE " " ";" commandtemp ${mta_main_ila_cmd}) -set(command ${commandtemp}) -foreach(filename ${mta_main_ila_files}) - add_test( - NAME mta_main_ila_tests/${filename} - COMMAND ${command} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) -endforeach() - -# observe mode: dump FSAM points-to + ILA instead of detecting races -# (ctest -R mta_observe_tests -VV). Both slicing on/off variants are run so the -# sliced and whole-program observers (and the ILA dumper) are all exercised. -set(mta_observe_sliced_cmd "mta -observe=true -enable-slicing=true") -set(mta_observe_whole_cmd "mta -observe=true -enable-slicing=false") -set(mta_observe_files - test_cases_bc/sliced_mta/basic.c.bc - test_cases_bc/sliced_mta/rich_races.c.bc - test_cases_bc/sliced_mta/lock_paths.c.bc -) -foreach(filename ${mta_observe_files}) - string(REPLACE " " ";" cmd_sliced ${mta_observe_sliced_cmd}) - add_test( - NAME mta_observe_tests/sliced/${filename} - COMMAND ${cmd_sliced} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) - string(REPLACE " " ";" cmd_whole ${mta_observe_whole_cmd}) - add_test( - NAME mta_observe_tests/whole/${filename} - COMMAND ${cmd_whole} ${CMAKE_CURRENT_SOURCE_DIR}/${filename} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) -endforeach() - # saber with the full SVFG on top of the pointer-only one (ctest -R saber_full_svfg_tests -VV) # Exercises SVFGBuilder::buildFullSVFG / SVFGOPT (plain saber uses the pointer-only SVFG). set(saber_full_cmd "saber -leak -saber-full-svfg=true -valid-tests -stat=false")