r316599 - CodeGen: fix PPC Darwin variadics

Saleem Abdulrasool via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 25 10:56:50 PDT 2017


Author: compnerd
Date: Wed Oct 25 10:56:50 2017
New Revision: 316599

URL: http://llvm.org/viewvc/llvm-project?rev=316599&view=rev
Log:
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.

Added:
    cfe/trunk/test/CodeGen/darwin-ppc-varargs.c
Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=316599&r1=316598&r2=316599&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Oct 25 10:56:50 2017
@@ -4036,7 +4036,10 @@ Address WinX86_64ABIInfo::EmitVAArg(Code
 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<ComplexType>())
+    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<BuiltinType>();
+    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<ComplexType>()) {
     // TODO: Implement this. For now ignore.

Added: cfe/trunk/test/CodeGen/darwin-ppc-varargs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/darwin-ppc-varargs.c?rev=316599&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/darwin-ppc-varargs.c (added)
+++ cfe/trunk/test/CodeGen/darwin-ppc-varargs.c Wed Oct 25 10:56:50 2017
@@ -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]]
+




More information about the cfe-commits mailing list