Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -3543,9 +3543,23 @@ 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 *overflow_arg_area = OverflowArea.getPointer(); + uint32_t Align = CGF.getContext().getTypeAlignInChars(Ty).getQuantity(); + if (Align > 4) { + // overflow_arg_area = (overflow_arg_area + align - 1) & -align; + llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, Align - 1); + overflow_arg_area = CGF.Builder.CreateGEP(overflow_arg_area, Offset); + llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(overflow_arg_area, + CGF.Int32Ty); + llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -(uint32_t)Align); + overflow_arg_area = + CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask), + overflow_arg_area->getType(), + "overflow_arg_area.align"); + } + + OverflowArea = Address(overflow_arg_area, CharUnits::fromQuantity(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]+}} = getelementptr i8, i8* %{{[0-9]+}}, i32 7 +// CHECK-PPC-NEXT: %{{[0-9]+}} = ptrtoint i8* %{{[0-9]+}} to i32 +// 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]]