bart | 64013ad | 2008-09-28 12:31:45 +0000 | [diff] [blame] | 1 | #define _XOPEN_SOURCE 600 // to enable posix_memalign() |
sewardj | 024598e | 2008-09-18 14:43:05 +0000 | [diff] [blame] | 2 | #include <assert.h> |
| 3 | #include <stdlib.h> |
| 4 | #include <malloc.h> // for memalign() |
sewardj | 024598e | 2008-09-18 14:43:05 +0000 | [diff] [blame] | 5 | static __attribute__((noinline)) void bar ( int ); /* fwds */ |
sewardj | 5400d2c | 2008-10-20 11:29:51 +0000 | [diff] [blame] | 6 | int main(void) { |
| 7 | int sum = 0; |
sewardj | 024598e | 2008-09-18 14:43:05 +0000 | [diff] [blame] | 8 | int* x1 = (int*)malloc(sizeof(int)); |
| 9 | int* x2 = new int; |
| 10 | int* x3 = new int[10]; |
| 11 | int* x4 = (int*)calloc(1, sizeof(int)); |
| 12 | int* x5 = (int*)memalign(8, sizeof(int)); |
| 13 | int* x6; void* v6; |
| 14 | int res = posix_memalign(&v6, 8, sizeof(int)); x6 = (int*)v6; |
sewardj | 024598e | 2008-09-18 14:43:05 +0000 | [diff] [blame] | 15 | assert(NULL != x1 && NULL != x2 && NULL != x3 && NULL != x4 && |
| 16 | NULL != x5 && 0 == res); |
sewardj | 5400d2c | 2008-10-20 11:29:51 +0000 | [diff] [blame] | 17 | |
sewardj | 024598e | 2008-09-18 14:43:05 +0000 | [diff] [blame] | 18 | __asm__ __volatile__("":::"memory"); |
| 19 | // all underruns |
| 20 | sum += x1[-1]; __asm__ __volatile__("":::"memory"); bar(1); |
| 21 | sum += x2[-1]; __asm__ __volatile__("":::"memory"); bar(2); |
| 22 | sum += x3[-1]; __asm__ __volatile__("":::"memory"); bar(3); |
| 23 | sum += x4[-1]; __asm__ __volatile__("":::"memory"); bar(4); |
| 24 | sum += x5[-1]; __asm__ __volatile__("":::"memory"); bar(5); |
| 25 | sum += x6[-1]; __asm__ __volatile__("":::"memory"); bar(6); |
| 26 | __asm__ __volatile__("":::"memory"); |
| 27 | return sum; |
| 28 | } |
| 29 | |
| 30 | /* What's with all this __asm__ __volatile__ stuff? Well, it's an |
| 31 | attempt to get gcc-4.1.2 not to claim the memory references that |
| 32 | we're interested in -- x1[-1] through x6[-1] -- appear on different |
| 33 | lines than they really do. By its own rules, gcc can't move code |
| 34 | across an __asm__ __volatile__, and the "memory" item says each one |
| 35 | clobbers memory in some way which gcc can't know, so that probably |
| 36 | (!) persuades it not to carry memory CSEs around either. */ |
| 37 | |
| 38 | static __attribute__((noinline)) void bar ( int x ) |
| 39 | { |
| 40 | __asm__ __volatile__("":::"memory"); |
| 41 | } |