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:
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:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits