diff options
Diffstat (limited to 'test/CodeGen/volatile.c')
-rw-r--r-- | test/CodeGen/volatile.c | 123 |
1 files changed, 115 insertions, 8 deletions
diff --git a/test/CodeGen/volatile.c b/test/CodeGen/volatile.c index 1a996de..0dcdc15 100644 --- a/test/CodeGen/volatile.c +++ b/test/CodeGen/volatile.c @@ -1,10 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm < %s -o %t -// RUN: grep volatile %t | count 28 -// RUN: grep memcpy %t | count 7 - -// The number 28 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 +// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s int S; volatile int vS; @@ -43,58 +37,171 @@ volatile_int vtS; int main() { int i; - +// CHECK: [[I:%[a-zA-Z0-9_.]+]] = alloca i32 // load i=S; +// CHECK: load i32* @S +// CHECK: store i32 {{.*}}, i32* [[I]] i=vS; +// CHECK: load volatile i32* @vS +// CHECK: store i32 {{.*}}, i32* [[I]] i=*pS; +// CHECK: [[PS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pS +// CHECK: load i32* [[PS_VAL]] +// CHECK: store i32 {{.*}}, i32* [[I]] i=*pvS; +// CHECK: [[PVS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pvS +// CHECK: load volatile i32* [[PVS_VAL]] +// CHECK: store i32 {{.*}}, i32* [[I]] i=A[2]; +// CHECK: load i32* getelementptr {{.*}} @A +// CHECK: store i32 {{.*}}, i32* [[I]] i=vA[2]; +// CHECK: load volatile i32* getelementptr {{.*}} @vA +// CHECK: store i32 {{.*}}, i32* [[I]] i=F.x; +// CHECK: load i32* getelementptr {{.*}} @F +// CHECK: store i32 {{.*}}, i32* [[I]] i=vF.x; +// CHECK: load volatile i32* getelementptr {{.*}} @vF +// CHECK: store i32 {{.*}}, i32* [[I]] i=F2.x; +// CHECK: load i32* getelementptr {{.*}} @F2 +// CHECK: store i32 {{.*}}, i32* [[I]] i=vF2.x; +// CHECK: load volatile i32* getelementptr {{.*}} @vF2 +// CHECK: store i32 {{.*}}, i32* [[I]] i=vpF2->x; +// CHECK: [[VPF2_VAL:%[a-zA-Z0-9_.]+]] = load {{%[a-zA-Z0-9_.]+}}** @vpF2 +// CHECK: [[ELT:%[a-zA-Z0-9_.]+]] = getelementptr {{.*}} [[VPF2_VAL]] +// CHECK: load volatile i32* [[ELT]] +// CHECK: store i32 {{.*}}, i32* [[I]] i=F3.x.y; +// CHECK: load i32* getelementptr {{.*}} @F3 +// CHECK: store i32 {{.*}}, i32* [[I]] i=vF3.x.y; +// CHECK: load volatile i32* getelementptr {{.*}} @vF3 +// CHECK: store i32 {{.*}}, i32* [[I]] i=BF.x; +// CHECK: load i8* getelementptr {{.*}} @BF +// CHECK: store i32 {{.*}}, i32* [[I]] i=vBF.x; +// CHECK: load volatile i8* getelementptr {{.*}} @vBF +// CHECK: store i32 {{.*}}, i32* [[I]] i=V[3]; +// CHECK: load <4 x i32>* @V +// CHECK: store i32 {{.*}}, i32* [[I]] i=vV[3]; +// CHECK: load volatile <4 x i32>* @vV +// CHECK: store i32 {{.*}}, i32* [[I]] i=VE.yx[1]; +// CHECK: load <4 x i32>* @VE +// CHECK: store i32 {{.*}}, i32* [[I]] i=vVE.zy[1]; +// CHECK: load volatile <4 x i32>* @vVE +// CHECK: store i32 {{.*}}, i32* [[I]] i = aggFct().x; // Note: not volatile + // N.b. Aggregate return is extremely target specific, all we can + // really say here is that there probably shouldn't be a volatile + // load. +// CHECK-NOT: load volatile +// CHECK: store i32 {{.*}}, i32* [[I]] i=vtS; +// CHECK: load volatile i32* @vtS +// CHECK: store i32 {{.*}}, i32* [[I]] // store S=i; +// CHECK: load i32* [[I]] +// CHECK: store i32 {{.*}}, i32* @S vS=i; +// CHECK: load i32* [[I]] +// CHECK: store volatile i32 {{.*}}, i32* @vS *pS=i; +// CHECK: load i32* [[I]] +// CHECK: [[PS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pS +// CHECK: store i32 {{.*}}, i32* [[PS_VAL]] *pvS=i; +// CHECK: load i32* [[I]] +// CHECK: [[PVS_VAL:%[a-zA-Z0-9_.]+]] = load i32** @pvS +// CHECK: store volatile i32 {{.*}}, i32* [[PVS_VAL]] A[2]=i; +// CHECK: load i32* [[I]] +// CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @A vA[2]=i; +// CHECK: load i32* [[I]] +// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vA F.x=i; +// CHECK: load i32* [[I]] +// CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @F vF.x=i; +// CHECK: load i32* [[I]] +// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF F2.x=i; +// CHECK: load i32* [[I]] +// CHECK: store i32 {{.*}}, i32* getelementptr {{.*}} @F2 vF2.x=i; +// CHECK: load i32* [[I]] +// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF2 vpF2->x=i; +// CHECK: load i32* [[I]] +// CHECK: [[VPF2_VAL:%[a-zA-Z0-9_.]+]] = load {{%[a-zA-Z0-9._]+}}** @vpF2 +// CHECK: [[ELT:%[a-zA-Z0-9_.]+]] = getelementptr {{.*}} [[VPF2_VAL]] +// CHECK: store volatile i32 {{.*}}, i32* [[ELT]] vF3.x.y=i; +// CHECK: load i32* [[I]] +// CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF3 BF.x=i; +// CHECK: load i32* [[I]] +// CHECK: load i8* getelementptr {{.*}} @BF +// CHECK: store i8 {{.*}}, i8* getelementptr {{.*}} @BF vBF.x=i; +// CHECK: load i32* [[I]] +// CHECK: load volatile i8* getelementptr {{.*}} @vBF +// CHECK: store volatile i8 {{.*}}, i8* getelementptr {{.*}} @vBF V[3]=i; +// CHECK: load i32* [[I]] +// CHECK: load <4 x i32>* @V +// CHECK: store <4 x i32> {{.*}}, <4 x i32>* @V vV[3]=i; +// CHECK: load i32* [[I]] +// CHECK: load volatile <4 x i32>* @vV +// CHECK: store volatile <4 x i32> {{.*}}, <4 x i32>* @vV vtS=i; +// CHECK: load i32* [[I]] +// CHECK: store volatile i32 {{.*}}, i32* @vtS // other ops: ++S; +// CHECK: load i32* @S +// CHECK: store i32 {{.*}}, i32* @S ++vS; +// CHECK: load volatile i32* @vS +// CHECK: store volatile i32 {{.*}}, i32* @vS i+=S; +// CHECK: load i32* @S +// CHECK: load i32* [[I]] +// CHECK: store i32 {{.*}}, i32* [[I]] i+=vS; +// CHECK: load volatile i32* @vS +// CHECK: load i32* [[I]] +// CHECK: store i32 {{.*}}, i32* [[I]] ++vtS; +// CHECK: load volatile i32* @vtS +// CHECK: store volatile i32 {{.*}}, i32* @vtS (void)vF2; + // From vF2 to a temporary +// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* {{.*}} @vF2 {{.*}}, i1 true) vF2 = vF2; + // vF2 to itself +// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true) vF2 = vF2 = vF2; + // vF2 to itself twice +// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true) +// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true) vF2 = (vF2, vF2); + // vF2 to a temporary, then vF2 to itself +// CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* {{.*@vF2.*}}, i1 true) +// CHECK: call void @llvm.memcpy.{{.*}}(i8* {{.*@vF2.*}}, i8* {{.*@vF2.*}}, i1 true) } |