summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGen/ppc64-struct-onefloat.c
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2012-10-12 19:26:17 +0000
committerBill Schmidt <wschmidt@linux.vnet.ibm.com>2012-10-12 19:26:17 +0000
commit84d3779819c3b7278d85d76c33f9ca8cf9a4facc (patch)
tree45c3bba5cb0a809923619784c8a0f937ceda982f /clang/test/CodeGen/ppc64-struct-onefloat.c
parent3073c58cab08369d1d29698882eec12d59259592 (diff)
downloadbcm5719-llvm-84d3779819c3b7278d85d76c33f9ca8cf9a4facc.tar.gz
bcm5719-llvm-84d3779819c3b7278d85d76c33f9ca8cf9a4facc.zip
This patch addresses PR13948.
For 64-bit PowerPC SVR4, an aggregate containing only one floating-point field (float, double, or long double) must be passed in a register as though just that field were present. This patch addresses the issue during Clang code generation by specifying in the ABIArgInfo for the argument that the underlying type is passed directly in a register. The included test case verifies flat and nested structs for the three data types. llvm-svn: 165816
Diffstat (limited to 'clang/test/CodeGen/ppc64-struct-onefloat.c')
-rw-r--r--clang/test/CodeGen/ppc64-struct-onefloat.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/clang/test/CodeGen/ppc64-struct-onefloat.c b/clang/test/CodeGen/ppc64-struct-onefloat.c
new file mode 100644
index 00000000000..4f7c8962257
--- /dev/null
+++ b/clang/test/CodeGen/ppc64-struct-onefloat.c
@@ -0,0 +1,65 @@
+// REQUIRES: ppc64-registered-target
+// RUN: %clang_cc1 -O0 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+typedef struct s1 { float f; } Sf;
+typedef struct s2 { double d; } Sd;
+typedef struct s3 { long double ld; } Sld;
+typedef struct s4 { Sf fs; } SSf;
+typedef struct s5 { Sd ds; } SSd;
+typedef struct s6 { Sld lds; } SSld;
+
+void bar(Sf a, Sd b, Sld c, SSf d, SSd e, SSld f) {}
+
+// CHECK: define void @bar
+// CHECK: %a = alloca %struct.s1, align 4
+// CHECK: %b = alloca %struct.s2, align 8
+// CHECK: %c = alloca %struct.s3, align 16
+// CHECK: %d = alloca %struct.s4, align 4
+// CHECK: %e = alloca %struct.s5, align 8
+// CHECK: %f = alloca %struct.s6, align 16
+// CHECK: %coerce.dive = getelementptr %struct.s1* %a, i32 0, i32 0
+// CHECK: store float %a.coerce, float* %coerce.dive, align 1
+// CHECK: %coerce.dive1 = getelementptr %struct.s2* %b, i32 0, i32 0
+// CHECK: store double %b.coerce, double* %coerce.dive1, align 1
+// CHECK: %coerce.dive2 = getelementptr %struct.s3* %c, i32 0, i32 0
+// CHECK: store ppc_fp128 %c.coerce, ppc_fp128* %coerce.dive2, align 1
+// CHECK: %coerce.dive3 = getelementptr %struct.s4* %d, i32 0, i32 0
+// CHECK: %coerce.dive4 = getelementptr %struct.s1* %coerce.dive3, i32 0, i32 0
+// CHECK: store float %d.coerce, float* %coerce.dive4, align 1
+// CHECK: %coerce.dive5 = getelementptr %struct.s5* %e, i32 0, i32 0
+// CHECK: %coerce.dive6 = getelementptr %struct.s2* %coerce.dive5, i32 0, i32 0
+// CHECK: store double %e.coerce, double* %coerce.dive6, align 1
+// CHECK: %coerce.dive7 = getelementptr %struct.s6* %f, i32 0, i32 0
+// CHECK: %coerce.dive8 = getelementptr %struct.s3* %coerce.dive7, i32 0, i32 0
+// CHECK: store ppc_fp128 %f.coerce, ppc_fp128* %coerce.dive8, align 1
+// CHECK: ret void
+
+void foo(void)
+{
+ Sf p1 = { 22.63f };
+ Sd p2 = { 19.47 };
+ Sld p3 = { -155.1l };
+ SSf p4 = { { 22.63f } };
+ SSd p5 = { { 19.47 } };
+ SSld p6 = { { -155.1l } };
+ bar(p1, p2, p3, p4, p5, p6);
+}
+
+// CHECK: define void @foo
+// CHECK: %coerce.dive = getelementptr %struct.s1* %p1, i32 0, i32 0
+// CHECK: %{{[0-9]+}} = load float* %coerce.dive, align 1
+// CHECK: %coerce.dive1 = getelementptr %struct.s2* %p2, i32 0, i32 0
+// CHECK: %{{[0-9]+}} = load double* %coerce.dive1, align 1
+// CHECK: %coerce.dive2 = getelementptr %struct.s3* %p3, i32 0, i32 0
+// CHECK: %{{[0-9]+}} = load ppc_fp128* %coerce.dive2, align 1
+// CHECK: %coerce.dive3 = getelementptr %struct.s4* %p4, i32 0, i32 0
+// CHECK: %coerce.dive4 = getelementptr %struct.s1* %coerce.dive3, i32 0, i32 0
+// CHECK: %{{[0-9]+}} = load float* %coerce.dive4, align 1
+// CHECK: %coerce.dive5 = getelementptr %struct.s5* %p5, i32 0, i32 0
+// CHECK: %coerce.dive6 = getelementptr %struct.s2* %coerce.dive5, i32 0, i32 0
+// CHECK: %{{[0-9]+}} = load double* %coerce.dive6, align 1
+// CHECK: %coerce.dive7 = getelementptr %struct.s6* %p6, i32 0, i32 0
+// CHECK: %coerce.dive8 = getelementptr %struct.s3* %coerce.dive7, i32 0, i32 0
+// CHECK: %{{[0-9]+}} = load ppc_fp128* %coerce.dive8, align 1
+// CHECK: call void @bar(float inreg %{{[0-9]+}}, double inreg %{{[0-9]+}}, ppc_fp128 inreg %{{[0-9]+}}, float inreg %{{[0-9]+}}, double inreg %{{[0-9]+}}, ppc_fp128 inreg %{{[0-9]+}})
+// CHECK: ret void
OpenPOWER on IntegriCloud