diff options
author | John McCall <rjmccall@apple.com> | 2011-06-24 21:55:10 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-06-24 21:55:10 +0000 |
commit | bc8d40d85f3fa1e34569834916f18fecaa635152 (patch) | |
tree | 47e76a7172c2f2244ee4bbe5fe71fc0bf65e63d3 /test | |
parent | 89f19e43730a2895cd81159d375c71c91872b8c2 (diff) |
Change the IR-generation of VLAs so that we capture bounds,
not sizes; so that we use well-typed allocas; and so that we
properly recurse through the full set of variably-modified types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133827 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CodeGen/vla.c | 20 | ||||
-rw-r--r-- | test/CodeGenCXX/vla.cpp | 43 | ||||
-rw-r--r-- | test/CodeGenObjC/arc.m | 37 |
3 files changed, 75 insertions, 25 deletions
diff --git a/test/CodeGen/vla.c b/test/CodeGen/vla.c index e5114a5b0d..f7cba25d93 100644 --- a/test/CodeGen/vla.c +++ b/test/CodeGen/vla.c @@ -88,13 +88,17 @@ int test2(int n) // http://llvm.org/PR8567 // CHECK: define double @test_PR8567 double test_PR8567(int n, double (*p)[n][5]) { - // CHECK: store [[vla_type:.*]] %p, - // CHECK: load i32* - // CHECK-NEXT: mul i32 40 - // CHECK-NEXT: [[byte_idx:%.*]] = mul i32 1 - // CHECK-NEXT: [[tmp_1:%.*]] = load [[vla_type]]* - // CHECK-NEXT: [[tmp_2:%.*]] = bitcast [[vla_type]] [[tmp_1]] to i8* - // CHECK-NEXT: [[idx:%.*]] = getelementptr inbounds i8* [[tmp_2]], i32 [[byte_idx]] - // CHECK-NEXT: bitcast i8* [[idx]] to [[vla_type]] + // CHECK: [[NV:%.*]] = alloca i32, align 4 + // CHECK-NEXT: [[PV:%.*]] = alloca [5 x double]*, align 4 + // CHECK-NEXT: store + // CHECK-NEXT: store + // CHECK-NEXT: [[N:%.*]] = load i32* [[NV]], align 4 + // CHECK-NEXT: [[P:%.*]] = load [5 x double]** [[PV]], align 4 + // CHECK-NEXT: [[T0:%.*]] = mul i32 1, [[N]] + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [5 x double]* [[P]], i32 [[T0]] + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [5 x double]* [[T1]], i32 2 + // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [5 x double]* [[T2]], i32 0, i32 3 + // CHECK-NEXT: [[T4:%.*]] = load double* [[T3]] + // CHECK-NEXT: ret double [[T4]] return p[1][2][3]; } diff --git a/test/CodeGenCXX/vla.cpp b/test/CodeGenCXX/vla.cpp new file mode 100644 index 0000000000..cee00f2771 --- /dev/null +++ b/test/CodeGenCXX/vla.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s + +// rdar://problem/9506377 +void test0(void *array, int n) { + // CHECK: define void @_Z5test0Pvi( + // CHECK: [[ARRAY:%.*]] = alloca i8*, align 8 + // CHECK-NEXT: [[N:%.*]] = alloca i32, align 4 + // CHECK-NEXT: [[REF:%.*]] = alloca i16*, align 8 + // CHECK-NEXT: [[S:%.*]] = alloca i16, align 2 + // CHECK-NEXT: store i8* + // CHECK-NEXT: store i32 + + // Capture the bounds. + // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[DIM0:%.*]] = zext i32 [[T0]] to i64 + // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], 1 + // CHECK-NEXT: [[DIM1:%.*]] = zext i32 [[T1]] to i64 + typedef short array_t[n][n+1]; + + // CHECK-NEXT: [[T0:%.*]] = load i8** [[ARRAY]], align 8 + // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i16* + // CHECK-NEXT: store i16* [[T1]], i16** [[REF]], align 8 + array_t &ref = *(array_t*) array; + + // CHECK-NEXT: [[T0:%.*]] = load i16** [[REF]] + // CHECK-NEXT: [[T1:%.*]] = mul i64 1, [[DIM1]] + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16* [[T0]], i64 [[T1]] + // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16* [[T2]], i64 2 + // CHECK-NEXT: store i16 3, i16* [[T3]] + ref[1][2] = 3; + + // CHECK-NEXT: [[T0:%.*]] = load i16** [[REF]] + // CHECK-NEXT: [[T1:%.*]] = mul i64 4, [[DIM1]] + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16* [[T0]], i64 [[T1]] + // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16* [[T2]], i64 5 + // CHECK-NEXT: [[T4:%.*]] = load i16* [[T3]] + // CHECK-NEXT: store i16 [[T4]], i16* [[S]], align 2 + short s = ref[4][5]; + + // CHECK-NEXT: ret void +} + diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m index 1d5b4f4220..2a51454e75 100644 --- a/test/CodeGenObjC/arc.m +++ b/test/CodeGenObjC/arc.m @@ -487,23 +487,23 @@ void test20(unsigned n) { id x[n]; // Capture the VLA size. + // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[DIM:%.*]] = zext i32 [[T0]] to i64 + + // Save the stack pointer. // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.stacksave() // CHECK-NEXT: store i8* [[T0]], i8** [[SAVED_STACK]] - // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 - // CHECK-NEXT: [[T1:%.*]] = zext i32 [[T0]] to i64 - // CHECK-NEXT: [[VLA_SIZE:%.*]] = mul i64 8, [[T1]] // Allocate the VLA. - // CHECK-NEXT: [[T0:%.*]] = alloca i8, i64 [[VLA_SIZE]], align 16 - // CHECK-NEXT: [[VLA:%.*]] = bitcast i8* [[T0]] to i8** + // CHECK-NEXT: [[VLA:%.*]] = alloca i8*, i64 [[DIM]], align 16 // Zero-initialize. // CHECK-NEXT: [[T0:%.*]] = bitcast i8** [[VLA]] to i8* - // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 [[VLA_SIZE]], i32 8, i1 false) + // CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[DIM]], 8 + // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 [[T1]], i32 8, i1 false) // Destroy. - // CHECK-NEXT: [[VLA_COUNT:%.*]] = udiv i64 [[VLA_SIZE]], 8 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[VLA]], i64 [[VLA_COUNT]] + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[VLA]], i64 [[DIM]] // CHECK-NEXT: br label // CHECK: [[CUR:%.*]] = phi i8** @@ -529,25 +529,28 @@ void test21(unsigned n) { id x[2][n][3]; // Capture the VLA size. + // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[DIM:%.*]] = zext i32 [[T0]] to i64 + // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.stacksave() // CHECK-NEXT: store i8* [[T0]], i8** [[SAVED_STACK]] - // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 - // CHECK-NEXT: [[T1:%.*]] = zext i32 [[T0]] to i64 - // CHECK-NEXT: [[T2:%.*]] = mul i64 24, [[T1]] - // CHECK-NEXT: [[VLA_SIZE:%.*]] = mul i64 [[T2]], 2 + // Allocate the VLA. - // CHECK-NEXT: [[T0:%.*]] = alloca i8, i64 [[VLA_SIZE]], align 16 - // CHECK-NEXT: [[VLA:%.*]] = bitcast i8* [[T0]] to [3 x i8*]* + // CHECK-NEXT: [[T0:%.*]] = mul nuw i64 2, [[DIM]] + // CHECK-NEXT: [[VLA:%.*]] = alloca [3 x i8*], i64 [[T0]], align 16 // Zero-initialize. // CHECK-NEXT: [[T0:%.*]] = bitcast [3 x i8*]* [[VLA]] to i8* - // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 [[VLA_SIZE]], i32 8, i1 false) + // CHECK-NEXT: [[T1:%.*]] = mul nuw i64 2, [[DIM]] + // CHECK-NEXT: [[T2:%.*]] = mul nuw i64 [[T1]], 24 + // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T0]], i8 0, i64 [[T2]], i32 8, i1 false) // Destroy. + // CHECK-NEXT: [[T0:%.*]] = mul nuw i64 2, [[DIM]] // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [3 x i8*]* [[VLA]], i32 0, i32 0 - // CHECK-NEXT: [[VLA_COUNT:%.*]] = udiv i64 [[VLA_SIZE]], 8 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 [[VLA_COUNT]] + // CHECK-NEXT: [[T1:%.*]] = mul nuw i64 [[T0]], 3 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 [[T1]] // CHECK-NEXT: br label // CHECK: [[CUR:%.*]] = phi i8** |