r220398 - MS ABI: Emit more canonical vbptr stores and loads

Reid Kleckner reid at kleckner.net
Wed Oct 22 10:26:00 PDT 2014


Author: rnk
Date: Wed Oct 22 12:26:00 2014
New Revision: 220398

URL: http://llvm.org/viewvc/llvm-project?rev=220398&view=rev
Log:
MS ABI: Emit more canonical vbptr stores and loads

This eliminates some i8* GEPs and makes the IR that clang emits a bit
more canonical. More work is needed for vftables, but that isn't a clear
win so I plan to send it for review.

Modified:
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-typeid.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
    cfe/trunk/test/CodeGenCXX/virtual-base-cast.cpp

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=220398&r1=220397&r2=220398&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Oct 22 12:26:00 2014
@@ -457,6 +457,7 @@ private:
                                        int32_t VBPtrOffset,
                                        int32_t VBTableOffset,
                                        llvm::Value **VBPtr = nullptr) {
+    assert(VBTableOffset % 4 == 0 && "should be byte offset into table of i32s");
     llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
                 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
     return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
@@ -917,9 +918,10 @@ void MicrosoftCXXABI::EmitVBPtrStores(Co
       Offs += Layout.getVBaseClassOffset(VBT->getVBaseWithVPtr());
     llvm::Value *VBPtr =
         CGF.Builder.CreateConstInBoundsGEP1_64(ThisInt8Ptr, Offs.getQuantity());
-    VBPtr = CGF.Builder.CreateBitCast(VBPtr, GV->getType()->getPointerTo(0),
+    llvm::Value *GVPtr = CGF.Builder.CreateConstInBoundsGEP2_32(GV, 0, 0);
+    VBPtr = CGF.Builder.CreateBitCast(VBPtr, GVPtr->getType()->getPointerTo(0),
                                       "vbptr." + VBT->ReusingBase->getName());
-    CGF.Builder.CreateStore(GV, VBPtr);
+    CGF.Builder.CreateStore(GVPtr, VBPtr);
   }
 }
 
@@ -2237,11 +2239,17 @@ MicrosoftCXXABI::GetVBaseOffsetFromVBPtr
   llvm::Value *VBPtr =
     Builder.CreateInBoundsGEP(This, VBPtrOffset, "vbptr");
   if (VBPtrOut) *VBPtrOut = VBPtr;
-  VBPtr = Builder.CreateBitCast(VBPtr, CGM.Int8PtrTy->getPointerTo(0));
+  VBPtr = Builder.CreateBitCast(VBPtr,
+                                CGM.Int32Ty->getPointerTo(0)->getPointerTo(0));
   llvm::Value *VBTable = Builder.CreateLoad(VBPtr, "vbtable");
 
+  // Translate from byte offset to table index. It improves analyzability.
+  llvm::Value *VBTableIndex = Builder.CreateAShr(
+      VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
+      "vbtindex", /*isExact=*/true);
+
   // Load an i32 offset from the vb-table.
-  llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableOffset);
+  llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex);
   VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0));
   return Builder.CreateLoad(VBaseOffs, "vbase_offs");
 }

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp?rev=220398&r1=220397&r2=220398&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp Wed Oct 22 12:26:00 2014
@@ -20,11 +20,10 @@ T* test1(V* x) { return &dynamic_cast<T&
 T* test2(A* x) { return &dynamic_cast<T&>(*x); }
 // CHECK-LABEL: define %struct.T* @"\01?test2@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
 // CHECK:        [[CAST:%.*]] = bitcast %struct.A* %x to i8*
-// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast %struct.A* %x to i8**
-// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
-// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
-// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
-// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST]], align 4
+// CHECK-NEXT:   [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A* %x, i32 0, i32 0
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4
 // CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[VBOFFS]]
 // CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1)
 // CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
@@ -34,11 +33,10 @@ T* test3(B* x) { return &dynamic_cast<T&
 // CHECK-LABEL: define %struct.T* @"\01?test3@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
 // CHECK:        [[VOIDP:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0
 // CHECK-NEXT:   [[VBPTR:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 4
-// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast i8* [[VBPTR:%.*]] to i8**
-// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
-// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
-// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
-// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST]], align 4
+// CHECK-NEXT:   [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR:%.*]] to i32**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4
 // CHECK-NEXT:   [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
 // CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[DELTA]]
 // CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1)
@@ -57,11 +55,10 @@ T* test5(A* x) { return dynamic_cast<T*>
 // CHECK:        [[CHECK:%.*]] = icmp eq %struct.A* %x, null
 // CHECK-NEXT:   br i1 [[CHECK]]
 // CHECK:        [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
-// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast %struct.A* %x to i8**
-// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
-// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
-// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
-// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A* %x, i32 0, i32 0
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4
 // CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[VBOFFS]]
 // CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
 // CHECK-NEXT:   [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
@@ -75,11 +72,10 @@ T* test6(B* x) { return dynamic_cast<T*>
 // CHECK-NEXT:   br i1 [[CHECK]]
 // CHECK:        [[CAST:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0
 // CHECK-NEXT:   [[VBPTR:%.*]] = getelementptr inbounds i8* [[CAST]], i32 4
-// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast i8* [[VBPTR]] to i8**
-// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
-// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
-// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
-// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4
 // CHECK-NEXT:   [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
 // CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[DELTA]]
 // CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
@@ -99,11 +95,10 @@ void* test8(A* x) { return dynamic_cast<
 // CHECK:        [[CHECK:%.*]] = icmp eq %struct.A* %x, null
 // CHECK-NEXT:   br i1 [[CHECK]]
 // CHECK:        [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
-// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast %struct.A* %x to i8**
-// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
-// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
-// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
-// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A* %x, i32 0, i32 0
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4
 // CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[VBOFFS]]
 // CHECK-NEXT:   [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
 // CHECK-NEXT:   br label
@@ -116,11 +111,10 @@ void* test9(B* x) { return dynamic_cast<
 // CHECK-NEXT:   br i1 [[CHECK]]
 // CHECK:        [[CAST:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0
 // CHECK-NEXT:   [[VBPTR:%.*]] = getelementptr inbounds i8* [[CAST]], i32 4
-// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast i8* [[VBPTR]] to i8**
-// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
-// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
-// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
-// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4
 // CHECK-NEXT:   [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
 // CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[DELTA]]
 // CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp?rev=220398&r1=220397&r2=220398&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp Wed Oct 22 12:26:00 2014
@@ -275,11 +275,11 @@ int loadDataMemberPointerVirtual(Virtual
 // CHECK:   %[[memptr1:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 1
 // CHECK:   %[[v6:.*]] = bitcast %{{.*}}* %[[o]] to i8*
 // CHECK:   %[[vbptr:.*]] = getelementptr inbounds i8* %[[v6]], i32 0
-// CHECK:   %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8**
-// CHECK:   %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]]
-// CHECK:   %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr1]]
-// CHECK:   %[[v8:.*]] = bitcast i8* %[[v7]] to i32*
-// CHECK:   %[[vbase_offs:.*]] = load i32* %[[v8]]
+// CHECK:   %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32**
+// CHECK:   %[[vbtable:.*]] = load i32** %[[vbptr_a:.*]]
+// CHECK:   %[[memptr1_shr:.*]] = ashr exact i32 %[[memptr1]], 2
+// CHECK:   %[[v7:.*]] = getelementptr inbounds i32* %[[vbtable]], i32 %[[memptr1_shr]]
+// CHECK:   %[[vbase_offs:.*]] = load i32* %[[v7]]
 // CHECK:   %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]]
 // CHECK:   %[[offset:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr0]]
 // CHECK:   %[[v11:.*]] = bitcast i8* %[[offset]] to i32*
@@ -309,11 +309,11 @@ int loadDataMemberPointerUnspecified(Uns
 //
 // CHECK: [[vadjust]]
 // CHECK:   %[[vbptr:.*]] = getelementptr inbounds i8* %[[base]], i32 %[[memptr1]]
-// CHECK:   %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8**
-// CHECK:   %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]]
-// CHECK:   %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr2]]
-// CHECK:   %[[v8:.*]] = bitcast i8* %[[v7]] to i32*
-// CHECK:   %[[vbase_offs:.*]] = load i32* %[[v8]]
+// CHECK:   %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32**
+// CHECK:   %[[vbtable:.*]] = load i32** %[[vbptr_a:.*]]
+// CHECK:   %[[memptr2_shr:.*]] = ashr exact i32 %[[memptr2]], 2
+// CHECK:   %[[v7:.*]] = getelementptr inbounds i32* %[[vbtable]], i32 %[[memptr2_shr]]
+// CHECK:   %[[vbase_offs:.*]] = load i32* %[[v7]]
 // CHECK:   %[[base_adj:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]]
 //
 // CHECK: [[skip]]
@@ -360,11 +360,11 @@ void callMemberPointerVirtualBase(Virtua
 // CHECK:   %[[memptr1:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 1
 // CHECK:   %[[memptr2:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 2
 // CHECK:   %[[vbptr:.*]] = getelementptr inbounds i8* %{{.*}}, i32 0
-// CHECK:   %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i8**
-// CHECK:   %[[vbtable:.*]] = load i8** %[[vbptr_a:.*]]
-// CHECK:   %[[v7:.*]] = getelementptr inbounds i8* %[[vbtable]], i32 %[[memptr2]]
-// CHECK:   %[[v8:.*]] = bitcast i8* %[[v7]] to i32*
-// CHECK:   %[[vbase_offs:.*]] = load i32* %[[v8]]
+// CHECK:   %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32**
+// CHECK:   %[[vbtable:.*]] = load i32** %[[vbptr_a:.*]]
+// CHECK:   %[[memptr2_shr:.*]] = ashr exact i32 %[[memptr2]], 2
+// CHECK:   %[[v7:.*]] = getelementptr inbounds i32* %[[vbtable]], i32 %[[memptr2_shr]]
+// CHECK:   %[[vbase_offs:.*]] = load i32* %[[v7]]
 // CHECK:   %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]]
 // CHECK:   %[[this_adjusted:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr1]]
 // CHECK:   %[[fptr:.*]] = bitcast i8* %[[memptr0]] to void ({{.*}})

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp?rev=220398&r1=220397&r2=220398&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp Wed Oct 22 12:26:00 2014
@@ -229,8 +229,8 @@ C::C() {
   // CHECK: [[INIT_VBASES]]
   // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::C"* %{{.*}} to i8*
   // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8* %[[this_i8]], i64 0
-  // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to [2 x i32]**
-  // CHECK-NEXT: store [2 x i32]* @"\01??_8C at constructors@@7B@", [2 x i32]** %[[vbptr]]
+  // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+  // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32]* @"\01??_8C at constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]]
   // CHECK-NEXT: bitcast %"struct.constructors::C"* %{{.*}} to i8*
   // CHECK-NEXT: getelementptr inbounds i8* %{{.*}}, i64 4
   // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"*
@@ -264,8 +264,8 @@ D::D() {
   // CHECK: [[INIT_VBASES]]
   // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::D"* %{{.*}} to i8*
   // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8* %[[this_i8]], i64 0
-  // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to [2 x i32]**
-  // CHECK-NEXT: store [2 x i32]* @"\01??_8D at constructors@@7B@", [2 x i32]** %[[vbptr]]
+  // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+  // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32]* @"\01??_8D at constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]]
   // CHECK-NEXT: bitcast %"struct.constructors::D"* %{{.*}} to i8*
   // CHECK-NEXT: getelementptr inbounds i8* %{{.*}}, i64 4
   // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"*
@@ -291,11 +291,11 @@ E::E() {
   // CHECK: [[INIT_VBASES]]
   // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::E"* %{{.*}} to i8*
   // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8* %[[this_i8]], i64 0
-  // CHECK-NEXT: %[[vbptr_E:.*]] = bitcast i8* %[[offs]] to [3 x i32]**
-  // CHECK-NEXT: store [3 x i32]* @"\01??_8E at constructors@@7B01@@", [3 x i32]** %[[vbptr_E]]
+  // CHECK-NEXT: %[[vbptr_E:.*]] = bitcast i8* %[[offs]] to i32**
+  // CHECK-NEXT: store i32* getelementptr inbounds ([3 x i32]* @"\01??_8E at constructors@@7B01@@", i32 0, i32 0), i32** %[[vbptr_E]]
   // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8* %[[this_i8]], i64 4
-  // CHECK-NEXT: %[[vbptr_C:.*]] = bitcast i8* %[[offs]] to [2 x i32]**
-  // CHECK-NEXT: store [2 x i32]* @"\01??_8E at constructors@@7BC at 1@@", [2 x i32]** %[[vbptr_C]]
+  // CHECK-NEXT: %[[vbptr_C:.*]] = bitcast i8* %[[offs]] to i32**
+  // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32]* @"\01??_8E at constructors@@7BC at 1@@", i32 0, i32 0), i32** %[[vbptr_C]]
   // CHECK-NEXT: bitcast %"struct.constructors::E"* %{{.*}} to i8*
   // CHECK-NEXT: getelementptr inbounds i8* %{{.*}}, i64 4
   // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"*

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp?rev=220398&r1=220397&r2=220398&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-thunks.cpp Wed Oct 22 12:26:00 2014
@@ -128,10 +128,9 @@ I::I() {}  // Emits vftable and forces t
 // CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc %struct.F* @"\01?goo at I@@UAEPAUF@@XZ"
 // CODEGEN: %[[ORIG_RET_i8:.*]] = bitcast %struct.F* %[[ORIG_RET]] to i8*
 // CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8* %[[ORIG_RET_i8]], i32 4
-// CODEGEN: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i8**
-// CODEGEN: %[[VBTABLE:.*]] = load i8** %[[VBPTR]]
-// CODEGEN: %[[VBASE_OFFSET_PTR_i8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 8
-// CODEGEN: %[[VBASE_OFFSET_PTR:.*]] = bitcast i8* %[[VBASE_OFFSET_PTR_i8]] to i32*
+// CODEGEN: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i32**
+// CODEGEN: %[[VBTABLE:.*]] = load i32** %[[VBPTR]]
+// CODEGEN: %[[VBASE_OFFSET_PTR:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 2
 // CODEGEN: %[[VBASE_OFFSET:.*]] = load i32* %[[VBASE_OFFSET_PTR]]
 // CODEGEN: %[[RES_i8:.*]] = getelementptr inbounds i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
 // CODEGEN: %[[RES:.*]] = bitcast i8* %[[RES_i8]] to %struct.F*

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-typeid.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-typeid.cpp?rev=220398&r1=220397&r2=220398&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-typeid.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-typeid.cpp Wed Oct 22 12:26:00 2014
@@ -31,11 +31,10 @@ const std::type_info* test3_typeid() { r
 // CHECK:        tail call i8* @__RTtypeid(i8* null)
 // CHECK-NEXT:   unreachable
 // CHECK:        [[THIS:%.*]] = bitcast %struct.A* [[CALL]] to i8*
-// CHECK-NEXT:   [[VBTBLP:%.*]] = bitcast %struct.A* [[CALL]] to i8**
-// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[VBTBLP]], align 4
-// CHECK-NEXT:   [[VBSLOT:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
-// CHECK-NEXT:   [[VBITCST:%.*]] = bitcast i8* [[VBSLOT]] to i32*
-// CHECK-NEXT:   [[VBASE_OFFS:%.*]] = load i32* [[VBITCST]], align 4
+// CHECK-NEXT:   [[VBTBLP:%.*]] = getelementptr inbounds %struct.A* [[CALL]], i32 0, i32 0
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i32** [[VBTBLP]], align 4
+// CHECK-NEXT:   [[VBSLOT:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1
+// CHECK-NEXT:   [[VBASE_OFFS:%.*]] = load i32* [[VBSLOT]], align 4
 // CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[THIS]], i32 [[VBASE_OFFS]]
 // CHECK-NEXT:   [[RT:%.*]] = tail call i8* @__RTtypeid(i8* [[ADJ]])
 // CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp?rev=220398&r1=220397&r2=220398&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp Wed Oct 22 12:26:00 2014
@@ -72,10 +72,9 @@ G::G() {}  // Forces vftable emission.
 // CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
 // CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
 // CHECK: %[[VBPTR_i8:.*]] = getelementptr inbounds i8* %[[VTORDISP_ADJUSTED_i8]], i32 -16
-// CHECK: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i8**
-// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR]]
-// CHECK: %[[VBOFFSET_PTR_i8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 12
-// CHECK: %[[VBOFFSET_PTR:.*]] = bitcast i8* %[[VBOFFSET_PTR_i8]] to i32*
+// CHECK: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR]]
+// CHECK: %[[VBOFFSET_PTR:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 3
 // CHECK: %[[VBASE_OFFSET:.*]] = load i32* %[[VBOFFSET_PTR]]
 // CHECK: %[[VBASE:.*]] = getelementptr inbounds i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
 // CHECK: %[[ARG_i8:.*]] = getelementptr i8* %[[VBASE]], i32 8

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp?rev=220398&r1=220397&r2=220398&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp Wed Oct 22 12:26:00 2014
@@ -122,10 +122,9 @@ void B::foo() {
 // CHECK: %[[THIS:.*]] = load %struct.B** %[[THIS_ADDR]]
 // CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
 // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8**
-// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]]
-// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4
-// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32*
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1
 // CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]]
 // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
 // CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8*
@@ -147,10 +146,9 @@ void call_vbase_bar(B *obj) {
 //
 // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
 // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8**
-// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]]
-// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4
-// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32*
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1
 // CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]]
 // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
 // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
@@ -161,10 +159,9 @@ void call_vbase_bar(B *obj) {
 //
 // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
 // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8**
-// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]]
-// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4
-// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32*
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1
 // CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]]
 // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
 // CHECK: %[[VBASE:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
@@ -181,10 +178,9 @@ void delete_B(B *obj) {
   delete obj;
 // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
 // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8**
-// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]]
-// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4
-// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32*
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1
 // CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]]
 // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
 // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]
@@ -195,10 +191,9 @@ void delete_B(B *obj) {
 //
 // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8*
 // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0
-// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i8**
-// CHECK: %[[VBTABLE:.*]] = load i8** %[[VBPTR8]]
-// CHECK: %[[VBENTRY8:.*]] = getelementptr inbounds i8* %[[VBTABLE]], i32 4
-// CHECK: %[[VBENTRY:.*]] = bitcast i8* %[[VBENTRY8]] to i32*
+// CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32**
+// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]]
+// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1
 // CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]]
 // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]]
 // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]]

Modified: cfe/trunk/test/CodeGenCXX/virtual-base-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virtual-base-cast.cpp?rev=220398&r1=220397&r2=220398&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/virtual-base-cast.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/virtual-base-cast.cpp Wed Oct 22 12:26:00 2014
@@ -20,11 +20,10 @@ A* a() { return x; }
 
 // MSVC: @"\01?a@@YAPAUA@@XZ"() [[NUW:#[0-9]+]] {
 // MSVC:   %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 0
-// MSVC:   %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i8**
-// MSVC:   %[[vbtable:.*]] = load i8** %[[vbptr]]
-// MSVC:   %[[entry:.*]] = getelementptr inbounds i8* {{.*}}, i32 4
-// MSVC:   %[[entry_i32:.*]] = bitcast i8* %[[entry]] to i32*
-// MSVC:   %[[offset:.*]] = load i32* %[[entry_i32]]
+// MSVC:   %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+// MSVC:   %[[vbtable:.*]] = load i32** %[[vbptr]]
+// MSVC:   %[[entry:.*]] = getelementptr inbounds i32* {{.*}}, i32 1
+// MSVC:   %[[offset:.*]] = load i32* %[[entry]]
 // MSVC:   add nsw i32 0, %[[offset]]
 // MSVC: }
 
@@ -38,11 +37,10 @@ B* b() { return x; }
 // Same as 'a' except we use a different vbtable offset.
 // MSVC: @"\01?b@@YAPAUB@@XZ"() [[NUW:#[0-9]+]] {
 // MSVC:   %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 0
-// MSVC:   %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i8**
-// MSVC:   %[[vbtable:.*]] = load i8** %[[vbptr]]
-// MSVC:   %[[entry:.*]] = getelementptr inbounds i8* {{.*}}, i32 8
-// MSVC:   %[[entry_i32:.*]] = bitcast i8* %[[entry]] to i32*
-// MSVC:   %[[offset:.*]] = load i32* %[[entry_i32]]
+// MSVC:   %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+// MSVC:   %[[vbtable:.*]] = load i32** %[[vbptr]]
+// MSVC:   %[[entry:.*]] = getelementptr inbounds i32* {{.*}}, i32 2
+// MSVC:   %[[offset:.*]] = load i32* %[[entry]]
 // MSVC:   add nsw i32 0, %[[offset]]
 // MSVC: }
 
@@ -58,11 +56,10 @@ BB* c() { return x; }
 // Same as 'a' except we use a different vbtable offset.
 // MSVC: @"\01?c@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] {
 // MSVC:   %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 0
-// MSVC:   %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i8**
-// MSVC:   %[[vbtable:.*]] = load i8** %[[vbptr]]
-// MSVC:   %[[entry:.*]] = getelementptr inbounds i8* {{.*}}, i32 16
-// MSVC:   %[[entry_i32:.*]] = bitcast i8* %[[entry]] to i32*
-// MSVC:   %[[offset:.*]] = load i32* %[[entry_i32]]
+// MSVC:   %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+// MSVC:   %[[vbtable:.*]] = load i32** %[[vbptr]]
+// MSVC:   %[[entry:.*]] = getelementptr inbounds i32* {{.*}}, i32 4
+// MSVC:   %[[offset:.*]] = load i32* %[[entry]]
 // MSVC:   add nsw i32 0, %[[offset]]
 // MSVC: }
 
@@ -78,11 +75,10 @@ BB* d() { return y; }
 // final add.
 // MSVC: @"\01?d@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] {
 // MSVC:   %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 4
-// MSVC:   %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i8**
-// MSVC:   %[[vbtable:.*]] = load i8** %[[vbptr]]
-// MSVC:   %[[entry:.*]] = getelementptr inbounds i8* {{.*}}, i32 16
-// MSVC:   %[[entry_i32:.*]] = bitcast i8* %[[entry]] to i32*
-// MSVC:   %[[offset:.*]] = load i32* %[[entry_i32]]
+// MSVC:   %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32**
+// MSVC:   %[[vbtable:.*]] = load i32** %[[vbptr]]
+// MSVC:   %[[entry:.*]] = getelementptr inbounds i32* {{.*}}, i32 4
+// MSVC:   %[[offset:.*]] = load i32* %[[entry]]
 // MSVC:   add nsw i32 4, %[[offset]]
 // MSVC: }
 





More information about the cfe-commits mailing list