// RUN: %clang_cc1 -emit-llvm < %s -o %t | |
// RUN: grep volatile %t | count 29 | |
// RUN: grep memcpy %t | count 7 | |
// The number 29 comes from the current codegen for volatile loads; | |
// if this number changes, it's not necessarily something wrong, but | |
// something has changed to affect volatile load/store codegen | |
int S; | |
volatile int vS; | |
int* pS; | |
volatile int* pvS; | |
int A[10]; | |
volatile int vA[10]; | |
struct { int x; } F; | |
struct { volatile int x; } vF; | |
struct { int x; } F2; | |
volatile struct { int x; } vF2; | |
volatile struct { int x; } *vpF2; | |
struct { struct { int y; } x; } F3; | |
volatile struct { struct { int y; } x; } vF3; | |
struct { int x:3; } BF; | |
struct { volatile int x:3; } vBF; | |
typedef int v4si __attribute__ ((vector_size (16))); | |
v4si V; | |
volatile v4si vV; | |
typedef __attribute__(( ext_vector_type(4) )) int extv4; | |
extv4 VE; | |
volatile extv4 vVE; | |
volatile struct {int x;} aggFct(void); | |
typedef volatile int volatile_int; | |
volatile_int vtS; | |
int main() { | |
int i; | |
// load | |
i=S; | |
i=vS; | |
i=*pS; | |
i=*pvS; | |
i=A[2]; | |
i=vA[2]; | |
i=F.x; | |
i=vF.x; | |
i=F2.x; | |
i=vF2.x; | |
i=vpF2->x; | |
i=F3.x.y; | |
i=vF3.x.y; | |
i=BF.x; | |
i=vBF.x; | |
i=V[3]; | |
i=vV[3]; | |
i=VE.yx[1]; | |
i=vVE.zy[1]; | |
i = aggFct().x; | |
i=vtS; | |
// store | |
S=i; | |
vS=i; | |
*pS=i; | |
*pvS=i; | |
A[2]=i; | |
vA[2]=i; | |
F.x=i; | |
vF.x=i; | |
F2.x=i; | |
vF2.x=i; | |
vpF2->x=i; | |
vF3.x.y=i; | |
BF.x=i; | |
vBF.x=i; | |
V[3]=i; | |
vV[3]=i; | |
vtS=i; | |
// other ops: | |
++S; | |
++vS; | |
i+=S; | |
i+=vS; | |
++vtS; | |
(void)vF2; | |
vF2 = vF2; | |
vF2 = vF2 = vF2; | |
vF2 = (vF2, vF2); | |
} |