spetrovic updated the summary for this revision.
spetrovic updated this revision to Diff 41142.
spetrovic marked 4 inline comments as done.
http://reviews.llvm.org/D14871
Files:
lib/CodeGen/TargetInfo.cpp
test/CodeGen/ppc-varargs-struct.c
Index: test/CodeGen/ppc-varargs-struct.c
===================================================================
--- test/CodeGen/ppc-varargs-struct.c
+++ test/CodeGen/ppc-varargs-struct.c
@@ -39,9 +39,13 @@
// CHECK-PPC:[[USING_OVERFLOW]]
// CHECK-PPC-NEXT: [[OVERFLOW_AREA_P:%[0-9]+]] = getelementptr inbounds
%struct.__va_list_tag, %struct.__va_list_tag* [[ARRAYDECAY]], i32 0, i32 3
// CHECK-PPC-NEXT: [[OVERFLOW_AREA:%.+]] = load i8*, i8**
[[OVERFLOW_AREA_P]], align 4
-// CHECK-PPC-NEXT: [[MEMADDR:%.+]] = bitcast i8* [[OVERFLOW_AREA]] to
%struct.x**
-// CHECK-PPC-NEXT: [[NEW_OVERFLOW_AREA:%[0-9]+]] = getelementptr inbounds i8,
i8* [[OVERFLOW_AREA]], i32 4
-// CHECK-PPC-NEXT: store i8* [[NEW_OVERFLOW_AREA]], i8** [[OVERFLOW_AREA_P]]
+// CHECK-PPC-NEXT: %{{[0-9]+}} = ptrtoint i8* %{{[0-9]+}} to i32
+// CHECK-PPC-NEXT: %{{[0-9]+}} = add i32 %{{[0-9]+}}, 7
+// CHECK-PPC-NEXT: %{{[0-9]+}} = and i32 %{{[0-9]+}}, -8
+// CHECK-PPC-NEXT: %overflow_arg_area.align = inttoptr i32 %{{[0-9]+}} to i8*
+// CHECK-PPC-NEXT: [[MEMADDR:%.+]] = bitcast i8* %overflow_arg_area.align to
%struct.x**
+// CHECK-PPC-NEXT: [[NEW_OVERFLOW_AREA:%[0-9]+]] = getelementptr inbounds i8,
i8* %overflow_arg_area.align, i32 4
+// CHECK-PPC-NEXT: store i8* [[NEW_OVERFLOW_AREA:%[0-9]+]], i8**
[[OVERFLOW_AREA_P]], align 4
// CHECK-PPC-NEXT: br label %[[CONT]]
//
// CHECK-PPC:[[CONT]]
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -223,6 +223,23 @@
return Addr;
}
+static Address emitRoundPointerUpToAlignment(CodeGenFunction &CGF,
+ llvm::Value *OverflowArgArea,
+ CharUnits Align) {
+ llvm::Value *PtrAsInt = OverflowArgArea;
+ // OverflowArgArea = (OverflowArgArea + Align - 1) & -Align;
+ PtrAsInt = CGF.Builder.CreatePtrToInt(PtrAsInt, CGF.IntPtrTy);
+ PtrAsInt = CGF.Builder.CreateAdd(PtrAsInt,
+ llvm::ConstantInt::get(CGF.IntPtrTy, Align.getQuantity() - 1));
+ llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty,
+ -Align.getQuantity());
+ PtrAsInt = CGF.Builder.CreateAnd(PtrAsInt, Mask);
+ PtrAsInt = CGF.Builder.CreateIntToPtr(PtrAsInt,
+ OverflowArgArea->getType(),
+ "overflow_arg_area.align");
+ return Address(PtrAsInt, Align);
+}
+
/// Emit va_arg for a platform using the common void* representation,
/// where arguments are simply emitted in an array of slots on the stack.
///
@@ -3543,9 +3560,14 @@
Builder.CreateStructGEP(VAList, 3, CharUnits::fromQuantity(4));
Address OverflowArea(Builder.CreateLoad(OverflowAreaAddr),
OverflowAreaAlign);
-
- // The current address is the address of the varargs element.
- // FIXME: do we not need to round up to alignment?
+ // Round up address of argument to alignment
+ llvm::Value *OverflowArgArea = OverflowArea.getPointer();
+ CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty);
+ if (Align > OverflowAreaAlign) {
+ OverflowArea = emitRoundPointerUpToAlignment(CGF, OverflowArgArea,
+ Align);
+ }
+
MemAddr = Builder.CreateElementBitCast(OverflowArea, DirectTy);
// Increase the overflow area.
Index: test/CodeGen/ppc-varargs-struct.c
===================================================================
--- test/CodeGen/ppc-varargs-struct.c
+++ test/CodeGen/ppc-varargs-struct.c
@@ -39,9 +39,13 @@
// CHECK-PPC:[[USING_OVERFLOW]]
// CHECK-PPC-NEXT: [[OVERFLOW_AREA_P:%[0-9]+]] = getelementptr inbounds %struct.__va_list_tag, %struct.__va_list_tag* [[ARRAYDECAY]], i32 0, i32 3
// CHECK-PPC-NEXT: [[OVERFLOW_AREA:%.+]] = load i8*, i8** [[OVERFLOW_AREA_P]], align 4
-// CHECK-PPC-NEXT: [[MEMADDR:%.+]] = bitcast i8* [[OVERFLOW_AREA]] to %struct.x**
-// CHECK-PPC-NEXT: [[NEW_OVERFLOW_AREA:%[0-9]+]] = getelementptr inbounds i8, i8* [[OVERFLOW_AREA]], i32 4
-// CHECK-PPC-NEXT: store i8* [[NEW_OVERFLOW_AREA]], i8** [[OVERFLOW_AREA_P]]
+// CHECK-PPC-NEXT: %{{[0-9]+}} = ptrtoint i8* %{{[0-9]+}} to i32
+// CHECK-PPC-NEXT: %{{[0-9]+}} = add i32 %{{[0-9]+}}, 7
+// CHECK-PPC-NEXT: %{{[0-9]+}} = and i32 %{{[0-9]+}}, -8
+// CHECK-PPC-NEXT: %overflow_arg_area.align = inttoptr i32 %{{[0-9]+}} to i8*
+// CHECK-PPC-NEXT: [[MEMADDR:%.+]] = bitcast i8* %overflow_arg_area.align to %struct.x**
+// CHECK-PPC-NEXT: [[NEW_OVERFLOW_AREA:%[0-9]+]] = getelementptr inbounds i8, i8* %overflow_arg_area.align, i32 4
+// CHECK-PPC-NEXT: store i8* [[NEW_OVERFLOW_AREA:%[0-9]+]], i8** [[OVERFLOW_AREA_P]], align 4
// CHECK-PPC-NEXT: br label %[[CONT]]
//
// CHECK-PPC:[[CONT]]
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -223,6 +223,23 @@
return Addr;
}
+static Address emitRoundPointerUpToAlignment(CodeGenFunction &CGF,
+ llvm::Value *OverflowArgArea,
+ CharUnits Align) {
+ llvm::Value *PtrAsInt = OverflowArgArea;
+ // OverflowArgArea = (OverflowArgArea + Align - 1) & -Align;
+ PtrAsInt = CGF.Builder.CreatePtrToInt(PtrAsInt, CGF.IntPtrTy);
+ PtrAsInt = CGF.Builder.CreateAdd(PtrAsInt,
+ llvm::ConstantInt::get(CGF.IntPtrTy, Align.getQuantity() - 1));
+ llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty,
+ -Align.getQuantity());
+ PtrAsInt = CGF.Builder.CreateAnd(PtrAsInt, Mask);
+ PtrAsInt = CGF.Builder.CreateIntToPtr(PtrAsInt,
+ OverflowArgArea->getType(),
+ "overflow_arg_area.align");
+ return Address(PtrAsInt, Align);
+}
+
/// Emit va_arg for a platform using the common void* representation,
/// where arguments are simply emitted in an array of slots on the stack.
///
@@ -3543,9 +3560,14 @@
Builder.CreateStructGEP(VAList, 3, CharUnits::fromQuantity(4));
Address OverflowArea(Builder.CreateLoad(OverflowAreaAddr),
OverflowAreaAlign);
-
- // The current address is the address of the varargs element.
- // FIXME: do we not need to round up to alignment?
+ // Round up address of argument to alignment
+ llvm::Value *OverflowArgArea = OverflowArea.getPointer();
+ CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty);
+ if (Align > OverflowAreaAlign) {
+ OverflowArea = emitRoundPointerUpToAlignment(CGF, OverflowArgArea,
+ Align);
+ }
+
MemAddr = Builder.CreateElementBitCast(OverflowArea, DirectTy);
// Increase the overflow area.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits