summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-06-05 03:00:18 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-06-05 03:00:18 +0000
commit303caedd4b41f6dcfa994abfc7dc59d39e6cd346 (patch)
tree850c3d970aed29491c914e924bbb74662b52d2c5 /clang/test
parent36af2529ee81efc8fca98ad65a3a9fadc9e6e45e (diff)
downloadbcm5719-llvm-303caedd4b41f6dcfa994abfc7dc59d39e6cd346.tar.gz
bcm5719-llvm-303caedd4b41f6dcfa994abfc7dc59d39e6cd346.zip
Implement SparcV9ABIInfo::EmitVAArg.
This could actually be implemented with the LLVM IR va_arg instruction, but it doesn't seem to offer any advantages over accessing the va_list pointer directly. Using the va_list pointer directly makes it possible to perform type coercion directly from the argument array, and the va_list updates are exposed to the optimizers. llvm-svn: 183292
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CodeGen/sparcv9-abi.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/clang/test/CodeGen/sparcv9-abi.c b/clang/test/CodeGen/sparcv9-abi.c
index b58c84689ad..22803a6d4c4 100644
--- a/clang/test/CodeGen/sparcv9-abi.c
+++ b/clang/test/CodeGen/sparcv9-abi.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple sparcv9-unknown-linux -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+#include <stdarg.h>
// CHECK: define void @f_void()
void f_void(void) {}
@@ -115,3 +116,66 @@ void call_tiny() {
struct tiny x = { 1 };
f_tiny(x);
}
+
+// CHECK: define signext i32 @f_variable(i8* %f, ...)
+// CHECK: %ap = alloca i8*
+// CHECK: call void @llvm.va_start
+//
+int f_variable(char *f, ...) {
+ int s = 0;
+ char c;
+ va_list ap;
+ va_start(ap, f);
+ while ((c = *f++)) switch (c) {
+
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 8
+// CHECK-DAG: store i8* %[[NXT]], i8** %ap
+// CHECK-DAG: %[[EXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 4
+// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[EXT]] to i32*
+// CHECK-DAG: load i32* %[[ADR]]
+// CHECK: br
+ case 'i':
+ s += va_arg(ap, int);
+ break;
+
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 8
+// CHECK-DAG: store i8* %[[NXT]], i8** %ap
+// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to i64*
+// CHECK-DAG: load i64* %[[ADR]]
+// CHECK: br
+ case 'l':
+ s += va_arg(ap, long);
+ break;
+
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 8
+// CHECK-DAG: store i8* %[[NXT]], i8** %ap
+// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.tiny*
+// CHECK: br
+ case 't':
+ s += va_arg(ap, struct tiny).a;
+ break;
+
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 16
+// CHECK-DAG: store i8* %[[NXT]], i8** %ap
+// CHECK-DAG: %[[ADR:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.small*
+// CHECK: br
+ case 's':
+ s += *va_arg(ap, struct small).a;
+ break;
+
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK-DAG: %[[NXT:[^ ]+]] = getelementptr i8* %[[CUR]], i32 8
+// CHECK-DAG: store i8* %[[NXT]], i8** %ap
+// CHECK-DAG: %[[IND:[^ ]+]] = bitcast i8* %[[CUR]] to %struct.medium**
+// CHECK-DAG: %[[ADR:[^ ]+]] = load %struct.medium** %[[IND]]
+// CHECK: br
+ case 'm':
+ s += *va_arg(ap, struct medium).a;
+ break;
+ }
+ return s;
+}
OpenPOWER on IntegriCloud