diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-06-03 06:58:52 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-06-03 06:58:52 +0000 |
commit | 06a67e2c6faee4645f43e786e292b5eafcb9b70f (patch) | |
tree | c0c702dd64a90ed2169866ecec654c4d02958670 /clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp | |
parent | e00fec8fe470a800423688b448434f3b2340d038 (diff) | |
download | bcm5719-llvm-06a67e2c6faee4645f43e786e292b5eafcb9b70f.tar.gz bcm5719-llvm-06a67e2c6faee4645f43e786e292b5eafcb9b70f.zip |
When emitting a multidimensional array new, emit the initializers for the
trailing elements as a single loop, rather than sometimes emitting a nest of
several loops. This fixes a bug where CodeGen would sometimes try to emit an
expression with the wrong type for the element being initialized. Plus various
other minor cleanups to the IR produced for array new initialization.
llvm-svn: 210079
Diffstat (limited to 'clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp | 87 |
1 files changed, 70 insertions, 17 deletions
diff --git a/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp b/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp index 8de88dcefb0..2393939b031 100644 --- a/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp +++ b/clang/test/CodeGenCXX/cxx11-initializer-array-new.cpp @@ -28,7 +28,7 @@ void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // // { 4, 5, 6 } // -// CHECK: %[[S_1:.*]] = getelementptr [3 x %[[S]]]* %[[S_0]], i32 1 +// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i32 1 // // CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4) @@ -56,7 +56,6 @@ void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // CHECK: store i64 %[[ELTS]], i64* %[[COOKIE]] // CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8* %[[ALLOC]], i64 8 // CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S]]* -// CHECK: %[[END_AS_S:.*]] = getelementptr inbounds %[[S]]* %[[START_AS_S]], i64 %[[ELTS]] // // Explicit initializers: // @@ -73,7 +72,7 @@ void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // // { 4, 5, 6 } // -// CHECK: %[[S_1:.*]] = getelementptr [3 x %[[S]]]* %[[S_0]], i32 1 +// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i32 1 // // CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4) @@ -82,26 +81,80 @@ void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]]* %[[S_1_1]], i64 1 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6) // -// CHECK: %[[S_2:.*]] = getelementptr [3 x %[[S]]]* %[[S_1]], i32 1 +// And the rest. +// +// CHECK: %[[S_2:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i32 1 // CHECK: %[[S_2_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[S_2]] to %[[S]]* -// CHECK: icmp eq %[[S]]* %[[S_2_AS_S]], %[[END_AS_S]] -// CHECK: br i1 // -// S[n-2][3] initialization loop: +// CHECK: %[[REST:.*]] = sub i64 %[[ELTS]], 6 +// CHECK: icmp eq i64 %[[REST]], 0 +// CHECK: br i1 // -// CHECK: %[[END_INNER:.*]] = getelementptr inbounds %[[S]]* %{{.*}}, i64 3 +// CHECK: %[[END:.*]] = getelementptr inbounds %[[S]]* %[[S_2_AS_S]], i64 %[[REST]] // CHECK: br label // -// S[3] initialization loop: +// CHECK: %[[CUR:.*]] = phi %[[S]]* [ %[[S_2_AS_S]], {{.*}} ], [ %[[NEXT:.*]], {{.*}} ] +// CHECK: call void @_ZN1SC1Ev(%[[S]]* %[[CUR]]) +// CHECK: %[[NEXT]] = getelementptr inbounds %[[S]]* %[[CUR]], i64 1 +// CHECK: icmp eq %[[S]]* %[[NEXT]], %[[END]] +// CHECK: br i1 // -// CHECK: call void @_ZN1SC1Ev(%[[S]]* -// CHECK: %[[NEXT_INNER:.*]] = getelementptr inbounds %[[S]]* %{{.*}}, i64 1 -// CHECK: icmp eq %[[S]]* %[[NEXT_INNER]], %[[END_INNER]] -// CHECK: br i1 +// CHECK: } + +struct T { int a; }; +void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; + +// CHECK-LABEL: define // -// CHECK: %[[NEXT_OUTER:.*]] = getelementptr [3 x %[[S]]]* %{{.*}}, i32 1 -// CHECK: %[[NEXT_OUTER_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[NEXT_OUTER]] to %[[S]]* -// CHECK: icmp eq %[[S]]* %[[NEXT_OUTER_AS_S]], %[[END_AS_S]] -// CHECK: br i1 +// CHECK: load i32* @n +// CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12) +// CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3 +// +// No cookie. +// CHECK-NOT: @llvm.uadd.with.overflow +// +// CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 %{{.*}}) +// +// CHECK: %[[START_AS_T:.*]] = bitcast i8* %[[ALLOC]] to %[[T:.*]]* +// +// Explicit initializers: +// +// { 1, 2, 3 } +// +// CHECK: %[[T_0:.*]] = bitcast %[[T]]* %[[START_AS_T]] to [3 x %[[T]]]* +// +// CHECK: %[[T_0_0:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_0]], i64 0, i64 0 +// CHECK: %[[T_0_0_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_0]], i32 0, i32 0 +// CHECK: store i32 1, i32* %[[T_0_0_0]] +// CHECK: %[[T_0_1:.*]] = getelementptr inbounds %[[T]]* %[[T_0_0]], i64 1 +// CHECK: %[[T_0_1_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_1]], i32 0, i32 0 +// CHECK: store i32 2, i32* %[[T_0_1_0]] +// CHECK: %[[T_0_2:.*]] = getelementptr inbounds %[[T]]* %[[T_0_1]], i64 1 +// CHECK: %[[T_0_2_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_2]], i32 0, i32 0 +// CHECK: store i32 3, i32* %[[T_0_2_0]] +// +// { 4, 5, 6 } +// +// CHECK: %[[T_1:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_0]], i32 1 +// +// CHECK: %[[T_1_0:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_1]], i64 0, i64 0 +// CHECK: %[[T_1_0_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_0]], i32 0, i32 0 +// CHECK: store i32 4, i32* %[[T_1_0_0]] +// CHECK: %[[T_1_1:.*]] = getelementptr inbounds %[[T]]* %[[T_1_0]], i64 1 +// CHECK: %[[T_1_1_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_1]], i32 0, i32 0 +// CHECK: store i32 5, i32* %[[T_1_1_0]] +// CHECK: %[[T_1_2:.*]] = getelementptr inbounds %[[T]]* %[[T_1_1]], i64 1 +// CHECK: %[[T_1_2_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_2]], i32 0, i32 0 +// CHECK: store i32 6, i32* %[[T_1_2_0]] +// +// And the rest gets memset to 0. +// +// CHECK: %[[T_2:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_1]], i32 1 +// CHECK: %[[T_2_AS_T:.*]] = bitcast [3 x %[[T]]]* %[[T_2]] to %[[T]]* +// +// CHECK: %[[SIZE:.*]] = sub i64 %{{.*}}, 24 +// CHECK: %[[REST:.*]] = bitcast %[[T]]* %[[T_2_AS_T]] to i8* +// CHECK: call void @llvm.memset.p0i8.i64(i8* %[[REST]], i8 0, i64 %[[SIZE]], i32 4, i1 false) // // CHECK: } + |