r251567 - Fix the calling convention of Mingw64 long double values

Yaron Keren via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 28 22:58:10 PDT 2015


Thanks!


2015-10-29 0:29 GMT+02:00 Reid Kleckner via cfe-commits <
cfe-commits at lists.llvm.org>:

> Author: rnk
> Date: Wed Oct 28 17:29:52 2015
> New Revision: 251567
>
> URL: http://llvm.org/viewvc/llvm-project?rev=251567&view=rev
> Log:
> Fix the calling convention of Mingw64 long double values
>
> GCC uses the x87DoubleExtended model for long doubles, and passes them
> indirectly by address through function calls.
>
> Also replace the existing mingw-long-double assembly emitting test with
> an IR-level test.
>
> Modified:
>     cfe/trunk/lib/Basic/Targets.cpp
>     cfe/trunk/lib/CodeGen/TargetInfo.cpp
>     cfe/trunk/test/CodeGen/mingw-long-double.c
>
> Modified: cfe/trunk/lib/Basic/Targets.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=251567&r1=251566&r2=251567&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Basic/Targets.cpp (original)
> +++ cfe/trunk/lib/Basic/Targets.cpp Wed Oct 28 17:29:52 2015
> @@ -4009,7 +4009,13 @@ public:
>  class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
>  public:
>    MinGWX86_64TargetInfo(const llvm::Triple &Triple)
> -      : WindowsX86_64TargetInfo(Triple) {}
> +      : WindowsX86_64TargetInfo(Triple) {
> +    // Mingw64 rounds long double size and alignment up to 16 bytes, but
> sticks
> +    // with x86 FP ops. Weird.
> +    LongDoubleWidth = LongDoubleAlign = 128;
> +    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
> +  }
> +
>    void getTargetDefines(const LangOptions &Opts,
>                          MacroBuilder &Builder) const override {
>      WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
>
> Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=251567&r1=251566&r2=251567&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
> +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Oct 28 17:29:52 2015
> @@ -1772,12 +1772,10 @@ public:
>
>  /// WinX86_64ABIInfo - The Windows X86_64 ABI information.
>  class WinX86_64ABIInfo : public ABIInfo {
> -
> -  ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs,
> -                      bool IsReturnType) const;
> -
>  public:
> -  WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
> +  WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT)
> +      : ABIInfo(CGT),
> +        IsMingw64(getTarget().getTriple().isWindowsGNUEnvironment()) {}
>
>    void computeInfo(CGFunctionInfo &FI) const override;
>
> @@ -1794,6 +1792,12 @@ public:
>      // FIXME: Assumes vectorcall is in use.
>      return isX86VectorCallAggregateSmallEnough(NumMembers);
>    }
> +
> +private:
> +  ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs,
> +                      bool IsReturnType) const;
> +
> +  bool IsMingw64;
>  };
>
>  class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {
> @@ -3317,7 +3321,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(Qu
>
>    TypeInfo Info = getContext().getTypeInfo(Ty);
>    uint64_t Width = Info.Width;
> -  unsigned Align =
> getContext().toCharUnitsFromBits(Info.Align).getQuantity();
> +  CharUnits Align = getContext().toCharUnitsFromBits(Info.Align);
>
>    const RecordType *RT = Ty->getAs<RecordType>();
>    if (RT) {
> @@ -3330,9 +3334,9 @@ ABIArgInfo WinX86_64ABIInfo::classify(Qu
>        return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
>
>      // FIXME: mingw-w64-gcc emits 128-bit struct as i128
> -    if (Width == 128 && getTarget().getTriple().isWindowsGNUEnvironment())
> -      return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
> -                                                          Width));
> +    if (Width == 128 && IsMingw64)
> +      return ABIArgInfo::getDirect(
> +          llvm::IntegerType::get(getVMContext(), Width));
>    }
>
>    // vectorcall adds the concept of a homogenous vector aggregate,
> similar to
> @@ -3346,8 +3350,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(Qu
>          return ABIArgInfo::getDirect();
>        return ABIArgInfo::getExpand();
>      }
> -    return ABIArgInfo::getIndirect(CharUnits::fromQuantity(Align),
> -                                   /*ByVal=*/false);
> +    return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
>    }
>
>
> @@ -3375,6 +3378,14 @@ ABIArgInfo WinX86_64ABIInfo::classify(Qu
>    if (BT && BT->getKind() == BuiltinType::Bool)
>      return ABIArgInfo::getExtend();
>
> +  // Mingw64 GCC uses the old 80 bit extended precision floating point
> unit. It
> +  // passes them indirectly through memory.
> +  if (IsMingw64 && BT && BT->getKind() == BuiltinType::LongDouble) {
> +    const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat();
> +    if (LDF == &llvm::APFloat::x87DoubleExtended)
> +      return ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
> +  }
> +
>    return ABIArgInfo::getDirect();
>  }
>
>
> Modified: cfe/trunk/test/CodeGen/mingw-long-double.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/mingw-long-double.c?rev=251567&r1=251566&r2=251567&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/CodeGen/mingw-long-double.c (original)
> +++ cfe/trunk/test/CodeGen/mingw-long-double.c Wed Oct 28 17:29:52 2015
> @@ -1,12 +1,41 @@
> -// REQUIRES: x86-registered-target
> -// RUN: %clang_cc1 -triple i686-pc-windows-gnu -S %s  -o - | FileCheck %s
> -check-prefix=CHECK_I686
> -// CHECK_I686: _lda,12
> -// CHECK_I686: _lds,16
> -// RUN: %clang_cc1 -triple x86_64-pc-windows-gnu -S %s  -o - | FileCheck
> %s -check-prefix=CHECK_X86_64
> -// CHECK_X86_64: lda,16
> -// CHECK_X86_64: lds,32
> -long double lda;
> +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -o - %s \
> +// RUN:    | FileCheck %s --check-prefix=GNU32
> +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -o - %s \
> +// RUN:    | FileCheck %s --check-prefix=GNU64
> +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -o - %s \
> +// RUN:    | FileCheck %s --check-prefix=MSC64
> +
>  struct {
>    char c;
>    long double ldb;
> -} lds;
> +} agggregate_LD = {};
> +// GNU32: %struct.anon = type { i8, x86_fp80 }
> +// GNU32: @agggregate_LD = global %struct.anon zeroinitializer, align 4
> +// GNU64: %struct.anon = type { i8, x86_fp80 }
> +// GNU64: @agggregate_LD = global %struct.anon zeroinitializer, align 16
> +// MSC64: %struct.anon = type { i8, double }
> +// MSC64: @agggregate_LD = global %struct.anon zeroinitializer, align 8
> +
> +long double dataLD = 1.0L;
> +// GNU32: @dataLD = global x86_fp80 0xK3FFF8000000000000000, align 4
> +// GNU64: @dataLD = global x86_fp80 0xK3FFF8000000000000000, align 16
> +// MSC64: @dataLD = global double 1.000000e+00, align 8
> +
> +long double _Complex dataLDC = {1.0L, 1.0L};
> +// GNU32: @dataLDC = global { x86_fp80, x86_fp80 } { x86_fp80
> 0xK3FFF8000000000000000, x86_fp80 0xK3FFF8000000000000000 }, align 4
> +// GNU64: @dataLDC = global { x86_fp80, x86_fp80 } { x86_fp80
> 0xK3FFF8000000000000000, x86_fp80 0xK3FFF8000000000000000 }, align 16
> +// MSC64: @dataLDC = global { double, double } { double 1.000000e+00,
> double 1.000000e+00 }, align 8
> +
> +long double TestLD(long double x) {
> +  return x * x;
> +}
> +// GNU32: define x86_fp80 @TestLD(x86_fp80 %x)
> +// GNU64: define void @TestLD(x86_fp80* noalias sret %agg.result,
> x86_fp80*)
> +// MSC64: define double @TestLD(double %x)
> +
> +long double _Complex TestLDC(long double _Complex x) {
> +  return x * x;
> +}
> +// GNU32: define void @TestLDC({ x86_fp80, x86_fp80 }* noalias sret
> %agg.result, { x86_fp80, x86_fp80 }* byval align 4 %x)
> +// GNU64: define void @TestLDC({ x86_fp80, x86_fp80 }* noalias sret
> %agg.result, { x86_fp80, x86_fp80 }* %x)
> +// MSC64: define void @TestLDC({ double, double }* noalias sret
> %agg.result, { double, double }* %x)
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151029/f5e9df4b/attachment-0001.html>


More information about the cfe-commits mailing list