Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -1108,6 +1108,7 @@ bool IsWin32StructABI; bool IsSoftFloatABI; bool IsMCUABI; + bool IsLinuxABI; unsigned DefaultNumRegisterParameters; static bool isRegisterSize(unsigned Size) { @@ -1173,6 +1174,7 @@ IsWin32StructABI(Win32StructABI), IsSoftFloatABI(SoftFloatABI), IsMCUABI(CGT.getTarget().getTriple().isOSIAMCU()), + IsLinuxABI(CGT.getTarget().getTriple().isOSLinux()), DefaultNumRegisterParameters(NumRegisterParameters) {} bool shouldPassIndirectlyForSwift(ArrayRef scalars, @@ -1597,6 +1599,9 @@ if (Align <= MinABIStackAlignInBytes) return 0; // Use default alignment. + if (IsLinuxABI && Ty->isFloatingType() && getContext().getTypeSize(Ty) == 128) + return 16; + // On non-Darwin, the stack type alignment is always 4. if (!IsDarwinVectorABI) { // Set explicit alignment, since we may need to realign the top. @@ -1890,6 +1895,9 @@ return getIndirectResult(Ty, /*ByVal=*/false, State); } + if (IsLinuxABI && Ty->isFloatingType() && getContext().getTypeSize(Ty) == 128) + return getIndirectResult(Ty, /*ByVal=*/true, State); + if (InReg) return ABIArgInfo::getDirectInReg(); return ABIArgInfo::getDirect(); Index: clang/test/CodeGen/x86-long-double.cpp =================================================================== --- clang/test/CodeGen/x86-long-double.cpp +++ clang/test/CodeGen/x86-long-double.cpp @@ -16,14 +16,14 @@ // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin -mlong-double-64 | \ // RUN: FileCheck --check-prefixes=FP64,FP64-X64 %s -// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686 -mlong-double-128 | \ -// RUN: FileCheck --check-prefix=FP128 %s +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-pc-linux-gnu -mlong-double-128 | \ +// RUN: FileCheck --check-prefixes=FP128,FP128-X32-LINUX %s // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin -mlong-double-128 | \ -// RUN: FileCheck --check-prefix=FP128 %s +// RUN: FileCheck --check-prefixes=FP128,FP128-X32-DARWIN %s // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64 -mlong-double-128 | \ -// RUN: FileCheck --check-prefix=FP128 %s +// RUN: FileCheck --check-prefixes=FP128,FP128-X64 %s // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin -mlong-double-128 | \ -// RUN: FileCheck --check-prefix=FP128 %s +// RUN: FileCheck --check-prefixes=FP128,FP128-X64 %s // Check -malign-double increases the alignment from 4 to 8 on x86-32. // RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686 -mlong-double-64 \ @@ -53,4 +53,6 @@ // FP64: double @_Z3fooe(double %d) // FP80: x86_fp80 @_Z3fooe(x86_fp80 %d) -// FP128: fp128 @_Z3foog(fp128 %d) +// FP128-X32-LINUX: fp128 @_Z3foog(fp128* byval(fp128) align 16 %0) +// FP128-X32-DARWIN: fp128 @_Z3foog(fp128 %d) +// FP128-X64: fp128 @_Z3foog(fp128 %d) Index: clang/test/CodeGen/x86_32-fp128-call-conv-linux.c =================================================================== --- /dev/null +++ clang/test/CodeGen/x86_32-fp128-call-conv-linux.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -mlong-double-128 -w -fblocks -ffreestanding -triple i386-pc-linux-gnu -emit-llvm -o %t %s || FileCheck < %t %s + + +// CHECK-LABEL: define void @testfp128 +// CHECK-NEXT: %a.addr = alloca fp128, align 16 +// CHECK-NEXT: %a = load fp128, fp128* %0, align 16 +// CHECK-NEXT: store fp128 %a, fp128* %a.addr, align 16 +void testfp128(__float128 a) { + return; +} + +// CHECK-LABEL: define void @testlongdouble +// CHECK-NEXT: %a.addr = alloca fp128, align 16 +// CHECK-NEXT: %a = load fp128, fp128* %0, align 16 +// CHECK-NEXT: store fp128 %a, fp128* %a.addr, align 16 +void testlongdouble(long double a) { + return; +} + +// CHECK-LABEL: define void @testPassArguments +// CHECK: call void @testfp128(fp128* byval(fp128) align 16 %{{.*}}) +// CHECK: call void @testlongdouble(fp128* byval(fp128) align 16 %{{.*}}) +void testPassArguments() { + __float128 a=1.0; + testfp128(a); + testlongdouble(a); + return; +}