Experiment with using first-class aggregates to represent member function
pointers.  I find the resulting code to be substantially cleaner, and it
makes it very easy to use the same APIs for data member pointers (which I have
conscientiously avoided here), and it avoids a plethora of potential
inefficiencies due to excessive memory copying, but we'll have to see if it
actually works.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111776 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp
index c0756fa..fa1977e 100644
--- a/test/CodeGenCXX/member-function-pointers.cpp
+++ b/test/CodeGenCXX/member-function-pointers.cpp
@@ -29,50 +29,42 @@
 void (A::*pc3)() = &A::vf1;
 
 void f() {
-  // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0)
-  // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 1)
+  // CHECK: store %0 zeroinitializer, %0* @pa
   pa = 0;
 
-  // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 0)
-  // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 1)
+  // Is this okay?  What are LLVM's volatile semantics for structs?
+  // CHECK: volatile store %0 zeroinitializer, %0* @vpa
   vpa = 0;
 
-  // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pc, i32 0, i32 0)
-  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 16
-  // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pc, i32 0, i32 1)
+  // CHECK: [[TMP:%.*]] = load %0* @pa, align 8
+  // CHECK: [[TMPPTR:%.*]] = extractvalue %0 [[TMP]], 0
+  // CHECK: [[TMPADJ:%.*]] = extractvalue %0 [[TMP]], 1
+  // CHECK: [[RES0:%.*]] = insertvalue %0 undef, i64 [[TMPPTR]], 0
+  // CHECK: [[ADJ:%.*]] = add i64 [[TMPADJ]], 16
+  // CHECK: [[RES1:%.*]] = insertvalue %0 [[RES0]], i64 [[ADJ]], 1
+  // CHECK: store %0 [[RES1]], %0* @pc, align 8
   pc = pa;
 
-  // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0)
-  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 16
-  // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pa, i32 0, i32 1)
+  // CHECK: [[TMP:%.*]] = load %0* @pc, align 8
+  // CHECK: [[TMPPTR:%.*]] = extractvalue %0 [[TMP]], 0
+  // CHECK: [[TMPADJ:%.*]] = extractvalue %0 [[TMP]], 1
+  // CHECK: [[RES0:%.*]] = insertvalue %0 undef, i64 [[TMPPTR]], 0
+  // CHECK: [[ADJ:%.*]] = sub i64 [[TMPADJ]], 16
+  // CHECK: [[RES1:%.*]] = insertvalue %0 [[RES0]], i64 [[ADJ]], 1
+  // CHECK: store %0 [[RES1]], %0* @pa, align 8
   pa = static_cast<void (A::*)()>(pc);
 }
 
 void f2() {
-  // CHECK: [[pa2ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 0 
-  // CHECK: store i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64* [[pa2ptr]]
-  // CHECK: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1
-  // CHECK: store i64 0, i64* [[pa2adj]]
+  // CHECK:      store %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }
   void (A::*pa2)() = &A::f;
   
-  // CHECK:      [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 
-  // CHECK:      store i64 1, i64* [[pa3ptr]]
-  // CHECK:      [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1
-  // CHECK:      store i64 0, i64* [[pa3adj]]
-  // CHECK-LP32: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 
-  // CHECK-LP32: store i32 1, i32* [[pa3ptr]]
-  // CHECK-LP32: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1
-  // CHECK-LP32: store i32 0, i32* [[pa3adj]]
+  // CHECK:      store %0 { i64 1, i64 0 }
+  // CHECK-LP32: store %0 { i32 1, i32 0 }
   void (A::*pa3)() = &A::vf1;
   
-  // CHECK:      [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0 
-  // CHECK:      store i64 9, i64* [[pa4ptr]]
-  // CHECK:      [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1
-  // CHECK:      store i64 0, i64* [[pa4adj]]
-  // CHECK-LP32: [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0 
-  // CHECK-LP32: store i32 5, i32* [[pa4ptr]]
-  // CHECK-LP32: [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1
-  // CHECK-LP32: store i32 0, i32* [[pa4adj]]
+  // CHECK:      store %0 { i64 9, i64 0 }
+  // CHECK-LP32: store %0 { i32 5, i32 0 }
   void (A::*pa4)() = &A::vf2;
 }
 
diff --git a/test/CodeGenCXX/x86_32-arguments.cpp b/test/CodeGenCXX/x86_32-arguments.cpp
index 023b729..e94e2ca 100644
--- a/test/CodeGenCXX/x86_32-arguments.cpp
+++ b/test/CodeGenCXX/x86_32-arguments.cpp
@@ -89,7 +89,7 @@
 s5 f5() { return s5(); }
 
 // CHECK: define i32 @_Z4f6_0M2s6i(i32 %a)
-// CHECK: define i64 @_Z4f6_1M2s6FivE(%{{.*}} byval %a)
+// CHECK: define i64 @_Z4f6_1M2s6FivE(%{{.*}} byval)
 // FIXME: It would be nice to avoid byval on the previous case.
 struct s6 {};
 typedef int s6::* s6_mdp;