================
@@ -0,0 +1,286 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-DEF
+// RUN: %clang_cc1 -msoft-float  -mfloat-abi soft -triple 
powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-SOFT-FLOAT
+
+// CHECK-GNU-DEF-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-DEF-SAME: (float noundef [[F:%.*]], [8 x i32] noundef 
[[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:    [[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, 
align 16
+// CHECK-GNU-DEF-NEXT:    [[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// CHECK-GNU-DEF-NEXT:    [[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:    store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
+// CHECK-GNU-DEF-NEXT:    store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:    [[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:    [[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    [[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:    store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:    [[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 
16
+// CHECK-GNU-DEF-NEXT:    ret [8 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-SOFT-FLOAT-SAME: (float noundef [[F:%.*]], ptr noundef byval({ 
ppc_fp128, ppc_fp128 }) align 16 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-SOFT-FLOAT-NEXT:  entry:
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[RETVAL:%.*]] = alloca { ppc_fp128, 
ppc_fp128 }, align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[X_REAL:%.*]] = load ppc_fp128, ptr 
[[X_REALP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[X_IMAG:%.*]] = load ppc_fp128, ptr 
[[X_IMAGP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds 
{ ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds 
{ ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store ppc_fp128 [[X_REAL]], ptr 
[[RETVAL_REALP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store ppc_fp128 [[X_IMAG]], ptr 
[[RETVAL_IMAGP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[TMP0:%.*]] = load [8 x i32], ptr 
[[RETVAL]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:    ret [8 x i32] [[TMP0]]
+//
+_Complex long double _cldouble(float f, _Complex long double x) {
+  return x;
+}
+
+// CHECK-GNU-DEF-LABEL: define dso_local [4 x i32] @testComplexDouble
+// CHECK-GNU-DEF-SAME: (float noundef [[W:%.*]], [1 x i64] noundef 
[[X_COERCE:%.*]], [4 x i32] noundef [[Z_COERCE:%.*]]) #[[ATTR0]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:    [[RETVAL:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:    [[X:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-DEF-NEXT:    [[Z:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:    [[W_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:    store [1 x i64] [[X_COERCE]], ptr [[X]], align 4
+// CHECK-GNU-DEF-NEXT:    store [4 x i32] [[Z_COERCE]], ptr [[Z]], align 8
+// CHECK-GNU-DEF-NEXT:    store float [[W]], ptr [[W_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:    [[Z_REALP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[Z]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[Z_REAL:%.*]] = load double, ptr [[Z_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:    [[Z_IMAGP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[Z]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    [[Z_IMAG:%.*]] = load double, ptr [[Z_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    store double [[Z_REAL]], ptr [[RETVAL_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:    store double [[Z_IMAG]], ptr [[RETVAL_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:    [[TMP0:%.*]] = load [4 x i32], ptr [[RETVAL]], align 
8
+// CHECK-GNU-DEF-NEXT:    ret [4 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [4 x i32] @testComplexDouble
+// CHECK-GNU-SOFT-FLOAT-SAME: (float noundef [[W:%.*]], [1 x i64] noundef 
[[X_COERCE:%.*]], [4 x i32] noundef [[Z_COERCE:%.*]]) #[[ATTR0]] {
+// CHECK-GNU-SOFT-FLOAT-NEXT:  entry:
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[RETVAL:%.*]] = alloca { double, double }, 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[X:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[Z:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[W_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store [1 x i64] [[X_COERCE]], ptr [[X]], 
align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store [4 x i32] [[Z_COERCE]], ptr [[Z]], 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store float [[W]], ptr [[W_ADDR]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[Z_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[Z]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[Z_REAL:%.*]] = load double, ptr 
[[Z_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[Z_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[Z]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[Z_IMAG:%.*]] = load double, ptr 
[[Z_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store double [[Z_REAL]], ptr 
[[RETVAL_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store double [[Z_IMAG]], ptr 
[[RETVAL_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[TMP0:%.*]] = load [4 x i32], ptr 
[[RETVAL]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    ret [4 x i32] [[TMP0]]
+//
+_Complex double testComplexDouble(float w, _Complex float x, _Complex double z)
+{
+  return z;
+}
+
+// CHECK-GNU-DEF-LABEL: define dso_local [4 x i32] @checkComplexDoubleOnStack
+// CHECK-GNU-DEF-SAME: (float noundef [[X1:%.*]], [1 x i64] noundef 
[[CF_COERCE:%.*]], float noundef [[X2:%.*]], [4 x i32] noundef 
[[CD_COERCE:%.*]]) #[[ATTR0]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:    [[RETVAL:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:    [[CF:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-DEF-NEXT:    [[CD:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:    [[X1_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:    [[X2_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:    [[COERCE:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-DEF-NEXT:    [[COERCE1:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:    [[COERCE2:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:    store [1 x i64] [[CF_COERCE]], ptr [[CF]], align 4
+// CHECK-GNU-DEF-NEXT:    store [4 x i32] [[CD_COERCE]], ptr [[CD]], align 8
+// CHECK-GNU-DEF-NEXT:    store float [[X1]], ptr [[X1_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:    store float [[X2]], ptr [[X2_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:    [[TMP0:%.*]] = load float, ptr [[X2_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:    [[CF_REALP:%.*]] = getelementptr inbounds { float, 
float }, ptr [[CF]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[CF_REAL:%.*]] = load float, ptr [[CF_REALP]], 
align 4
+// CHECK-GNU-DEF-NEXT:    [[CF_IMAGP:%.*]] = getelementptr inbounds { float, 
float }, ptr [[CF]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    [[CF_IMAG:%.*]] = load float, ptr [[CF_IMAGP]], 
align 4
+// CHECK-GNU-DEF-NEXT:    [[CD_REALP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[CD]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[CD_REAL:%.*]] = load double, ptr [[CD_REALP]], 
align 8
+// CHECK-GNU-DEF-NEXT:    [[CD_IMAGP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[CD]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    [[CD_IMAG:%.*]] = load double, ptr [[CD_IMAGP]], 
align 8
+// CHECK-GNU-DEF-NEXT:    [[COERCE_REALP:%.*]] = getelementptr inbounds { 
float, float }, ptr [[COERCE]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[COERCE_IMAGP:%.*]] = getelementptr inbounds { 
float, float }, ptr [[COERCE]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    store float [[CF_REAL]], ptr [[COERCE_REALP]], align 
4
+// CHECK-GNU-DEF-NEXT:    store float [[CF_IMAG]], ptr [[COERCE_IMAGP]], align 
4
+// CHECK-GNU-DEF-NEXT:    [[TMP1:%.*]] = load [1 x i64], ptr [[COERCE]], align 
4
+// CHECK-GNU-DEF-NEXT:    [[COERCE1_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[COERCE1]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[COERCE1_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[COERCE1]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    store double [[CD_REAL]], ptr [[COERCE1_REALP]], 
align 8
+// CHECK-GNU-DEF-NEXT:    store double [[CD_IMAG]], ptr [[COERCE1_IMAGP]], 
align 8
+// CHECK-GNU-DEF-NEXT:    [[TMP2:%.*]] = load [4 x i32], ptr [[COERCE1]], 
align 8
+// CHECK-GNU-DEF-NEXT:    [[CALL:%.*]] = call [4 x i32] 
@testComplexDouble(float noundef [[TMP0]], [1 x i64] noundef [[TMP1]], [4 x 
i32] noundef [[TMP2]])
+// CHECK-GNU-DEF-NEXT:    store [4 x i32] [[CALL]], ptr [[COERCE2]], align 8
+// CHECK-GNU-DEF-NEXT:    [[COERCE2_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[COERCE2]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[COERCE2_REAL:%.*]] = load double, ptr 
[[COERCE2_REALP]], align 8
+// CHECK-GNU-DEF-NEXT:    [[COERCE2_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[COERCE2]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    [[COERCE2_IMAG:%.*]] = load double, ptr 
[[COERCE2_IMAGP]], align 8
+// CHECK-GNU-DEF-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:    store double [[COERCE2_REAL]], ptr [[RETVAL_REALP]], 
align 8
+// CHECK-GNU-DEF-NEXT:    store double [[COERCE2_IMAG]], ptr [[RETVAL_IMAGP]], 
align 8
+// CHECK-GNU-DEF-NEXT:    [[TMP3:%.*]] = load [4 x i32], ptr [[RETVAL]], align 
8
+// CHECK-GNU-DEF-NEXT:    ret [4 x i32] [[TMP3]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [4 x i32] 
@checkComplexDoubleOnStack
+// CHECK-GNU-SOFT-FLOAT-SAME: (float noundef [[X1:%.*]], [1 x i64] noundef 
[[CF_COERCE:%.*]], float noundef [[X2:%.*]], ptr noundef byval({ double, double 
}) align 8 [[CD:%.*]]) #[[ATTR0]] {
+// CHECK-GNU-SOFT-FLOAT-NEXT:  entry:
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[RETVAL:%.*]] = alloca { double, double }, 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CF:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[X1_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[X2_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE:%.*]] = alloca { float, float }, 
align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE1:%.*]] = alloca { double, double }, 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE2:%.*]] = alloca { double, double }, 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store [1 x i64] [[CF_COERCE]], ptr [[CF]], 
align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store float [[X1]], ptr [[X1_ADDR]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store float [[X2]], ptr [[X2_ADDR]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[TMP0:%.*]] = load float, ptr [[X2_ADDR]], 
align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CF_REALP:%.*]] = getelementptr inbounds { 
float, float }, ptr [[CF]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CF_REAL:%.*]] = load float, ptr 
[[CF_REALP]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CF_IMAGP:%.*]] = getelementptr inbounds { 
float, float }, ptr [[CF]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CF_IMAG:%.*]] = load float, ptr 
[[CF_IMAGP]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CD_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[CD]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CD_REAL:%.*]] = load double, ptr 
[[CD_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CD_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[CD]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CD_IMAG:%.*]] = load double, ptr 
[[CD_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE_REALP:%.*]] = getelementptr inbounds 
{ float, float }, ptr [[COERCE]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE_IMAGP:%.*]] = getelementptr inbounds 
{ float, float }, ptr [[COERCE]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store float [[CF_REAL]], ptr 
[[COERCE_REALP]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store float [[CF_IMAG]], ptr 
[[COERCE_IMAGP]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[TMP1:%.*]] = load [1 x i64], ptr 
[[COERCE]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE1_REALP:%.*]] = getelementptr 
inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE1_IMAGP:%.*]] = getelementptr 
inbounds { double, double }, ptr [[COERCE1]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store double [[CD_REAL]], ptr 
[[COERCE1_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store double [[CD_IMAG]], ptr 
[[COERCE1_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[TMP2:%.*]] = load [4 x i32], ptr 
[[COERCE1]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[CALL:%.*]] = call [4 x i32] 
@testComplexDouble(float noundef [[TMP0]], [1 x i64] noundef [[TMP1]], [4 x 
i32] noundef [[TMP2]])
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store [4 x i32] [[CALL]], ptr [[COERCE2]], 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE2_REALP:%.*]] = getelementptr 
inbounds { double, double }, ptr [[COERCE2]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE2_REAL:%.*]] = load double, ptr 
[[COERCE2_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE2_IMAGP:%.*]] = getelementptr 
inbounds { double, double }, ptr [[COERCE2]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[COERCE2_IMAG:%.*]] = load double, ptr 
[[COERCE2_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[RETVAL_REALP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[RETVAL_IMAGP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store double [[COERCE2_REAL]], ptr 
[[RETVAL_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    store double [[COERCE2_IMAG]], ptr 
[[RETVAL_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    [[TMP3:%.*]] = load [4 x i32], ptr 
[[RETVAL]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:    ret [4 x i32] [[TMP3]]
+//
+_Complex double checkComplexDoubleOnStack(float x1, _Complex float cf, float 
x2, _Complex double cd)
----------------
Long5hot wrote:

Below assembly's generated with -fcomplex-ppc-gnu-abi -O1 --target=ppc32 -S  
-msoft-float

"use-soft-float"="true" get's passed in IR in attributes

_Complex double testComplexDouble(float w, _Complex float x, _Complex double z)
{
  return z;
}

testComplexDouble:                      # @testComplexDouble
.Lfunc_begin2:
        .cfi_startproc
# %bb.0:
        mr      6, 10
        mr      5, 9
        mr      4, 8
        mr      3, 7
        blr
.Lfunc_end2:
        .size   testComplexDouble, .Lfunc_end2-.Lfunc_begin2
        .cfi_endproc
                                        # -- End function

_Complex double checkComplexDoubleOnStack(float x1, _Complex float cf, float 
x2, _Complex double cd)
{
  return testComplexDouble(x2, cf, cd);
}

        .globl  checkComplexDoubleOnStack       # -- Begin function 
checkComplexDoubleOnStack
        .p2align        2
        .type   checkComplexDoubleOnStack,@function
checkComplexDoubleOnStack:              # @checkComplexDoubleOnStack
.Lfunc_begin3:
        .cfi_startproc
# %bb.0:
        lwz 3, 0(8)
        lwz 4, 4(8)
        lwz 5, 8(8)
        lwz 6, 12(8)
        blr

https://github.com/llvm/llvm-project/pull/77732
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to