CCTLib
Calling-context and data-object attribution library for Intel Pin
deadspy_prefetch_tp.c
Go to the documentation of this file.
1 // Deadspy ISA test: PREFETCH must not clear the "was-written" shadow.
2 //
3 // Prefetch has no architectural effect on program state -- it only hints
4 // to the hardware cache. If deadspy treated prefetch as a real read, it
5 // would erase the "was-written" marker set by a preceding store, so the
6 // following store to the same address would be missed as a dead write.
7 //
8 // Per iteration:
9 // movq %[v], (%[p]) // store #1 -- kills prime
10 // prefetcht0 (%[p]) // prefetch -- MUST NOT clear shadow
11 // movq %[v], (%[p]) // store #2 -- kills store #1
12 //
13 // Prime is one memset, so per iter we expect 2 * 8B dead writes:
14 // * store #1 kills prime
15 // * store #2 kills store #1
16 // 20000 iters * 16B = 320000 dead bytes.
17 //
18 // The gtest threshold picks a value well above baseline noise but below
19 // the expected 320K, so a regression that lets prefetch clear the shadow
20 // (dropping the workload dead to 0) trips the test.
21 #include <stdint.h>
22 #include <string.h>
23 #define WORK_COUNT 20000
24 static volatile uint64_t sink;
25 static uint64_t buf[WORK_COUNT];
26 int main(int argc, char** argv) {
27  (void)argc; (void)argv;
28  memset(buf, 0xAA, sizeof(buf)); // prime
29  for (int i = 0; i < WORK_COUNT; ++i) {
30  uint64_t v = 0x11;
31  __asm__ __volatile__(
32  "movq %[v], (%[p])\n\t"
33  "prefetcht0 (%[p])\n\t"
34  "movq %[v], (%[p])\n\t"
35  :
36  : [p] "r"(&buf[i]), [v] "r"(v)
37  : "memory");
38  }
39  sink = buf[0];
40  return 0;
41 }
#define WORK_COUNT
int main(int argc, char **argv)
static uint64_t buf[WORK_COUNT]
static volatile uint64_t sink