diff options
author | ed <ed@FreeBSD.org> | 2009-06-02 17:58:47 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-06-02 17:58:47 +0000 |
commit | f27e5a09a0d815b8a4814152954ff87dadfdefc0 (patch) | |
tree | ce7d964cbb5e39695b71481698f10cb099c23d4a /test/CodeGen | |
download | FreeBSD-src-f27e5a09a0d815b8a4814152954ff87dadfdefc0.zip FreeBSD-src-f27e5a09a0d815b8a4814152954ff87dadfdefc0.tar.gz |
Import Clang, at r72732.
Diffstat (limited to 'test/CodeGen')
190 files changed, 5206 insertions, 0 deletions
diff --git a/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c b/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c new file mode 100644 index 0000000..3b15824 --- /dev/null +++ b/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +int array[] = {1, 2, 3, 4, 5}; + diff --git a/test/CodeGen/2008-02-07-bitfield-bug.c b/test/CodeGen/2008-02-07-bitfield-bug.c new file mode 100644 index 0000000..dc2ebb7 --- /dev/null +++ b/test/CodeGen/2008-02-07-bitfield-bug.c @@ -0,0 +1,11 @@ +// RUN: clang-cc %s -emit-llvm -o %t +// PR1990 + +struct test { + char a[3]; + unsigned char b:1; +}; + +void f(struct test *t) { + t->b = 1; +} diff --git a/test/CodeGen/2008-02-08-bitfield-bug.c b/test/CodeGen/2008-02-08-bitfield-bug.c new file mode 100644 index 0000000..fc69e58 --- /dev/null +++ b/test/CodeGen/2008-02-08-bitfield-bug.c @@ -0,0 +1,9 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +struct test { + unsigned a:1; + unsigned b:1; +}; + +struct test *t; + diff --git a/test/CodeGen/2008-02-26-inline-asm-bug.c b/test/CodeGen/2008-02-26-inline-asm-bug.c new file mode 100644 index 0000000..a6816f5 --- /dev/null +++ b/test/CodeGen/2008-02-26-inline-asm-bug.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -emit-llvm < %s | grep "\$0,\$1" + +void f() { + int d1, d2; + asm("%0,%1": "=r" (d1) : "r" (d2)); +} diff --git a/test/CodeGen/2008-07-17-no-emit-on-error.c b/test/CodeGen/2008-07-17-no-emit-on-error.c new file mode 100644 index 0000000..89aeb18 --- /dev/null +++ b/test/CodeGen/2008-07-17-no-emit-on-error.c @@ -0,0 +1,10 @@ +// RUN: rm -f %t1.bc +// RUN: not clang-cc %s -emit-llvm-bc -o %t1.bc +// RUN: not test -f %t1.bc + +void f() { +} + +void g() { + *10; +} diff --git a/test/CodeGen/2008-07-21-mixed-var-fn-decl.c b/test/CodeGen/2008-07-21-mixed-var-fn-decl.c new file mode 100644 index 0000000..c55c86b --- /dev/null +++ b/test/CodeGen/2008-07-21-mixed-var-fn-decl.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -emit-llvm -o - %s | grep -e "@g[0-9] " | count 2 + +int g0, f0(); +int f1(), g1; + diff --git a/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c b/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c new file mode 100644 index 0000000..19bf9a2 --- /dev/null +++ b/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c @@ -0,0 +1,11 @@ +// RUN: clang-cc --emit-llvm -o %t %s && +// RUN: grep "i8 52" %t | count 1 + +struct et7 { + float lv7[0]; + char mv7:6; +} yv7 = { + {}, + 52, +}; + diff --git a/test/CodeGen/2008-07-22-packed-bitfield-access.c b/test/CodeGen/2008-07-22-packed-bitfield-access.c new file mode 100644 index 0000000..437a4be --- /dev/null +++ b/test/CodeGen/2008-07-22-packed-bitfield-access.c @@ -0,0 +1,10 @@ +// RUN: clang-cc %s -emit-llvm -o - + +int main () { + struct foo { + unsigned a:16; + unsigned b:32 __attribute__ ((packed)); + } x; + x.b = 0x56789abcL; + return 0; +} diff --git a/test/CodeGen/2008-07-29-override-alias-decl.c b/test/CodeGen/2008-07-29-override-alias-decl.c new file mode 100644 index 0000000..43f4e3e --- /dev/null +++ b/test/CodeGen/2008-07-29-override-alias-decl.c @@ -0,0 +1,12 @@ +// RUN: clang-cc -emit-llvm -o - %s | grep -e "^@f" | count 1 + +int x() {} + +int f() __attribute__((weak, alias("x"))); + +/* Test that we link to the alias correctly instead of making a new + forward definition. */ +int f(); +int h() { + return f(); +} diff --git a/test/CodeGen/2008-07-30-implicit-initialization.c b/test/CodeGen/2008-07-30-implicit-initialization.c new file mode 100644 index 0000000..2f4c14e --- /dev/null +++ b/test/CodeGen/2008-07-30-implicit-initialization.c @@ -0,0 +1,28 @@ +// RUN: clang-cc -triple i386-unknown-unknown --emit-llvm-bc -o - %s | opt --std-compile-opts | llvm-dis > %t && +// RUN: grep "ret i32" %t | count 2 && +// RUN: grep "ret i32 0" %t | count 2 +// <rdar://problem/6113085> + +struct s0 { + int x, y; +}; + +int f0() { + struct s0 x = {0}; + return x.y; +} + +#if 0 +/* Optimizer isn't smart enough to reduce this since we use + memset. Hrm. */ +int f1() { + struct s0 x[2] = { {0} }; + return x[1].x; +} +#endif + +int f2() { + int x[2] = { 0 }; + return x[1]; +} + diff --git a/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c b/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c new file mode 100644 index 0000000..c374f8d --- /dev/null +++ b/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c @@ -0,0 +1,28 @@ +// RUN: clang-cc --emit-llvm -o - %s +// <rdar://problem/6108358> + +/* For posterity, the issue here begins initial "char []" decl for + * s. This is a tentative definition and so a global was being + * emitted, however the mapping in GlobalDeclMap referred to a bitcast + * of this global. + * + * The problem was that later when the correct definition for s is + * emitted we were doing a RAUW on the old global which was destroying + * the bitcast in the GlobalDeclMap (since it cannot be replaced + * properly), leaving a dangling pointer. + * + * The purpose of bar is just to trigger a use of the old decl + * sometime after the dangling pointer has been introduced. + */ + +char s[]; + +static void bar(void *db) { + eek(s); +} + +char s[5] = "hi"; + +int foo() { + bar(0); +} diff --git a/test/CodeGen/2008-07-31-asm-labels.c b/test/CodeGen/2008-07-31-asm-labels.c new file mode 100644 index 0000000..f114f65 --- /dev/null +++ b/test/CodeGen/2008-07-31-asm-labels.c @@ -0,0 +1,33 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: grep "@pipe()" %t | count 0 && +// RUN: grep '_thisIsNotAPipe' %t | count 3 && +// RUN: grep 'g0' %t | count 0 && +// RUN: grep '_renamed' %t | count 2 && +// RUN: clang-cc -DUSE_DEF -emit-llvm -o %t %s && +// RUN: grep "@pipe()" %t | count 0 && +// RUN: grep '_thisIsNotAPipe' %t | count 3 +// <rdr://6116729> + +void pipe() asm("_thisIsNotAPipe"); + +void f0() { + pipe(); +} + +void pipe(int); + +void f1() { + pipe(1); +} + +#ifdef USE_DEF +void pipe(int arg) { + int x = 10; +} +#endif + +// PR3698 +extern int g0 asm("_renamed"); +int f2() { + return g0; +} diff --git a/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c b/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c new file mode 100644 index 0000000..0ce4ba6 --- /dev/null +++ b/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c @@ -0,0 +1,25 @@ +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis | grep "ret i32 1" | count 3 +// <rdr://6115726> + +int f0() { + int x; + unsigned short n = 1; + int *a = &x; + int *b = &x; + a = a - n; + b -= n; + return a == b; +} + +int f1(int *a) { + long b = a - (int*) 1; + a -= (int*) 1; + return b == (long) a; +} + +int f2(long n) { + int *b = n + (int*) 1; + n += (int*) 1; + return b == (int*) n; +} + diff --git a/test/CodeGen/2008-08-04-void-pointer-arithmetic.c b/test/CodeGen/2008-08-04-void-pointer-arithmetic.c new file mode 100644 index 0000000..22815f3 --- /dev/null +++ b/test/CodeGen/2008-08-04-void-pointer-arithmetic.c @@ -0,0 +1,6 @@ +// RUN: clang-cc --emit-llvm -o - %s +// <rdar://problem/6122967> + +int f0(void *a, void *b) { + return a - b; +} diff --git a/test/CodeGen/2008-08-19-cast-of-typedef.c b/test/CodeGen/2008-08-19-cast-of-typedef.c new file mode 100644 index 0000000..3db5e90 --- /dev/null +++ b/test/CodeGen/2008-08-19-cast-of-typedef.c @@ -0,0 +1,10 @@ +// RUN: clang-cc --emit-llvm -o %t %s + +typedef short T[4]; +struct s { + T f0; +}; + +void foo(struct s *x) { + bar((long) x->f0); +} diff --git a/test/CodeGen/2008-08-25-incompatible-cond-expr.m b/test/CodeGen/2008-08-25-incompatible-cond-expr.m new file mode 100644 index 0000000..3cc42d8 --- /dev/null +++ b/test/CodeGen/2008-08-25-incompatible-cond-expr.m @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm -o %t %s + +@protocol P0 +@end +@interface A <P0> +@end + +id f0(int a, id<P0> x, A* p) { + return a ? x : p; +} diff --git a/test/CodeGen/2008-09-22-bad-switch-type.c b/test/CodeGen/2008-09-22-bad-switch-type.c new file mode 100644 index 0000000..2526dd9 --- /dev/null +++ b/test/CodeGen/2008-09-22-bad-switch-type.c @@ -0,0 +1,34 @@ +// RUN: clang-cc -emit-llvm -o %t %s +// PR2817 + +void f0(void) { + switch (0) { + case (unsigned long long) 0 < 0: + break; + } + + switch (0) { + case (unsigned long long) 0 > 0: + break; + } + + switch (0) { + case (unsigned long long) 0 <= 0: + break; + } + + switch (0) { + case (unsigned long long) 0 >= 0: + break; + } + + switch (0) { + case (unsigned long long) 0 == 0: + break; + } + + switch (0) { + case (unsigned long long) 0 != 0: + break; + } +} diff --git a/test/CodeGen/2008-12-02-logical-or-fold.c b/test/CodeGen/2008-12-02-logical-or-fold.c new file mode 100644 index 0000000..d54bf28 --- /dev/null +++ b/test/CodeGen/2008-12-02-logical-or-fold.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm -o - %s | grep "store i32 1" +// PR3150 + +int a() {return 1||1;} diff --git a/test/CodeGen/2009-01-21-invalid-debug-info.m b/test/CodeGen/2009-01-21-invalid-debug-info.m new file mode 100644 index 0000000..9a955a1 --- /dev/null +++ b/test/CodeGen/2009-01-21-invalid-debug-info.m @@ -0,0 +1,16 @@ +// RUN: clang-cc -S -g -o %t.s %s + +// FIXME: This test case can be removed at some point (since it will +// no longer effectively test anything). The reason it was causing +// trouble was the synthesized self decl in im1 was causing the debug +// info for I1* to be generated, but referring to an invalid compile +// unit. This was later referred to by f1 and created ill formed debug +// information. + +@interface I1 @end + +@implementation I1 +-im0 {} +@end + +I1 *f1(void) { return 0; } diff --git a/test/CodeGen/2009-03-22-increment-bitfield.c b/test/CodeGen/2009-03-22-increment-bitfield.c new file mode 100644 index 0000000..f0aaafd --- /dev/null +++ b/test/CodeGen/2009-03-22-increment-bitfield.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm -O1 < %s | grep "ret i32 0" + +int a(void) { + return ++(struct x {unsigned x : 2;}){3}.x; +} + + diff --git a/test/CodeGen/2009-04-23-dbg.c b/test/CodeGen/2009-04-23-dbg.c new file mode 100644 index 0000000..4be6dab --- /dev/null +++ b/test/CodeGen/2009-04-23-dbg.c @@ -0,0 +1,20 @@ +// RUN: clang-cc -g -o %t %s -emit-llvm-bc && llc %t -f -o %t.s +# 1 "a.c" +# 1 "a.c" 1 +# 1 "<built-in>" 1 +# 103 "<built-in>" +# 103 "<command line>" 1 + +# 1 "/private/tmp/a.h" 1 +int bar; +# 105 "<command line>" 2 +# 105 "<built-in>" 2 +# 1 "a.c" 2 +# 1 "/private/tmp/a.h" 1 +int bar; +# 2 "a.c" 2 + +int main() { + bar = 0; + return 0; +} diff --git a/test/CodeGen/2009-05-22-callingconv.c b/test/CodeGen/2009-05-22-callingconv.c new file mode 100644 index 0000000..2b70d84 --- /dev/null +++ b/test/CodeGen/2009-05-22-callingconv.c @@ -0,0 +1,25 @@ +// RUN: clang-cc %s -emit-llvm -o - | grep call | grep x86_stdcallcc +void abort(void) __attribute__((__noreturn__)); +typedef void re_string_t; +typedef void re_dfa_t; +typedef int reg_errcode_t; +static reg_errcode_t re_string_construct (re_string_t *pstr, const char *str, + int len, char * trans, + int icase, const re_dfa_t *dfa) + __attribute__ ((regparm (3), stdcall)); +static reg_errcode_t +re_string_construct (pstr, str, len, trans, icase, dfa) + re_string_t *pstr; + const char *str; + int len, icase; + char * trans; + const re_dfa_t *dfa; +{ + if (dfa != (void*)0x282020c0) + abort(); +return 0; +} +int main() +{ + return re_string_construct(0, 0, 0, 0, 0, (void*)0x282020c0); +} diff --git a/test/CodeGen/2009-05-28-const-typedef.c b/test/CodeGen/2009-05-28-const-typedef.c new file mode 100644 index 0000000..e46e83b --- /dev/null +++ b/test/CodeGen/2009-05-28-const-typedef.c @@ -0,0 +1,17 @@ +// RUN: clang-cc -emit-llvm %s -o - +// PR4281 + +typedef struct { + int i; +} something; + +typedef const something const_something; + +something fail(void); + +int +main(int argc, char *argv[]) +{ + const_something R = fail(); +} + diff --git a/test/CodeGen/2009-06-01-addrofknr.c b/test/CodeGen/2009-06-01-addrofknr.c new file mode 100644 index 0000000..16a5bbf --- /dev/null +++ b/test/CodeGen/2009-06-01-addrofknr.c @@ -0,0 +1,21 @@ +// RUN: clang-cc %s -o %t -emit-llvm -verify +// PR4289 + +struct funcptr { + int (*func)(); +}; + +static int func(f) + void *f; +{ +} + +int +main(int argc, char *argv[]) +{ + struct funcptr fp; + + fp.func = &func; + fp.func = func; +} + diff --git a/test/CodeGen/OpaqueStruct.c b/test/CodeGen/OpaqueStruct.c new file mode 100644 index 0000000..b994c30 --- /dev/null +++ b/test/CodeGen/OpaqueStruct.c @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -emit-llvm -o %t +typedef struct a b; + +b* x; + +struct a { + b* p; +}; + +void f() { + b* z = x->p; +} diff --git a/test/CodeGen/PR2001-bitfield-reload.c b/test/CodeGen/PR2001-bitfield-reload.c new file mode 100644 index 0000000..797b494 --- /dev/null +++ b/test/CodeGen/PR2001-bitfield-reload.c @@ -0,0 +1,17 @@ +// RUN: clang-cc -triple i386-unknown-unknown --emit-llvm-bc -o - %s | opt --std-compile-opts | llvm-dis > %t && +// RUN: grep "ret i32" %t | count 1 && +// RUN: grep "ret i32 1" %t | count 1 +// PR2001 + +/* Test that the result of the assignment properly uses the value *in + the bitfield* as opposed to the RHS. */ +static int foo(int i) { + struct { + int f0 : 2; + } x; + return (x.f0 = i); +} + +int bar() { + return foo(-5) == -1; +} diff --git a/test/CodeGen/PR2413-void-address-cast-error.c b/test/CodeGen/PR2413-void-address-cast-error.c new file mode 100644 index 0000000..95a4c6d --- /dev/null +++ b/test/CodeGen/PR2413-void-address-cast-error.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -emit-llvm %s -o - +void f() +{ + void *addr; + addr = (void *)( ((long int)addr + 7L) ); +} diff --git a/test/CodeGen/PR2643-null-store-to-bitfield.c b/test/CodeGen/PR2643-null-store-to-bitfield.c new file mode 100644 index 0000000..6a5b0e9 --- /dev/null +++ b/test/CodeGen/PR2643-null-store-to-bitfield.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm -o - %s +// PR2643 + +void foo() { + struct { + int a : 1; + int b : 1; + } entry = {0}; +} + diff --git a/test/CodeGen/PR2743-reference-missing-static.c b/test/CodeGen/PR2743-reference-missing-static.c new file mode 100644 index 0000000..e152c52 --- /dev/null +++ b/test/CodeGen/PR2743-reference-missing-static.c @@ -0,0 +1,16 @@ +// RUN: clang-cc -emit-llvm -o %t %s +// PR2743 +// <rdr://6094512> + +/* CodeGen should handle this even if it makes it past + sema. Unfortunately this test will become useless once sema starts + rejecting this. */ + +static void e0(); +void f0() { e0(); } + +inline void e1(); +void f1() { e1(); } + +void e2() __attribute__((weak)); +void f2() { e2(); } diff --git a/test/CodeGen/PR3130-cond-constant.c b/test/CodeGen/PR3130-cond-constant.c new file mode 100644 index 0000000..e488eeb --- /dev/null +++ b/test/CodeGen/PR3130-cond-constant.c @@ -0,0 +1,3 @@ +// RUN: clang-cc -emit-llvm %s -o - + +int a = 2.0 ? 1 : 2; diff --git a/test/CodeGen/PR3589-freestanding-libcalls.c b/test/CodeGen/PR3589-freestanding-libcalls.c new file mode 100644 index 0000000..90b5fff --- /dev/null +++ b/test/CodeGen/PR3589-freestanding-libcalls.c @@ -0,0 +1,9 @@ +// RUN: clang-cc -emit-llvm %s -o - | grep 'declare i32 @printf' | count 1 && +// RUN: clang-cc -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 1 && +// RUN: clang-cc -ffreestanding -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 0 + +#include <stdio.h> + +void f0() { + printf("hello\n"); +} diff --git a/test/CodeGen/PR3613-static-decl.c b/test/CodeGen/PR3613-static-decl.c new file mode 100644 index 0000000..365b9b2 --- /dev/null +++ b/test/CodeGen/PR3613-static-decl.c @@ -0,0 +1,16 @@ +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm -o %t %s && +// RUN: grep '@g0 = internal global .struct.s0 <{ i32 3 }>' %t | count 1 + +struct s0 { + int a; +}; + +static struct s0 g0; + +static int f0(void) { + return g0.a; +} + +static struct s0 g0 = {3}; + +void *g1 = f0; diff --git a/test/CodeGen/PR3709-int-to-pointer-sign.c b/test/CodeGen/PR3709-int-to-pointer-sign.c new file mode 100644 index 0000000..24c42f6 --- /dev/null +++ b/test/CodeGen/PR3709-int-to-pointer-sign.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -emit-llvm %s -o - -O1 -triple=x86_64-gnu-linux | grep "i64 -1" + +// PR3709 +long long a() { return (long long)(int*)-1;} + diff --git a/test/CodeGen/PR3869-indirect-goto-long.c b/test/CodeGen/PR3869-indirect-goto-long.c new file mode 100644 index 0000000..140e4ec --- /dev/null +++ b/test/CodeGen/PR3869-indirect-goto-long.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm-bc -o - %s +// PR3869 +int a(long long b) { goto *b; } + diff --git a/test/CodeGen/address-space-cast.c b/test/CodeGen/address-space-cast.c new file mode 100644 index 0000000..2fba5ec --- /dev/null +++ b/test/CodeGen/address-space-cast.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm < %s + +volatile unsigned char* const __attribute__((address_space(1))) serial_ctrl = 0x02; + diff --git a/test/CodeGen/address-space.c b/test/CodeGen/address-space.c new file mode 100644 index 0000000..3b6a8e6 --- /dev/null +++ b/test/CodeGen/address-space.c @@ -0,0 +1,20 @@ +// RUN: clang-cc -emit-llvm < %s | grep '@foo.*global.*addrspace(1)' && +// RUN: clang-cc -emit-llvm < %s | grep '@ban.*global.*addrspace(1)' && +// RUN: clang-cc -emit-llvm < %s | grep 'load.*addrspace(1)' | count 2 && +// RUN: clang-cc -emit-llvm < %s | grep 'load.*addrspace(2).. @A' && +// RUN: clang-cc -emit-llvm < %s | grep 'load.*addrspace(2).. @B' + +int foo __attribute__((address_space(1))); +int ban[10] __attribute__((address_space(1))); + +int bar() { return foo; } + +int baz(int i) { return ban[i]; } + +// Both A and B point into addrspace(2). +__attribute__((address_space(2))) int *A, *B; + +void test3() { + *A = *B; +} + diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c new file mode 100644 index 0000000..b0c71fb --- /dev/null +++ b/test/CodeGen/alias.c @@ -0,0 +1,32 @@ +// RUN: clang-cc -triple i386-pc-linux-gnu -emit-llvm -o %t %s && +// RUN: grep '@g0 = common global i32 0' %t && +// RUN: grep '@f1 = alias void ()\* @f0' %t && +// RUN: grep '@g1 = alias i32\* @g0' %t && +// RUN: grep 'define void @f0() nounwind {' %t && + +void f0(void) { } +extern void f1(void); +extern void f1(void) __attribute((alias("f0"))); + +int g0; +extern int g1; +extern int g1 __attribute((alias("g0"))); + +// Make sure that aliases cause referenced values to be emitted. +// PR3200 +// RUN: grep 'define internal i32 @foo1()' %t && +static inline int foo1() { return 0; } +int foo() __attribute__((alias("foo1"))); + + +// RUN: grep '@bar1 = internal global i32 42' %t +static int bar1 = 42; +int bar() __attribute__((alias("bar1"))); + + +extern int test6(); +void test7() { test6(); } // test6 is emitted as extern. + +// test6 changes to alias. +int test6() __attribute__((alias("test7"))); + diff --git a/test/CodeGen/align-local.c b/test/CodeGen/align-local.c new file mode 100644 index 0000000..afbe1d5 --- /dev/null +++ b/test/CodeGen/align-local.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -emit-llvm < %s | grep "align 16" | count 2 + +typedef struct __attribute((aligned(16))) {int x[4];} ff; + +int a() { + ff a; + struct {int x[4];} b __attribute((aligned(16))); +} diff --git a/test/CodeGen/alignof.c b/test/CodeGen/alignof.c new file mode 100644 index 0000000..d39f4e4 --- /dev/null +++ b/test/CodeGen/alignof.c @@ -0,0 +1,12 @@ +// RUN: clang-cc -triple i386-unknown-unknown -O1 -emit-llvm -o %t %s && +// RUN: grep 'ret i32 4' %t + +enum e0 { E0 }; +struct s0 { + enum e0 a:31; +}; + +struct s0 t1_tmp; +int f0() { + return __alignof__(t1_tmp); +} diff --git a/test/CodeGen/array.c b/test/CodeGen/array.c new file mode 100644 index 0000000..5bcc26e --- /dev/null +++ b/test/CodeGen/array.c @@ -0,0 +1,14 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +int f() { + int a[2]; + a[0] = 0; +} + +int f2() { + int x = 0; + int y = 1; + int a[10] = { y, x, 2, 3}; + int b[10] = { 2,4,x,6,y,8}; + int c[5] = { 0,1,2,3}; +} diff --git a/test/CodeGen/asm-2.c b/test/CodeGen/asm-2.c new file mode 100644 index 0000000..f5b378e --- /dev/null +++ b/test/CodeGen/asm-2.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm %s -o %t -triple i386-pc-linux-gnu -O2 && +// RUN: not grep "load" %t + +// <rdar://problem/6841383> +int cpuid(unsigned data) { + int a, b; + + asm("xyz" :"=a"(a), "=d"(b) : "a"(data)); + return a + b; +} diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c new file mode 100644 index 0000000..58373fc --- /dev/null +++ b/test/CodeGen/asm.c @@ -0,0 +1,103 @@ +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm %s -o %t && +void t1(int len) { + __asm__ volatile("" : "=&r"(len), "+&r"(len)); +} + +void t2(unsigned long long t) { + __asm__ volatile("" : "+m"(t)); +} + +void t3(unsigned char *src, unsigned long long temp) { + __asm__ volatile("" : "+m"(temp), "+r"(src)); +} + +void t4() { + unsigned long long a; + struct reg { unsigned long long a, b; } b; + + __asm__ volatile ("":: "m"(a), "m"(b)); +} + +// PR3417 +void t5(int i) { + asm("nop" : "=r"(i) : "0"(t5)); +} + +// PR3641 +void t6(void) { + __asm__ volatile("" : : "i" (t6)); +} + +// RUN: grep "T7 NAMED: \$1" %t && +void t7(int a) { + __asm__ volatile("T7 NAMED: %[input]" : "+r"(a): [input] "i" (4)); +} + +// RUN: grep "T8 NAMED MODIFIER: \${0:c}" %t +void t8() { + __asm__ volatile("T8 NAMED MODIFIER: %c[input]" :: [input] "i" (4)); +} + +// PR3682 +unsigned t9(unsigned int a) { + asm("bswap %0 %1" : "+r" (a)); + return a; +} + +// PR3908 +// RUN: grep "PR3908 \$1 \$3 \$2 \$0" %t +void t10(int r) { + __asm__("PR3908 %[lf] %[xx] %[li] %[r]" : [r] "+r" (r) : [lf] "mx" (0), [li] "mr" (0), [xx] "x" ((double)(0))); +} + + +// PR3373 +unsigned t11(signed char input) { + unsigned output; + __asm__("xyz" + : "=a" (output) + : "0" (input)); + return output; +} + +// PR3373 +unsigned char t12(unsigned input) { + unsigned char output; + __asm__("xyz" + : "=a" (output) + : "0" (input)); + return output; +} + +unsigned char t13(unsigned input) { + unsigned char output; + __asm__("xyz %1" + : "=a" (output) + : "0" (input)); + return output; +} + +struct large { + int x[1000]; +}; + +unsigned long t15(int x, struct large *P) { + __asm__("xyz " + : "=r" (x) + : "m" (*P), "0" (x)); + return x; +} + + + + +// bitfield destination of an asm. +struct S { + int a : 4; +}; + +void t14(struct S *P) { + __asm__("abc %0" : "=r"(P->a) ); +} + + diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c new file mode 100644 index 0000000..66dc702 --- /dev/null +++ b/test/CodeGen/atomic.c @@ -0,0 +1,53 @@ +// RUN: clang-cc %s -emit-llvm -o - -triple=i686-apple-darwin9 > %t1 && +// RUN: grep @llvm.atomic.load.add.i32 %t1 | count 3 && +// RUN: grep @llvm.atomic.load.sub.i8 %t1 | count 2 && +// RUN: grep @llvm.atomic.load.min.i32 %t1 && +// RUN: grep @llvm.atomic.load.max.i32 %t1 && +// RUN: grep @llvm.atomic.load.umin.i32 %t1 && +// RUN: grep @llvm.atomic.load.umax.i32 %t1 && +// RUN: grep @llvm.atomic.swap.i32 %t1 && +// RUN: grep @llvm.atomic.cmp.swap.i32 %t1 | count 4 && +// RUN: grep @llvm.atomic.load.and.i32 %t1 | count 2 && +// RUN: grep @llvm.atomic.load.or.i8 %t1 && +// RUN: grep @llvm.atomic.load.xor.i8 %t1 + + +int atomic(void) +{ + // non-sensical test for sync functions + int old; + int val = 1; + char valc = 1; + unsigned int uval = 1; + int cmp = 0; + + old = __sync_fetch_and_add(&val, 1); + old = __sync_fetch_and_sub(&valc, 2); + old = __sync_fetch_and_min(&val, 3); + old = __sync_fetch_and_max(&val, 4); + old = __sync_fetch_and_umin(&uval, 5u); + old = __sync_fetch_and_umax(&uval, 6u); + old = __sync_lock_test_and_set(&val, 7); + old = __sync_val_compare_and_swap(&val, 4, 1976); + old = __sync_bool_compare_and_swap(&val, 4, 1976); + old = __sync_fetch_and_and(&val, 0x9); + old = __sync_fetch_and_or(&val, 0xa); + old = __sync_fetch_and_xor(&val, 0xb); + old = __sync_fetch_and_nand(&val, 0xb); + + old = __sync_add_and_fetch(&val, 1); + old = __sync_sub_and_fetch(&val, 2); + old = __sync_and_and_fetch(&valc, 3); + old = __sync_or_and_fetch(&valc, 4); + old = __sync_xor_and_fetch(&valc, 5); + old = __sync_nand_and_fetch(&valc, 5); + + + __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0); + + + __sync_lock_release(&val); + __sync_synchronize (); + + return old; +} diff --git a/test/CodeGen/attr-cleanup.c b/test/CodeGen/attr-cleanup.c new file mode 100644 index 0000000..03dde33 --- /dev/null +++ b/test/CodeGen/attr-cleanup.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +// <rdar://problem/6827047> +void f(void* arg); +void g() { + __attribute__((cleanup(f))) void *g; +} + diff --git a/test/CodeGen/attr-nodebug.c b/test/CodeGen/attr-nodebug.c new file mode 100644 index 0000000..b96ad26 --- /dev/null +++ b/test/CodeGen/attr-nodebug.c @@ -0,0 +1,12 @@ +// RUN: clang-cc -g -emit-llvm -o %t %s && +// RUN: not grep 'call void @llvm.dbg.func.start' %t + +void t1() __attribute__((nodebug)); + +void t1() +{ + int a = 10; + + a++; +} + diff --git a/test/CodeGen/attr-noinline.c b/test/CodeGen/attr-noinline.c new file mode 100644 index 0000000..199c291 --- /dev/null +++ b/test/CodeGen/attr-noinline.c @@ -0,0 +1,9 @@ +// RUN: clang-cc -g -emit-llvm -o %t %s && +// RUN: grep 'noinline' %t + +void t1() __attribute__((noinline)); + +void t1() +{ +} + diff --git a/test/CodeGen/attr-used.c b/test/CodeGen/attr-used.c new file mode 100644 index 0000000..8521ffd --- /dev/null +++ b/test/CodeGen/attr-used.c @@ -0,0 +1,14 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: grep '@llvm.used = .*@g0' %t && +// RUN: grep '@llvm.used = .*@f0' %t && +// RUN: grep '@llvm.used = .*@f1.l0' %t + + +int g0 __attribute__((used)); + +static void __attribute__((used)) f0(void) { +} + +void f1() { + static int l0 __attribute__((used)) = 5225; +} diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c new file mode 100644 index 0000000..d45d512 --- /dev/null +++ b/test/CodeGen/attributes.c @@ -0,0 +1,59 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: grep 't1.*noreturn' %t && +// RUN: grep 't2.*nounwind' %t && +// RUN: grep 'weak.*t3' %t && +// RUN: grep 'hidden.*t4' %t && +// RUN: grep 't5.*weak' %t && +// RUN: grep 't6.*protected' %t && +// RUN: grep 't7.*noreturn' %t && +// RUN: grep 't7.*nounwind' %t && +// RUN: grep 't9.*alias.*weak.*t8' %t && +// RUN: grep '@t10().*section "SECT"' %t && +// RUN: grep '@t11().*section "SECT"' %t && +// RUN: grep '@t12 =.*section "SECT"' %t && +// RUN: grep '@t13 =.*section "SECT"' %t && +// RUN: grep '@t14.x =.*section "SECT"' %t +// RUN: grep 'declare extern_weak i32 @t15()' %t && +// RUN: grep '@t16 = extern_weak global i32' %t + +void t1() __attribute__((noreturn)); +void t1() {} + +void t2() __attribute__((nothrow)); +void t2() {} + +void t3() __attribute__((weak)); +void t3() {} + +void t4() __attribute__((visibility("hidden"))); +void t4() {} + +int t5 __attribute__((weak)) = 2; + +int t6 __attribute__((visibility("protected"))); + +void t7() __attribute__((noreturn, nothrow)); +void t7() {} + +void __t8() {} +void t9() __attribute__((weak, alias("__t8"))); + +void t10(void) __attribute__((section("SECT"))); +void t10(void) {} +void __attribute__((section("SECT"))) t11(void) {} + +int t12 __attribute__((section("SECT"))); +struct s0 { int x; }; +struct s0 t13 __attribute__((section("SECT"))) = { 0 }; + +void t14(void) { + static int x __attribute__((section("SECT"))) = 0; +} + +int __attribute__((weak_import)) t15(void); +extern int t16 __attribute__((weak_import)); +int t17() { + return t15() + t16; +} + + diff --git a/test/CodeGen/bitfield-assign.c b/test/CodeGen/bitfield-assign.c new file mode 100644 index 0000000..05d4dda --- /dev/null +++ b/test/CodeGen/bitfield-assign.c @@ -0,0 +1,44 @@ +/* Check that the result of a bitfield assignment is properly + truncated and does not generate a redundant load. */ + +/* Check that we get one load for each simple assign and two for the + compound assign (load the old value before the add then load again + to store back). Also check that our g0 pattern is good. */ +// RUN: clang-cc -triple i386-unknown-unknown -O0 -emit-llvm -o %t %s && +// RUN: grep 'load ' %t | count 5 && +// RUN: grep "@g0" %t | count 4 && + +// Check that we got the right value. +// RUN: clang-cc -triple i386-unknown-unknown -O3 -emit-llvm -o %t %s && +// RUN: grep 'load ' %t | count 0 && +// RUN: grep "@g0" %t | count 0 + +struct s0 { + int f0 : 2; + _Bool f1 : 1; + unsigned f2 : 2; +}; + +int g0(); + +void f0(void) { + struct s0 s; + if ((s.f0 = 3) != -1) g0(); +} + +void f1(void) { + struct s0 s; + if ((s.f1 = 3) != 1) g0(); +} + +void f2(void) { + struct s0 s; + if ((s.f2 = 3) != 3) g0(); +} + +void f3(void) { + struct s0 s; + // Just check this one for load counts. + s.f0 += 3; +} + diff --git a/test/CodeGen/bitfield-init.c b/test/CodeGen/bitfield-init.c new file mode 100644 index 0000000..7459614 --- /dev/null +++ b/test/CodeGen/bitfield-init.c @@ -0,0 +1,14 @@ +// RUN: clang-cc %s -emit-llvm -o %t +typedef struct { unsigned int i: 1; } c; +const c d = { 1 }; + +// PR2310 +struct Token { + unsigned n : 31; +}; +void sqlite3CodeSubselect(){ + struct Token one = { 1 }; +} + +typedef union T0 { char field0 : 2; } T0; +T0 T0_values = { 0 }; diff --git a/test/CodeGen/bitfield-promote.c b/test/CodeGen/bitfield-promote.c new file mode 100644 index 0000000..5894e51 --- /dev/null +++ b/test/CodeGen/bitfield-promote.c @@ -0,0 +1,19 @@ +// RUN: clang -O3 -emit-llvm -S -o %t %s && +// RUN: grep 'ret i64 4294967292' %t | count 2 && +// RUN: grep 'ret i64 -4' %t | count 1 && +// RUN: true + +long long f0(void) { + struct { unsigned f0 : 32; } x = { 18 }; + return (long long) (x.f0 - (int) 22); +} + +long long f1(void) { + struct { unsigned f0 : 31; } x = { 18 }; + return (long long) (x.f0 - (int) 22); +} + +long long f2(void) { + struct { unsigned f0 ; } x = { 18 }; + return (long long) (x.f0 - (int) 22); +} diff --git a/test/CodeGen/bitfield.c b/test/CodeGen/bitfield.c new file mode 100644 index 0000000..02f2de7 --- /dev/null +++ b/test/CodeGen/bitfield.c @@ -0,0 +1,74 @@ +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o %t -O3 && +// RUN: grep "ret i32" %t | count 4 && +// RUN: grep "ret i32 1" %t | count 4 + +static int f0(int n) { + struct s0 { + int a : 30; + int b : 2; + long long c : 31; + } x = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }; + + x.a += n; + x.b += n; + x.c += n; + + return x.a + x.b + x.c; +} + +int g0(void) { + return f0(-1) + 44335655; +} + +static int f1(void) { + struct s1 { + int a:13; + char b; + unsigned short c:7; + } x; + + x.a = -40; + x.b = 10; + x.c = 15; + + return x.a + x.b + x.c; +} + +int g1(void) { + return f1() + 16; +} + +static int f2(void) { + struct s2 { + short a[3]; + int b : 15; + } x; + + x.a[0] = x.a[1] = x.a[2] = -40; + x.b = 10; + + return x.b; +} + +int g2(void) { + return f2() - 9; +} + +static int f3(int n) { + struct s3 { + unsigned a:16; + unsigned b:28 __attribute__ ((packed)); + } x = { 0xdeadbeef, 0xdeadbeef }; + struct s4 { + signed a:16; + signed b:28 __attribute__ ((packed)); + } y; + y.a = -0x56789abcL; + y.b = -0x56789abcL; + return ((y.a += x.a += n) + + (y.b += x.b += n)); +} + +int g3(void) { + return f3(20) + 130725747; +} diff --git a/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c new file mode 100644 index 0000000..10498cb --- /dev/null +++ b/test/CodeGen/blocks-1.c @@ -0,0 +1,78 @@ +// RUN: clang-cc %s -emit-llvm -o %t -fblocks && +// RUN: grep "_Block_object_dispose" %t | count 17 && +// RUN: grep "__copy_helper_block_" %t | count 16 && +// RUN: grep "__destroy_helper_block_" %t | count 16 && +// RUN: grep "__Block_byref_id_object_copy_" %t | count 2 && +// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2 && +// RUN: grep "i32 135)" %t | count 2 && +// RUN: grep "_Block_object_assign" %t | count 10 + +#include <stdio.h> + +void test1() { + __block int a; + int b=2; + a=1; + printf("a is %d, b is %d\n", a, b); + ^{ a = 10; printf("a is %d, b is %d\n", a, b); }(); + printf("a is %d, b is %d\n", a, b); + a = 1; + printf("a is %d, b is %d\n", a, b); +} + +void test2() { + __block int a; + a=1; + printf("a is %d\n", a); + ^{ + ^{ + a = 10; + }(); + }(); + printf("a is %d\n", a); + a = 1; + printf("a is %d\n", a); +} + +void test3() { + __block int k; + __block int (^j)(int); + ^{j=0; k=0;}(); +} + +int test4() { + extern int g; + static int i = 1; + ^(int j){ i = j; g = 0; }(0); + return i + g; +} + +int g; + +void test5() { + __block struct { int i; } i; + ^{ (void)i; }(); +} + +void test6() { + __block int i; + ^{ i=1; }(); + ^{}(); +} + +void test7() { + ^{ + __block int i; + ^{ i = 1; }(); + }(); +} + +int main() { + int rv = 0; + test1(); + test2(); + test3(); + rv += test4(); + test5(); + return rv; +} diff --git a/test/CodeGen/blocks-2.c b/test/CodeGen/blocks-2.c new file mode 100644 index 0000000..5ee2a73 --- /dev/null +++ b/test/CodeGen/blocks-2.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -g %s -emit-llvm -o %t -fblocks +// RUN: grep "func.start" %t | count 4 +// 1 declaration, 1 bar, 1 test_block_dbg and 1 for the block. + +static __inline__ __attribute__((always_inline)) int bar(int va, int vb) { return (va == vb); } + +int test_block_dbg() { + extern int g; + static int i = 1; + ^(int j){ i = bar(3,4); }(0); + return i + g; +} + diff --git a/test/CodeGen/blocks-seq.c b/test/CodeGen/blocks-seq.c new file mode 100644 index 0000000..f637fbc --- /dev/null +++ b/test/CodeGen/blocks-seq.c @@ -0,0 +1,18 @@ +// RUN: clang-cc -fblocks -triple x86_64-apple-darwin10 -emit-llvm -o %t %s && +// RUN: grep '%call = call i32 (...)\* @rhs()' %t | count 1 && +// If this fails, see about sliding %4, %5, %6 and %7... +// RUN: grep '%forwarding1 = getelementptr %0\* %i, i32 0, i32 1' %t | count 1 && +// RUN: grep '%4 = bitcast i8\*\* %forwarding1 to %0\*\*' %t | count 1 && +// RUN: grep '%5 = load %0\*\* %4' %t | count 1 && +// RUN: grep '%call2 = call i32 (...)\* @rhs()' %t | count 1 && +// RUN: grep '%forwarding3 = getelementptr %0\* %i, i32 0, i32 1' %t | count 1 && +// RUN: grep '%6 = bitcast i8\*\* %forwarding3 to %0\*\*' %t | count 1 && +// RUN: grep '%7 = load %0\*\* %6' %t | count 1 + +int rhs(); + +void foo() { + __block int i; + i = rhs(); + i += rhs(); +} diff --git a/test/CodeGen/blocks.c b/test/CodeGen/blocks.c new file mode 100644 index 0000000..39c5b06 --- /dev/null +++ b/test/CodeGen/blocks.c @@ -0,0 +1,30 @@ +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o %t -fblocks && +void (^f)(void) = ^{}; + +// rdar://6768379 +int f0(int (^a0)()) { + return a0(1, 2, 3); +} + +// Verify that attributes on blocks are set correctly. +typedef struct s0 T; +struct s0 { + int a[64]; +}; + +// RUN: grep 'internal void @__f2_block_invoke_(.struct.s0\* noalias sret .*, .*, .* byval .*)' %t && +struct s0 f2(struct s0 a0) { + return ^(struct s0 a1){ return a1; }(a0); +} + +// This should not crash: rdar://6808051 +void *P = ^{ + void *Q = __func__; +}; + +void (^test1)(void) = ^(void) { + __block int i; + ^ { i = 1; }(); +}; + +// RUN: true diff --git a/test/CodeGen/bool-bitfield.c b/test/CodeGen/bool-bitfield.c new file mode 100644 index 0000000..50990a4 --- /dev/null +++ b/test/CodeGen/bool-bitfield.c @@ -0,0 +1,54 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +// From GCC PR19331 +struct SysParams +{ + unsigned short tag; + unsigned short version; + unsigned int seqnum; + int contrast; + int igain_1, igain_2; + int oattn_1, oattn_2; + int max_out_vltg_1, max_out_vltg_2; + int max_mains_current; + int meters_mode; + int input_select; + _Bool input_parallelch2:1; + _Bool cliplmt_ch1:1; + _Bool cliplmt_ch2:1; + _Bool gate_ch1:1; + _Bool gate_ch2:1; + _Bool mute_ch1:1; + _Bool mute_ch2:1; + _Bool brownout:1; + _Bool power_on:1; + _Bool pwrup_mute:1; + _Bool keylock:1; + _Bool dsp_ch1:1; + _Bool dsp_ch2:1; + int dsp_preset; + long unlock_code; +}; +extern struct SysParams params; + +void foo(void *); +void kcmd_setParams(void) +{ + struct { + unsigned char igain_1; + unsigned char igain_2; + unsigned char max_out_vltg_1; + unsigned char max_out_vltg_2; + unsigned char max_imains; + unsigned char cliplmt_ch1:1; + unsigned char cliplmt_ch2:1; + unsigned char gate_ch1:1; + unsigned char gate_ch2:1; + } msg; + foo(&msg); + params.cliplmt_ch1 = msg.cliplmt_ch1; + params.cliplmt_ch2 = msg.cliplmt_ch2; + params.gate_ch1 = msg.gate_ch1; + params.gate_ch2 = msg.gate_ch2; +} + diff --git a/test/CodeGen/bool-convert.c b/test/CodeGen/bool-convert.c new file mode 100644 index 0000000..4df81bb --- /dev/null +++ b/test/CodeGen/bool-convert.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm < %s | grep i1 | count 1 +// All of these should uses the memory representation of _Bool +struct teststruct1 {_Bool a, b;} test1; +_Bool* test2; +_Bool test3[10]; +_Bool (*test4)[]; +void f(int x) { + _Bool test5; + _Bool test6[x]; +} diff --git a/test/CodeGen/bool-init.c b/test/CodeGen/bool-init.c new file mode 100644 index 0000000..7d331ed --- /dev/null +++ b/test/CodeGen/bool-init.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm < %s | grep i1 | count 1 + +// Check that the type of this global isn't i1 +_Bool test = &test; diff --git a/test/CodeGen/boolassign.c b/test/CodeGen/boolassign.c new file mode 100644 index 0000000..2d14f8c --- /dev/null +++ b/test/CodeGen/boolassign.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +int testBoolAssign(void) { +int ss; +if ((ss = ss && ss)) {} +} diff --git a/test/CodeGen/builtin-count-zeros.c b/test/CodeGen/builtin-count-zeros.c new file mode 100644 index 0000000..374acc4 --- /dev/null +++ b/test/CodeGen/builtin-count-zeros.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm %s -o - | grep 'cttz' | count 2 && +// RUN: clang-cc -emit-llvm %s -o - | grep 'ctlz' | count 2 + +int a(int a) {return __builtin_ctz(a) + __builtin_clz(a);} diff --git a/test/CodeGen/builtin-memfns.c b/test/CodeGen/builtin-memfns.c new file mode 100644 index 0000000..9ae380c --- /dev/null +++ b/test/CodeGen/builtin-memfns.c @@ -0,0 +1,15 @@ +// RUN: clang-cc -triple i386-pc-linux-gnu -emit-llvm -o %t %s && +// RUN: grep '@llvm.memset.i32' %t && +// RUN: grep '@llvm.memcpy.i32' %t && +// RUN: grep '@llvm.memmove.i32' %t && +// RUN: grep __builtin %t | count 0 + +int main(int argc, char **argv) { + unsigned char a = 0x11223344; + unsigned char b = 0x11223344; + __builtin_bzero(&a, sizeof(a)); + __builtin_memset(&a, 0, sizeof(a)); + __builtin_memcpy(&a, &b, sizeof(a)); + __builtin_memmove(&a, &b, sizeof(a)); + return 0; +} diff --git a/test/CodeGen/builtin-nanf.c b/test/CodeGen/builtin-nanf.c new file mode 100644 index 0000000..e048c7a --- /dev/null +++ b/test/CodeGen/builtin-nanf.c @@ -0,0 +1,15 @@ +// RUN: clang-cc -triple x86_64-apple-darwin9 -emit-llvm -o %t %s && +// RUN: grep 'float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x7FF8000020000000, float 0x7FF8000000000000, float 0x7FF80001E0000000, float 0x7FF8001E00000000, float 0x7FF801E000000000, float 0x7FF81E0000000000, float 0x7FF9E00000000000, float 0x7FFFFFFFE0000000' %t + +float n[] = { + __builtin_nanf("0"), + __builtin_nanf(""), + __builtin_nanf("1"), + __builtin_nanf("0x7fc00000"), + __builtin_nanf("0x7fc0000f"), + __builtin_nanf("0x7fc000f0"), + __builtin_nanf("0x7fc00f00"), + __builtin_nanf("0x7fc0f000"), + __builtin_nanf("0x7fcf0000"), + __builtin_nanf("0xffffffff"), +}; diff --git a/test/CodeGen/builtin-rename.c b/test/CodeGen/builtin-rename.c new file mode 100644 index 0000000..d0b5c24 --- /dev/null +++ b/test/CodeGen/builtin-rename.c @@ -0,0 +1,8 @@ +// RUN: clang-cc %s -emit-llvm -o - | grep 'declare.*printf' | count 1 +// PR3612 + +int printf(const char *, ...); + +int foo(void) { + return printf(printf); +} diff --git a/test/CodeGen/builtin-stackaddress.c b/test/CodeGen/builtin-stackaddress.c new file mode 100644 index 0000000..5c6d540 --- /dev/null +++ b/test/CodeGen/builtin-stackaddress.c @@ -0,0 +1,9 @@ +// RUN: clang-cc -emit-llvm < %s | grep "llvm.returnaddress" && +// RUN: clang-cc -emit-llvm < %s | grep "llvm.frameaddress" +void* a(unsigned x) { +return __builtin_return_address(0); +} + +void* c(unsigned x) { +return __builtin_frame_address(0); +} diff --git a/test/CodeGen/builtin-unwind-init.c b/test/CodeGen/builtin-unwind-init.c new file mode 100644 index 0000000..49a016a --- /dev/null +++ b/test/CodeGen/builtin-unwind-init.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm < %s -o - | grep -F "llvm.eh.unwind.init" + +int a() { __builtin_unwind_init(); } + diff --git a/test/CodeGen/builtinmemcpy.c b/test/CodeGen/builtinmemcpy.c new file mode 100644 index 0000000..d1fdebb --- /dev/null +++ b/test/CodeGen/builtinmemcpy.c @@ -0,0 +1,3 @@ +// RUN: clang-cc -emit-llvm < %s -o - | grep "llvm.memcpy" + +char* x(char* a, char* b) {return __builtin_memcpy(a, b, 4);} diff --git a/test/CodeGen/builtins-ffs_parity_popcount.c b/test/CodeGen/builtins-ffs_parity_popcount.c new file mode 100644 index 0000000..4746998 --- /dev/null +++ b/test/CodeGen/builtins-ffs_parity_popcount.c @@ -0,0 +1,15 @@ +// RUN: clang-cc -emit-llvm -o - %s > %t +// RUN: ! grep "__builtin" %t + +#include <stdio.h> + +void test(int M, long long N) { + printf("%d %lld: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", + M, N, + __builtin_ffs(M), __builtin_ffsl(M), __builtin_ffsll(M), + __builtin_parity(M), __builtin_parityl(M), __builtin_parityll(M), + __builtin_popcount(M), __builtin_popcountl(M), __builtin_popcountll(M), + __builtin_ffs(N), __builtin_ffsl(N), __builtin_ffsll(N), + __builtin_parity(N), __builtin_parityl(N), __builtin_parityll(N), + __builtin_popcount(N), __builtin_popcountl(N), __builtin_popcountll(N)); +} diff --git a/test/CodeGen/builtins-powi.c b/test/CodeGen/builtins-powi.c new file mode 100644 index 0000000..73f752f --- /dev/null +++ b/test/CodeGen/builtins-powi.c @@ -0,0 +1,29 @@ +// RUN: clang-cc -emit-llvm -o - %s > %t +// RUN: ! grep "__builtin" %t + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +void test(long double a, int b) { + printf("%Lf**%d: %08x %08x %016Lx\n", + a, b, + __builtin_powi(a, b), + __builtin_powif(a, b), + __builtin_powil(a, b) + ); +} + +int main() { + int i; + + test(-1,-1LL); + test(0,0); + test(1,1); + + for (i=0; i<3; i++) { + test(random(), i); + } + + return 0; +} diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c new file mode 100644 index 0000000..33ab360 --- /dev/null +++ b/test/CodeGen/builtins-x86.c @@ -0,0 +1,522 @@ +// RUN: clang-cc -DUSE_64 -triple x86_64-unknown-unknown -emit-llvm -o %t %s && +// RUN: clang-cc -DUSE_ALL -triple x86_64-unknown-unknown -fsyntax-only -o %t %s + +#ifdef USE_ALL +#define USE_3DNOW +#define USE_64 +#define USE_SSE4 +#endif + +// 64-bit +typedef char V8c __attribute__((vector_size(8 * sizeof(char)))); +typedef signed short V4s __attribute__((vector_size(8))); +typedef signed int V2i __attribute__((vector_size(8))); +typedef signed long long V1LLi __attribute__((vector_size(8))); + +typedef float V2f __attribute__((vector_size(8))); + +// 128-bit +typedef char V16c __attribute__((vector_size(16))); +typedef signed short V8s __attribute__((vector_size(16))); +typedef signed int V4i __attribute__((vector_size(16))); +typedef signed long long V2LLi __attribute__((vector_size(16))); + +typedef float V4f __attribute__((vector_size(16))); +typedef double V2d __attribute__((vector_size(16))); + +void f0() { + signed char tmp_c; +// unsigned char tmp_Uc; + signed short tmp_s; +#ifdef USE_ALL + unsigned short tmp_Us; +#endif + signed int tmp_i; + unsigned int tmp_Ui; + signed long long tmp_LLi; +// unsigned long long tmp_ULLi; + float tmp_f; + double tmp_d; + + void* tmp_vp; + const void* tmp_vCp; + char* tmp_cp; + const char* tmp_cCp; + int* tmp_ip; + float* tmp_fp; + const float* tmp_fCp; + double* tmp_dp; + const double* tmp_dCp; + +#define imm_i 32 +#define imm_i_0_2 0 +#define imm_i_0_4 3 +#define imm_i_0_8 7 +#define imm_i_0_16 15 + // Check this. +#define imm_i_0_256 0 + + V2i* tmp_V2ip; + V1LLi* tmp_V1LLip; + V2LLi* tmp_V2LLip; + + // 64-bit + V8c tmp_V8c; + V4s tmp_V4s; + V2i tmp_V2i; + V1LLi tmp_V1LLi; +#ifdef USE_3DNOW + V2f tmp_V2f; +#endif + + // 128-bit + V16c tmp_V16c; + V8s tmp_V8s; + V4i tmp_V4i; + V2LLi tmp_V2LLi; + V4f tmp_V4f; + V2d tmp_V2d; + + tmp_i = __builtin_ia32_comieq(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_comilt(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_comile(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_comigt(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_comige(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_comineq(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_ucomieq(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_ucomilt(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_ucomile(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_ucomigt(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_ucomige(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_ucomineq(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_comisdeq(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_comisdlt(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_comisdle(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_comisdgt(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_comisdge(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_comisdneq(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_ucomisdeq(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_ucomisdlt(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_ucomisdle(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_ucomisdgt(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_ucomisdge(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_ucomisdneq(tmp_V2d, tmp_V2d); + tmp_V4f = __builtin_ia32_addps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_subps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_mulps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_divps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_addss(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_subss(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_mulss(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_divss(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 0); + tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 1); + tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 2); + tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 3); + tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 4); + tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 5); + tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 6); + tmp_V4f = __builtin_ia32_cmpps(tmp_V4f, tmp_V4f, 7); + tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 0); + tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 1); + tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 2); + tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 3); + tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 4); + tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 5); + tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 6); + tmp_V4f = __builtin_ia32_cmpss(tmp_V4f, tmp_V4f, 7); + tmp_V4f = __builtin_ia32_minps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_maxps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_minss(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_maxss(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_andps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_andnps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_orps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_xorps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_movss(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_movhlps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_movlhps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_unpckhps(tmp_V4f, tmp_V4f); + tmp_V4f = __builtin_ia32_unpcklps(tmp_V4f, tmp_V4f); + tmp_V8c = __builtin_ia32_paddb(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_paddw(tmp_V4s, tmp_V4s); + tmp_V2i = __builtin_ia32_paddd(tmp_V2i, tmp_V2i); + + tmp_V1LLi = __builtin_ia32_paddq(tmp_V1LLi, tmp_V1LLi); + tmp_V8c = __builtin_ia32_psubb(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_psubw(tmp_V4s, tmp_V4s); + tmp_V2i = __builtin_ia32_psubd(tmp_V2i, tmp_V2i); + tmp_V1LLi = __builtin_ia32_psubq(tmp_V1LLi, tmp_V1LLi); + tmp_V8c = __builtin_ia32_paddsb(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_paddsw(tmp_V4s, tmp_V4s); + tmp_V8c = __builtin_ia32_psubsb(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_psubsw(tmp_V4s, tmp_V4s); + tmp_V8c = __builtin_ia32_paddusb(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_paddusw(tmp_V4s, tmp_V4s); + tmp_V8c = __builtin_ia32_psubusb(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_psubusw(tmp_V4s, tmp_V4s); + tmp_V4s = __builtin_ia32_pmullw(tmp_V4s, tmp_V4s); + tmp_V4s = __builtin_ia32_pmulhw(tmp_V4s, tmp_V4s); + tmp_V4s = __builtin_ia32_pmulhuw(tmp_V4s, tmp_V4s); + tmp_V1LLi = __builtin_ia32_pand(tmp_V1LLi, tmp_V1LLi); + tmp_V1LLi = __builtin_ia32_pandn(tmp_V1LLi, tmp_V1LLi); + tmp_V1LLi = __builtin_ia32_por(tmp_V1LLi, tmp_V1LLi); + tmp_V1LLi = __builtin_ia32_pxor(tmp_V1LLi, tmp_V1LLi); + tmp_V8c = __builtin_ia32_pavgb(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_pavgw(tmp_V4s, tmp_V4s); + tmp_V8c = __builtin_ia32_pcmpeqb(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_pcmpeqw(tmp_V4s, tmp_V4s); + tmp_V2i = __builtin_ia32_pcmpeqd(tmp_V2i, tmp_V2i); + tmp_V8c = __builtin_ia32_pcmpgtb(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_pcmpgtw(tmp_V4s, tmp_V4s); + tmp_V2i = __builtin_ia32_pcmpgtd(tmp_V2i, tmp_V2i); + tmp_V8c = __builtin_ia32_pmaxub(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_pmaxsw(tmp_V4s, tmp_V4s); + tmp_V8c = __builtin_ia32_pminub(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_pminsw(tmp_V4s, tmp_V4s); + tmp_V8c = __builtin_ia32_punpckhbw(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_punpckhwd(tmp_V4s, tmp_V4s); + tmp_V2i = __builtin_ia32_punpckhdq(tmp_V2i, tmp_V2i); + tmp_V8c = __builtin_ia32_punpcklbw(tmp_V8c, tmp_V8c); + tmp_V4s = __builtin_ia32_punpcklwd(tmp_V4s, tmp_V4s); + tmp_V2i = __builtin_ia32_punpckldq(tmp_V2i, tmp_V2i); + tmp_V2d = __builtin_ia32_addpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_subpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_mulpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_divpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_addsd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_subsd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_mulsd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_divsd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 0); + tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 1); + tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 2); + tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 3); + tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 4); + tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 5); + tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 6); + tmp_V2d = __builtin_ia32_cmppd(tmp_V2d, tmp_V2d, 7); + tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 0); + tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 1); + tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 2); + tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 3); + tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 4); + tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 5); + tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 6); + tmp_V2d = __builtin_ia32_cmpsd(tmp_V2d, tmp_V2d, 7); + tmp_V2d = __builtin_ia32_minpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_maxpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_minsd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_maxsd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_andpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_andnpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_orpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_xorpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_movsd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_unpckhpd(tmp_V2d, tmp_V2d); + tmp_V2d = __builtin_ia32_unpcklpd(tmp_V2d, tmp_V2d); + tmp_V16c = __builtin_ia32_paddb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_paddw128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_paddd128(tmp_V4i, tmp_V4i); + tmp_V2LLi = __builtin_ia32_paddq128(tmp_V2LLi, tmp_V2LLi); + tmp_V16c = __builtin_ia32_psubb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_psubw128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_psubd128(tmp_V4i, tmp_V4i); + tmp_V2LLi = __builtin_ia32_psubq128(tmp_V2LLi, tmp_V2LLi); + tmp_V16c = __builtin_ia32_paddsb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_paddsw128(tmp_V8s, tmp_V8s); + tmp_V16c = __builtin_ia32_psubsb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_psubsw128(tmp_V8s, tmp_V8s); + tmp_V16c = __builtin_ia32_paddusb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_paddusw128(tmp_V8s, tmp_V8s); + tmp_V16c = __builtin_ia32_psubusb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_psubusw128(tmp_V8s, tmp_V8s); + tmp_V8s = __builtin_ia32_pmullw128(tmp_V8s, tmp_V8s); + tmp_V8s = __builtin_ia32_pmulhw128(tmp_V8s, tmp_V8s); + tmp_V2LLi = __builtin_ia32_pand128(tmp_V2LLi, tmp_V2LLi); + tmp_V2LLi = __builtin_ia32_pandn128(tmp_V2LLi, tmp_V2LLi); + tmp_V2LLi = __builtin_ia32_por128(tmp_V2LLi, tmp_V2LLi); + tmp_V2LLi = __builtin_ia32_pxor128(tmp_V2LLi, tmp_V2LLi); + tmp_V16c = __builtin_ia32_pavgb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_pavgw128(tmp_V8s, tmp_V8s); + tmp_V16c = __builtin_ia32_pcmpeqb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_pcmpeqw128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_pcmpeqd128(tmp_V4i, tmp_V4i); + tmp_V16c = __builtin_ia32_pcmpgtb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_pcmpgtw128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_pcmpgtd128(tmp_V4i, tmp_V4i); + tmp_V16c = __builtin_ia32_pmaxub128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_pmaxsw128(tmp_V8s, tmp_V8s); + tmp_V16c = __builtin_ia32_pminub128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_pminsw128(tmp_V8s, tmp_V8s); + tmp_V16c = __builtin_ia32_punpckhbw128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_punpckhwd128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_punpckhdq128(tmp_V4i, tmp_V4i); + tmp_V2LLi = __builtin_ia32_punpckhqdq128(tmp_V2LLi, tmp_V2LLi); + tmp_V16c = __builtin_ia32_punpcklbw128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_punpcklwd128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_punpckldq128(tmp_V4i, tmp_V4i); + tmp_V2LLi = __builtin_ia32_punpcklqdq128(tmp_V2LLi, tmp_V2LLi); + tmp_V8s = __builtin_ia32_packsswb128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_packssdw128(tmp_V4i, tmp_V4i); + tmp_V8s = __builtin_ia32_packuswb128(tmp_V8s, tmp_V8s); + tmp_V8s = __builtin_ia32_pmulhuw128(tmp_V8s, tmp_V8s); + tmp_V4f = __builtin_ia32_addsubps(tmp_V4f, tmp_V4f); + tmp_V2d = __builtin_ia32_addsubpd(tmp_V2d, tmp_V2d); + tmp_V4f = __builtin_ia32_haddps(tmp_V4f, tmp_V4f); + tmp_V2d = __builtin_ia32_haddpd(tmp_V2d, tmp_V2d); + tmp_V4f = __builtin_ia32_hsubps(tmp_V4f, tmp_V4f); + tmp_V2d = __builtin_ia32_hsubpd(tmp_V2d, tmp_V2d); + tmp_V8s = __builtin_ia32_phaddw128(tmp_V8s, tmp_V8s); + tmp_V4s = __builtin_ia32_phaddw(tmp_V4s, tmp_V4s); + tmp_V4i = __builtin_ia32_phaddd128(tmp_V4i, tmp_V4i); + tmp_V2i = __builtin_ia32_phaddd(tmp_V2i, tmp_V2i); + tmp_V8s = __builtin_ia32_phaddsw128(tmp_V8s, tmp_V8s); + tmp_V4s = __builtin_ia32_phaddsw(tmp_V4s, tmp_V4s); + tmp_V8s = __builtin_ia32_phsubw128(tmp_V8s, tmp_V8s); + tmp_V4s = __builtin_ia32_phsubw(tmp_V4s, tmp_V4s); + tmp_V4i = __builtin_ia32_phsubd128(tmp_V4i, tmp_V4i); + tmp_V2i = __builtin_ia32_phsubd(tmp_V2i, tmp_V2i); + tmp_V8s = __builtin_ia32_phsubsw128(tmp_V8s, tmp_V8s); + tmp_V4s = __builtin_ia32_phsubsw(tmp_V4s, tmp_V4s); + tmp_V16c = __builtin_ia32_pmaddubsw128(tmp_V16c, tmp_V16c); + tmp_V8c = __builtin_ia32_pmaddubsw(tmp_V8c, tmp_V8c); + tmp_V8s = __builtin_ia32_pmulhrsw128(tmp_V8s, tmp_V8s); + tmp_V4s = __builtin_ia32_pmulhrsw(tmp_V4s, tmp_V4s); + tmp_V16c = __builtin_ia32_pshufb128(tmp_V16c, tmp_V16c); + tmp_V8c = __builtin_ia32_pshufb(tmp_V8c, tmp_V8c); + tmp_V16c = __builtin_ia32_psignb128(tmp_V16c, tmp_V16c); + tmp_V8c = __builtin_ia32_psignb(tmp_V8c, tmp_V8c); + tmp_V8s = __builtin_ia32_psignw128(tmp_V8s, tmp_V8s); + tmp_V4s = __builtin_ia32_psignw(tmp_V4s, tmp_V4s); + tmp_V4i = __builtin_ia32_psignd128(tmp_V4i, tmp_V4i); + tmp_V2i = __builtin_ia32_psignd(tmp_V2i, tmp_V2i); + tmp_V16c = __builtin_ia32_pabsb128(tmp_V16c); + tmp_V8c = __builtin_ia32_pabsb(tmp_V8c); + tmp_V8s = __builtin_ia32_pabsw128(tmp_V8s); + tmp_V4s = __builtin_ia32_pabsw(tmp_V4s); + tmp_V4i = __builtin_ia32_pabsd128(tmp_V4i); + tmp_V2i = __builtin_ia32_pabsd(tmp_V2i); + tmp_V4s = __builtin_ia32_psllw(tmp_V4s, tmp_V1LLi); + tmp_V2i = __builtin_ia32_pslld(tmp_V2i, tmp_V1LLi); + tmp_V1LLi = __builtin_ia32_psllq(tmp_V1LLi, tmp_V1LLi); + tmp_V4s = __builtin_ia32_psrlw(tmp_V4s, tmp_V1LLi); + tmp_V2i = __builtin_ia32_psrld(tmp_V2i, tmp_V1LLi); + tmp_V1LLi = __builtin_ia32_psrlq(tmp_V1LLi, tmp_V1LLi); + tmp_V4s = __builtin_ia32_psraw(tmp_V4s, tmp_V1LLi); + tmp_V2i = __builtin_ia32_psrad(tmp_V2i, tmp_V1LLi); +#ifdef USE_ALL + tmp_V4s = __builtin_ia32_pshufw(tmp_V4s, imm_i); +#endif + tmp_V2i = __builtin_ia32_pmaddwd(tmp_V4s, tmp_V4s); + tmp_V8c = __builtin_ia32_packsswb(tmp_V4s, tmp_V4s); + tmp_V4s = __builtin_ia32_packssdw(tmp_V2i, tmp_V2i); + tmp_V8c = __builtin_ia32_packuswb(tmp_V4s, tmp_V4s); + + (void) __builtin_ia32_ldmxcsr(tmp_Ui); + tmp_Ui = __builtin_ia32_stmxcsr(); + tmp_V4f = __builtin_ia32_cvtpi2ps(tmp_V4f, tmp_V2i); + tmp_V2i = __builtin_ia32_cvtps2pi(tmp_V4f); + tmp_V4f = __builtin_ia32_cvtsi2ss(tmp_V4f, tmp_i); +#ifdef USE_64 + tmp_V4f = __builtin_ia32_cvtsi642ss(tmp_V4f, tmp_LLi); +#endif + tmp_i = __builtin_ia32_cvtss2si(tmp_V4f); +#ifdef USE_64 + tmp_LLi = __builtin_ia32_cvtss2si64(tmp_V4f); +#endif + tmp_V2i = __builtin_ia32_cvttps2pi(tmp_V4f); + tmp_i = __builtin_ia32_cvttss2si(tmp_V4f); +#ifdef USE_64 + tmp_LLi = __builtin_ia32_cvttss2si64(tmp_V4f); +#endif + (void) __builtin_ia32_maskmovq(tmp_V8c, tmp_V8c, tmp_cp); + tmp_V4f = __builtin_ia32_loadups(tmp_fCp); + (void) __builtin_ia32_storeups(tmp_fp, tmp_V4f); + tmp_V4f = __builtin_ia32_loadhps(tmp_V4f, tmp_V2ip); + tmp_V4f = __builtin_ia32_loadlps(tmp_V4f, tmp_V2ip); + (void) __builtin_ia32_storehps(tmp_V2ip, tmp_V4f); + (void) __builtin_ia32_storelps(tmp_V2ip, tmp_V4f); + tmp_i = __builtin_ia32_movmskps(tmp_V4f); + tmp_i = __builtin_ia32_pmovmskb(tmp_V8c); + (void) __builtin_ia32_movntps(tmp_fp, tmp_V4f); + (void) __builtin_ia32_movntq(tmp_V1LLip, tmp_V1LLi); + (void) __builtin_ia32_sfence(); + + tmp_V4s = __builtin_ia32_psadbw(tmp_V8c, tmp_V8c); + tmp_V4f = __builtin_ia32_rcpps(tmp_V4f); + tmp_V4f = __builtin_ia32_rcpss(tmp_V4f); + tmp_V4f = __builtin_ia32_rsqrtps(tmp_V4f); + tmp_V4f = __builtin_ia32_rsqrtss(tmp_V4f); + tmp_V4f = __builtin_ia32_sqrtps(tmp_V4f); + tmp_V4f = __builtin_ia32_sqrtss(tmp_V4f); + tmp_V4f = __builtin_ia32_shufps(tmp_V4f, tmp_V4f, imm_i); +#ifdef USE_3DNOW + (void) __builtin_ia32_femms(); + tmp_V8c = __builtin_ia32_pavgusb(tmp_V8c, tmp_V8c); + tmp_V2i = __builtin_ia32_pf2id(tmp_V2f); + tmp_V2f = __builtin_ia32_pfacc(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfadd(tmp_V2f, tmp_V2f); + tmp_V2i = __builtin_ia32_pfcmpeq(tmp_V2f, tmp_V2f); + tmp_V2i = __builtin_ia32_pfcmpge(tmp_V2f, tmp_V2f); + tmp_V2i = __builtin_ia32_pfcmpgt(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfmax(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfmin(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfmul(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfrcp(tmp_V2f); + tmp_V2f = __builtin_ia32_pfrcpit1(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfrcpit2(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfrsqrt(tmp_V2f); + tmp_V2f = __builtin_ia32_pfrsqit1(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfsub(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfsubr(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pi2fd(tmp_V2i); + tmp_V4s = __builtin_ia32_pmulhrw(tmp_V4s, tmp_V4s); +#endif +#ifdef USE_3DNOWA + tmp_V2i = __builtin_ia32_pf2iw(tmp_V2f); + tmp_V2f = __builtin_ia32_pfnacc(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pfpnacc(tmp_V2f, tmp_V2f); + tmp_V2f = __builtin_ia32_pi2fw(tmp_V2i); + tmp_V2f = __builtin_ia32_pswapdsf(tmp_V2f); + tmp_V2i = __builtin_ia32_pswapdsi(tmp_V2i); +#endif + (void) __builtin_ia32_maskmovdqu(tmp_V16c, tmp_V16c, tmp_cp); + tmp_V2d = __builtin_ia32_loadupd(tmp_dCp); + (void) __builtin_ia32_storeupd(tmp_dp, tmp_V2d); + tmp_V2d = __builtin_ia32_loadhpd(tmp_V2d, tmp_dCp); + tmp_V2d = __builtin_ia32_loadlpd(tmp_V2d, tmp_dCp); + tmp_i = __builtin_ia32_movmskpd(tmp_V2d); + tmp_i = __builtin_ia32_pmovmskb128(tmp_V16c); + (void) __builtin_ia32_movnti(tmp_ip, tmp_i); + (void) __builtin_ia32_movntpd(tmp_dp, tmp_V2d); + (void) __builtin_ia32_movntdq(tmp_V2LLip, tmp_V2LLi); + tmp_V4i = __builtin_ia32_pshufd(tmp_V4i, imm_i); + tmp_V8s = __builtin_ia32_pshuflw(tmp_V8s, imm_i); + tmp_V8s = __builtin_ia32_pshufhw(tmp_V8s, imm_i); + tmp_V2LLi = __builtin_ia32_psadbw128(tmp_V16c, tmp_V16c); + tmp_V2d = __builtin_ia32_sqrtpd(tmp_V2d); + tmp_V2d = __builtin_ia32_sqrtsd(tmp_V2d); + tmp_V2d = __builtin_ia32_shufpd(tmp_V2d, tmp_V2d, imm_i); + tmp_V2d = __builtin_ia32_cvtdq2pd(tmp_V4i); + tmp_V4f = __builtin_ia32_cvtdq2ps(tmp_V4i); + tmp_V2LLi = __builtin_ia32_cvtpd2dq(tmp_V2d); + tmp_V2i = __builtin_ia32_cvtpd2pi(tmp_V2d); + tmp_V4f = __builtin_ia32_cvtpd2ps(tmp_V2d); + tmp_V4i = __builtin_ia32_cvttpd2dq(tmp_V2d); + tmp_V2i = __builtin_ia32_cvttpd2pi(tmp_V2d); + tmp_V2d = __builtin_ia32_cvtpi2pd(tmp_V2i); + tmp_i = __builtin_ia32_cvtsd2si(tmp_V2d); + tmp_i = __builtin_ia32_cvttsd2si(tmp_V2d); +#ifdef USE_64 + tmp_LLi = __builtin_ia32_cvtsd2si64(tmp_V2d); + tmp_LLi = __builtin_ia32_cvttsd2si64(tmp_V2d); +#endif + tmp_V4i = __builtin_ia32_cvtps2dq(tmp_V4f); + tmp_V2d = __builtin_ia32_cvtps2pd(tmp_V4f); + tmp_V4i = __builtin_ia32_cvttps2dq(tmp_V4f); + tmp_V2d = __builtin_ia32_cvtsi2sd(tmp_V2d, tmp_i); +#ifdef USE_64 + tmp_V2d = __builtin_ia32_cvtsi642sd(tmp_V2d, tmp_LLi); +#endif + tmp_V4f = __builtin_ia32_cvtsd2ss(tmp_V4f, tmp_V2d); + tmp_V2d = __builtin_ia32_cvtss2sd(tmp_V2d, tmp_V4f); + (void) __builtin_ia32_clflush(tmp_vCp); + (void) __builtin_ia32_lfence(); + (void) __builtin_ia32_mfence(); + tmp_V16c = __builtin_ia32_loaddqu(tmp_cCp); + (void) __builtin_ia32_storedqu(tmp_cp, tmp_V16c); + tmp_V4s = __builtin_ia32_psllwi(tmp_V4s, tmp_i); + tmp_V2i = __builtin_ia32_pslldi(tmp_V2i, tmp_i); + tmp_V1LLi = __builtin_ia32_psllqi(tmp_V1LLi, tmp_i); + tmp_V4s = __builtin_ia32_psrawi(tmp_V4s, tmp_i); + tmp_V2i = __builtin_ia32_psradi(tmp_V2i, tmp_i); + tmp_V4s = __builtin_ia32_psrlwi(tmp_V4s, tmp_i); + tmp_V2i = __builtin_ia32_psrldi(tmp_V2i, tmp_i); + tmp_V1LLi = __builtin_ia32_psrlqi(tmp_V1LLi, tmp_i); + tmp_V1LLi = __builtin_ia32_pmuludq(tmp_V2i, tmp_V2i); + tmp_V2LLi = __builtin_ia32_pmuludq128(tmp_V4i, tmp_V4i); + tmp_V8s = __builtin_ia32_psraw128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_psrad128(tmp_V4i, tmp_V4i); + tmp_V8s = __builtin_ia32_psrlw128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_psrld128(tmp_V4i, tmp_V4i); + tmp_V2LLi = __builtin_ia32_psrlq128(tmp_V2LLi, tmp_V2LLi); + tmp_V8s = __builtin_ia32_psllw128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_pslld128(tmp_V4i, tmp_V4i); + tmp_V2LLi = __builtin_ia32_psllq128(tmp_V2LLi, tmp_V2LLi); + tmp_V8s = __builtin_ia32_psllwi128(tmp_V8s, tmp_i); + tmp_V4i = __builtin_ia32_pslldi128(tmp_V4i, tmp_i); + tmp_V2LLi = __builtin_ia32_psllqi128(tmp_V2LLi, tmp_i); + tmp_V8s = __builtin_ia32_psrlwi128(tmp_V8s, tmp_i); + tmp_V4i = __builtin_ia32_psrldi128(tmp_V4i, tmp_i); + tmp_V2LLi = __builtin_ia32_psrlqi128(tmp_V2LLi, tmp_i); + tmp_V8s = __builtin_ia32_psrawi128(tmp_V8s, tmp_i); + tmp_V4i = __builtin_ia32_psradi128(tmp_V4i, tmp_i); + tmp_V8s = __builtin_ia32_pmaddwd128(tmp_V8s, tmp_V8s); + (void) __builtin_ia32_monitor(tmp_vp, tmp_Ui, tmp_Ui); + (void) __builtin_ia32_mwait(tmp_Ui, tmp_Ui); +#ifdef USE_ALL + tmp_V4f = __builtin_ia32_movshdup(tmp_V4f); + tmp_V4f = __builtin_ia32_movsldup(tmp_V4f); +#endif + tmp_V16c = __builtin_ia32_lddqu(tmp_cCp); + tmp_V2LLi = __builtin_ia32_palignr128(tmp_V2LLi, tmp_V2LLi, imm_i); + tmp_V1LLi = __builtin_ia32_palignr(tmp_V1LLi, tmp_V1LLi, imm_i); + tmp_V2i = __builtin_ia32_vec_init_v2si(tmp_i, tmp_i); + tmp_V4s = __builtin_ia32_vec_init_v4hi(tmp_s, tmp_s, tmp_s, tmp_s); + tmp_V8c = __builtin_ia32_vec_init_v8qi(tmp_c, tmp_c, tmp_c, tmp_c, tmp_c, tmp_c, tmp_c, tmp_c); + tmp_d = __builtin_ia32_vec_ext_v2df(tmp_V2d, imm_i_0_2); + tmp_LLi = __builtin_ia32_vec_ext_v2di(tmp_V2LLi, imm_i_0_2); + tmp_f = __builtin_ia32_vec_ext_v4sf(tmp_V4f, imm_i_0_4); + tmp_i = __builtin_ia32_vec_ext_v4si(tmp_V4i, imm_i_0_4); +#ifdef USE_ALL + tmp_Us = __builtin_ia32_vec_ext_v8hi(tmp_V8s, imm_i_0_8); + tmp_s = __builtin_ia32_vec_ext_v4hi(tmp_V4s, imm_i_0_4); +#endif + tmp_i = __builtin_ia32_vec_ext_v2si(tmp_V2i, imm_i_0_2); + tmp_V8s = __builtin_ia32_vec_set_v8hi(tmp_V8s, tmp_s, imm_i_0_8); + tmp_V4s = __builtin_ia32_vec_set_v4hi(tmp_V4s, tmp_s, imm_i_0_4); + tmp_V4i = __builtin_ia32_loadlv4si(tmp_V2ip); + (void) __builtin_ia32_storelv4si(tmp_V2ip, tmp_V2LLi); +#ifdef USE_SSE4 + tmp_V16c = __builtin_ia32_pblendvb128(tmp_V16c, tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_pblendw128(tmp_V8s, tmp_V8s, imm_i_0_256); + tmp_V2d = __builtin_ia32_blendpd(tmp_V2d, tmp_V2d, imm_i_0_256); + tmp_V4f = __builtin_ia32_blendps(tmp_V4f, tmp_V4f, imm_i_0_256); + tmp_V2d = __builtin_ia32_blendvpd(tmp_V2d, tmp_V2d, tmp_V2d); + tmp_V4f = __builtin_ia32_blendvps(tmp_V4f, tmp_V4f, tmp_V4f); + tmp_V8s = __builtin_ia32_packusdw128(tmp_V4i, tmp_V4i); + tmp_V16c = __builtin_ia32_pmaxsb128(tmp_V16c, tmp_V16c); + tmp_V4i = __builtin_ia32_pmaxsd128(tmp_V4i, tmp_V4i); + tmp_V4i = __builtin_ia32_pmaxud128(tmp_V4i, tmp_V4i); + tmp_V8s = __builtin_ia32_pmaxuw128(tmp_V8s, tmp_V8s); + tmp_V16c = __builtin_ia32_pminsb128(tmp_V16c, tmp_V16c); + tmp_V4i = __builtin_ia32_pminsd128(tmp_V4i, tmp_V4i); + tmp_V4i = __builtin_ia32_pminud128(tmp_V4i, tmp_V4i); + tmp_V8s = __builtin_ia32_pminuw128(tmp_V8s, tmp_V8s); + tmp_V4i = __builtin_ia32_pmovsxbd128(tmp_V16c); + tmp_V2LLi = __builtin_ia32_pmovsxbq128(tmp_V16c); + tmp_V8s = __builtin_ia32_pmovsxbw128(tmp_V16c); + tmp_V2LLi = __builtin_ia32_pmovsxdq128(tmp_V4i); + tmp_V4i = __builtin_ia32_pmovsxwd128(tmp_V8s); + tmp_V2LLi = __builtin_ia32_pmovsxwq128(tmp_V8s); + tmp_V4i = __builtin_ia32_pmovzxbd128(tmp_V16c); + tmp_V2LLi = __builtin_ia32_pmovzxbq128(tmp_V16c); + tmp_V8s = __builtin_ia32_pmovzxbw128(tmp_V16c); + tmp_V2LLi = __builtin_ia32_pmovzxdq128(tmp_V4i); + tmp_V4i = __builtin_ia32_pmovzxwd128(tmp_V8s); + tmp_V2LLi = __builtin_ia32_pmovzxwq128(tmp_V8s); + tmp_V2LLi = __builtin_ia32_pmuldq128(tmp_V4i, tmp_V4i); + tmp_V4i = __builtin_ia32_pmulld128(tmp_V4i, tmp_V4i); + tmp_V4f = __builtin_ia32_roundps(tmp_V4f, imm_i_0_16); + // tmp_V4f = __builtin_ia32_roundss(tmp_V4f, tmp_V4f, imm_i_0_16); + // tmp_V2d = __builtin_ia32_roundsd(tmp_V2d, tmp_V2d, imm_i_0_16); + tmp_V2d = __builtin_ia32_roundpd(tmp_V2d, imm_i_0_16); + tmp_V16c = __builtin_ia32_vec_set_v16qi(tmp_V16c, tmp_i, tmp_i); + tmp_V4i = __builtin_ia32_vec_set_v4si(tmp_V4i, tmp_i, tmp_i); + tmp_V4f = __builtin_ia32_insertps128(tmp_V4f, tmp_V4f, tmp_i); + tmp_V2LLi = __builtin_ia32_vec_set_v2di(tmp_V2LLi, tmp_LLi, tmp_i); +#endif +} + + diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c new file mode 100644 index 0000000..ce5cd74 --- /dev/null +++ b/test/CodeGen/builtins.c @@ -0,0 +1,124 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: not grep __builtin %t + +#include <stdio.h> +#include <math.h> + +void p(char *str, int x) { + printf("%s: %d\n", str, x); +} +void q(char *str, double x) { + printf("%s: %f\n", str, x); +} + +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 V(n,args) p(#n #args, (__builtin_##n args, 0)) + P(types_compatible_p, (int, float)); + P(choose_expr, (0, 10, 20)); + P(constant_p, (sizeof(10))); + P(expect, (N == 12, 0)); + V(prefetch, (&N)); + V(prefetch, (&N, 1)); + V(prefetch, (&N, 1, 0)); + + // Numeric Constants + + Q(huge_val, ()); + Q(huge_valf, ()); + Q(huge_vall, ()); + Q(inf, ()); + Q(inff, ()); + Q(infl, ()); + + // FIXME: + // XXX note funny semantics for the (last) argument + // P(fpclassify, (FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, 1.0)); + // P(isinf_sign, (1.0)); + + Q(nan, ("")); + Q(nanf, ("")); + Q(nanl, ("")); + Q(nans, ("")); + Q(nan, ("10")); + Q(nanf, ("10")); + Q(nanl, ("10")); + Q(nans, ("10")); + + P(isgreater, (1., 2.)); + P(isgreaterequal, (1., 2.)); + P(isless, (1., 2.)); + P(islessequal, (1., 2.)); + P(islessgreater, (1., 2.)); + P(isunordered, (1., 2.)); + + // Bitwise & Numeric Functions + + P(abs, (N)); + + P(clz, (N)); + P(clzl, (N)); + P(clzll, (N)); + P(ctz, (N)); + P(ctzl, (N)); + P(ctzll, (N)); + P(ffs, (N)); + P(ffsl, (N)); + P(ffsll, (N)); + P(parity, (N)); + P(parityl, (N)); + P(parityll, (N)); + P(popcount, (N)); + P(popcountl, (N)); + P(popcountll, (N)); + Q(powi, (1.2f, N)); + Q(powif, (1.2f, N)); + Q(powil, (1.2f, N)); + + // Lib functions + int a, b, n = random(); // Avoid optimizing out. + char s0[10], s1[] = "Hello"; + V(strcat, (s0, s1)); + V(strcmp, (s0, s1)); + V(strncat, (s0, s1, n)); + V(strchr, (s0, s1[0])); + V(strrchr, (s0, s1[0])); + V(strcpy, (s0, s1)); + V(strncpy, (s0, s1, n)); + + // Object size checking + V(__memset_chk, (s0, 0, sizeof s0, n)); + V(__memcpy_chk, (s0, s1, sizeof s0, n)); + V(__memmove_chk, (s0, s1, sizeof s0, n)); + V(__mempcpy_chk, (s0, s1, sizeof s0, n)); + V(__strncpy_chk, (s0, s1, sizeof s0, n)); + V(__strcpy_chk, (s0, s1, n)); + s0[0] = 0; + V(__strcat_chk, (s0, s1, n)); + P(object_size, (s0, 0)); + P(object_size, (s0, 1)); + P(object_size, (s0, 2)); + P(object_size, (s0, 3)); + + // Whatever + + P(bswap32, (N)); + P(bswap64, (N)); + // FIXME + // V(clear_cache, (&N, &N+1)); + V(trap, ()); + P(extract_return_addr, (&N)); + + return 0; +} + + + +void strcat() {} + +void foo() { + __builtin_strcat(0, 0); +} + diff --git a/test/CodeGen/builtinshufflevector.c b/test/CodeGen/builtinshufflevector.c new file mode 100644 index 0000000..9a3ae61 --- /dev/null +++ b/test/CodeGen/builtinshufflevector.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -emit-llvm < %s | grep 'shufflevector' | count 1 +typedef int v4si __attribute__ ((vector_size (16))); + +v4si a(v4si x, v4si y) {return __builtin_shufflevector(x, y, 3, 2, 5, 7);} + diff --git a/test/CodeGen/c-strings.c b/test/CodeGen/c-strings.c new file mode 100644 index 0000000..ee85f60 --- /dev/null +++ b/test/CodeGen/c-strings.c @@ -0,0 +1,36 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: grep "hello" %t | count 3 && +// RUN: grep 'c"hello\\00"' %t | count 2 && +// RUN: grep 'c"hello\\00\\00\\00"' %t | count 1 && +// RUN: grep 'c"ola"' %t | count 1 + +/* Should be 3 hello string, two global (of different sizes), the rest + are shared. */ + +void f0() { + bar("hello"); +} + +void f1() { + static char *x = "hello"; + bar(x); +} + +void f2() { + static char x[] = "hello"; + bar(x); +} + +void f3() { + static char x[8] = "hello"; + bar(x); +} + +void f4() { + static struct s { + char *name; + } x = { "hello" }; + gaz(&x); +} + +char x[3] = "ola"; diff --git a/test/CodeGen/cast-to-union.c b/test/CodeGen/cast-to-union.c new file mode 100644 index 0000000..03aee3e --- /dev/null +++ b/test/CodeGen/cast-to-union.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -emit-llvm < %s -o %t && +// RUN: grep "store i32 351, i32*" %t && +// RUN: grep "w = global %0 <{ i32 2, i8 0, i8 0, i8 0, i8 0 }>" %t && +// RUN: grep "y = global %1 <{ double 7.300000e+01 }>" %t + +union u { int i; double d; }; + +void foo() { + union u ola = (union u) 351; +} + +union u w = (union u)2; +union u y = (union u)73.0; diff --git a/test/CodeGen/cast.c b/test/CodeGen/cast.c new file mode 100644 index 0000000..6fb2b11 --- /dev/null +++ b/test/CodeGen/cast.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +extern void go(const void *p); +float v[2] = { 0.0, 1.0 }; +void foo(void) { go(v); } + diff --git a/test/CodeGen/cfstring.c b/test/CodeGen/cfstring.c new file mode 100644 index 0000000..a78dfda --- /dev/null +++ b/test/CodeGen/cfstring.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -emit-llvm %s -o %t +#define CFSTR __builtin___CFStringMakeConstantString + +void f() { + CFSTR("Hello, World!"); +} + +// rdar://6248329 +void *G = CFSTR("yo joe"); + +void h() { + static void* h = CFSTR("Goodbye, World!"); +} diff --git a/test/CodeGen/cfstring2.c b/test/CodeGen/cfstring2.c new file mode 100644 index 0000000..ceefeb9 --- /dev/null +++ b/test/CodeGen/cfstring2.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +typedef const struct __CFString * CFStringRef; + +#define CFSTR(x) (CFStringRef) __builtin___CFStringMakeConstantString (x) + +void f() { + CFSTR("Hello, World!"); +} + +// rdar://6151192 +void *G = CFSTR("yo joe"); + diff --git a/test/CodeGen/cleanup-stack.c b/test/CodeGen/cleanup-stack.c new file mode 100644 index 0000000..b0c5e88 --- /dev/null +++ b/test/CodeGen/cleanup-stack.c @@ -0,0 +1,25 @@ +// RUN: clang-cc -triple i386-unknown-unknown -O3 -emit-llvm %s -o %t && +// RUN: grep "ret i32 9" %t + +struct s0 { + int *var; + int addend; +}; + +static void f0(struct s0 *p) { + *p->var += p->addend; +} + +int f1(void) { + int var = 0; + + { + struct s0 x __attribute__((cleanup(f0))) = { &var, 2 }; + struct s0 y __attribute__((cleanup(f0))) = { &var, 3 }; + { + struct s0 y __attribute__((cleanup(f0))) = { &var, 4 }; + } + } + + return var; +} diff --git a/test/CodeGen/complex.c b/test/CodeGen/complex.c new file mode 100644 index 0000000..6a0d3d6 --- /dev/null +++ b/test/CodeGen/complex.c @@ -0,0 +1,61 @@ +// RUN: clang-cc -emit-llvm < %s + +int main(void) +{ + double _Complex a = 5; + double _Complex b = 42; + + return a * b != b * a; +} + +_Complex double bar(int); +void test(_Complex double*); +void takecomplex(_Complex double); + +void test2(int c) { + _Complex double X; + X = bar(1); + test(&X); + takecomplex(X); +} + +_Complex double g1, g2; +_Complex float cf; +double D; + +void test3() { + g1 = g1 + g2; + g1 = g1 - g2; + g1 = g1 * g2; + g1 = +-~g1; + + double Gr = __real g1; + + cf += D; + // FIXME: Currently unsupported! + //D += cf; + cf /= g1; + g1 = g1 + D; + g1 = D + g1; +} + +void t1() { + (__real__ cf) = 4.0; +} + +void t2() { + (__imag__ cf) = 4.0; +} + +// PR1960 +void t3() { + __complex__ long long v = 2; +} + +// PR3131 +float _Complex t4(); + +void t5() { + float _Complex x = t4(); +} + diff --git a/test/CodeGen/compound-literal.c b/test/CodeGen/compound-literal.c new file mode 100644 index 0000000..ef04367 --- /dev/null +++ b/test/CodeGen/compound-literal.c @@ -0,0 +1,12 @@ +// RUN: clang-cc < %s -emit-llvm + +int* a = &(int){1}; +struct s {int a, b, c;} * b = &(struct s) {1, 2, 3}; +// Not working; complex constants are broken +// _Complex double * x = &(_Complex double){1.0f}; + +int xxx() { +int* a = &(int){1}; +struct s {int a, b, c;} * b = &(struct s) {1, 2, 3}; +_Complex double * x = &(_Complex double){1.0f}; +} diff --git a/test/CodeGen/compound-type.c b/test/CodeGen/compound-type.c new file mode 100644 index 0000000..352f6cc --- /dev/null +++ b/test/CodeGen/compound-type.c @@ -0,0 +1,7 @@ +// RUN: clang-cc < %s -emit-llvm -triple i686-pc-linux-gnu > %t && +// RUN: grep "div i32" %t && +// RUN: grep "shl i32" %t + +unsigned char a,b; +void c(void) {a <<= b;} +void d(void) {a /= b;} diff --git a/test/CodeGen/compound.c b/test/CodeGen/compound.c new file mode 100644 index 0000000..c546007 --- /dev/null +++ b/test/CodeGen/compound.c @@ -0,0 +1,25 @@ +// RUN: clang-cc < %s -emit-llvm +int A; +long long B; +int C; +int *P; +void test1() { + C = (A /= B); + + P -= 4; + + C = P - (P+10); +} + +short x; +void test2(char c) { x += c; } + +void foo(char *strbuf) { + int stufflen = 4; + strbuf += stufflen; +} + + +// Aggregate cast to void +union uu { int a;}; void f(union uu p) { (void) p;} + diff --git a/test/CodeGen/conditional-gnu-ext.c b/test/CodeGen/conditional-gnu-ext.c new file mode 100644 index 0000000..1483d8a --- /dev/null +++ b/test/CodeGen/conditional-gnu-ext.c @@ -0,0 +1,12 @@ +// RUN: clang-cc -emit-llvm %s -o %t +// PR1824 + +int foo(int x, short y) { + return x ?: y; +} + +// rdar://6586493 +float test(float x, int Y) { + return Y != 0 ? : x; +} + diff --git a/test/CodeGen/conditional.c b/test/CodeGen/conditional.c new file mode 100644 index 0000000..2228670 --- /dev/null +++ b/test/CodeGen/conditional.c @@ -0,0 +1,44 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +float test1(int cond, float a, float b) +{ + return cond ? a : b; +} +double test2(int cond, float a, double b) +{ + return cond ? a : b; +} + +void f(); + +void test3(){ + 1 ? f() : (void)0; +} + +void test4() { +int i; short j; +float* k = 1 ? &i : &j; +} + +void test5() { + const int* cip; + void* vp; + cip = 0 ? vp : cip; +} + +void test6(); +void test7(int); +void* test8() {return 1 ? test6 : test7;} + + +void _efree(void *ptr); + +void _php_stream_free3() +{ + (1 ? free(0) : _efree(0)); +} + +void _php_stream_free4() +{ + 1 ? _efree(0) : free(0); +} diff --git a/test/CodeGen/const-init.c b/test/CodeGen/const-init.c new file mode 100644 index 0000000..0364cc1 --- /dev/null +++ b/test/CodeGen/const-init.c @@ -0,0 +1,104 @@ +// RUN: clang-cc -triple i386-pc-linux-gnu -verify -emit-llvm -o %t %s && + +#include <stdint.h> + +// Brace-enclosed string array initializers +char a[] = { "asdf" }; + +// Double-implicit-conversions of array/functions (not legal C, but +// clang accepts it for gcc compat). +intptr_t b = a; // expected-warning {{incompatible pointer to integer conversion}} +int c(); +void *d = c; +intptr_t e = c; // expected-warning {{incompatible pointer to integer conversion}} + +int f, *g = __extension__ &f, *h = (1 != 1) ? &f : &f; + +union s2 { + struct { + struct { } *f0; + } f0; +}; + +int g0 = (int)(&(((union s2 *) 0)->f0.f0) - 0); + +// RUN: grep '@g1x = global %. { double 1.000000e+00, double 0.000000e+00 }' %t && +_Complex double g1x = 1.0f; +// RUN: grep '@g1y = global %. { double 0.000000e+00, double 1.000000e+00 }' %t && +_Complex double g1y = 1.0fi; +// RUN: grep '@g1 = global %. { i8 1, i8 10 }' %t && +_Complex char g1 = (char) 1 + (char) 10 * 1i; +// RUN: grep '@g2 = global %2 { i32 1, i32 10 }' %t && +_Complex int g2 = 1 + 10i; +// RUN: grep '@g3 = global %. { float 1.000000e+00, float 1.000000e+01 }' %t && +_Complex float g3 = 1.0 + 10.0i; +// RUN: grep '@g4 = global %. { double 1.000000e+00, double 1.000000e+01 }' %t && +_Complex double g4 = 1.0 + 10.0i; +// RUN: grep '@g5 = global %2 zeroinitializer' %t && +_Complex int g5 = (2 + 3i) == (5 + 7i); +// RUN: grep '@g6 = global %. { double -1.100000e+01, double 2.900000e+01 }' %t && +_Complex double g6 = (2.0 + 3.0i) * (5.0 + 7.0i); +// RUN: grep '@g7 = global i32 1' %t && +int g7 = (2 + 3i) * (5 + 7i) == (-11 + 29i); +// RUN: grep '@g8 = global i32 1' %t && +int g8 = (2.0 + 3.0i) * (5.0 + 7.0i) == (-11.0 + 29.0i); +// RUN: grep '@g9 = global i32 0' %t && +int g9 = (2 + 3i) * (5 + 7i) != (-11 + 29i); +// RUN: grep '@g10 = global i32 0' %t && +int g10 = (2.0 + 3.0i) * (5.0 + 7.0i) != (-11.0 + 29.0i); + + +// Global references +// RUN: grep '@g11.l0 = internal global i32 ptrtoint (i32 ()\* @g11 to i32)' %t && +long g11() { + static long l0 = (long) g11; + return l0; +} + +// RUN: grep '@g12 = global i32 ptrtoint (i8\* @g12_tmp to i32)' %t && +static char g12_tmp; +long g12 = (long) &g12_tmp; + +// RUN: grep '@g13 = global \[1 x .struct.g13_s0\] \[.struct.g13_s0 <{ i32 ptrtoint (i8\* @g12_tmp to i32) }>\]' %t && +struct g13_s0 { + long a; +}; +struct g13_s0 g13[] = { + { (long) &g12_tmp } +}; + +// RUN: grep '@g14 = global i8\* inttoptr (i64 100 to i8\*)' %t && +void *g14 = (void*) 100; + +// RUN: grep '@g15 = global i32 -1' %t && +int g15 = (int) (char) ((void*) 0 + 255); + +// RUN: grep '@g16 = global i64 4294967295' %t && +long long g16 = (long long) ((void*) 0xFFFFFFFF); + +// RUN: grep '@g17 = global i32\* @g15' %t && +int *g17 = (int *) ((long) &g15); + +// RUN: grep '@g18.p = internal global \[1 x i32\*\] \[i32\* @g19\]' %t && +void g18(void) { + extern int g19; + static int *p[] = { &g19 }; +} + +// RUN: grep '@g20.l0 = internal global .struct.g20_s1 <{ .struct.g20_s0\* null, .struct.g20_s0\*\* getelementptr (.struct.g20_s1\* @g20.l0, i32 0, i32 0) }>' %t && + +struct g20_s0; +struct g20_s1 { + struct g20_s0 *f0, **f1; +}; +void *g20(void) { + static struct g20_s1 l0 = { ((void*) 0), &l0.f0 }; + return l0.f1; +} + +// PR4108 +struct g21 {int g21;}; +const struct g21 g21 = (struct g21){1}; + +// RUN: true + diff --git a/test/CodeGen/const-label-addr.c b/test/CodeGen/const-label-addr.c new file mode 100644 index 0000000..f8c35c6 --- /dev/null +++ b/test/CodeGen/const-label-addr.c @@ -0,0 +1,4 @@ +// RUN: clang-cc %s -emit-llvm -o %t +int a() { +A:;static void* a = &&A; +} diff --git a/test/CodeGen/constant-comparison.c b/test/CodeGen/constant-comparison.c new file mode 100644 index 0000000..ea3e896 --- /dev/null +++ b/test/CodeGen/constant-comparison.c @@ -0,0 +1,12 @@ +// RUN: clang-cc -emit-llvm %s -o - 2>&1 | not grep warning && +// RUN: clang-cc -emit-llvm %s -o - | grep @b | count 1 + +int a, b; +int *c1 = 1 < 2 ? &a : &b; +int *c2 = 3 != 3LL ? &b : &a; +int *c3 = !(3 <= 4.0) ? &b : &a; +int *c4 = &a - (6 * 5 > 30); +int *c5 = &a + (6 * 5 >= 30); +int c6 = 44 < 33; + + diff --git a/test/CodeGen/constructor-attribute.c b/test/CodeGen/constructor-attribute.c new file mode 100644 index 0000000..9a1fa76 --- /dev/null +++ b/test/CodeGen/constructor-attribute.c @@ -0,0 +1,38 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: grep -e "global_ctors.*@A" %t && +// RUN: grep -e "global_dtors.*@B" %t && +// RUN: grep -e "global_ctors.*@C" %t && +// RUN: grep -e "global_dtors.*@D" %t + +#include <stdio.h> + +void A() __attribute__((constructor)); +void B() __attribute__((destructor)); + +void A() { + printf("A\n"); +} + +void B() { + printf("B\n"); +} + +static void C() __attribute__((constructor)); + +static void D() __attribute__((destructor)); + +static int foo() { + return 10; +} + +static void C() { + printf("A: %d\n", foo()); +} + +static void D() { + printf("B\n"); +} + +int main() { + return 0; +} diff --git a/test/CodeGen/cxx-condition.cpp b/test/CodeGen/cxx-condition.cpp new file mode 100644 index 0000000..330a17a --- /dev/null +++ b/test/CodeGen/cxx-condition.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +void f() { + int a; + if (int x=a) ++a; else a=x; + while (int x=a) ++a; + for (; int x=a; --a) ; + switch (int x=0) { } +} diff --git a/test/CodeGen/cxx-default-arg.cpp b/test/CodeGen/cxx-default-arg.cpp new file mode 100644 index 0000000..8391b9c --- /dev/null +++ b/test/CodeGen/cxx-default-arg.cpp @@ -0,0 +1,25 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +// Note: define CLANG_GENERATE_KNOWN_GOOD and compile to generate code +// that makes all of the defaulted arguments explicit. The resulting +// byte code should be identical to the compilation without +// CLANG_GENERATE_KNOWN_GOOD. +#ifdef CLANG_GENERATE_KNOWN_GOOD +# define DEFARG(...) __VA_ARGS__ +#else +# define DEFARG(...) +#endif + +extern int x; +struct S { float x; float y; } s; +double _Complex c; + +void f(int i = 0, int j = 1, int k = x, struct S t = s, double _Complex d = c); + +void g() { + f(0, 1, x, s DEFARG(, c)); + f(0, 1, x DEFARG(, s, c)); + f(0, 1 DEFARG(, x, s, c)); + f(0 DEFARG(, 1, x, s, c)); + f(DEFARG(0, 1, x, s, c)); +} diff --git a/test/CodeGen/cxx-value-init.cpp b/test/CodeGen/cxx-value-init.cpp new file mode 100644 index 0000000..e238698 --- /dev/null +++ b/test/CodeGen/cxx-value-init.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +enum E {}; +int v1 = E(); +float v2 = float(); + +void f() { + int v3 = int(); + _Complex int v4 = typeof(_Complex int)(); + _Complex float v5 = typeof(_Complex float)(); +} diff --git a/test/CodeGen/darwin-string-literals.c b/test/CodeGen/darwin-string-literals.c new file mode 100644 index 0000000..ff245fc --- /dev/null +++ b/test/CodeGen/darwin-string-literals.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm %s -o %t && + +// RUN: grep -F '@"\01LC" = internal constant [8 x i8] c"string0\00"' %t && +// RUN: grep -F '@"\01LC1" = internal constant [8 x i8] c"string1\00", section "__TEXT,__cstring,cstring_literals"' %t && +// RUN: grep -F '@__utf16_string_ = internal global [35 x i8] c"h\00e\00l\00l\00o\00 \00\92! \00\03& \00\90! \00w\00o\00r\00l\00d\00\00", section "__TEXT,__ustring", align 2' %t && +// RUN: true + +const char *g0 = "string0"; +const void *g1 = __builtin___CFStringMakeConstantString("string1"); +const void *g2 = __builtin___CFStringMakeConstantString("hello \u2192 \u2603 \u2190 world"); diff --git a/test/CodeGen/debug-info.c b/test/CodeGen/debug-info.c new file mode 100644 index 0000000..e0ec2c9 --- /dev/null +++ b/test/CodeGen/debug-info.c @@ -0,0 +1,37 @@ +// RUN: clang-cc -o %t --emit-llvm -g %s + +// PR3023 +void convert(void) { + struct { typeof(0) f0; } v0; +} + +// PR2784 +struct OPAQUE; +typedef struct OPAQUE *PTR; +PTR p; + + +// PR2950 +struct s0; +struct s0 { struct s0 *p; } g0; + +struct s0 *f0(struct s0 *a0) { + return a0->p; +} + +// PR3134 +char xpto[]; + +// PR3427 +struct foo { + int a; + void *ptrs[]; +}; +struct foo bar; + +// PR4143 +struct foo2 { + enum bar *bar; +}; + +struct foo2 foo2; diff --git a/test/CodeGen/designated-initializers.c b/test/CodeGen/designated-initializers.c new file mode 100644 index 0000000..4669339 --- /dev/null +++ b/test/CodeGen/designated-initializers.c @@ -0,0 +1,21 @@ +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o - | grep "<{ i8\* null, i32 1024 }>" && +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o - | grep "i32 0, i32 22" + +struct foo { + void *a; + int b; +}; + +union { int i; float f; } u = { }; + +int main(int argc, char **argv) +{ + union { int i; float f; } u2 = { }; + static struct foo foo = { + .b = 1024, + }; +} + +int b[2] = { + [1] 22 +}; diff --git a/test/CodeGen/dllimport-dllexport.c b/test/CodeGen/dllimport-dllexport.c new file mode 100644 index 0000000..fe49ae7 --- /dev/null +++ b/test/CodeGen/dllimport-dllexport.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm < %s -o %t && +// RUN: grep 'dllexport' %t | count 1 && +// RUN: not grep 'dllimport' %t + +void __attribute__((dllimport)) foo1(); +void __attribute__((dllexport)) foo1(){} +void __attribute__((dllexport)) foo2(); diff --git a/test/CodeGen/dostmt.c b/test/CodeGen/dostmt.c new file mode 100644 index 0000000..4fb3dcd --- /dev/null +++ b/test/CodeGen/dostmt.c @@ -0,0 +1,70 @@ +// RUN: clang-cc %s -emit-llvm -o - + +int bar(); +int test0() { + int i; + i = 1 + 2; + do { + i = bar(); + i = bar(); + } while(0); + return i; +} + + +int test1() { + int i; + i = 1 + 2; + do { + i = bar(); + if (i == 42) + break; + i = bar(); + } while(1); + return i; +} + + +int test2() { + int i; + i = 1 + 2; + do { + i = bar(); + if (i == 42) + continue; + i = bar(); + } while(1); + return i; +} + + +int test3() { + int i; + i = 1 + 2; + do { + i = bar(); + if (i == 42) + break; + } while(0); + return i; +} + + +int test4() { + int i; + i = 1 + 2; + do { + i = bar(); + if (i == 42) + continue; + } while(0); + return i; +} + +// rdar://6103124 +void test5() { + do { break; } while(0); +} + + + diff --git a/test/CodeGen/emit-all-decls.c b/test/CodeGen/emit-all-decls.c new file mode 100644 index 0000000..775cb6f --- /dev/null +++ b/test/CodeGen/emit-all-decls.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: not grep "@foo" %t && +// RUN: clang-cc -femit-all-decls -emit-llvm -o %t %s && +// RUN: grep "@foo" %t + +static void foo() { + +} diff --git a/test/CodeGen/empty-union-init.c b/test/CodeGen/empty-union-init.c new file mode 100644 index 0000000..8448b3d --- /dev/null +++ b/test/CodeGen/empty-union-init.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -emit-llvm < %s -o - +// PR2419 + +struct Mem { + union { + } u; +}; + +struct Mem *columnMem(){ + static const struct Mem nullMem = { {} }; +} + + diff --git a/test/CodeGen/enum.c b/test/CodeGen/enum.c new file mode 100644 index 0000000..172d308 --- /dev/null +++ b/test/CodeGen/enum.c @@ -0,0 +1,18 @@ +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm-bc -o - | opt -std-compile-opts | llvm-dis | grep 'ret i32 6' + +static enum { foo, bar = 1U } z; + +int main (void) +{ + int r = 0; + + if (bar - 2 < 0) + r += 4; + if (foo - 1 < 0) + r += 2; + if (z - 1 < 0) + r++; + + return r; +} + diff --git a/test/CodeGen/exprs.c b/test/CodeGen/exprs.c new file mode 100644 index 0000000..36cfff9 --- /dev/null +++ b/test/CodeGen/exprs.c @@ -0,0 +1,118 @@ +// RUN: clang-cc %s -emit-llvm -o - + +// PR1895 +// sizeof function +int zxcv(void); +int x=sizeof(zxcv); +int y=__alignof__(zxcv); + + +void *test(int *i) { + short a = 1; + i += a; + i + a; + a + i; +} + +_Bool test2b; +int test2() {if (test2b);} + +// PR1921 +int test3() { + const unsigned char *bp; + bp -= (short)1; +} + +// PR2080 - sizeof void +int t1 = sizeof(void); +int t2 = __alignof__(void); +void test4() { + t1 = sizeof(void); + t2 = __alignof__(void); + + t1 = sizeof(test4()); + t2 = __alignof__(test4()); +} + +// 'const float' promotes to double in varargs. +int test5(const float x, float float_number) { + return __builtin_isless(x, float_number); +} + +// this one shouldn't fold +int ola() { + int a=2; + if ((0, (int)a) & 2) { return 1; } + return 2; +} + +// this one shouldn't fold as well +void eMaisUma() { + double t[1]; + if (*t) + return; +} + +// rdar://6520707 +void f0(void (*fp)(void), void (*fp2)(void)) { + int x = fp - fp2; +} + +// noop casts as lvalues. +struct X { + int Y; +}; +struct X foo(); +int bar() { + return ((struct X)foo()).Y + 1; +} + +// PR3809: INC/DEC of function pointers. +void f2(void); +unsigned f1(void) { + void (*fp)(void) = f2; + + ++fp; + fp++; + --fp; + fp--; + return (unsigned) fp; +} + +union f3_x {int x; float y;}; +int f3() {return ((union f3_x)2).x;} + +union f4_y {int x; _Complex float y;}; +_Complex float f4() {return ((union f4_y)(_Complex float)2.0).y;} + +struct f5_a { int a; } f5_a; +union f5_z {int x; struct f5_a y;}; +struct f5_a f5() {return ((union f5_z)f5_a).y;} + +// ?: in "lvalue" +struct s6 { int f0; }; +int f6(int a0, struct s6 a1, struct s6 a2) { + return (a0 ? a1 : a2).f0; +} + +// PR4026 +void f7() { + __func__; +} + +// PR4067 +int f8() { + return ({ foo(); }).Y; +} + +// rdar://6880558 +struct S; +struct C { + int i; + struct S *tab[]; +}; +struct S { struct C c; }; +void f9(struct S *x) { + foo(((void)1, x->c).tab[0]); +} + diff --git a/test/CodeGen/ext-vector-shuffle.c b/test/CodeGen/ext-vector-shuffle.c new file mode 100644 index 0000000..37d3ed4 --- /dev/null +++ b/test/CodeGen/ext-vector-shuffle.c @@ -0,0 +1,15 @@ +// RUN: clang-cc %s -emit-llvm -o - | not grep 'extractelement' +// RUN: clang-cc %s -emit-llvm -o - | not grep 'insertelement' +// RUN: clang-cc %s -emit-llvm -o - | grep 'shufflevector' + +typedef __attribute__(( ext_vector_type(2) )) float float2; +typedef __attribute__(( ext_vector_type(4) )) float float4; + +float2 test1(float4 V) { + return V.xy + V.wz; +} + +float4 test2(float4 V) { + float2 W = V.ww; + return W.xyxy + W.yxyx; +} diff --git a/test/CodeGen/ext-vector.c b/test/CodeGen/ext-vector.c new file mode 100644 index 0000000..e3b6211 --- /dev/null +++ b/test/CodeGen/ext-vector.c @@ -0,0 +1,129 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +typedef __attribute__(( ext_vector_type(4) )) float float4; +typedef __attribute__(( ext_vector_type(2) )) float float2; +typedef __attribute__(( ext_vector_type(4) )) int int4; + +float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 }; + +const float4 bar = (float4){ 1.0, 2.0, 3.0, __builtin_inff() }; + +float4 test1(float4 V) { + return V.wzyx+V; +} + +float2 vec2, vec2_2; +float4 vec4, vec4_2; +float f; + +void test2() { + vec2 = vec4.xy; // shorten + f = vec2.x; // extract elt + vec4 = vec4.yyyy; // splat + + vec2.x = f; // insert one. + vec2.yx = vec2; // reverse +} + +void test3(float4 *out) { + *out = ((float4) {1.0f, 2.0f, 3.0f, 4.0f }); +} + +void test4(float4 *out) { + float a = 1.0f; + float b = 2.0f; + float c = 3.0f; + float d = 4.0f; + *out = ((float4) {a,b,c,d}); +} + +void test5(float4 *out) { + float a; + float4 b; + + a = 1.0f; + b = a; + b = b * 5.0f; + b = 5.0f * b; + b *= a; + + *out = b; +} + +void test6(float4 *ap, float4 *bp, float c) { + float4 a = *ap; + float4 b = *bp; + + a = a + b; + a = a - b; + a = a * b; + a = a / b; + + a = a + c; + a = a - c; + a = a * c; + a = a / c; + + a += b; + a -= b; + a *= b; + a /= b; + + a += c; + a -= c; + a *= c; + a /= c; + + // Vector comparisons can sometimes crash the x86 backend: rdar://6326239, + // reject them until the implementation is stable. +#if 0 + int4 cmp; + cmp = a < b; + cmp = a <= b; + cmp = a < b; + cmp = a >= b; + cmp = a == b; + cmp = a != b; +#endif +} + +void test7(int4 *ap, int4 *bp, int c) { + int4 a = *ap; + int4 b = *bp; + + a = a + b; + a = a - b; + a = a * b; + a = a / b; + a = a % b; + + a = a + c; + a = a - c; + a = a * c; + a = a / c; + a = a % c; + + a += b; + a -= b; + a *= b; + a /= b; + a %= b; + + a += c; + a -= c; + a *= c; + a /= c; + a %= c; + + // Vector comparisons can sometimes crash the x86 backend: rdar://6326239, + // reject them until the implementation is stable. +#if 0 + int4 cmp; + cmp = a < b; + cmp = a <= b; + cmp = a < b; + cmp = a >= b; + cmp = a == b; + cmp = a != b; +#endif +} diff --git a/test/CodeGen/extern-block-var.c b/test/CodeGen/extern-block-var.c new file mode 100644 index 0000000..e8de3e7 --- /dev/null +++ b/test/CodeGen/extern-block-var.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +int f() { + extern int a; + return a; +} diff --git a/test/CodeGen/flexible-array-init.c b/test/CodeGen/flexible-array-init.c new file mode 100644 index 0000000..fb98a8e --- /dev/null +++ b/test/CodeGen/flexible-array-init.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm -o - %s | grep 7 | count 1 && +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm -o - %s | grep 11 | count 1 && +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm -o - %s | grep 13 | count 1 && +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm -o - %s | grep 15 | count 1 + +struct { int x; int y[]; } a = { 1, 7, 11 }; + +struct { int x; int y[]; } b = { 1, { 13, 15 } }; diff --git a/test/CodeGen/func-decl-cleanup.c b/test/CodeGen/func-decl-cleanup.c new file mode 100644 index 0000000..4808e12 --- /dev/null +++ b/test/CodeGen/func-decl-cleanup.c @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -emit-llvm -o - + + +// PR2360 +typedef void fn_t(); + +fn_t a,b; + +void b() +{ +} + diff --git a/test/CodeGen/func-return-member.c b/test/CodeGen/func-return-member.c new file mode 100644 index 0000000..e6fc562 --- /dev/null +++ b/test/CodeGen/func-return-member.c @@ -0,0 +1,23 @@ +// RUN: clang-cc -emit-llvm < %s 2>&1 | not grep 'cannot codegen this l-value expression yet' + +struct frk { float _Complex c; int x; }; +struct faz { struct frk f; }; +struct fuz { struct faz f; }; + +extern struct fuz foo(void); + +int X; +struct frk F; +float _Complex C; + +void bar(void) { + X = foo().f.f.x; +} + +void bun(void) { + F = foo().f.f; +} + +void ban(void) { + C = foo().f.f.c; +} diff --git a/test/CodeGen/function-attributes.c b/test/CodeGen/function-attributes.c new file mode 100644 index 0000000..ba2e4e4 --- /dev/null +++ b/test/CodeGen/function-attributes.c @@ -0,0 +1,69 @@ +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm -o %t %s && +// RUN: grep 'define signext i8 @f0(i32 %x) nounwind' %t && +// RUN: grep 'define zeroext i8 @f1(i32 %x) nounwind' %t && +// RUN: grep 'define void @f2(i8 signext %x) nounwind' %t && +// RUN: grep 'define void @f3(i8 zeroext %x) nounwind' %t && +// RUN: grep 'define signext i16 @f4(i32 %x) nounwind' %t && +// RUN: grep 'define zeroext i16 @f5(i32 %x) nounwind' %t && +// RUN: grep 'define void @f6(i16 signext %x) nounwind' %t && +// RUN: grep 'define void @f7(i16 zeroext %x) nounwind' %t && + +signed char f0(int x) { return x; } + +unsigned char f1(int x) { return x; } + +void f2(signed char x) { } + +void f3(unsigned char x) { } + +signed short f4(int x) { return x; } + +unsigned short f5(int x) { return x; } + +void f6(signed short x) { } + +void f7(unsigned short x) { } + +// RUN: grep 'define void @f8() nounwind alwaysinline' %t && +void __attribute__((always_inline)) f8(void) { } + +// RUN: grep 'call void @f9_t() noreturn' %t && +void __attribute__((noreturn)) f9_t(void); +void f9(void) { f9_t(); } + +// FIXME: We should be setting nounwind on calls. +// RUN: grep 'call i32 @f10_t() readnone' %t && +int __attribute__((const)) f10_t(void); +int f10(void) { return f10_t(); } +int f11(void) { + exit: + return f10_t(); +} +int f12(int arg) { + return arg ? 0 : f10_t(); +} + +// RUN: grep 'define void @f13() nounwind readnone' %t && +void f13(void) __attribute__((pure)) __attribute__((const)); +void f13(void){} + + +// Ensure that these get inlined: rdar://6853279 +// RUN: not grep '@ai_' %t && +static __inline__ __attribute__((always_inline)) +int ai_1() { return 4; } + +static __inline__ __attribute__((always_inline)) +struct { + int a, b, c, d, e; +} ai_2() { } + + +int foo() { + ai_2(); + return ai_1(); +} + + + +// RUN: true diff --git a/test/CodeGen/function-decay.m b/test/CodeGen/function-decay.m new file mode 100644 index 0000000..5652fdb --- /dev/null +++ b/test/CodeGen/function-decay.m @@ -0,0 +1,10 @@ +// RUN: clang-cc %s -emit-llvm -o - + +@interface I0 @end +@implementation I0 +- (void) im0: (int (void)) a0 { +} +@end + +void func(int pf(void)) { +} diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c new file mode 100644 index 0000000..9855992 --- /dev/null +++ b/test/CodeGen/functions.c @@ -0,0 +1,35 @@ +// RUN: clang-cc %s -emit-llvm -o %t && + +int g(); + +int foo(int i) { + return g(i); +} + +int g(int i) { + return g(i); +} + +// rdar://6110827 +typedef void T(void); +void test3(T f) { + f(); +} + +int a(int); +int a() {return 1;} + +// RUN: grep 'define void @f0()' %t && +void f0() {} + +void f1(); +// RUN: grep 'call void @f1()' %t && +void f2(void) { + f1(1, 2, 3); +} +// RUN: grep 'define void @f1()' %t && +void f1() {} + +// RUN: grep 'define .* @f3' %t | not grep -F '...' +struct foo { int X, Y, Z; } f3() { +} diff --git a/test/CodeGen/global-decls.c b/test/CodeGen/global-decls.c new file mode 100644 index 0000000..80222ea --- /dev/null +++ b/test/CodeGen/global-decls.c @@ -0,0 +1,22 @@ +// RUN: clang-cc -triple i386-pc-linux-gnu -emit-llvm -o %t %s && + +// RUN: grep '@g0_ext = extern_weak global i32' %t && +extern int g0_ext __attribute__((weak)); +// RUN: grep 'declare extern_weak i32 @g1_ext()' %t && +extern int __attribute__((weak)) g1_ext (void); + +// RUN: grep '@g0_common = weak global i32' %t && +int g0_common __attribute__((weak)); + +// RUN: grep '@g0_def = weak global i32' %t && +int g0_def __attribute__((weak)) = 52; +// RUN: grep 'define weak i32 @g1_def()' %t && +int __attribute__((weak)) g1_def (void) {} + +// Force _ext references +void f0() { + int a = g0_ext; + int b = g1_ext(); +} + +// RUN: true diff --git a/test/CodeGen/global-init.c b/test/CodeGen/global-init.c new file mode 100644 index 0000000..4b769f8 --- /dev/null +++ b/test/CodeGen/global-init.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm -o - %s | not grep "common" + +// This checks that the global won't be marked as common. +// (It shouldn't because it's being initialized). + +int a; +int a = 242; diff --git a/test/CodeGen/global-with-initialiser.c b/test/CodeGen/global-with-initialiser.c new file mode 100644 index 0000000..29b4e21 --- /dev/null +++ b/test/CodeGen/global-with-initialiser.c @@ -0,0 +1,25 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +const int globalInt = 1; +int globalIntWithFloat = 1.5f; +int globalIntArray[5] = { 1, 2 }; +int globalIntFromSizeOf = sizeof(globalIntArray); +char globalChar = 'a'; +char globalCharArray[5] = { 'a', 'b' }; +float globalFloat = 1.0f; +float globalFloatWithInt = 1; +float globalFloatArray[5] = { 1.0f, 2.0f }; +double globalDouble = 1.0; +double globalDoubleArray[5] = { 1.0, 2.0 }; +char *globalString = "abc"; +char *globalStringArray[5] = { "123", "abc" }; +long double globalLongDouble = 1; +long double globalLongDoubleArray[5] = { 1.0, 2.0 }; + +struct Struct { + int member1; + float member2; + char *member3; +}; + +struct Struct globalStruct = { 1, 2.0f, "foobar"}; diff --git a/test/CodeGen/globalinit.c b/test/CodeGen/globalinit.c new file mode 100644 index 0000000..2798cae --- /dev/null +++ b/test/CodeGen/globalinit.c @@ -0,0 +1,51 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +int A[10] = { 1,2,3,4,5 }; + + +extern int x[]; +void foo() { x[0] = 1; } +int x[10]; +void bar() { x[0] = 1; } + + +extern int y[]; +void *g = y; + +int latin_ptr2len (char *p); +int (*mb_ptr2len) (char *p) = latin_ptr2len; + + +char string[8] = "string"; // extend init +char string2[4] = "string"; // truncate init + +char *test(int c) { + static char buf[10]; + static char *bufptr = buf; + + return c ? buf : bufptr; +} + + +_Bool booltest = 0; +void booltest2() { + static _Bool booltest3 = 4; +} + +// Scalars in braces. +static int a = { 1 }; + +// References to enums. +enum { + EnumA, EnumB +}; + +int c[] = { EnumA, EnumB }; + +// Binary operators +int d[] = { EnumA | EnumB }; + +// PR1968 +static int array[]; +static int array[4]; + diff --git a/test/CodeGen/illegal-UTF8.m b/test/CodeGen/illegal-UTF8.m new file mode 100644 index 0000000..a9d5a37 --- /dev/null +++ b/test/CodeGen/illegal-UTF8.m @@ -0,0 +1,8 @@ +// RUN: clang %s -S -m64 -o - + +@class NSString; + +// FIXME: GCC emits the following warning: +// CodeGen/illegal-UTF8.m:4: warning: input conversion stopped due to an input byte that does not belong to the input codeset UTF-8 + +NSString *S = @"\xff\xff___WAIT___"; diff --git a/test/CodeGen/incomplete-function-type.c b/test/CodeGen/incomplete-function-type.c new file mode 100644 index 0000000..a641268 --- /dev/null +++ b/test/CodeGen/incomplete-function-type.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm %s -o - | not grep opaque + +enum teste1 test1f(void), (*test1)(void) = test1f; +struct tests2 test2f(), (*test2)() = test2f; +struct tests3; +void test3f(struct tests3), (*test3)(struct tests3) = test3f; +enum teste1 { TEST1 }; +struct tests2 { int x,y,z,a,b,c,d,e,f,g; }; +struct tests3 { float x; }; + diff --git a/test/CodeGen/indirect-goto.c b/test/CodeGen/indirect-goto.c new file mode 100644 index 0000000..b9a6019 --- /dev/null +++ b/test/CodeGen/indirect-goto.c @@ -0,0 +1,20 @@ +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t && +// RUN: grep "ret i32" %t | count 1 && +// RUN: grep "ret i32 210" %t | count 1 + +static int foo(unsigned i) { + const void *addrs[] = { &&L1, &&L2, &&L3, &&L4, &&L5 }; + int res = 1; + + goto *addrs[i]; + L5: res *= 11; + L4: res *= 7; + L3: res *= 5; + L2: res *= 3; + L1: res *= 2; + return res; +} + +int bar() { + return foo(3); +} diff --git a/test/CodeGen/init-with-member-expr.c b/test/CodeGen/init-with-member-expr.c new file mode 100644 index 0000000..7750dbf --- /dev/null +++ b/test/CodeGen/init-with-member-expr.c @@ -0,0 +1,21 @@ +// RUN: clang-cc < %s -emit-llvm +struct test { + int a; +}; + +extern struct test t; + +int *b=&t.a; + + +// PR2049 +typedef struct mark_header_tag { + unsigned char mark[7]; +} mark_header_t; +int is_rar_archive(int fd) { + const mark_header_t rar_hdr[2] = {{0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}, {'U', 'n', 'i', 'q', 'u', 'E', '!'}}; + foo(rar_hdr); + + return 0; +} + diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c new file mode 100644 index 0000000..2e239cf --- /dev/null +++ b/test/CodeGen/init.c @@ -0,0 +1,31 @@ +// RUN: clang-cc -triple i386-unknown-unknown -emit-llvm %s -o %t && + +void f1() { + // Scalars in braces. + int a = { 1 }; +} + +void f2() { + int a[2][2] = { { 1, 2 }, { 3, 4 } }; + int b[3][3] = { { 1, 2 }, { 3, 4 } }; + int *c[2] = { &a[1][1], &b[2][2] }; + int *d[2][2] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} }; + int *e[3][3] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} }; + char ext[3][3] = {".Y",".U",".V"}; +} + +typedef void (* F)(void); +extern void foo(void); +struct S { F f; }; +void f3() { + struct S a[1] = { { foo } }; +} + +// Constants +// RUN: grep '@g3 = constant i32 10' %t && +// RUN: grep '@f4.g4 = internal constant i32 12' %t +const int g3 = 10; +int f4() { + static const int g4 = 12; + return g4; +} diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c new file mode 100644 index 0000000..234f1f8 --- /dev/null +++ b/test/CodeGen/inline.c @@ -0,0 +1,86 @@ +// RUN: echo "C89 tests:" && +// RUN: clang %s -emit-llvm -S -o %t -std=c89 && +// RUN: grep "define available_externally i32 @ei()" %t && +// RUN: grep "define i32 @foo()" %t && +// RUN: grep "define i32 @bar()" %t && +// RUN: grep "define void @unreferenced1()" %t && +// RUN: not grep unreferenced2 %t && +// RUN: grep "define void @gnu_inline()" %t && +// RUN: grep "define available_externally void @gnu_ei_inline()" %t && +// RUN: grep "define i32 @test1" %t && +// RUN: grep "define i32 @test2" %t && +// RUN: grep "define void @test3()" %t && +// RUN: grep "define available_externally i32 @test4" %t && +// RUN: grep "define available_externally i32 @test5" %t && + +// RUN: echo "\nC99 tests:" && +// RUN: clang %s -emit-llvm -S -o %t -std=c99 && +// RUN: grep "define i32 @ei()" %t && +// RUN: grep "define available_externally i32 @foo()" %t && +// RUN: grep "define i32 @bar()" %t && +// RUN: not grep unreferenced1 %t && +// RUN: grep "define void @unreferenced2()" %t && +// RUN: grep "define void @gnu_inline()" %t && +// RUN: grep "define available_externally void @gnu_ei_inline()" %t && +// RUN: grep "define i32 @test1" %t && +// RUN: grep "define i32 @test2" %t && +// RUN: grep "define available_externally void @test3" %t && +// RUN: grep "define available_externally i32 @test4" %t && +// RUN: grep "define i32 @test5" %t && + +// RUN: echo "\nC++ tests:" && +// RUN: clang %s -emit-llvm -S -o %t -std=c++98 && +// RUN: grep "define linkonce_odr i32 @_Z2eiv()" %t && +// RUN: grep "define linkonce_odr i32 @_Z3foov()" %t && +// RUN: grep "define i32 @_Z3barv()" %t && +// RUN: not grep unreferenced %t && +// RUN: grep "define void @_Z10gnu_inlinev()" %t && +// RUN: grep "define available_externally void @_Z13gnu_ei_inlinev()" %t + +extern __inline int ei() { return 123; } + +__inline int foo() { + return ei(); +} + +int bar() { return foo(); } + + +__inline void unreferenced1() {} +extern __inline void unreferenced2() {} + +__inline __attribute((__gnu_inline__)) void gnu_inline() {} + +// PR3988 +extern __inline __attribute__((gnu_inline)) void gnu_ei_inline() {} +void (*P)() = gnu_ei_inline; + +// <rdar://problem/6818429> +int test1(); +__inline int test1() { return 4; } +__inline int test2() { return 5; } +__inline int test2(); +int test2(); + +void test_test1() { test1(); } +void test_test2() { test2(); } + +// PR3989 +extern __inline void test3() __attribute__((gnu_inline)); +__inline void test3() {} + +void test_test3() { test3(); } + +extern int test4(void); +extern __inline __attribute__ ((__gnu_inline__)) int test4(void) +{ +} + +void test_test4() { test4(); } + +extern __inline int test5(void); +extern __inline int __attribute__ ((__gnu_inline__)) test5(void) +{ +} + +void test_test5() { test5(); } diff --git a/test/CodeGen/int-to-pointer.c b/test/CodeGen/int-to-pointer.c new file mode 100644 index 0000000..7cefc39 --- /dev/null +++ b/test/CodeGen/int-to-pointer.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +void *test(int i) +{ + return (void *)i; +} diff --git a/test/CodeGen/kr-func-promote.c b/test/CodeGen/kr-func-promote.c new file mode 100644 index 0000000..d4c3851 --- /dev/null +++ b/test/CodeGen/kr-func-promote.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o - | grep "i32 @a(i32)" + +int a(); +int a(x) short x; {return x;} + diff --git a/test/CodeGen/kr-style-block.c b/test/CodeGen/kr-style-block.c new file mode 100644 index 0000000..ac788dc --- /dev/null +++ b/test/CodeGen/kr-style-block.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm %s -o %t -fblocks + +void foo (void(^)()); + +int main() +{ +foo( + ^() { } +); +} diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c new file mode 100644 index 0000000..6953216 --- /dev/null +++ b/test/CodeGen/libcalls.c @@ -0,0 +1,22 @@ +// RUN: clang-cc -fmath-errno=1 -emit-llvm -o %t %s && +// RUN: grep "declare " %t | count 6 && +// RUN: grep "declare " %t | grep "@llvm." | count 1 && +// RUN: clang-cc -fmath-errno=0 -emit-llvm -o %t %s && +// RUN: grep "declare " %t | count 6 && +// RUN: grep "declare " %t | grep -v "@llvm." | count 0 + +// IRgen only pays attention to const; it should always call llvm for +// this. +float sqrtf(float) __attribute__((const)); + +void test_sqrt(float a0, double a1, long double a2) { + float l0 = sqrtf(a0); + double l1 = sqrt(a1); + long double l2 = sqrtl(a2); +} + +void test_pow(float a0, double a1, long double a2) { + float l0 = powf(a0, a0); + double l1 = pow(a1, a1); + long double l2 = powl(a2, a2); +} diff --git a/test/CodeGen/lineno-dbginfo.c b/test/CodeGen/lineno-dbginfo.c new file mode 100644 index 0000000..fe9e59a --- /dev/null +++ b/test/CodeGen/lineno-dbginfo.c @@ -0,0 +1,5 @@ +// RUN: echo "#include <stdio.h>" > %t.h +// RUN: clang -S -save-temps -g -include %t.h %s -emit-llvm -o %t.ll +// RUN: grep "i32 5" %t.ll +// outer is at line number 5. +int outer = 42; diff --git a/test/CodeGen/linkage-redecl.c b/test/CodeGen/linkage-redecl.c new file mode 100644 index 0000000..b015ca8 --- /dev/null +++ b/test/CodeGen/linkage-redecl.c @@ -0,0 +1,11 @@ +// RUN: clang-cc -emit-llvm %s -o - |grep internal + +// C99 6.2.2p3 +// PR3425 +static void f(int x); + +void g0() { + f(5); +} + +extern void f(int x) { } // still has internal linkage diff --git a/test/CodeGen/long-double-x86.c b/test/CodeGen/long-double-x86.c new file mode 100644 index 0000000..b01ce0b --- /dev/null +++ b/test/CodeGen/long-double-x86.c @@ -0,0 +1,4 @@ +// RUN: clang-cc %s -emit-llvm -o - -triple=i686-apple-darwin9 | grep x86_fp80 + +long double x = 0; +int checksize[sizeof(x) == 16 ? 1 : -1]; diff --git a/test/CodeGen/mandel.c b/test/CodeGen/mandel.c new file mode 100644 index 0000000..6f46ee4 --- /dev/null +++ b/test/CodeGen/mandel.c @@ -0,0 +1,67 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +/* Sparc is not C99-compliant */ +#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) + +int main() { return 0; } + +#else /* sparc */ + +#define ESCAPE 2 +#define IMAGE_WIDTH 150 +#define IMAGE_HEIGHT 50 +#if 1 +#define IMAGE_SIZE 60 +#else +#define IMAGE_SIZE 5000 +#endif +#define START_X -2.1 +#define END_X 1.0 +#define START_Y -1.25 +#define MAX_ITER 100 + +#define step_X ((END_X - START_X)/IMAGE_WIDTH) +#define step_Y ((-START_Y - START_Y)/IMAGE_HEIGHT) + +#define I 1.0iF + +#include <math.h> + +#include <stdio.h> + +volatile double __complex__ accum; + +void mandel() { + int x, y, n; + for (y = 0; y < IMAGE_HEIGHT; ++y) { + for (x = 0; x < IMAGE_WIDTH; ++x) { + double __complex__ c = (START_X+x*step_X) + (START_Y+y*step_Y) * I; + double __complex__ z = 0.0; + + for (n = 0; n < MAX_ITER; ++n) { + z = z * z + c; + if (hypot(__real__ z, __imag__ z) >= ESCAPE) + break; + } + + if (n == MAX_ITER) + putchar(' '); + else if (n > 6) + putchar('.'); + else if (n > 3) + putchar('+'); + else if (n > 2) + putchar('x'); + else + putchar('*'); + } + putchar('\n'); + } +} + +int main() { + mandel(); + return 0; +} + +#endif /* sparc */ diff --git a/test/CodeGen/mangle.c b/test/CodeGen/mangle.c new file mode 100644 index 0000000..17d74ba --- /dev/null +++ b/test/CodeGen/mangle.c @@ -0,0 +1,54 @@ +// RUN: clang-cc -triple i386-pc-linux-gnu -emit-llvm -o %t %s && +// RUN: grep '@_Z2f0i' %t && +// RUN: grep '@_Z2f0l' %t && + +// Make sure we mangle overloadable, even in C system headers. + +# 1 "somesystemheader.h" 1 3 4 +void __attribute__((__overloadable__)) f0(int a) {} +void __attribute__((__overloadable__)) f0(long b) {} + + + +// These should get merged. +void foo() __asm__("bar"); +void foo2() __asm__("bar"); + +// RUN: grep '@"\\01foo"' %t && +// RUN: grep '@"\\01bar"' %t + +int nux __asm__("foo"); +extern float nux2 __asm__("foo"); + +int test() { + foo(); + foo2(); + + return nux + nux2; +} + + +// Function becomes a variable. +void foo3() __asm__("var"); + +void test2() { + foo3(); +} +int foo4 __asm__("var") = 4; + + +// Variable becomes a function +extern int foo5 __asm__("var2"); + +void test3() { + foo5 = 1; +} + +void foo6() __asm__("var2"); +void foo6() { +} + + + +int foo7 __asm__("foo7") __attribute__((used)); +float foo8 __asm__("foo7") = 42; diff --git a/test/CodeGen/merge-attrs.c b/test/CodeGen/merge-attrs.c new file mode 100644 index 0000000..1aab47a --- /dev/null +++ b/test/CodeGen/merge-attrs.c @@ -0,0 +1,13 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +void *malloc(__SIZE_TYPE__ size) __attribute__ ((__nothrow__)); + +inline static void __zend_malloc() { + malloc(1); +} + +void *malloc(__SIZE_TYPE__ size) __attribute__ ((__nothrow__)); + +void fontFetch() { + __zend_malloc(1); +} diff --git a/test/CodeGen/merge-statics.c b/test/CodeGen/merge-statics.c new file mode 100644 index 0000000..c442669 --- /dev/null +++ b/test/CodeGen/merge-statics.c @@ -0,0 +1,13 @@ +// RUN: clang-cc < %s -emit-llvm | grep internal | count 1 + +// The two decls for 'a' should merge into one llvm GlobalVariable. + +struct s { int x; }; +static struct s a; + +struct s *ap1 = &a; + +static struct s a = { + 10 +}; + diff --git a/test/CodeGen/mmintrin-test.c b/test/CodeGen/mmintrin-test.c new file mode 100644 index 0000000..2a9ab56 --- /dev/null +++ b/test/CodeGen/mmintrin-test.c @@ -0,0 +1,26 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -mcpu=pentium4 -emit-llvm -o %t %s && +// RUN: grep define %t | count 1 && +// RUN: clang-cc -triple i386-apple-darwin9 -mcpu=pentium4 -g -emit-llvm -o %t %s && +// RUN: grep define %t | count 1 + +#include <mmintrin.h> +#include <stdio.h> + +int main(int argc, char *argv[]) { + int array[16] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }; + __m64 *p = (__m64 *)array; + + __m64 accum = _mm_setzero_si64(); + + for (int i=0; i<8; ++i) + accum = _mm_add_pi32(p[i], accum); + + __m64 accum2 = _mm_unpackhi_pi32(accum, accum); + accum = _mm_add_pi32(accum, accum2); + + int result = _mm_cvtsi64_si32(accum); + _mm_empty(); + printf("%d\n", result ); + + return 0; +} diff --git a/test/CodeGen/no-common.c b/test/CodeGen/no-common.c new file mode 100644 index 0000000..190873c --- /dev/null +++ b/test/CodeGen/no-common.c @@ -0,0 +1,6 @@ +// RUN: clang -emit-llvm -S -o %t %s && +// RUN: grep '@x = common global' %t && +// RUN: clang -fno-common -emit-llvm -S -o %t %s && +// RUN: grep '@x = global' %t + +int x; diff --git a/test/CodeGen/offsetof.c b/test/CodeGen/offsetof.c new file mode 100644 index 0000000..b0f5727 --- /dev/null +++ b/test/CodeGen/offsetof.c @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +// PR2910 +struct sockaddr_un { + unsigned char sun_len; + char sun_path[104]; +}; + +int test(int len) { + return __builtin_offsetof(struct sockaddr_un, sun_path[len+1]); +} + diff --git a/test/CodeGen/opaque-pointer.c b/test/CodeGen/opaque-pointer.c new file mode 100644 index 0000000..7f78b91 --- /dev/null +++ b/test/CodeGen/opaque-pointer.c @@ -0,0 +1,13 @@ +// RUN: clang-cc %s -emit-llvm -o - +struct test; + +typedef void (*my_func) (struct test *); +my_func handler; + +struct test { + char a; +}; + +char f(struct test *t) { + return t->a; +} diff --git a/test/CodeGen/overloadable.c b/test/CodeGen/overloadable.c new file mode 100644 index 0000000..4b58c82 --- /dev/null +++ b/test/CodeGen/overloadable.c @@ -0,0 +1,26 @@ +// RUN: clang-cc -emit-llvm %s -o - | grep _Z1fPA10_1X +int __attribute__((overloadable)) f(int x) { return x; } +float __attribute__((overloadable)) f(float x) { return x; } +double __attribute__((overloadable)) f(double x) { return x; } +double _Complex __attribute__((overloadable)) f(double _Complex x) { return x; } +typedef short v4hi __attribute__ ((__vector_size__ (8))); +v4hi __attribute__((overloadable)) f(v4hi x) { return x; } + +struct X { }; +void __attribute__((overloadable)) f(struct X (*ptr)[10]) { } + +void __attribute__((overloadable)) f(int x, int y, ...) { } + +int main() { + int iv = 17; + float fv = 3.0f; + double dv = 4.0; + double _Complex cdv; + v4hi vv; + + iv = f(iv); + fv = f(fv); + dv = f(dv); + cdv = f(cdv); + vv = f(vv); +} diff --git a/test/CodeGen/parameter-passing.c b/test/CodeGen/parameter-passing.c new file mode 100644 index 0000000..2ace299 --- /dev/null +++ b/test/CodeGen/parameter-passing.c @@ -0,0 +1,57 @@ +// Check the various ways in which the three classes of values +// (scalar, complex, aggregate) interact with parameter passing +// (function entry, function return, call argument, call result). +// +// We also check _Bool and empty structures, as these can have annoying +// corner cases. + +// RUN: clang-cc %s -triple i386-unknown-unknown -O3 -emit-llvm -o %t && +// RUN: not grep '@g0' %t && + +// RUN: clang-cc %s -triple x86_64-unknown-unknown -O3 -emit-llvm -o %t && +// RUN: not grep '@g0' %t && + +// RUN: clang-cc %s -triple ppc-unknown-unknown -O3 -emit-llvm -o %t && +// RUN: not grep '@g0' %t && +// RUN: true + +typedef _Bool BoolTy; +typedef int ScalarTy; +typedef _Complex int ComplexTy; +typedef struct { int a, b, c; } AggrTy; +typedef struct { int a[0]; } EmptyTy; + +static int result; + +static BoolTy bool_id(BoolTy a) { return a; } +static AggrTy aggr_id(AggrTy a) { return a; } +static EmptyTy empty_id(EmptyTy a) { return a; } +static ScalarTy scalar_id(ScalarTy a) { return a; } +static ComplexTy complex_id(ComplexTy a) { return a; } + +static void bool_mul(BoolTy a) { result *= a; } + +static void aggr_mul(AggrTy a) { result *= a.a * a.b * a.c; } + +static void empty_mul(EmptyTy a) { result *= 53; } + +static void scalar_mul(ScalarTy a) { result *= a; } + +static void complex_mul(ComplexTy a) { result *= __real a * __imag a; } + +extern void g0(void); + +void f0(void) { + result = 1; + + bool_mul(bool_id(1)); + aggr_mul(aggr_id((AggrTy) { 2, 3, 5})); + empty_mul(empty_id((EmptyTy) {})); + scalar_mul(scalar_id(7)); + complex_mul(complex_id(11 + 13i)); + + // This call should be eliminated. + if (result != 2 * 3 * 5 * 7 * 11 * 13 * 53) + g0(); +} + diff --git a/test/CodeGen/pascal-string.c b/test/CodeGen/pascal-string.c new file mode 100644 index 0000000..fcd807c --- /dev/null +++ b/test/CodeGen/pascal-string.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -emit-llvm -o - %s -fpascal-strings | grep "05Hello" + +unsigned char * Foo( void ) +{ + static unsigned char s[256] = "\pHello"; + return s; +} + diff --git a/test/CodeGen/pointer-arithmetic.c b/test/CodeGen/pointer-arithmetic.c new file mode 100644 index 0000000..5049875 --- /dev/null +++ b/test/CodeGen/pointer-arithmetic.c @@ -0,0 +1,22 @@ +// RUN: clang-cc -S %s -o - + +typedef int Int; + +int f0(int *a, Int *b) { return a - b; } + +int f1(const char *a, char *b) { return b - a; } + +// GNU extensions +typedef void (*FP)(void); +void *f2(void *a, int b) { return a + b; } +void *f2_1(void *a, int b) { return (a += b); } +void *f3(int a, void *b) { return a + b; } +void *f3_1(int a, void *b) { return (a += b); } +void *f4(void *a, int b) { return a - b; } +void *f4_1(void *a, int b) { return (a -= b); } +FP f5(FP a, int b) { return a + b; } +FP f5_1(FP a, int b) { return (a += b); } +FP f6(int a, FP b) { return a + b; } +FP f6_1(int a, FP b) { return (a += b); } +FP f7(FP a, int b) { return a - b; } +FP f7_1(FP a, int b) { return (a -= b); } diff --git a/test/CodeGen/pointer-cmp-type.c b/test/CodeGen/pointer-cmp-type.c new file mode 100644 index 0000000..d88c091 --- /dev/null +++ b/test/CodeGen/pointer-cmp-type.c @@ -0,0 +1,3 @@ +// RUN: clang-cc -emit-llvm %s -o - | grep "icmp ult" + +int a(char* a, char* b) {return a<b;} diff --git a/test/CodeGen/pointer-to-int.c b/test/CodeGen/pointer-to-int.c new file mode 100644 index 0000000..e40bd91 --- /dev/null +++ b/test/CodeGen/pointer-to-int.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -emit-llvm %s -o - + +int test(void* i) +{ + return (int)i; +} + +// rdar://6093986 +int test2(void) { + float x[2]; + return x; +} + diff --git a/test/CodeGen/private-extern.c b/test/CodeGen/private-extern.c new file mode 100644 index 0000000..f3ffe54 --- /dev/null +++ b/test/CodeGen/private-extern.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm -o %t %s && +// RUN: grep '@g0 = external hidden constant i32' %t && +// RUN: grep '@g1 = hidden constant i32 1' %t + +__private_extern__ const int g0; +__private_extern__ const int g1 = 1; + +int f0(void) { + return g0; +} diff --git a/test/CodeGen/rdr-6098585-default-after-caserange.c b/test/CodeGen/rdr-6098585-default-after-caserange.c new file mode 100644 index 0000000..3a11ad6 --- /dev/null +++ b/test/CodeGen/rdr-6098585-default-after-caserange.c @@ -0,0 +1,18 @@ +// RUN: clang-cc -triple i386-unknown-unknown --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t && +// RUN: grep "ret i32" %t | count 1 && +// RUN: grep "ret i32 10" %t | count 1 + +// Ensure that default after a case range is not ignored. + +static int f1(unsigned x) { + switch(x) { + case 10 ... 0xFFFFFFFF: + return 0; + default: + return 10; + } +} + +int g() { + return f1(2); +} diff --git a/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c b/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c new file mode 100644 index 0000000..f1d15dc --- /dev/null +++ b/test/CodeGen/rdr-6098585-default-fallthrough-to-caserange.c @@ -0,0 +1,20 @@ +// RUN: clang-cc -triple i386-unknown-unknown --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t && +// RUN: grep "ret i32 10" %t + +// Ensure that this doesn't compile to infinite loop in g() due to +// miscompilation of fallthrough from default to a (tested) case +// range. + +static int f0(unsigned x) { + switch(x) { + default: + x += 1; + case 10 ... 0xFFFFFFFF: + return 0; + } +} + +int g() { + f0(1); + return 10; +} diff --git a/test/CodeGen/rdr-6098585-empty-case-range.c b/test/CodeGen/rdr-6098585-empty-case-range.c new file mode 100644 index 0000000..ca5ff1b --- /dev/null +++ b/test/CodeGen/rdr-6098585-empty-case-range.c @@ -0,0 +1,23 @@ +// RUN: clang-cc -triple i386-unknown-unknown --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t && +// RUN: grep "ret i32" %t | count 2 && +// RUN: grep "ret i32 3" %t | count 2 + +// This generated incorrect code because of poor switch chaining. +int f1(int x) { + switch(x) { + default: + return 3; + case 10 ... 0xFFFFFFFF: + return 0; + } +} + +// This just asserted because of the way case ranges were calculated. +int f2(int x) { + switch (x) { + default: + return 3; + case 10 ... -1: + return 0; + } +} diff --git a/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c b/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c new file mode 100644 index 0000000..b347449 --- /dev/null +++ b/test/CodeGen/rdr-6098585-fallthrough-to-empty-range.c @@ -0,0 +1,15 @@ +// RUN: clang-cc -triple i386-unknown-unknown --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t && +// RUN: grep "ret i32 %" %t + +// Make sure return is not constant (if empty range is skipped or miscompiled) + +int f0(unsigned x) { + switch(x) { + case 2: + // fallthrough empty range + case 10 ... 9: + return 10; + default: + return 0; + } +} diff --git a/test/CodeGen/rdr-6098585-unsigned-caserange.c b/test/CodeGen/rdr-6098585-unsigned-caserange.c new file mode 100644 index 0000000..8003598 --- /dev/null +++ b/test/CodeGen/rdr-6098585-unsigned-caserange.c @@ -0,0 +1,12 @@ +// RUN: clang-cc -triple i386-unknown-unknown --emit-llvm-bc -o - %s | opt -std-compile-opts | llvm-dis > %t && +// RUN: grep "ret i32" %t | count 1 && +// RUN: grep "ret i32 3" %t | count 1 + +int f2(unsigned x) { + switch(x) { + default: + return 3; + case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned. + return 0; + } +} diff --git a/test/CodeGen/rdr-6732143-dangling-block-reference.m b/test/CodeGen/rdr-6732143-dangling-block-reference.m new file mode 100644 index 0000000..2d1baa6 --- /dev/null +++ b/test/CodeGen/rdr-6732143-dangling-block-reference.m @@ -0,0 +1,10 @@ +// RUN: clang-cc -triple x86_64-apple-darwin9 -emit-llvm %s -o - + +void f0(id x) { + @synchronized (x) { + do { ; } while(0); + @try { + } @finally { + } + } +} diff --git a/test/CodeGen/regparm.c b/test/CodeGen/regparm.c new file mode 100644 index 0000000..fdf07ea --- /dev/null +++ b/test/CodeGen/regparm.c @@ -0,0 +1,19 @@ +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o - | grep inreg | count 2 + +#define FASTCALL __attribute__((regparm(2))) + +typedef struct { + int aaa; + double bbbb; + int ccc[200]; +} foo; + +static void FASTCALL +reduced(char b, double c, foo* d, double e, int f) +{ +} + +int +main(void) { + reduced(0, 0.0, 0, 0.0, 0); +} diff --git a/test/CodeGen/shared-string-literals.c b/test/CodeGen/shared-string-literals.c new file mode 100644 index 0000000..a05975b --- /dev/null +++ b/test/CodeGen/shared-string-literals.c @@ -0,0 +1,9 @@ +// RUN: clang-cc -emit-llvm %s -o %t + +char *globalString = "abc"; +char *globalStringArray[5] = { "123", "abc" }; +char *anotherGlobalString = "123"; + +int main() { + printf("123"); +} diff --git a/test/CodeGen/sizeof-vla.c b/test/CodeGen/sizeof-vla.c new file mode 100644 index 0000000..af50885 --- /dev/null +++ b/test/CodeGen/sizeof-vla.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s + +// PR3442 + +static void *g(unsigned long len); + +void +f(int n) +{ + unsigned begin_set[n]; + + g(sizeof(begin_set)); +} diff --git a/test/CodeGen/statements.c b/test/CodeGen/statements.c new file mode 100644 index 0000000..1ff7601 --- /dev/null +++ b/test/CodeGen/statements.c @@ -0,0 +1,13 @@ +// RUN: clang-cc < %s -emit-llvm + +void test1(int x) { +switch (x) { +case 111111111111111111111111111111111111111: +bar(); +} +} + +// Mismatched type between return and function result. +int test2() { return; } +void test3() { return 4; } + diff --git a/test/CodeGen/static-forward-decl-fun.c b/test/CodeGen/static-forward-decl-fun.c new file mode 100644 index 0000000..a945df3 --- /dev/null +++ b/test/CodeGen/static-forward-decl-fun.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +static int staticfun(void); +int (*staticuse1)(void) = staticfun; +static int staticfun() {return 1;} +int (*staticuse2)(void) = staticfun; diff --git a/test/CodeGen/static-forward-decl.c b/test/CodeGen/static-forward-decl.c new file mode 100644 index 0000000..f12c22f --- /dev/null +++ b/test/CodeGen/static-forward-decl.c @@ -0,0 +1,5 @@ +// RUN: clang-cc %s -emit-llvm -o - -triple=i686-apple-darwin9 | grep "global i32 10" + +static int i; +int*j=&i; +static int i = 10; diff --git a/test/CodeGen/static-local-union.c b/test/CodeGen/static-local-union.c new file mode 100644 index 0000000..f276b20 --- /dev/null +++ b/test/CodeGen/static-local-union.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm < %s + +int a() {static union{int a;} r[2] = {1,2};return r[1].a;} + diff --git a/test/CodeGen/static-order.c b/test/CodeGen/static-order.c new file mode 100644 index 0000000..243e96b --- /dev/null +++ b/test/CodeGen/static-order.c @@ -0,0 +1,19 @@ +// RUN: clang-cc -emit-llvm -o - %s | not grep "zeroinitializer" + +struct s { + int a; +}; + +static void *v; + +static struct s a; + +static struct s a = { + 10 +}; + +void *f() +{ + if (a.a) + return v; +} diff --git a/test/CodeGen/staticinit.c b/test/CodeGen/staticinit.c new file mode 100644 index 0000000..91fcdcf --- /dev/null +++ b/test/CodeGen/staticinit.c @@ -0,0 +1,31 @@ +// RUN: clang-cc -triple i386-pc-linux-gnu -emit-llvm -o %t %s && +// RUN: grep "g.b = internal global i8. getelementptr" %t && + +struct AStruct { + int i; + char *s; + double d; +}; + +void f() { + static int i = 42; + static int is[] = { 1, 2, 3, 4 }; + static char* str = "forty-two"; + static char* strs[] = { "one", "two", "three", "four" }; + static struct AStruct myStruct = { 1, "two", 3.0 }; +} + +void g() { + static char a[10]; + static char *b = a; +} + +struct s { void *p; }; + +void foo(void) { + static struct s var = {((void*)&((char*)0)[0])}; +} + +// RUN: grep "f1.l0 = internal global i32 ptrtoint (i32 ()\* @f1 to i32)" %t +int f1(void) { static int l0 = (unsigned) f1; } + diff --git a/test/CodeGen/stdcall-fastcall.c b/test/CodeGen/stdcall-fastcall.c new file mode 100644 index 0000000..11b6521 --- /dev/null +++ b/test/CodeGen/stdcall-fastcall.c @@ -0,0 +1,17 @@ +// RUN: clang-cc -emit-llvm < %s | grep 'fastcallcc' | count 4 +// RUN: clang-cc -emit-llvm < %s | grep 'stdcallcc' | count 4 + +void __attribute__((fastcall)) f1(void); +void __attribute__((stdcall)) f2(void); +void __attribute__((fastcall)) f3(void) { + f1(); +} +void __attribute__((stdcall)) f4(void) { + f2(); +} + +int main(void) { + f3(); f4(); + return 0; +} + diff --git a/test/CodeGen/string-init.c b/test/CodeGen/string-init.c new file mode 100644 index 0000000..38c7ec0 --- /dev/null +++ b/test/CodeGen/string-init.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm %s -o %t && +// RUN: grep 'internal constant \[10 x i8\]' %t && +// RUN: not grep -F "[5 x i8]" %t && +// RUN: not grep "store " %t + +void test(void) { + char a[10] = "asdf"; + char b[10] = { "asdf" }; +} + diff --git a/test/CodeGen/string-literal.c b/test/CodeGen/string-literal.c new file mode 100644 index 0000000..a401193 --- /dev/null +++ b/test/CodeGen/string-literal.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm %s -o - + +int main() { + char a[10] = "abc"; + + void *foo = L"AB"; +} diff --git a/test/CodeGen/struct-comma.c b/test/CodeGen/struct-comma.c new file mode 100644 index 0000000..d7f50da --- /dev/null +++ b/test/CodeGen/struct-comma.c @@ -0,0 +1,4 @@ +// RUN: clang-cc %s -emit-llvm -o - + +struct S {int a, b;} x; +void a(struct S* b) {*b = (r(), x);} diff --git a/test/CodeGen/struct-copy.c b/test/CodeGen/struct-copy.c new file mode 100644 index 0000000..62c29ab --- /dev/null +++ b/test/CodeGen/struct-copy.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm %s -o - | grep 'call.*llvm.memcpy' +struct x { int a[100]; }; + + +void foo(struct x *P, struct x *Q) { + *P = *Q; +} diff --git a/test/CodeGen/struct-init.c b/test/CodeGen/struct-init.c new file mode 100644 index 0000000..a38442b --- /dev/null +++ b/test/CodeGen/struct-init.c @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -emit-llvm -o - + +typedef struct _zend_ini_entry zend_ini_entry; +struct _zend_ini_entry { + void *mh_arg1; +}; + +char a; + +const zend_ini_entry ini_entries[] = { + { ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)}, +}; diff --git a/test/CodeGen/struct-passing.c b/test/CodeGen/struct-passing.c new file mode 100644 index 0000000..9a4f476 --- /dev/null +++ b/test/CodeGen/struct-passing.c @@ -0,0 +1,21 @@ +// RUN: clang-cc -triple i386-pc-linux-gnu -emit-llvm -o %t %s && +// RUN: grep 'declare i32 @f0() readnone$' %t && +// RUN: grep 'declare i32 @f1() readonly$' %t && +// RUN: grep 'declare void @f2(.* noalias sret)$' %t && +// RUN: grep 'declare void @f3(.* noalias sret)$' %t && +// RUN: grep 'declare void @f4(.* byval)$' %t && +// RUN: grep 'declare void @f5(.* byval)$' %t && +// RUN: true +// PR3835 + +typedef int T0; +typedef struct { int a[16]; } T1; + +T0 __attribute__((const)) f0(void); +T0 __attribute__((pure)) f1(void); +T1 __attribute__((const)) f2(void); +T1 __attribute__((pure)) f3(void); +void __attribute__((const)) f4(T1 a); +void __attribute__((pure)) f5(T1 a); + +void *ps[] = { f0, f1, f2, f3, f4, f5 }; diff --git a/test/CodeGen/struct-x86-darwin.c b/test/CodeGen/struct-x86-darwin.c new file mode 100644 index 0000000..050e26d --- /dev/null +++ b/test/CodeGen/struct-x86-darwin.c @@ -0,0 +1,25 @@ +// RUN: clang-cc < %s -emit-llvm > %t1 -triple=i686-apple-darwin9 +// Run grep "STest1 = type <{ i32, \[4 x i16\], double }>" %t1 && +// RUN: grep "STest2 = type <{ i16, i16, i32, i32 }>" %t1 && +// RUN: grep "STest3 = type <{ i8, i8, i16, i32 }>" %t1 && +// RUN: grep "STestB1 = type <{ i8, i8 }>" %t1 && +// RUN: grep "STestB2 = type <{ i8, i8, i8 }>" %t1 && +// RUN: grep "STestB3 = type <{ i8, i8 }>" %t1 && +// RUN: grep "STestB4 = type <{ i8, i8, i8, i8 }>" %t1 && +// RUN: grep "STestB5 = type <{ i8, i8, i8, i8, i8, i8 }>" %t1 && +// RUN: grep "STestB6 = type <{ i8, i8, i8, i8 }>" %t1 +// Test struct layout for x86-darwin target + +struct STest1 {int x; short y[4]; double z; } st1; +struct STest2 {short a,b; int c,d; } st2; +struct STest3 {char a; short b; int c; } st3; + +// Bitfields +struct STestB1 {char a; char b:2; } stb1; +struct STestB2 {char a; char b:5; char c:4; } stb2; +struct STestB3 {char a; char b:2; } stb3; +struct STestB4 {char a; short b:2; char c; } stb4; +struct STestB5 {char a; short b:10; char c; } stb5; +struct STestB6 {int a:1; char b; int c:13 } stb6; + +// Packed struct STestP1 {char a; short b; int c; } __attribute__((__packed__)) stp1; diff --git a/test/CodeGen/struct.c b/test/CodeGen/struct.c new file mode 100644 index 0000000..ed36842 --- /dev/null +++ b/test/CodeGen/struct.c @@ -0,0 +1,192 @@ +// RUN: clang-cc -triple i386-unknown-unknown %s -emit-llvm -o - + +struct { + int x; + int y; +} point; + +void fn1() { + point.x = 42; +} + +/* Nested member */ +struct { + struct { + int a; + int b; + } p1; +} point2; + +void fn2() { + point2.p1.a = 42; +} + +/* Indirect reference */ +typedef struct __sf { + unsigned char *c; + short flags; +} F; + +typedef struct __sf2 { + F *ff; +} F2; + +int fn3(F2 *c) { + if (c->ff->c >= 0) + return 1; + else + return 0; +} + +/* Nested structs */ +typedef struct NA { + int data; + struct NA *next; +} NA; +void f1() { NA a; } + +typedef struct NB { + int d1; + struct _B2 { + int d2; + struct NB *n2; + } B2; +} NB; + +void f2() { NB b; } + +extern NB *f3(); +void f4() { + f3()->d1 = 42; +} + +void f5() { + (f3())->d1 = 42; +} + +/* Function calls */ +typedef struct { + int location; + int length; +} range; +extern range f6(); +void f7() +{ + range r = f6(); +} + +/* Member expressions */ +typedef struct { + range range1; + range range2; +} rangepair; + +void f8() +{ + rangepair p; + + range r = p.range1; +} + +void f9(range *p) +{ + range r = *p; +} + +void f10(range *p) +{ + range r = p[0]; +} + +/* _Bool types */ + +struct _w +{ + short a,b; + short c,d; + short e,f; + short g; + + unsigned int h,i; + + _Bool j,k; +} ws; + +/* Implicit casts (due to typedefs) */ +typedef struct _a +{ + int a; +} a; + +void f11() +{ + struct _a a1; + a a2; + + a1 = a2; + a2 = a1; +} + +/* Implicit casts (due to const) */ +void f12() +{ + struct _a a1; + const struct _a a2; + + a1 = a2; +} + +/* struct initialization */ +struct a13 {int b; int c;}; +struct a13 c13 = {5}; +typedef struct a13 a13; +struct a14 { short a; int b; } x = {1, 1}; + +/* flexible array members */ +struct a15 {char a; int b[];} c15; +int a16(void) {c15.a = 1;} + +/* compound literals */ +void f13() +{ + a13 x; x = (a13){1,2}; +} + +/* va_arg */ +int f14(int i, ...) { + __builtin_va_list l; + __builtin_va_start(l,i); + a13 b = __builtin_va_arg(l, a13); + int c = __builtin_va_arg(l, a13).c; + return b.b; +} + +/* Attribute packed */ +struct __attribute__((packed)) S2839 { double a[19]; signed char b; } s2839[5]; + +struct __attribute__((packed)) SS { long double a; char b; } SS; + + +/* As lvalue */ + +int f15() { + extern range f15_ext(); + return f15_ext().location; +} + +range f16() { + extern rangepair f16_ext(); + return f16_ext().range1; +} + +int f17() { + extern range f17_ext(); + range r; + return (r = f17_ext()).location; +} + +range f18() { + extern rangepair f18_ext(); + rangepair rp; + return (rp = f18_ext()).range1; +} diff --git a/test/CodeGen/switch.c b/test/CodeGen/switch.c new file mode 100644 index 0000000..3254fbf --- /dev/null +++ b/test/CodeGen/switch.c @@ -0,0 +1,87 @@ +// RUN: clang-cc %s -emit-llvm-bc -o - | opt -std-compile-opts -disable-output + +int foo(int i) { + int j = 0; + switch (i) { + case -1: + j = 1; break; + case 1 : + j = 2; break; + case 2: + j = 3; break; + default: + j = 42; break; + } + j = j + 1; + return j; +} + + +int foo2(int i) { + int j = 0; + switch (i) { + case 1 : + j = 2; break; + case 2 ... 10: + j = 3; break; + default: + j = 42; break; + } + j = j + 1; + return j; +} + + +int foo3(int i) { + int j = 0; + switch (i) { + default: + j = 42; break; + case 111: + j = 111; break; + case 0 ... 100: + j = 1; break; + case 222: + j = 222; break; + } + return j; +} + + +int foo4(int i) { + int j = 0; + switch (i) { + case 111: + j = 111; break; + case 0 ... 100: + j = 1; break; + case 222: + j = 222; break; + default: + j = 42; break; + case 501 ... 600: + j = 5; break; + } + return j; +} + +void foo5(){ + switch(0){ + default: + if (0) { + + } + } +} + +void foo6(){ + switch(0){ + } +} + +void foo7(){ + switch(0){ + foo7(); + } +} + diff --git a/test/CodeGen/tentative-decls.c b/test/CodeGen/tentative-decls.c new file mode 100644 index 0000000..3301c23 --- /dev/null +++ b/test/CodeGen/tentative-decls.c @@ -0,0 +1,39 @@ +// RUN: clang-cc -emit-llvm -o %t %s && + +// RUN: grep '@r = common global \[1 x .*\] zeroinitializer' %t && + +int r[]; +int (*a)[] = &r; + +struct s0; +struct s0 x; +// RUN: grep '@x = common global .struct.s0 zeroinitializer' %t && + +struct s0 y; +// RUN: grep '@y = common global .struct.s0 zeroinitializer' %t && +struct s0 *f0() { + return &y; +} + +struct s0 { + int x; +}; + +// RUN: grep '@b = common global \[1 x .*\] zeroinitializer' %t && +int b[]; +int *f1() { + return b; +} + +// Check that the most recent tentative definition wins. +// RUN: grep '@c = common global \[4 x .*\] zeroinitializer' %t && +int c[]; +int c[4]; + +// Check that we emit static tentative definitions +// RUN: grep '@c5 = internal global \[1 x .*\] zeroinitializer' %t && +static int c5[]; +static int func() { return c5[0]; } +int callfunc() { return func(); } + +// RUN: true diff --git a/test/CodeGen/thread-specifier.c b/test/CodeGen/thread-specifier.c new file mode 100644 index 0000000..456f7a6 --- /dev/null +++ b/test/CodeGen/thread-specifier.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -triple i686-pc-linux-gnu -emit-llvm -o - %s | grep thread_local | count 4 + +__thread int a; +extern __thread int b; +int c() { return &b; } +int d() { + __thread static int e; + __thread static union {float a; int b;} f = {.b = 1}; +} + diff --git a/test/CodeGen/trapv.c b/test/CodeGen/trapv.c new file mode 100644 index 0000000..c96488b --- /dev/null +++ b/test/CodeGen/trapv.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -ftrapv %s -emit-llvm -o %t && +// RUN: grep "__overflow_handler" %t | count 2 + +unsigned int ui, uj, uk; +int i, j, k; + +void foo() { + ui = uj + uk; + i = j + k; +} diff --git a/test/CodeGen/typedef-func.c b/test/CodeGen/typedef-func.c new file mode 100644 index 0000000..a64426d --- /dev/null +++ b/test/CodeGen/typedef-func.c @@ -0,0 +1,16 @@ +// RUN: clang-cc -emit-llvm < %s + +// PR2414 +struct mad_frame{}; +enum mad_flow {}; + +typedef enum mad_flow filter_func_t(void *, struct mad_frame *); + +filter_func_t mono_filter; + +void addfilter2(filter_func_t *func){} + +void setup_filters() +{ + addfilter2( mono_filter); +} diff --git a/test/CodeGen/typedef.c b/test/CodeGen/typedef.c new file mode 100644 index 0000000..3bdd52f --- /dev/null +++ b/test/CodeGen/typedef.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -emit-llvm %s -o - + +typedef struct { int i; } Value; +typedef Value *PValue; + +int get_value(PValue v) { + return v->i; +} diff --git a/test/CodeGen/types.c b/test/CodeGen/types.c new file mode 100644 index 0000000..75cb851 --- /dev/null +++ b/test/CodeGen/types.c @@ -0,0 +1,34 @@ +// RUN: clang-cc -emit-llvm <%s + +struct FileName { + struct FileName *next; +} *fnhead; + + +struct ieeeExternal { + struct ieeeExternal *next; +} *exthead; + + +void test1() +{ + struct ieeeExternal *exttmp = exthead; +} + +struct MpegEncContext; +typedef struct MpegEncContext {int pb;} MpegEncContext; +static void test2(void) {MpegEncContext s; s.pb;} + + +struct Village; + +struct List { + struct Village *v; +}; + +struct Village { + struct List returned; +}; + +void test3(struct List a) { +} diff --git a/test/CodeGen/uint128_t.c b/test/CodeGen/uint128_t.c new file mode 100644 index 0000000..b3bf727 --- /dev/null +++ b/test/CodeGen/uint128_t.c @@ -0,0 +1,18 @@ +// RUN: clang-cc %s -emit-llvm -o - -triple=x86_64-apple-darwin9 + +typedef unsigned long long uint64_t; +extern uint64_t numer; +extern uint64_t denom; + +uint64_t +f(uint64_t val) +{ + __uint128_t tmp; + + tmp = val; + tmp *= numer; + tmp /= denom; + + return tmp; +} + diff --git a/test/CodeGen/union-init.c b/test/CodeGen/union-init.c new file mode 100644 index 0000000..c882d31 --- /dev/null +++ b/test/CodeGen/union-init.c @@ -0,0 +1,31 @@ +// RUN: clang-cc -emit-llvm < %s -o - + +// A nice and complicated initialization example with unions from Python +typedef int Py_ssize_t; + +typedef union _gc_head { + struct { + union _gc_head *gc_next; + union _gc_head *gc_prev; + Py_ssize_t gc_refs; + } gc; + long double dummy; /* force worst-case alignment */ +} PyGC_Head; + +struct gc_generation { + PyGC_Head head; + int threshold; /* collection threshold */ + int count; /* count of allocations or collections of younger + generations */ +}; + +#define NUM_GENERATIONS 3 +#define GEN_HEAD(n) (&generations[n].head) + +/* linked lists of container objects */ +struct gc_generation generations[NUM_GENERATIONS] = { + /* PyGC_Head, threshold, count */ + {{{GEN_HEAD(0), GEN_HEAD(0), 0}}, 700, 0}, + {{{GEN_HEAD(1), GEN_HEAD(1), 0}}, 10, 0}, + {{{GEN_HEAD(2), GEN_HEAD(2), 0}}, 10, 0}, +}; diff --git a/test/CodeGen/union.c b/test/CodeGen/union.c new file mode 100644 index 0000000..4884690 --- /dev/null +++ b/test/CodeGen/union.c @@ -0,0 +1,41 @@ +// RUN: clang-cc %s -emit-llvm -o - + +union u_tag { + int a; + float b; +} u; + +void f() { + u.b = 11; +} + +float get_b(union u_tag *my_u) { + return my_u->b; +} + +int f2( float __x ) { + union{ + float __f; + unsigned int __u; + }__u; + return (int)(__u.__u >> 31); +} + +typedef union { int i; int *j; } value; + +int f3(value v) { + return *v.j; +} + +enum E9 { one, two }; +union S65 { enum E9 a; } ; union S65 s65; +void fS65() { enum E9 e = s65.a; } + +typedef union{ + unsigned char x[65536]; +} q; +int qfunc() {q buf; unsigned char* x = buf.x;} + +union RR {_Bool a : 1;} RRU; +int RRF(void) {return RRU.a;} + diff --git a/test/CodeGen/unwind-attr.c b/test/CodeGen/unwind-attr.c new file mode 100644 index 0000000..b2890c4 --- /dev/null +++ b/test/CodeGen/unwind-attr.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -fexceptions -emit-llvm -o - %s | grep "@foo() {" | count 1 && +// RUN: clang-cc -emit-llvm -o - %s | grep "@foo() nounwind {" | count 1 + +int foo(void) { +} diff --git a/test/CodeGen/var-align.c b/test/CodeGen/var-align.c new file mode 100644 index 0000000..b0b62ae --- /dev/null +++ b/test/CodeGen/var-align.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm %s -o - | grep "align 16" | count 2 + +__attribute((aligned(16))) float a[128]; +union {int a[4]; __attribute((aligned(16))) float b[4];} u; diff --git a/test/CodeGen/variable-array.c b/test/CodeGen/variable-array.c new file mode 100644 index 0000000..f5621c2 --- /dev/null +++ b/test/CodeGen/variable-array.c @@ -0,0 +1,19 @@ +// RUN: clang-cc -emit-llvm < %s | grep puts | count 4 + +// PR3248 +int a(int x) +{ + int (*y)[x]; + return sizeof(*(puts("asdf"),y)); +} + +// PR3247 +int b() { + return sizeof(*(char(*)[puts("asdf")])0); +} + +// PR3247 +int c() { + static int (*y)[puts("asdf")]; + return sizeof(*y); +} diff --git a/test/CodeGen/vector.c b/test/CodeGen/vector.c new file mode 100644 index 0000000..2e753b4 --- /dev/null +++ b/test/CodeGen/vector.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -emit-llvm %s -o - +typedef short __v4hi __attribute__ ((__vector_size__ (8))); + +void f() +{ + __v4hi A = (__v4hi)0LL; +} + +__v4hi x = {1,2,3}; +__v4hi y = {1,2,3,4}; + +typedef int vty __attribute((vector_size(16))); +int a() { vty b; return b[2LL]; } diff --git a/test/CodeGen/visibility.c b/test/CodeGen/visibility.c new file mode 100644 index 0000000..bb9b6e0 --- /dev/null +++ b/test/CodeGen/visibility.c @@ -0,0 +1,41 @@ +// RUN: clang-cc -triple i386-unknown-unknown -fvisibility=default -emit-llvm -o %t %s && +// RUN: grep '@g_com = common global i32 0' %t && +// RUN: grep '@g_def = global i32 0' %t && +// RUN: grep '@g_ext = external global i32' %t && +// RUN: grep '@g_deferred = internal global' %t && +// RUN: grep 'declare void @f_ext()' %t && +// RUN: grep 'define internal void @f_deferred()' %t && +// RUN: grep 'define i32 @f_def()' %t && +// RUN: clang-cc -triple i386-unknown-unknown -fvisibility=protected -emit-llvm -o %t %s && +// RUN: grep '@g_com = common protected global i32 0' %t && +// RUN: grep '@g_def = protected global i32 0' %t && +// RUN: grep '@g_ext = external global i32' %t && +// RUN: grep '@g_deferred = internal global' %t && +// RUN: grep 'declare void @f_ext()' %t && +// RUN: grep 'define internal void @f_deferred()' %t && +// RUN: grep 'define protected i32 @f_def()' %t && +// RUN: clang-cc -triple i386-unknown-unknown -fvisibility=hidden -emit-llvm -o %t %s && +// RUN: grep '@g_com = common hidden global i32 0' %t &&a +// RUN: grep '@g_def = hidden global i32 0' %t && +// RUN: grep '@g_ext = external global i32' %t && +// RUN: grep '@g_deferred = internal global' %t && +// RUN: grep 'declare void @f_ext()' %t && +// RUN: grep 'define internal void @f_deferred()' %t && +// RUN: grep 'define hidden i32 @f_def()' %t && +// RUN: true + +int g_com; +int g_def = 0; +extern int g_ext; +static char g_deferred[] = "hello"; + +extern void f_ext(void); + +static void f_deferred(void) { +} + +int f_def(void) { + f_ext(); + f_deferred(); + return g_com + g_def + g_ext + g_deferred[0]; +} diff --git a/test/CodeGen/vla.c b/test/CodeGen/vla.c new file mode 100644 index 0000000..844e49e --- /dev/null +++ b/test/CodeGen/vla.c @@ -0,0 +1,37 @@ +// RUN: clang-cc %s -emit-llvm -o %t + +int b(char* x); + +// Extremely basic VLA test +void a(int x) { + char arry[x]; + arry[0] = 10; + b(arry); +} + +int c(int n) +{ + return sizeof(int[n]); +} + +int f0(int x) { + int vla[x]; + return vla[x-1]; +} + +void +f(int count) +{ + int a[count]; + + do { } while (0); + + if (a[0] != 3) { + } +} + +void g(int count) { + // Make sure we emit sizes correctly in some obscure cases + int (*a[5])[count]; + int (*b)[][count]; +} diff --git a/test/CodeGen/volatile-1.c b/test/CodeGen/volatile-1.c new file mode 100644 index 0000000..ac3b4c2 --- /dev/null +++ b/test/CodeGen/volatile-1.c @@ -0,0 +1,143 @@ +// RUN: clang-cc -Wno-unused-value -emit-llvm < %s -o %t && +// RUN: grep volatile %t | count 145 && +// RUN: grep memcpy %t | count 4 + +volatile int i, j, k; +volatile int ar[5]; +volatile char c; +volatile _Complex int ci; +volatile struct S { +#ifdef __cplusplus + void operator =(volatile struct S&o) volatile; +#endif + int i; +} a, b; + +//void operator =(volatile struct S&o1, volatile struct S&o2) volatile; +#include <stdio.h> + +int main() { + // A use. + i; + // A use of the real part + (float)(ci); + // A use. + (void)ci; + // A use. + (void)a; + // Not a use. + (void)(ci=ci); + // Not a use. + (void)(i=j); + ci+=ci; + (ci += ci) + ci; + asm("nop"); + (i += j) + k; + asm("nop"); + // A use + (i += j) + 1; + asm("nop"); + ci+ci; + // A use. + __real i; + // A use. + +ci; + asm("nop"); + // Not a use. + (void)(i=i); + (float)(i=i); + // A use. + (void)i; + i=i; + i=i=i; +#ifndef __cplusplus + // Not a use. + (void)__builtin_choose_expr(0, i=i, j=j); +#endif + // A use. + k ? (i=i) : (j=j); + (void)(i,(i=i)); + i=i,i; + (i=j,k=j); + (i=j,k); + (i,j); + i=c=k; + i+=k; + // A use of both. + ci; +#ifndef __cplusplus + // A use of _real. + (int)ci; + // A use of both. + (_Bool)ci; +#endif + ci=ci; + ci=ci=ci; + __imag ci = __imag ci = __imag ci; + // Not a use. + __real (i = j); + // Not a use. + __imag i; + + // ============================================================ + // FIXME: Test cases we get wrong. + + // A use. We load all of a into a copy of a, then load i. gcc forgets to do + // the assignment. + // (a = a).i; + + // ============================================================ + // Test cases where we intentionally differ from gcc, due to suspected bugs in + // gcc. + + // Not a use. gcc forgets to do the assignment. + ((a=a),a); + + // Not a use. gcc gets this wrong, it doesn't emit the copy! + // (void)(a=a); + + // Not a use. gcc got this wrong in 4.2 and omitted the side effects + // entirely, but it is fixed in 4.4.0. + __imag (i = j); + +#ifndef __cplusplus + // A use of the real part + (float)(ci=ci); + // Not a use, bug? gcc treats this as not a use, that's probably a bug due to + // tree folding ignoring volatile. + (int)(ci=ci); +#endif + + // A use. + (float)(i=i); + // A use. gcc treats this as not a use, that's probably a bug due to tree + // folding ignoring volatile. + (int)(i=i); + + // A use. + -(i=j); + // A use. gcc treats this a not a use, that's probably a bug due to tree + // folding ignoring volatile. + +(i=k); + + // A use. gcc treats this a not a use, that's probably a bug due to tree + // folding ignoring volatile. + __real (ci=ci); + + // A use. + i + 0; + // A use. + (i=j) + i; + // A use. gcc treats this as not a use, that's probably a bug due to tree + // folding ignoring volatile. + (i=j) + 0; + +#ifdef __cplusplus + (i,j)=k; + (j=k,i)=i; + struct { int x; } s, s1; + printf("s is at %p\n", &s); + printf("s is at %p\n", &(s = s1)); + printf("s.x is at %p\n", &((s = s1).x)); +#endif +} diff --git a/test/CodeGen/volatile.c b/test/CodeGen/volatile.c new file mode 100644 index 0000000..212a0ae --- /dev/null +++ b/test/CodeGen/volatile.c @@ -0,0 +1,94 @@ +// RUN: clang-cc -emit-llvm < %s -o %t && +// RUN: grep volatile %t | count 25 && +// RUN: grep memcpy %t | count 7 + +// The number 25 comes from the current codegen for volatile loads; +// if this number changes, it's not necessarily something wrong, but +// something has changed to affect volatile load/store codegen + +int S; +volatile int vS; + +int* pS; +volatile int* pvS; + +int A[10]; +volatile int vA[10]; + +struct { int x; } F; +struct { volatile int x; } vF; + +struct { int x; } F2; +volatile struct { int x; } vF2; +volatile struct { int x; } *vpF2; + +struct { struct { int y; } x; } F3; +volatile struct { struct { int y; } x; } vF3; + +struct { int x:3; } BF; +struct { volatile int x:3; } vBF; + +typedef int v4si __attribute__ ((vector_size (16))); +v4si V; +volatile v4si vV; + +typedef __attribute__(( ext_vector_type(4) )) int extv4; +extv4 VE; +volatile extv4 vVE; + +volatile struct {int x;} aggFct(void); + +void main() { + int i; + + // load + i=S; + i=vS; + i=*pS; + i=*pvS; + i=A[2]; + i=vA[2]; + i=F.x; + i=vF.x; + i=F2.x; + i=vF2.x; + i=vpF2->x; + i=F3.x.y; + i=vF3.x.y; + i=BF.x; + i=vBF.x; + i=V[3]; + i=vV[3]; + i=VE.yx[1]; + i=vVE.zy[1]; + i = aggFct().x; + + + // store + S=i; + vS=i; + *pS=i; + *pvS=i; + A[2]=i; + vA[2]=i; + F.x=i; + vF.x=i; + F2.x=i; + vF2.x=i; + vpF2->x=i; + vF3.x.y=i; + BF.x=i; + vBF.x=i; + V[3]=i; + vV[3]=i; + + // other ops: + ++S; + ++vS; + i+=S; + i+=vS; + (void)vF2; + vF2 = vF2; + vF2 = vF2 = vF2; + vF2 = (vF2, vF2); +} diff --git a/test/CodeGen/weak-global.c b/test/CodeGen/weak-global.c new file mode 100644 index 0000000..d4ee52f --- /dev/null +++ b/test/CodeGen/weak-global.c @@ -0,0 +1,3 @@ +// RUN: clang-cc -emit-llvm < %s | grep common + +int i; diff --git a/test/CodeGen/weak-incomplete.c b/test/CodeGen/weak-incomplete.c new file mode 100644 index 0000000..a15dbac --- /dev/null +++ b/test/CodeGen/weak-incomplete.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -emit-llvm < %s | grep 'extern_weak' | count 1 + +struct S; +void __attribute__((weak)) foo1(struct S); +void (*foo2)(struct S) = foo1; diff --git a/test/CodeGen/whilestmt.c b/test/CodeGen/whilestmt.c new file mode 100644 index 0000000..95e18f4 --- /dev/null +++ b/test/CodeGen/whilestmt.c @@ -0,0 +1,62 @@ +// RUN: clang-cc %s -emit-llvm -o - + +int bar(); +int foo() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + i = bar(); + }; + return i; +} + + +int foo1() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + if (i == 42) + break; + i = bar(); + }; + return i; +} + + +int foo2() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + if (i == 42) + continue; + i = bar(); + }; + return i; +} + + +int foo3() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + if (i == 42) + break; + }; + return i; +} + + +int foo4() { + int i; + i = 1 + 2; + while(1) { + i = bar(); + if (i == 42) + continue; + }; + return i; +} diff --git a/test/CodeGen/writable-strings.c b/test/CodeGen/writable-strings.c new file mode 100644 index 0000000..c8b70d5 --- /dev/null +++ b/test/CodeGen/writable-strings.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -emit-llvm -o - -fwritable-strings %s + +int main() { + char *str = "abc"; + str[0] = '1'; + printf("%s", str); +} + diff --git a/test/CodeGen/x86.c b/test/CodeGen/x86.c new file mode 100644 index 0000000..10808dc --- /dev/null +++ b/test/CodeGen/x86.c @@ -0,0 +1,23 @@ +// RUN: clang-cc %s -triple=i686-pc-linux-gnu -emit-llvm -o - > %t1 +// RUN: grep "ax" %t1 && +// RUN: grep "bx" %t1 && +// RUN: grep "cx" %t1 && +// RUN: grep "dx" %t1 && +// RUN: grep "di" %t1 && +// RUN: grep "si" %t1 && +// RUN: grep "st" %t1 && +// RUN: grep "st(1)" %t1 + +void test1() { + int d1, d2; + asm ("" : "=a" (d1), "=b" (d2) : + "c" (0), "d" (0), "S" (0), "D" (0), "t" (0), "u" (0)); +} + + +// rdar://6803924 +typedef double T __attribute__ ((__vector_size__ (16))); +T test2(T va) { + return __builtin_ia32_shufpd(va, va, 3); +} + diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c new file mode 100644 index 0000000..8980c66 --- /dev/null +++ b/test/CodeGen/x86_32-arguments.c @@ -0,0 +1,157 @@ +// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm -o %t %s && +// RUN: grep 'define signext i8 @f0()' %t && +// RUN: grep 'define signext i16 @f1()' %t && +// RUN: grep 'define i32 @f2()' %t && +// RUN: grep 'define float @f3()' %t && +// RUN: grep 'define double @f4()' %t && +// RUN: grep 'define x86_fp80 @f5()' %t && +// RUN: grep 'define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8\* %a4)' %t && +// RUN: grep 'define void @f7(i32 %a0)' %t && +// RUN: grep 'define i64 @f8_1()' %t && +// RUN: grep 'define void @f8_2(i32 %a0.0, i32 %a0.1)' %t && + +char f0(void) { +} + +short f1(void) { +} + +int f2(void) { +} + +float f3(void) { +} + +double f4(void) { +} + +long double f5(void) { +} + +void f6(char a0, short a1, int a2, long long a3, void *a4) { +} + +typedef enum { A, B, C } E; + +void f7(E a0) { +} + +struct s8 { + int a; + int b; +}; +struct s8 f8_1(void) { +} +void f8_2(struct s8 a0) { +} + +// This should be passed just as s8. + +// RUN: grep 'define i64 @f9_1()' %t && + +// FIXME: llvm-gcc expands this, this may have some value for the +// backend in terms of optimization but doesn't change the ABI. +// RUN: grep 'define void @f9_2(%.truct.s9\* byval %a0)' %t && +struct s9 { + int a : 17; + int b; +}; +struct s9 f9_1(void) { +} +void f9_2(struct s9 a0) { +} + +// Return of small structures and unions + +// RUN: grep 'float @f10()' %t && +struct s10 { + union { }; + float f; +} f10(void) {} + +// Small vectors and 1 x {i64,double} are returned in registers + +// RUN: grep 'i32 @f11()' %t && +// RUN: grep -F 'void @f12(<2 x i32>* noalias sret %agg.result)' %t && +// RUN: grep 'i64 @f13()' %t && +// RUN: grep 'i64 @f14()' %t && +// RUN: grep '<2 x i64> @f15()' %t && +// RUN: grep '<2 x i64> @f16()' %t && +typedef short T11 __attribute__ ((vector_size (4))); +T11 f11(void) {} +typedef int T12 __attribute__ ((vector_size (8))); +T12 f12(void) {} +typedef long long T13 __attribute__ ((vector_size (8))); +T13 f13(void) {} +typedef double T14 __attribute__ ((vector_size (8))); +T14 f14(void) {} +typedef long long T15 __attribute__ ((vector_size (16))); +T15 f15(void) {} +typedef double T16 __attribute__ ((vector_size (16))); +T16 f16(void) {} + +// And when the single element in a struct (but not for 64 and +// 128-bits). + +// RUN: grep 'i32 @f17()' %t && +// RUN: grep -F 'void @f18(%2* noalias sret %agg.result)' %t && +// RUN: grep -F 'void @f19(%3* noalias sret %agg.result)' %t && +// RUN: grep -F 'void @f20(%4* noalias sret %agg.result)' %t && +// RUN: grep -F 'void @f21(%5* noalias sret %agg.result)' %t && +// RUN: grep -F 'void @f22(%6* noalias sret %agg.result)' %t && +struct { T11 a; } f17(void) {} +struct { T12 a; } f18(void) {} +struct { T13 a; } f19(void) {} +struct { T14 a; } f20(void) {} +struct { T15 a; } f21(void) {} +struct { T16 a; } f22(void) {} + +// Single element structures are handled specially + +// RUN: grep -F 'float @f23()' %t && +// RUN: grep -F 'float @f24()' %t && +// RUN: grep -F 'float @f25()' %t && +struct { float a; } f23(void) {} +struct { float a[1]; } f24(void) {} +struct { struct {} a; struct { float a[1]; } b; } f25(void) {} + +// Small structures are handled recursively +// RUN: grep -F 'i32 @f26()' %t && +// RUN: grep 'void @f27(%.truct.s27\* noalias sret %agg.result)' %t && +struct s26 { struct { char a, b; } a; struct { char a, b; } b; } f26(void) {} +struct s27 { struct { char a, b, c; } a; struct { char a; } b; } f27(void) {} + +// RUN: grep 'void @f28(%.truct.s28\* noalias sret %agg.result)' %t && +struct s28 { int a; int b[]; } f28(void) {} + +// RUN: grep 'define i16 @f29()' %t && +struct s29 { struct { } a[1]; char b; char c; } f29(void) {} + +// RUN: grep 'define i16 @f30()' %t && +struct s30 { char a; char b : 4; } f30(void) {} + +// RUN: grep 'define float @f31()' %t && +struct s31 { char : 0; float b; char : 0; } f31(void) {} + +// RUN: grep 'define i32 @f32()' %t && +struct s32 { char a; unsigned : 0; } f32(void) {} + +// RUN: grep 'define float @f33()' %t && +struct s33 { float a; long long : 0; } f33(void) {} + +// RUN: grep 'define float @f34()' %t && +struct s34 { struct { int : 0; } a; float b; } f34(void) {} + +// RUN: grep 'define i16 @f35()' %t && +struct s35 { struct { int : 0; } a; char b; char c; } f35(void) {} + +// RUN: grep 'define i16 @f36()' %t && +struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) {} + +// RUN: grep 'define float @f37()' %t && +struct s37 { float c[1][1]; } f37(void) {} + +// RUN: grep 'define void @f38(.struct.s38. noalias sret .agg.result)' %t && +struct s38 { char a[3]; short b; } f38(void) {} + +// RUN: true diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c new file mode 100644 index 0000000..6f7ec82 --- /dev/null +++ b/test/CodeGen/x86_64-arguments.c @@ -0,0 +1,85 @@ +// RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s && +// RUN: grep 'define signext i8 @f0()' %t && +// RUN: grep 'define signext i16 @f1()' %t && +// RUN: grep 'define i32 @f2()' %t && +// RUN: grep 'define float @f3()' %t && +// RUN: grep 'define double @f4()' %t && +// RUN: grep 'define x86_fp80 @f5()' %t && +// RUN: grep 'define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8\* %a4)' %t && +// RUN: grep 'define void @f7(i32 %a0)' %t && +// RUN: grep 'type { i64, double }.*type .0' %t && +// RUN: grep 'define .0 @f8_1()' %t && +// RUN: grep 'define void @f8_2(.0)' %t && + +char f0(void) { +} + +short f1(void) { +} + +int f2(void) { +} + +float f3(void) { +} + +double f4(void) { +} + +long double f5(void) { +} + +void f6(char a0, short a1, int a2, long long a3, void *a4) { +} + +typedef enum { A, B, C } E; + +void f7(E a0) { +} + +// Test merging/passing of upper eightbyte with X87 class. +union u8 { + long double a; + int b; +}; +union u8 f8_1() {} +void f8_2(union u8 a0) {} + +// RUN: grep 'define i64 @f9()' %t && +struct s9 { int a; int b; int : 0; } f9(void) {} + +// RUN: grep 'define void @f10(i64)' %t && +struct s10 { int a; int b; int : 0; }; +void f10(struct s10 a0) {} + +// RUN: grep 'define void @f11(.union.anon. noalias sret .agg.result)' %t && +union { long double a; float b; } f11() {} + +// RUN: grep 'define i64 @f12_0()' %t && +// RUN: grep 'define void @f12_1(i64)' %t && +struct s12 { int a __attribute__((aligned(16))); }; +struct s12 f12_0(void) {} +void f12_1(struct s12 a0) {} + +// Check that sret parameter is accounted for when checking available integer +// registers. +// RUN: grep 'define void @f13(.struct.s13_0. noalias sret .agg.result, i32 .a, i32 .b, i32 .c, i32 .d, .struct.s13_1. byval .e, i32 .f)' %t && + +struct s13_0 { long long f0[3]; }; +struct s13_0 f13(int a, int b, int c, int d, + struct s13_1 { long long f0[2]; } e, int f) {} + +// RUN: grep 'define void @f14(.*, i8 signext .X)' %t && +void f14(int a, int b, int c, int d, int e, int f, + char X) {} +// RUN: grep 'define void @f15(.*, i8\* .X)' %t && +void f15(int a, int b, int c, int d, int e, int f, + void *X) {} +// RUN: grep 'define void @f16(.*, float .X)' %t && +void f16(float a, float b, float c, float d, float e, float f, float g, float h, + float X) {} +// RUN: grep 'define void @f17(.*, x86_fp80 .X)' %t && +void f17(float a, float b, float c, float d, float e, float f, float g, float h, + long double X) {} + +// RUN: true |