Convert the standard default-construction loops to use phis and
partial destruction.

llvm-svn: 135033
diff --git a/clang/test/CodeGenCXX/new-overflow.cpp b/clang/test/CodeGenCXX/new-overflow.cpp
index fd56d5e..68f89c3 100644
--- a/clang/test/CodeGenCXX/new-overflow.cpp
+++ b/clang/test/CodeGenCXX/new-overflow.cpp
@@ -18,7 +18,7 @@
   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
   // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
   // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T3]])
-  // CHECK:      icmp ult i32 {{.*}}, [[N]]
+  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
   elt *test(short s) {
     return new elt[s];
   }
@@ -41,7 +41,7 @@
   // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
   // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
   // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T4]])
-  // CHECK:      icmp ult i32 {{.*}}, [[T3]]
+  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
   elt *test(short s) {
     return new elt[s];
   }
@@ -69,7 +69,7 @@
   // CHECK-NEXT: [[T7:%.*]] = extractvalue { i32, i1 } [[T4]], 0
   // CHECK-NEXT: [[T8:%.*]] = select i1 [[T6]], i32 -1, i32 [[T7]]
   // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T8]])
-  // CHECK:      icmp ult i32 {{.*}}, [[T3]]
+  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
   elt *test(short s) {
     return new elt[s];
   }
@@ -88,7 +88,7 @@
   // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
   // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
   // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T1]])
-  // CHECK:      icmp ult i32 {{.*}}, [[N]]
+  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
   elt *test(short s) {
     return new elt[s];
   }
@@ -107,7 +107,7 @@
   // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
   // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
   // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T1]])
-  // CHECK:      icmp ult i32 {{.*}}, [[N]]
+  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
   elt *test(int s) {
     return new elt[s];
   }
@@ -129,7 +129,7 @@
   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
   // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
   // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T3]])
-  // CHECK:      icmp ult i32 {{.*}}, [[N]]
+  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
   elt *test(unsigned short s) {
     return new elt[s];
   }
@@ -152,7 +152,7 @@
   // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
   // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
   // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T4]])
-  // CHECK:      icmp ult i32 {{.*}}, [[T3]]
+  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
   elt *test(unsigned short s) {
     return new elt[s];
   }
@@ -177,7 +177,7 @@
   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
   // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
   // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T6]])
-  // CHECK:      icmp ult i32 {{.*}}, [[T1]]
+  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
   elt *test(long long s) {
     return new elt[s];
   }
@@ -202,7 +202,7 @@
   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
   // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
   // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T6]])
-  // CHECK:      icmp ult i32 {{.*}}, [[T1]]
+  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
   elt *test(unsigned long long s) {
     return new elt[s];
   }
diff --git a/clang/test/CodeGenCXX/new.cpp b/clang/test/CodeGenCXX/new.cpp
index bd307f1..3a72bb8 100644
--- a/clang/test/CodeGenCXX/new.cpp
+++ b/clang/test/CodeGenCXX/new.cpp
@@ -182,12 +182,17 @@
   }
 
   // CHECK:    define void @_ZN6test155test1EPv(
-  // CHECK:      [[P:%.*]] = load i8*
+  // CHECK:      [[P:%.*]] = load i8**
   // CHECK-NEXT: icmp eq i8* [[P]], null
   // CHECK-NEXT: br i1
-  // CHECK:      [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
-  // CHECK:      [[T1:%.*]] = getelementptr inbounds [[A]]* [[T0]],
-  // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T1]])
+  // CHECK:      [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+  // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5
+  // CHECK-NEXT: br label
+  // CHECK:      [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+  // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]])
+  // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1
+  // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+  // CHECK-NEXT: br i1 [[DONE]]
   void test1(void *p) {
     new (p) A[5];
   }
@@ -202,9 +207,13 @@
   // CHECK-NEXT: [[P:%.*]] = load i8*
   // CHECK-NEXT: icmp eq i8* [[P]], null
   // CHECK-NEXT: br i1
-  // CHECK:      [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
-  // CHECK:      [[T1:%.*]] = getelementptr inbounds [[A]]* [[T0]],
-  // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T1]])
+  // CHECK:      [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+  // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0
+  // CHECK-NEXT: br i1 [[ISEMPTY]],
+  // CHECK:      [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 [[T0]]
+  // CHECK-NEXT: br label
+  // CHECK:      [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]],
+  // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]])
   void test2(void *p, int n) {
     new (p) A[n];
   }
diff --git a/clang/test/CodeGenCXX/partial-destruction.cpp b/clang/test/CodeGenCXX/partial-destruction.cpp
index 5299552..f929d2d 100644
--- a/clang/test/CodeGenCXX/partial-destruction.cpp
+++ b/clang/test/CodeGenCXX/partial-destruction.cpp
@@ -118,3 +118,38 @@
   // CHECK:      invoke void @_ZN5test11AD1Ev([[A]]* [[Y]])
   // CHECK:      invoke void @_ZN5test11AD1Ev([[A]]* [[X]])
 }
+
+namespace test2 {
+  struct A { A(); ~A(); };
+
+  void test() {
+    A v[4][7];
+
+    // CHECK:    define void @_ZN5test24testEv()
+    // CHECK:      [[V:%.*]] = alloca [4 x [7 x [[A:%.*]]]], align 1
+    // CHECK-NEXT: alloca i8*
+    // CHECK-NEXT: alloca i32
+    // CHECK-NEXT: alloca i32
+
+    // Main initialization loop.
+    // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x [7 x [[A]]]]* [[V]], i32 0, i32 0, i32 0
+    // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 28
+    // CHECK-NEXT: br label
+    // CHECK:      [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+    // CHECK-NEXT: invoke void @_ZN5test21AC1Ev([[A]]* [[CUR]])
+    // CHECK:      [[NEXT:%.*]] = getelementptr inbounds [[A]]* [[CUR]], i64 1
+    // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+    // CHECK-NEXT: br i1 [[DONE]],
+
+    // Partial destruction landing pad.
+    // CHECK:      llvm.eh.exception()
+    // CHECK:      [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[CUR]]
+    // CHECK-NEXT: br i1 [[EMPTY]],
+    // CHECK:      [[PAST:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[DEL:%.*]], {{%.*}} ]
+    // CHECK-NEXT: [[DEL]] = getelementptr inbounds [[A]]* [[PAST]], i64 -1
+    // CHECK-NEXT: invoke void @_ZN5test21AD1Ev([[A]]* [[DEL]])
+    // CHECK:      [[T0:%.*]] = icmp eq [[A]]* [[DEL]], [[BEGIN]]
+    // CHECK-NEXT: br i1 [[T0]],
+  }
+
+}
diff --git a/clang/test/CodeGenCXX/value-init.cpp b/clang/test/CodeGenCXX/value-init.cpp
index 6178c24..04a18b3 100644
--- a/clang/test/CodeGenCXX/value-init.cpp
+++ b/clang/test/CodeGenCXX/value-init.cpp
@@ -204,7 +204,6 @@
   };
   // CHECK:    define void @_ZN5test64testEv()
   // CHECK:      [[ARR:%.*]] = alloca [10 x [20 x [[A:%.*]]]],
-  // CHECK-NEXT: [[IDX:%.*]] = alloca i64
 
   // CHECK-NEXT: [[INNER:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[ARR]], i64 0, i64 0
   // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 0, i64 0
@@ -222,23 +221,17 @@
   // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 10
   // CHECK-NEXT: br label
   // CHECK:      [[CUR:%.*]] = phi [20 x [[A]]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
-  // CHECK-NEXT: [[FIRST:%.*]] = bitcast [20 x [[A]]]* [[CUR]] to [[A]]*
 
-  // TODO: this loop should use phis, too, and for preference would be
-  // merged with the outer loop.
-  // CHECK-NEXT: store i64 0, i64* [[IDX]]
+  // Inner loop.
+  // CHECK-NEXT: [[IBEGIN:%.*]] = getelementptr inbounds [20 x [[A]]]* [[CUR]], i32 0, i32 0
+  // CHECK-NEXT: [[IEND:%.*]] = getelementptr inbounds [[A]]* [[IBEGIN]], i64 20
   // CHECK-NEXT: br label
-  // CHECK:      [[T0:%.*]] = load i64* [[IDX]]
-  // CHECK-NEXT: [[T1:%.*]] = icmp ult i64 [[T0]], 20
-  // CHECK-NEXT: br i1 [[T1]]
-  // CHECK:      [[T0:%.*]] = load i64* [[IDX]]
-  // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]]* [[FIRST]], i64 [[T0]]
-  // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[T1]])
-  // CHECK-NEXT: br label
-  // CHECK:      [[T0:%.*]] = load i64* [[IDX]]
-  // CHECK-NEXT: [[T1:%.*]] = add i64 [[T0]], 1
-  // CHECK-NEXT: store i64 [[T1]], i64* [[IDX]]
-  // CHECK-NEXT: br label
+  // CHECK:      [[ICUR:%.*]] = phi [[A]]* [ [[IBEGIN]], {{%.*}} ], [ [[INEXT:%.*]], {{%.*}} ]
+  // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[ICUR]])
+  // CHECK-NEXT: [[INEXT:%.*]] = getelementptr inbounds [[A]]* [[ICUR]], i64 1
+  // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[INEXT]], [[IEND]]
+  // CHECK-NEXT: br i1 [[T0]],
+
   // CHECK:      [[NEXT]] = getelementptr inbounds [20 x [[A]]]* [[CUR]], i64 1
   // CHECK-NEXT: [[T0:%.*]] = icmp eq [20 x [[A]]]* [[NEXT]], [[END]]
   // CHECK-NEXT: br i1 [[T0]]