diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -1269,7 +1269,8 @@ // Note that this intentionally doesn't include _Complex _Bool. if (!S.getLangOpts().CPlusPlus) S.Diag(TSTLoc, diag::ext_integer_complex); - } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { + } else if (TypeSpecType != TST_float && TypeSpecType != TST_double && + TypeSpecType != TST_float128) { S.Diag(TSCLoc, diag::err_invalid_complex_spec) << getSpecifierName((TST)TypeSpecType, Policy); TypeSpecComplex = TSC_unspecified; diff --git a/clang/test/CodeGen/ppc64-complex-parms.c b/clang/test/CodeGen/ppc64-complex-parms.c --- a/clang/test/CodeGen/ppc64-complex-parms.c +++ b/clang/test/CodeGen/ppc64-complex-parms.c @@ -1,8 +1,19 @@ +// REQUIRES: powerpc-registered-target // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +float128 -DTEST_F128 -triple \ +// RUN: powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s \ +// RUN: --check-prefix CHECK-F128 float crealf(_Complex float); double creal(_Complex double); long double creall(_Complex long double); +#ifdef TEST_F128 +__float128 crealf128(_Complex __float128); +__float128 foo_f128(_Complex __float128 x) { + return crealf128(x); +} +// CHECK-F128: define fp128 @foo_f128(fp128 {{[%A-Za-z0-9.]+}}, fp128 {{[%A-Za-z0-9.]+}}) +#endif float foo_float(_Complex float x) { return crealf(x); diff --git a/clang/test/CodeGen/ppc64-complex-return.c b/clang/test/CodeGen/ppc64-complex-return.c --- a/clang/test/CodeGen/ppc64-complex-return.c +++ b/clang/test/CodeGen/ppc64-complex-return.c @@ -1,9 +1,20 @@ // REQUIRES: powerpc-registered-target // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -target-feature +float128 -DTEST_F128 -triple \ +// RUN: powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s \ +// RUN: --check-prefix CHECK-F128 float crealf(_Complex float); double creal(_Complex double); long double creall(_Complex long double); +#ifdef TEST_F128 +__float128 crealf128(_Complex __float128); +_Complex __float128 foo_f128(_Complex __float128 x) { + return x; +} + +// CHECK-F128: define { fp128, fp128 } @foo_f128(fp128 {{[%A-Za-z0-9.]+}}, fp128 {{[%A-Za-z0-9.]+}}) [[NUW:#[0-9]+]] { +#endif _Complex float foo_float(_Complex float x) { return x; @@ -80,6 +91,17 @@ // CHECK: extractvalue { ppc_fp128, ppc_fp128 } [[VAR3]], 0 // CHECK: extractvalue { ppc_fp128, ppc_fp128 } [[VAR3]], 1 +#ifdef TEST_F128 +__float128 bar_f128(void) { + return crealf128(foo_f128(2.0Q - 2.5Qi)); +} + +// CHECK-F128: define fp128 @bar_f128() [[NUW]] { +// CHECK-F128: [[VAR3:[%A-Za-z0-9.]+]] = call { fp128, fp128 } @foo_f128 +// CHECK-F128: extractvalue { fp128, fp128 } [[VAR3]], 0 +// CHECK-F128: extractvalue { fp128, fp128 } [[VAR3]], 1 +#endif + int bar_int(void) { return __real__(foo_int(2 - 3i)); }