[PATCH] D20449: [Basic] Change x86_64-windows-macho targets to use Windows-style va_lists.

Charles Davis via cfe-commits cfe-commits at lists.llvm.org
Thu May 19 13:52:20 PDT 2016


cdavis5x created this revision.
cdavis5x added a reviewer: rsmith.
cdavis5x added a subscriber: cfe-commits.

This is a very strange target. Sema thinks it's targeting a Darwin-esque
system, while IRGen thinks it's targeting a Windows'ish system. The result
is that Clang can no longer compile `__builtin_va_arg` (either for a normal
or Win64 `va_list`) properly. So, for this target, explicitly set the
`va_list` kind to `CharPtr`, the same as Win64. This is what users expect,
anyway.

Fixes PR27663.

http://reviews.llvm.org/D20449

Files:
  lib/Basic/Targets.cpp
  test/CodeGen/windows-macho.c

Index: test/CodeGen/windows-macho.c
===================================================================
--- /dev/null
+++ test/CodeGen/windows-macho.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-windows-macho -emit-llvm -Os %s -o - \
+// RUN:    | FileCheck %s
+
+// Test that, when we compile a function that uses varargs on a
+// Windows-with-Mach-O triple, we can actually compile it, and it actually
+// conforms to the Win64 ABI.
+
+// PR27663
+
+// CHECK-LABEL: i32 @va_sum
+int va_sum(unsigned int count, ...) {
+  int sum = 0;
+  __builtin_ms_va_list ap;
+
+  __builtin_ms_va_start(ap, count);
+  // CHECK: %[[AP:.*]] = alloca i8*
+  // CHECK: call void @llvm.va_start
+  while (count) {
+    sum += __builtin_va_arg(ap, int);
+    // CHECK: %[[AP_CUR_PRE:.*]] = load i8*, i8** %[[AP]]
+    // CHECK: %[[AP_CUR:.*]] = phi i8* [ %[[AP_NEXT:.*]], {{.*}} ], [ %[[AP_CUR_PRE]], {{.*}} ]
+    // CHECK: %[[AP_NEXT]] = getelementptr inbounds i8, i8* %[[AP_CUR]], i64 8
+    // CHECK-NEXT: store i8* %[[AP_NEXT]], i8** %[[AP]]
+    // CHECK-NEXT: bitcast i8* %[[AP_CUR]] to i32*
+    --count;
+  }
+  __builtin_ms_va_end(ap);
+  return sum;
+}
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -4444,6 +4444,39 @@
   }
 };
 
+class EFIMachOX86_64TargetInfo : public DarwinX86_64TargetInfo {
+public:
+  EFIMachOX86_64TargetInfo(const llvm::Triple &Triple,
+                           const TargetOptions &Opts)
+      : DarwinX86_64TargetInfo(Triple, Opts) {}
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
+    DarwinX86_64TargetInfo::getTargetDefines(Opts, Builder);
+    addCygMingDefines(Opts, Builder);
+  }
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::CharPtrBuiltinVaList;
+  }
+
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+    switch (CC) {
+    case CC_X86StdCall:
+    case CC_X86ThisCall:
+    case CC_X86FastCall:
+      return CCCR_Ignore;
+    case CC_C:
+    case CC_X86VectorCall:
+    case CC_IntelOclBicc:
+    case CC_X86_64SysV:
+      return CCCR_OK;
+    default:
+      return CCCR_Warning;
+    }
+  }
+};
+
 class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
 public:
   OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
@@ -8362,8 +8395,11 @@
     }
 
   case llvm::Triple::x86_64:
-    if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO())
+    if (Triple.isOSDarwin() ||
+        (!Triple.isOSWindows() && Triple.isOSBinFormatMachO()))
       return new DarwinX86_64TargetInfo(Triple, Opts);
+    if (Triple.isOSWindows() && Triple.isOSBinFormatMachO())
+      return new EFIMachOX86_64TargetInfo(Triple, Opts);
 
     switch (os) {
     case llvm::Triple::CloudABI:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20449.57855.patch
Type: text/x-patch
Size: 2914 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160519/76ba4c3a/attachment.bin>


More information about the cfe-commits mailing list