aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGen
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-03-03 17:28:16 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-03-03 17:28:16 +0000
commit79ade4e028932fcb9dab15e2fb2305ca15ab0f14 (patch)
treee1a885aadfd80632f5bd70d4bd2d37e715e35a79 /test/CodeGen
parentecb7e5c8afe929ee38155db94de6b084ec32a645 (diff)
Notes
Diffstat (limited to 'test/CodeGen')
-rw-r--r--test/CodeGen/2010-02-16-DbgScopes.c18
-rw-r--r--test/CodeGen/2010-02-18-Dbg-VectorType.c9
-rw-r--r--test/CodeGen/attributes.c6
-rw-r--r--test/CodeGen/blocksignature.c94
-rw-r--r--test/CodeGen/builtins.c45
-rw-r--r--test/CodeGen/cast-emit.c12
-rw-r--r--test/CodeGen/dllimport-dllexport.c11
-rw-r--r--test/CodeGen/extern-inline.c25
-rw-r--r--test/CodeGen/functions.c21
9 files changed, 229 insertions, 12 deletions
diff --git a/test/CodeGen/2010-02-16-DbgScopes.c b/test/CodeGen/2010-02-16-DbgScopes.c
new file mode 100644
index 000000000000..b11f920156e4
--- /dev/null
+++ b/test/CodeGen/2010-02-16-DbgScopes.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -g < %s | grep lexical | count 5
+// Test to check number of lexical scope identified in debug info.
+
+extern int bar();
+extern void foobar();
+void foo(int s) {
+ unsigned loc = 0;
+ if (s) {
+ if (bar()) {
+ foobar();
+ }
+ } else {
+ loc = 1;
+ if (bar()) {
+ loc = 2;
+ }
+ }
+}
diff --git a/test/CodeGen/2010-02-18-Dbg-VectorType.c b/test/CodeGen/2010-02-18-Dbg-VectorType.c
new file mode 100644
index 000000000000..eb17d11ac89b
--- /dev/null
+++ b/test/CodeGen/2010-02-18-Dbg-VectorType.c
@@ -0,0 +1,9 @@
+// RUN: %clang -emit-llvm -S -O0 -g %s -o - | grep DW_TAG_typedef | grep float4
+typedef float float4 __attribute__((vector_size(16)));
+
+int main(){
+ volatile float4 x = (float4) { 0.0f, 1.0f, 2.0f, 3.0f };
+ x += x;
+ return 0;
+}
+
diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c
index 770ce766dfba..4fdf1a51762b 100644
--- a/test/CodeGen/attributes.c
+++ b/test/CodeGen/attributes.c
@@ -30,6 +30,12 @@ int t12 __attribute__((section("SECT")));
void __t8() {}
void t9() __attribute__((weak, alias("__t8")));
+static void t22(void) __attribute__((weakref("t8")));
+// CHECK: @t22 = alias weak void ()* @t8
+
+static void t23(void) __attribute__((weakref, alias("t8")));
+// CHECK: @t23 = alias weak void ()* @t8
+
// CHECK: declare extern_weak i32 @t15()
int __attribute__((weak_import)) t15(void);
int t17() {
diff --git a/test/CodeGen/blocksignature.c b/test/CodeGen/blocksignature.c
new file mode 100644
index 000000000000..6ed8750e9b1e
--- /dev/null
+++ b/test/CodeGen/blocksignature.c
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64
+// RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32
+
+// X64: @.str = private constant [6 x i8] c"v8@?0\00"
+// X64: @__block_literal_global = internal constant %1 { i8** @_NSConcreteGlobalBlock, i32 1342177280,
+// X64: @.str1 = private constant [12 x i8] c"i16@?0c8f12\00"
+// X64: store i32 1073741824, i32*
+
+// X32: @.str = private constant [6 x i8] c"v4@?0\00"
+// X32: @__block_literal_global = internal constant %1 { i8** @_NSConcreteGlobalBlock, i32 1342177280,
+// X32: @.str1 = private constant [11 x i8] c"i12@?0c4f8\00"
+// X32: store i32 1073741824, i32*
+
+// rdar://7635294
+
+
+int globalInt;
+void (^global)(void) = ^{ ++globalInt; };
+
+
+void foo(int param) {
+ extern int rand(void);
+ extern void rand_r(int (^b)(char x, float y)); // name a function present at runtime
+ while (param--)
+ rand_r(^(char x, float y){ return x + (int)y + param + rand(); }); // generate a local block binding param
+}
+
+#if 0
+#include <stdio.h>
+enum {
+ BLOCK_HAS_COPY_DISPOSE = (1 << 25),
+ BLOCK_HAS_CXX_OBJ = (1 << 26),
+ BLOCK_IS_GLOBAL = (1 << 28),
+ BLOCK_HAS_DESCRIPTOR = (1 << 29),
+ BLOCK_HAS_OBJC_TYPE = (1 << 30)
+};
+
+struct block_descriptor_big {
+ unsigned long int reserved;
+ unsigned long int size;
+ void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE
+ void (*dispose)(void *); // conditional on BLOCK_HAS_COPY_DISPOSE
+ const char *signature; // conditional on BLOCK_HAS_OBJC
+ const char *layout; // conditional on BLOCK_HAS_OBJC
+};
+struct block_descriptor_small {
+ unsigned long int reserved;
+ unsigned long int size;
+ const char *signature; // conditional on BLOCK_HAS_OBJC
+ const char *layout; // conditional on BLOCK_HAS_OBJC
+};
+
+struct block_layout_abi { // can't change
+ void *isa;
+ int flags;
+ int reserved;
+ void (*invoke)(void *, ...);
+ struct block_descriptor_big *descriptor;
+};
+
+const char *getBlockSignature(void *block) {
+ struct block_layout_abi *layout = (struct block_layout_abi *)block;
+ if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return NULL;
+ if (layout->flags & BLOCK_HAS_COPY_DISPOSE)
+ return layout->descriptor->signature;
+ else
+ return ((struct block_descriptor_small *)layout->descriptor)->signature;
+}
+
+
+
+int main(int argc, char *argv[]) {
+ printf("desired global flags: %d\n", BLOCK_IS_GLOBAL | BLOCK_HAS_OBJC_TYPE);
+ printf("desired stack flags: %d\n", BLOCK_HAS_OBJC_TYPE);
+
+ printf("types for global: %s\n", getBlockSignature(global));
+ printf("types for local: %s\n", getBlockSignature(^int(char x, float y) { return (int)(y + x); }));
+ return 0;
+}
+
+/*
+x86_64
+desired global flags: 1342177280
+desired stack flags: 1073741824
+types for global: v8@?0
+types for local: i16@?0c8f12
+
+i386
+desired global flags: 1342177280
+desired stack flags: 1073741824
+types for global: v4@?0
+types for local: i12@?0c4f8
+*/
+#endif
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index 4fa4785755b9..417ca7def5f2 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -emit-llvm -o %t %s
// RUN: not grep __builtin %t
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple | FileCheck %s
int printf(const char *, ...);
@@ -9,11 +10,17 @@ void p(char *str, int x) {
void q(char *str, double x) {
printf("%s: %f\n", str, x);
}
+void r(char *str, void *ptr) {
+ printf("%s: %p\n", str, ptr);
+}
+
+int random(void);
int main() {
int N = random();
#define P(n,args) p(#n #args, __builtin_##n args)
#define Q(n,args) q(#n #args, __builtin_##n args)
+#define R(n,args) r(#n #args, __builtin_##n args)
#define V(n,args) p(#n #args, (__builtin_##n args, 0))
P(types_compatible_p, (int, float));
P(choose_expr, (0, 10, 20));
@@ -110,16 +117,48 @@ int main() {
// FIXME
// V(clear_cache, (&N, &N+1));
V(trap, ());
- P(extract_return_addr, (&N));
+ R(extract_return_addr, (&N));
return 0;
}
-void strcat() {}
-
void foo() {
__builtin_strcat(0, 0);
}
+// CHECK: define void @bar(
+void bar() {
+ float f;
+ double d;
+ long double ld;
+
+ // LLVM's hex representation of float constants is really unfortunate;
+ // basically it does a float-to-double "conversion" and then prints the
+ // hex form of that. That gives us wierd artifacts like exponents
+ // that aren't numerically similar to the original exponent and
+ // significand bit-patterns that are offset by three bits (because
+ // the exponent was expanded from 8 bits to 11).
+ //
+ // 0xAE98 == 1010111010011000
+ // 0x15D3 == 1010111010011
+
+ f = __builtin_huge_valf(); // CHECK: float 0x7FF0000000000000
+ d = __builtin_huge_val(); // CHECK: double 0x7FF0000000000000
+ ld = __builtin_huge_vall(); // CHECK: x86_fp80 0xK7FFF8000000000000000
+ f = __builtin_nanf(""); // CHECK: float 0x7FF8000000000000
+ d = __builtin_nan(""); // CHECK: double 0x7FF8000000000000
+ ld = __builtin_nanl(""); // CHECK: x86_fp80 0xK7FFFC000000000000000
+ f = __builtin_nanf("0xAE98"); // CHECK: float 0x7FF815D300000000
+ d = __builtin_nan("0xAE98"); // CHECK: double 0x7FF800000000AE98
+ ld = __builtin_nanl("0xAE98"); // CHECK: x86_fp80 0xK7FFFC00000000000AE98
+ f = __builtin_nansf(""); // CHECK: float 0x7FF4000000000000
+ d = __builtin_nans(""); // CHECK: double 0x7FF4000000000000
+ ld = __builtin_nansl(""); // CHECK: x86_fp80 0xK7FFFA000000000000000
+ f = __builtin_nansf("0xAE98"); // CHECK: float 0x7FF015D300000000
+ d = __builtin_nans("0xAE98"); // CHECK: double 0x7FF000000000AE98
+ ld = __builtin_nansl("0xAE98");// CHECK: x86_fp80 0xK7FFF800000000000AE98
+
+}
+// CHECK: }
diff --git a/test/CodeGen/cast-emit.c b/test/CodeGen/cast-emit.c
new file mode 100644
index 000000000000..4e33fa32f788
--- /dev/null
+++ b/test/CodeGen/cast-emit.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+typedef union {
+ int i;
+ float f;
+} MyUnion;
+void unionf(MyUnion a);
+void uniontest(float a) {
+ f((MyUnion)1.0f);
+// CHECK: store float 1.000000e+00
+}
+
diff --git a/test/CodeGen/dllimport-dllexport.c b/test/CodeGen/dllimport-dllexport.c
index c7c2420ea77e..c187503c5cfa 100644
--- a/test/CodeGen/dllimport-dllexport.c
+++ b/test/CodeGen/dllimport-dllexport.c
@@ -1,7 +1,12 @@
-// RUN: %clang_cc1 -emit-llvm < %s -o %t
-// RUN: grep 'dllexport' %t | count 1
-// RUN: not grep 'dllimport' %t
+// RUN: %clang_cc1 -triple i386-mingw32 -emit-llvm < %s | FileCheck %s
void __attribute__((dllimport)) foo1();
void __attribute__((dllexport)) foo1(){}
+// CHECK: define dllexport void @foo1
void __attribute__((dllexport)) foo2();
+
+// PR6269
+__declspec(dllimport) void foo3();
+__declspec(dllexport) void foo3(){}
+// CHECK: define dllexport void @foo3
+__declspec(dllexport) void foo4();
diff --git a/test/CodeGen/extern-inline.c b/test/CodeGen/extern-inline.c
new file mode 100644
index 000000000000..5dd9bfda574c
--- /dev/null
+++ b/test/CodeGen/extern-inline.c
@@ -0,0 +1,25 @@
+// RUN: %clang -S -emit-llvm -std=gnu89 -o - %s | FileCheck %s
+// PR5253
+
+// If an extern inline function is redefined, functions should call the
+// redefinition.
+extern inline int f(int a) {return a;}
+int g(void) {return f(0);}
+// CHECK: call i32 @f
+int f(int b) {return 1+b;}
+// CHECK: load i32* %{{.*}}
+// CHECK: add nsw i32 1, %{{.*}}
+int h(void) {return f(1);}
+// CHECK: call i32 @f
+
+// It shouldn't matter if the function was redefined static.
+extern inline int f2(int a, int b) {return a+b;}
+int g2(void) {return f2(0,1);}
+// CHECK: call i32 @f2
+static int f2(int a, int b) {return a*b;}
+// CHECK: load i32* %{{.*}}
+// CHECK: load i32* %{{.*}}
+// CHECK: mul i32 %{{.*}}, %{{.*}}
+int h2(void) {return f2(1,2);}
+// CHECK: call i32 @f2
+
diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c
index cb9a4ef81f13..5629ef582a60 100644
--- a/test/CodeGen/functions.c
+++ b/test/CodeGen/functions.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o %t
+// RUN: %clang_cc1 %s -emit-llvm -o - -verify | FileCheck %s
int g();
@@ -19,22 +19,31 @@ void test3(T f) {
int a(int);
int a() {return 1;}
-// RUN: grep 'define void @f0()' %t
void f0() {}
+// CHECK: define void @f0()
void f1();
-// RUN: grep 'call void @f1()' %t
void f2(void) {
+// CHECK: call void @f1()
f1(1, 2, 3);
}
-// RUN: grep 'define void @f1()' %t
+// CHECK: define void @f1()
void f1() {}
-// RUN: grep 'define .* @f3' %t | not grep -F '...'
+// CHECK: define {{.*}} @f3{{\(\)|\(.*sret.*\)}}
struct foo { int X, Y, Z; } f3() {
while (1) {}
}
// PR4423 - This shouldn't crash in codegen
void f4() {}
-void f5() { f4(42); }
+void f5() { f4(42); } //expected-warning {{too many arguments}}
+
+// Qualifiers on parameter types shouldn't make a difference.
+static void f6(const float f, const float g) {
+}
+void f7(float f, float g) {
+ f6(f, g);
+// CHECK: define void @f7(float{{.*}}, float{{.*}})
+// CHECK: call void @f6(float{{.*}}, float{{.*}})
+}