From: Saleem Abdulrasool Date: Wed, 25 Oct 2017 17:56:50 +0000 (+0000) Subject: CodeGen: fix PPC Darwin variadics X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5da49565c168f50d865783a0b7f6e6881ecbee34;p=clang CodeGen: fix PPC Darwin variadics Darwin uses char * for the variadic list type (va_list). We use the PPC SVR4 ABI for PPC, which uses a structure type for the va_list. When constructing the GEP, we would fail due to the incorrect handling for the va_list. Correct this to use the right type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316599 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 2651d87389..b1773b7090 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -4036,7 +4036,10 @@ Address WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, namespace { /// PPC32_SVR4_ABIInfo - The 32-bit PowerPC ELF (SVR4) ABI information. class PPC32_SVR4_ABIInfo : public DefaultABIInfo { -bool IsSoftFloatABI; + bool IsSoftFloatABI; + + CharUnits getParamTypeAlignment(QualType Ty) const; + public: PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, bool SoftFloatABI) : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI) {} @@ -4058,13 +4061,46 @@ public: bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const override; }; +} + +CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { + // Complex types are passed just like their elements + if (const ComplexType *CTy = Ty->getAs()) + Ty = CTy->getElementType(); + + if (Ty->isVectorType()) + return CharUnits::fromQuantity(getContext().getTypeSize(Ty) == 128 ? 16 + : 4); + // For single-element float/vector structs, we consider the whole type + // to have the same alignment requirements as its single element. + const Type *AlignTy = nullptr; + if (const Type *EltType = isSingleElementStruct(Ty, getContext())) { + const BuiltinType *BT = EltType->getAs(); + if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) || + (BT && BT->isFloatingPoint())) + AlignTy = EltType; + } + + if (AlignTy) + return CharUnits::fromQuantity(AlignTy->isVectorType() ? 16 : 4); + return CharUnits::fromQuantity(4); } // TODO: this implementation is now likely redundant with // DefaultABIInfo::EmitVAArg. Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, QualType Ty) const { + if (getTarget().getTriple().isOSDarwin()) { + auto TI = getContext().getTypeInfoInChars(Ty); + TI.second = getParamTypeAlignment(Ty); + + CharUnits SlotSize = CharUnits::fromQuantity(4); + return emitVoidPtrVAArg(CGF, VAList, Ty, + classifyArgumentType(Ty).isIndirect(), TI, SlotSize, + /*AllowHigherAlign=*/true); + } + const unsigned OverflowLimit = 8; if (const ComplexType *CTy = Ty->getAs()) { // TODO: Implement this. For now ignore. diff --git a/test/CodeGen/darwin-ppc-varargs.c b/test/CodeGen/darwin-ppc-varargs.c new file mode 100644 index 0000000000..c2a0d19223 --- /dev/null +++ b/test/CodeGen/darwin-ppc-varargs.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple powerpc-apple-macosx10.5.0 -target-feature +altivec -Os -emit-llvm -o - %s | FileCheck %s + +int f(__builtin_va_list args) { return __builtin_va_arg(args, int); } + +// CHECK: @f(i8* {{.*}}[[PARAM:%[a-zA-Z0-9]+]]) +// CHECK: [[BITCAST:%[0-9]+]] = bitcast i8* [[PARAM]] to i32* +// CHECK: [[VALUE:%[0-9]+]] = load i32, i32* [[BITCAST]], align 4 +// CHECK: ret i32 [[VALUE]] + +void h(vector int); +int g(__builtin_va_list args) { + int i = __builtin_va_arg(args, int); + h(__builtin_va_arg(args, vector int)); + int j = __builtin_va_arg(args, int); + return i + j; +} + +// CHECK: @g(i8* {{.*}}[[PARAM:%[a-zA-Z0-9]+]]) +// CHECK: [[NEXT:%[-_.a-zA-Z0-9]+]] = getelementptr inbounds i8, i8* [[PARAM]], i32 4 +// CHECK: [[BITCAST:%[0-9]+]] = bitcast i8* [[PARAM]] to i32* +// CHECK: [[LOAD:%[0-9]+]] = load i32, i32* [[BITCAST]], align 4 +// CHECK: [[PTRTOINT:%[0-9]+]] = ptrtoint i8* [[NEXT]] to i32 +// CHECK: [[ADD:%[0-9]+]] = add i32 [[PTRTOINT]], 15 +// CHECK: [[AND:%[0-9]+]] = and i32 [[ADD]], -16 +// CHECK: [[INTTOPTR:%[0-9]+]] = inttoptr i32 [[AND]] to <4 x i32>* +// CHECK: [[ARG:%[0-9]]] = load <4 x i32>, <4 x i32>* [[INTTOPTR]], align 16 +// CHECK: call void @h(<4 x i32> [[ARG]] +