diff options
author | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
---|---|---|
committer | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
commit | be1de4be954c80875ad4108e0a33e8e131b2f2c0 (patch) | |
tree | 1fbbecf276bf7c7bdcbb4dd446099d6d90eaa516 /clang/test/CodeGen | |
parent | c4626a62754862d20b41e8a46a3574264ea80e6d (diff) | |
parent | f1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 (diff) |
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Diffstat (limited to 'clang/test/CodeGen')
669 files changed, 25146 insertions, 0 deletions
diff --git a/clang/test/CodeGen/2002-01-23-LoadQISIReloadFailure.c b/clang/test/CodeGen/2002-01-23-LoadQISIReloadFailure.c new file mode 100644 index 0000000..ec454c8 --- /dev/null +++ b/clang/test/CodeGen/2002-01-23-LoadQISIReloadFailure.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* Regression test. Just compile .c -> .ll to test */ +int foo(void) { + unsigned char *pp; + unsigned w_cnt; + + w_cnt += *pp; + + return w_cnt; +} diff --git a/clang/test/CodeGen/2002-01-24-ComplexSpaceInType.c b/clang/test/CodeGen/2002-01-24-ComplexSpaceInType.c new file mode 100644 index 0000000..9af533d --- /dev/null +++ b/clang/test/CodeGen/2002-01-24-ComplexSpaceInType.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +// This caused generation of the following type name: +// %Array = uninitialized global [10 x %complex int] +// +// which caused problems because of the space int the complex int type +// + +struct { int X, Y; } Array[10]; + +void foo() {} diff --git a/clang/test/CodeGen/2002-01-24-HandleCallInsnSEGV.c b/clang/test/CodeGen/2002-01-24-HandleCallInsnSEGV.c new file mode 100644 index 0000000..739a841 --- /dev/null +++ b/clang/test/CodeGen/2002-01-24-HandleCallInsnSEGV.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +void *dlclose(void*); + +void ap_os_dso_unload(void *handle) +{ + dlclose(handle); + return; /* This return triggers the bug: Weird */ +} diff --git a/clang/test/CodeGen/2002-02-13-ConditionalInCall.c b/clang/test/CodeGen/2002-02-13-ConditionalInCall.c new file mode 100644 index 0000000..d389371 --- /dev/null +++ b/clang/test/CodeGen/2002-02-13-ConditionalInCall.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* Test problem where bad code was generated with a ?: statement was + in a function call argument */ + +void foo(int, double, float); + +void bar(int x) { + foo(x, x ? 1.0 : 12.5, 1.0f); +} + diff --git a/clang/test/CodeGen/2002-02-13-ReloadProblem.c b/clang/test/CodeGen/2002-02-13-ReloadProblem.c new file mode 100644 index 0000000..da7f5e4 --- /dev/null +++ b/clang/test/CodeGen/2002-02-13-ReloadProblem.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* This triggered a problem in reload, fixed by disabling most of the + * steps of compilation in GCC. Before this change, the code went through + * the entire backend of GCC, even though it was unnecessary for LLVM output + * now it is skipped entirely, and since reload doesn't run, it can't cause + * a problem. + */ + +extern int tolower(int); + +const char *rangematch(const char *pattern, int test, int c) { + + if ((c <= test) | (tolower(c) <= tolower((unsigned char)test))) + return 0; + + return pattern; +} diff --git a/clang/test/CodeGen/2002-02-13-TypeVarNameCollision.c b/clang/test/CodeGen/2002-02-13-TypeVarNameCollision.c new file mode 100644 index 0000000..c76aef0 --- /dev/null +++ b/clang/test/CodeGen/2002-02-13-TypeVarNameCollision.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* This testcase causes a symbol table collision. Type names and variable + * names should be in distinct namespaces + */ + +typedef struct foo { + int X, Y; +} FOO; + +static FOO foo[100]; + +int test() { + return foo[4].Y; +} + diff --git a/clang/test/CodeGen/2002-02-13-UnnamedLocal.c b/clang/test/CodeGen/2002-02-13-UnnamedLocal.c new file mode 100644 index 0000000..58a9f5a --- /dev/null +++ b/clang/test/CodeGen/2002-02-13-UnnamedLocal.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* Testcase for a problem where GCC allocated xqic to a register, + * and did not have a VAR_DECL that explained the stack slot to LLVM. + * Now the LLVM code synthesizes a stack slot if one is presented that + * has not been previously recognized. This is where alloca's named + * 'local' come from now. + */ + +typedef struct { + short x; +} foostruct; + +int foo(foostruct ic); + +void test() { + foostruct xqic; + foo(xqic); +} + + diff --git a/clang/test/CodeGen/2002-02-14-EntryNodePreds.c b/clang/test/CodeGen/2002-02-14-EntryNodePreds.c new file mode 100644 index 0000000..60d1104 --- /dev/null +++ b/clang/test/CodeGen/2002-02-14-EntryNodePreds.c @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* GCC Used to generate code that contained a branch to the entry node of + * the do_merge function. This is illegal LLVM code. To fix this, GCC now + * inserts an entry node regardless of whether or not it has to insert allocas. + */ + +struct edge_rec +{ + struct VERTEX *v; + struct edge_rec *next; + int wasseen; + int more_data; +}; + +typedef struct edge_rec *QUAD_EDGE; + +typedef struct { + QUAD_EDGE left, right; +} EDGE_PAIR; + +struct EDGE_STACK { + int ptr; + QUAD_EDGE *elts; + int stack_size; +}; + +int do_merge(QUAD_EDGE ldo, QUAD_EDGE rdo) { + int lvalid; + QUAD_EDGE basel,rcand; + while (1) { + if (!lvalid) { + return (int)basel->next; + } + } +} + diff --git a/clang/test/CodeGen/2002-02-16-RenamingTest.c b/clang/test/CodeGen/2002-02-16-RenamingTest.c new file mode 100644 index 0000000..bb23e68 --- /dev/null +++ b/clang/test/CodeGen/2002-02-16-RenamingTest.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* test that locals are renamed with . notation */ + +void abc(void *); + +void Test5(double X) { + abc(&X); + { + int X; + abc(&X); + { + float X; + abc(&X); + } + } +} + diff --git a/clang/test/CodeGen/2002-02-17-ArgumentAddress.c b/clang/test/CodeGen/2002-02-17-ArgumentAddress.c new file mode 100644 index 0000000..d1ad6a8 --- /dev/null +++ b/clang/test/CodeGen/2002-02-17-ArgumentAddress.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +int test(int X) { + return X; +} + +void abc(int *X); +int def(int Y, int Z) { + abc(&Z); + return Y; +} + +struct Test { short X, x; int Y, Z; }; + +int Testing(struct Test *A) { + return A->X+A->Y; +} + +int Test2(int X, struct Test A, int Y) { + return X+Y+A.X+A.Y; +} +int Test3(struct Test A, struct Test B) { + return A.X+A.Y+B.Y+B.Z; +} + +struct Test Test4(struct Test A) { + return A; +} + +int Test6() { + int B[200]; + return B[4]; +} + +struct STest2 { int X; short Y[4]; double Z; }; + +struct STest2 Test7(struct STest2 X) { + return X; +} diff --git a/clang/test/CodeGen/2002-02-18-64bitConstant.c b/clang/test/CodeGen/2002-02-18-64bitConstant.c new file mode 100644 index 0000000..95da72d --- /dev/null +++ b/clang/test/CodeGen/2002-02-18-64bitConstant.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* GCC wasn't handling 64 bit constants right fixed */ + +int printf(const char * restrict format, ...); + +int main() { + long long Var = 123455678902ll; + printf("%lld\n", Var); +} diff --git a/clang/test/CodeGen/2002-02-18-StaticData.c b/clang/test/CodeGen/2002-02-18-StaticData.c new file mode 100644 index 0000000..d0cf524 --- /dev/null +++ b/clang/test/CodeGen/2002-02-18-StaticData.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +double FOO = 17; +double BAR = 12.0; +float XX = 12.0f; + +static char *procnames[] = { + "EXIT" +}; + +void *Data[] = { &FOO, &BAR, &XX }; + diff --git a/clang/test/CodeGen/2002-03-11-LargeCharInString.c b/clang/test/CodeGen/2002-03-11-LargeCharInString.c new file mode 100644 index 0000000..9270873 --- /dev/null +++ b/clang/test/CodeGen/2002-03-11-LargeCharInString.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +int strcmp(const char *s1, const char *s2); + +int test(char *X) { + /* LLVM-GCC used to emit: + %.LC0 = internal global [3 x sbyte] c"\1F\FFFFFF8B\00" + */ + return strcmp(X, "\037\213"); +} diff --git a/clang/test/CodeGen/2002-03-12-ArrayInitialization.c b/clang/test/CodeGen/2002-03-12-ArrayInitialization.c new file mode 100644 index 0000000..f05b838 --- /dev/null +++ b/clang/test/CodeGen/2002-03-12-ArrayInitialization.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* GCC would generate bad code if not enough initializers are + specified for an array. + */ + +int a[10] = { 0, 2}; + +char str[10] = "x"; + +void *Arr[5] = { 0, 0 }; + +float F[12] = { 1.23f, 34.7f }; + +struct Test { int X; double Y; }; + +struct Test Array[10] = { { 2, 12.0 }, { 3, 24.0 } }; + +int B[4][4] = { { 1, 2, 3, 4}, { 5, 6, 7 }, { 8, 9 } }; diff --git a/clang/test/CodeGen/2002-03-12-StructInitialize.c b/clang/test/CodeGen/2002-03-12-StructInitialize.c new file mode 100644 index 0000000..1316fbb --- /dev/null +++ b/clang/test/CodeGen/2002-03-12-StructInitialize.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +typedef struct Connection_Type { + long to; + char type[10]; + long length; +} Connection; + +Connection link[3] += { {1, "link1", 10}, + {2, "link2", 20}, + {3, "link3", 30} }; + diff --git a/clang/test/CodeGen/2002-03-12-StructInitializer.c b/clang/test/CodeGen/2002-03-12-StructInitializer.c new file mode 100644 index 0000000..a65675b --- /dev/null +++ b/clang/test/CodeGen/2002-03-12-StructInitializer.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* GCC was not emitting string constants of the correct length when + * embedded into a structure field like this. It thought the strlength + * was -1. + */ + +typedef struct Connection_Type { + long to; + char type[10]; + long length; +} Connection; + +Connection link[3] += { {1, "link1", 10}, + {2, "link2", 20}, + {3, "link3", 30} }; + diff --git a/clang/test/CodeGen/2002-03-14-BrokenPHINode.c b/clang/test/CodeGen/2002-03-14-BrokenPHINode.c new file mode 100644 index 0000000..eb05859 --- /dev/null +++ b/clang/test/CodeGen/2002-03-14-BrokenPHINode.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* GCC was generating PHI nodes with an arity < #pred of the basic block the + * PHI node lived in. This was breaking LLVM because the number of entries + * in a PHI node must equal the number of predecessors for a basic block. + */ + +int trys(char *s, int x) +{ + int asa; + double Val; + int LLS; + if (x) { + asa = LLS + asa; + } else { + } + return asa+(int)Val; +} + diff --git a/clang/test/CodeGen/2002-03-14-BrokenSSA.c b/clang/test/CodeGen/2002-03-14-BrokenSSA.c new file mode 100644 index 0000000..65e5cfa --- /dev/null +++ b/clang/test/CodeGen/2002-03-14-BrokenSSA.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* This code used to break GCC's SSA computation code. It would create + uses of B & C that are not dominated by their definitions. See: + http://gcc.gnu.org/ml/gcc/2002-03/msg00697.html + */ +int bar(); +int foo() +{ + int a,b,c; + + a = b + c; + b = bar(); + c = bar(); + return a + b + c; +} + diff --git a/clang/test/CodeGen/2002-03-14-QuotesInStrConst.c b/clang/test/CodeGen/2002-03-14-QuotesInStrConst.c new file mode 100644 index 0000000..de4bdd6 --- /dev/null +++ b/clang/test/CodeGen/2002-03-14-QuotesInStrConst.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* GCC was not escaping quotes in string constants correctly, so this would + * get emitted: + * %.LC1 = internal global [32 x sbyte] c"*** Word "%s" on line %d is not\00" + */ + +const char *Foo() { + return "*** Word \"%s\" on line %d is not"; +} diff --git a/clang/test/CodeGen/2002-04-07-SwitchStmt.c b/clang/test/CodeGen/2002-04-07-SwitchStmt.c new file mode 100644 index 0000000..cf1ec79 --- /dev/null +++ b/clang/test/CodeGen/2002-04-07-SwitchStmt.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +int printf(const char *, ...); +int foo(); + +int main() { + while (foo()) { + switch (foo()) { + case 0: + case 1: + case 2: + case 3: + printf("3"); + case 4: printf("4"); + case 5: + case 6: + default: + break; + } + } + return 0; +} diff --git a/clang/test/CodeGen/2002-04-08-LocalArray.c b/clang/test/CodeGen/2002-04-08-LocalArray.c new file mode 100644 index 0000000..9b5ef79 --- /dev/null +++ b/clang/test/CodeGen/2002-04-08-LocalArray.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* GCC is not outputting the static array to the LLVM backend, so bad things + * happen. Note that if this is defined static, everything seems fine. + */ +double test(unsigned X) { + double student_t[30]={0.0 , 12.706 , 4.303 , 3.182 , 2.776 , 2.571 , + 2.447 , 2.365 , 2.306 , 2.262 , 2.228 , + 2.201 , 2.179 , 2.160 , 2.145 , 2.131 , + 2.120 , 2.110 , 2.101 , 2.093 , 2.086 , + 2.080 , 2.074 , 2.069 , 2.064 , 2.060 , + 2.056 , 2.052 , 2.048 , 2.045 }; + return student_t[X]; +} diff --git a/clang/test/CodeGen/2002-04-09-StructRetVal.c b/clang/test/CodeGen/2002-04-09-StructRetVal.c new file mode 100644 index 0000000..f043ab7 --- /dev/null +++ b/clang/test/CodeGen/2002-04-09-StructRetVal.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct S { + int i; + short s1, s2; +}; + +struct S func_returning_struct(void); + +void loop(void) { + func_returning_struct(); +} diff --git a/clang/test/CodeGen/2002-04-10-StructParameters.c b/clang/test/CodeGen/2002-04-10-StructParameters.c new file mode 100644 index 0000000..72cebc6 --- /dev/null +++ b/clang/test/CodeGen/2002-04-10-StructParameters.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +typedef struct { + char p; + short q; + char r; + int X; + short Y, Z; + int Q; +} foo; + +int test(foo X, float); +int testE(char,short,char,int,int,float); +void test3(foo *X) { + X->q = 1; +} + +void test2(foo Y) { + testE(Y.p, Y.q, Y.r, Y.X, Y.Y, 0.1f); + test(Y, 0.1f); + test2(Y); + test3(&Y); +} + diff --git a/clang/test/CodeGen/2002-05-23-StaticValues.c b/clang/test/CodeGen/2002-05-23-StaticValues.c new file mode 100644 index 0000000..b8c25b7 --- /dev/null +++ b/clang/test/CodeGen/2002-05-23-StaticValues.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* Make sure the frontend is correctly marking static stuff as internal! */ + +int X; +static int Y = 12; + +static void foo(int Z) { + Y = Z; +} + +void *test() { + foo(12); + return &Y; +} diff --git a/clang/test/CodeGen/2002-05-23-TypeNameCollision.c b/clang/test/CodeGen/2002-05-23-TypeNameCollision.c new file mode 100644 index 0000000..c15c952 --- /dev/null +++ b/clang/test/CodeGen/2002-05-23-TypeNameCollision.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* Testcase for when struct tag conflicts with typedef name... grr */ + +typedef struct foo { + struct foo *X; + int Y; +} * foo; + +foo F1; +struct foo *F2; + +enum bar { test1, test2 }; + +typedef float bar; + +enum bar B1; +bar B2; + diff --git a/clang/test/CodeGen/2002-05-24-Alloca.c b/clang/test/CodeGen/2002-05-24-Alloca.c new file mode 100644 index 0000000..30ba8bb --- /dev/null +++ b/clang/test/CodeGen/2002-05-24-Alloca.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +typedef __SIZE_TYPE__ size_t; +void *alloca(size_t size); +char *strcpy(char *restrict s1, const char *restrict s2); +int puts(const char *s); +int main(int argc, char **argv) { + char *C = (char*)alloca(argc); + strcpy(C, argv[0]); + puts(C); +} diff --git a/clang/test/CodeGen/2002-06-25-FWriteInterfaceFailure.c b/clang/test/CodeGen/2002-06-25-FWriteInterfaceFailure.c new file mode 100644 index 0000000..24c67d1 --- /dev/null +++ b/clang/test/CodeGen/2002-06-25-FWriteInterfaceFailure.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +typedef struct _IO_FILE FILE; +extern FILE *stderr; +int fprintf(FILE * restrict stream, const char * restrict format, ...); + +void test() { + fprintf(stderr, "testing\n"); +} diff --git a/clang/test/CodeGen/2002-07-14-MiscListTests.c b/clang/test/CodeGen/2002-07-14-MiscListTests.c new file mode 100644 index 0000000..901701a --- /dev/null +++ b/clang/test/CodeGen/2002-07-14-MiscListTests.c @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +// Test list stuff + +void *malloc(unsigned); + +// Test opaque structure support. the list type is defined later +struct list; + +struct list *PassThroughList(struct list *L) { + return L; +} + + +// Recursive data structure tests... + +typedef struct list { + int Data; + struct list *Next; +} list; + +list *Data; + +void foo() { + static int Foo = 0; // Test static local variable + Foo += 1; // Increment static variable + + Data = (list*)malloc(12); // This is not a proper list allocation +} + +extern list ListNode1; +list ListNode3 = { 4, 0 }; +list ListNode2 = { 3, &ListNode3 }; +list ListNode0 = { 1, &ListNode1 }; +list ListNode1 = { 2, &ListNode2 }; + + +list ListArray[10]; + +// Iterative insert fn +void InsertIntoListTail(list **L, int Data) { + while (*L) + L = &(*L)->Next; + *L = (list*)malloc(sizeof(list)); + (*L)->Data = Data; + (*L)->Next = 0; +} + +// Recursive list search fn +list *FindData(list *L, int Data) { + if (L == 0) return 0; + if (L->Data == Data) return L; + return FindData(L->Next, Data); +} + +void foundIt(void); + +// Driver fn... +void DoListStuff() { + list *MyList = 0; + InsertIntoListTail(&MyList, 100); + InsertIntoListTail(&MyList, 12); + InsertIntoListTail(&MyList, 42); + InsertIntoListTail(&MyList, 1123); + InsertIntoListTail(&MyList, 1213); + + if (FindData(MyList, 75)) foundIt(); + if (FindData(MyList, 42)) foundIt(); + if (FindData(MyList, 700)) foundIt(); +} + diff --git a/clang/test/CodeGen/2002-07-14-MiscTests.c b/clang/test/CodeGen/2002-07-14-MiscTests.c new file mode 100644 index 0000000..2a65124 --- /dev/null +++ b/clang/test/CodeGen/2002-07-14-MiscTests.c @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -w -emit-llvm %s -o /dev/null + +/* These are random tests that I used when working on the GCC frontend + originally. */ + +// test floating point comparison! +int floatcomptest(double *X, double *Y, float *x, float *y) { + return *X < *Y || *x < *y; +} + +extern void *malloc(unsigned); + +// Exposed a bug +void *memset_impl(void *dstpp, int c, unsigned len) { + long long int dstp = (long long int) dstpp; + + while (dstp % 4 != 0) + { + ((unsigned char *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + return dstpp; +} + +// TEST problem with signed/unsigned versions of the same constants being shared +// incorrectly! +// +static char *temp; +static int remaining; +static char *localmalloc(int size) { + char *blah; + + if (size>remaining) + { + temp = (char *) malloc(32768); + remaining = 32768; + return temp; + } + return 0; +} + +typedef struct { double X; double Y; int Z; } PBVTest; + +PBVTest testRetStruct(float X, double Y, int Z) { + PBVTest T = { X, Y, Z }; + return T; +} +PBVTest testRetStruct2(void); // external func no inlining + + +double CallRetStruct(float X, double Y, int Z) { + PBVTest T = testRetStruct2(); + return T.X+X+Y+Z; +} + + diff --git a/clang/test/CodeGen/2002-07-14-MiscTests2.c b/clang/test/CodeGen/2002-07-14-MiscTests2.c new file mode 100644 index 0000000..ad13017 --- /dev/null +++ b/clang/test/CodeGen/2002-07-14-MiscTests2.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +// Test ?: in function calls +extern fp(int, char*); +char *Ext; +void +__bb_exit_func (void) +{ + fp (12, Ext ? Ext : "<none>"); +} + + diff --git a/clang/test/CodeGen/2002-07-14-MiscTests3.c b/clang/test/CodeGen/2002-07-14-MiscTests3.c new file mode 100644 index 0000000..f7ded4e --- /dev/null +++ b/clang/test/CodeGen/2002-07-14-MiscTests3.c @@ -0,0 +1,182 @@ +// RUN: %clang_cc1 -w -emit-llvm %s -o /dev/null + +void *malloc(unsigned); +int puts(const char *s); + +struct FunStructTest { + int Test1; + char *Pointer; + int Array[12]; +}; + +struct SubStruct { + short X, Y; +}; + +struct Quad { + int w; + struct SubStruct SS; + struct SubStruct *SSP; + char c; + int y; +}; + +struct Quad GlobalQuad = { 4, {1, 2}, 0, 3, 156 }; + +typedef int (*FuncPtr)(int); + +unsigned PtrFunc(int (*Func)(int), int X) { + return Func(X); +} + +char PtrFunc2(FuncPtr FuncTab[30], int Num) { + return FuncTab[Num]('b'); +} + +extern char SmallArgs2(char w, char x, long long Zrrk, char y, char z); +extern int SomeFunc(void); +char SmallArgs(char w, char x, char y, char z) { + SomeFunc(); + return SmallArgs2(w-1, x+1, y, z, w); +} + +static int F0(struct Quad Q, int i) { /* Pass Q by value */ + struct Quad R; + if (i) R.SS = Q.SS; + Q.SSP = &R.SS; + Q.w = Q.y = Q.c = 1; + return Q.SS.Y + i + R.y - Q.c; +} + +int F1(struct Quad *Q, int i) { /* Pass Q by address */ + struct Quad R; +#if 0 + if (i) R.SS = Q->SS; +#else + if (i) R = *Q; +#endif + Q->w = Q->y = Q->c = 1; + return Q->SS.Y+i+R.y-Q->c; +} + + +int BadFunc(float Val) { + int Result; + if (Val > 12.345) Result = 4; + return Result; /* Test use of undefined value */ +} + +int RealFunc(void) { + return SomeUndefinedFunction(1, 4, 5); +} + +extern int EF1(int *, char *, int *); + +int Func(int Param, long long Param2) { + int Result = Param; + + {{{{ + char c; int X; + EF1(&Result, &c, &X); + }}} + + { // c & X are duplicate names! + char c; int X; + EF1(&Result, &c, &X); + } + + } + return Result; +} + + +short FunFunc(long long x, char z) { + return x+z; +} + +unsigned castTest(int X) { return X; } + +double TestAdd(double X, float Y) { + return X+Y+.5; +} + +int func(int i, int j) { + while (i != 20) + i += 2; + + j += func(2, i); + return (i * 3 + j*2)*j; +} + +int SumArray(int Array[], int Num) { + int i, Result = 0; + for (i = 0; i < Num; ++i) + Result += Array[i]; + + return Result; +} + +int ArrayParam(int Values[100]) { + return EF1((int*)Values[50], (char*)1, &Values[50]); +} + +int ArrayToSum(void) { + int A[100], i; + for (i = 0; i < 100; ++i) + A[i] = i*4; + + return A[A[0]]; //SumArray(A, 100); +} + + +int ExternFunc(long long, unsigned*, short, unsigned char); + +int main(int argc, char *argv[]) { + unsigned i; + puts("Hello world!\n"); + + ExternFunc(-1, 0, (short)argc, 2); + //func(argc, argc); + + for (i = 0; i < 10; i++) + puts(argv[3]); + return 0; +} + +double MathFunc(double X, double Y, double Z, + double AA, double BB, double CC, double DD, + double EE, double FF, double GG, double HH, + double aAA, double aBB, double aCC, double aDD, + double aEE, double aFF) { + return X + Y + Z + AA + BB + CC + DD + EE + FF + GG + HH + + aAA + aBB + aCC + aDD + aEE + aFF; +} + + + +void strcpy(char *s1, char *s2) { + while (*s1++ = *s2++); +} + +void strcat(char *s1, char *s2) { + while (*s1++); + s1--; + while (*s1++ = *s2++); +} + +int strcmp(char *s1, char *s2) { + while (*s1++ == *s2++); + if (*s1 == 0) { + if (*s2 == 0) { + return 0; + } else { + return -1; + } + } else { + if (*s2 == 0) { + return 1; + } else { + return (*(--s1) - *(--s2)); + } + } +} diff --git a/clang/test/CodeGen/2002-07-16-HardStringInit.c b/clang/test/CodeGen/2002-07-16-HardStringInit.c new file mode 100644 index 0000000..b307359 --- /dev/null +++ b/clang/test/CodeGen/2002-07-16-HardStringInit.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + char auto_kibitz_list[100][20] = { + {"diepx"}, + {"ferret"}, + {"knightc"}, + {"knightcap"}}; + diff --git a/clang/test/CodeGen/2002-07-17-StringConstant.c b/clang/test/CodeGen/2002-07-17-StringConstant.c new file mode 100644 index 0000000..5b86a5b --- /dev/null +++ b/clang/test/CodeGen/2002-07-17-StringConstant.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +char * foo() { return "\\begin{"; } diff --git a/clang/test/CodeGen/2002-07-30-SubregSetAssertion.c b/clang/test/CodeGen/2002-07-30-SubregSetAssertion.c new file mode 100644 index 0000000..39e97b3 --- /dev/null +++ b/clang/test/CodeGen/2002-07-30-SubregSetAssertion.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +union X { + void *B; +}; + +union X foo() { + union X A; + A.B = (void*)123; + return A; +} diff --git a/clang/test/CodeGen/2002-07-30-UnionTest.c b/clang/test/CodeGen/2002-07-30-UnionTest.c new file mode 100644 index 0000000..d5b92e7 --- /dev/null +++ b/clang/test/CodeGen/2002-07-30-UnionTest.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +union X; +struct Empty {}; +union F {}; +union Q { union Q *X; }; +union X { + char C; + int A, Z; + long long B; + void *b1; + struct { int A; long long Z; } Q; +}; + +union X foo(union X A) { + A.C = 123; + A.A = 39249; + //A.B = (void*)123040123321; + A.B = 12301230123123LL; + A.Z = 1; + return A; +} diff --git a/clang/test/CodeGen/2002-07-30-VarArgsCallFailure.c b/clang/test/CodeGen/2002-07-30-VarArgsCallFailure.c new file mode 100644 index 0000000..784305d --- /dev/null +++ b/clang/test/CodeGen/2002-07-30-VarArgsCallFailure.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +int tcount; +void test(char *, const char*, int); +void foo() { + char Buf[10]; + test(Buf, "n%%%d", tcount++); +} diff --git a/clang/test/CodeGen/2002-07-31-BadAssert.c b/clang/test/CodeGen/2002-07-31-BadAssert.c new file mode 100644 index 0000000..512a63a --- /dev/null +++ b/clang/test/CodeGen/2002-07-31-BadAssert.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +typedef struct +{ + unsigned char type; /* Indicates, NORMAL, SUBNORMAL, etc. */ +} InternalFPF; + + +static void SetInternalFPFZero(InternalFPF *dest) { + dest->type=0; +} + +void denormalize(InternalFPF *ptr) { + SetInternalFPFZero(ptr); +} + diff --git a/clang/test/CodeGen/2002-07-31-SubregFailure.c b/clang/test/CodeGen/2002-07-31-SubregFailure.c new file mode 100644 index 0000000..5c7f38f --- /dev/null +++ b/clang/test/CodeGen/2002-07-31-SubregFailure.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +typedef union { + long (*ap)[4]; +} ptrs; + +void DoAssignIteration() { + ptrs abase; + abase.ap+=27; + Assignment(*abase.ap); +} + + diff --git a/clang/test/CodeGen/2002-08-02-UnionTest.c b/clang/test/CodeGen/2002-08-02-UnionTest.c new file mode 100644 index 0000000..2be1499 --- /dev/null +++ b/clang/test/CodeGen/2002-08-02-UnionTest.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* In this testcase, the return value of foo() is being promoted to a register + * which breaks stuff + */ +int printf(const char * restrict format, ...); + +union X { char X; void *B; int a, b, c, d;}; + +union X foo() { + union X Global; + Global.B = (void*)123; /* Interesting part */ + return Global; +} + +int main() { + union X test = foo(); + printf("0x%p", test.B); +} diff --git a/clang/test/CodeGen/2002-08-19-RecursiveLocals.c b/clang/test/CodeGen/2002-08-19-RecursiveLocals.c new file mode 100644 index 0000000..89c67ba --- /dev/null +++ b/clang/test/CodeGen/2002-08-19-RecursiveLocals.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* This testcase doesn't actually test a bug, it's just the result of me + * figuring out the syntax for forward declaring a static variable. */ +struct list { + int x; + struct list *Next; +}; + +static struct list B; /* Forward declare static */ +static struct list A = { 7, &B }; +static struct list B = { 8, &A }; + +extern struct list D; /* forward declare normal var */ + +struct list C = { 7, &D }; +struct list D = { 8, &C }; + diff --git a/clang/test/CodeGen/2002-09-08-PointerShifts.c b/clang/test/CodeGen/2002-09-08-PointerShifts.c new file mode 100644 index 0000000..7d1ba6e --- /dev/null +++ b/clang/test/CodeGen/2002-09-08-PointerShifts.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +int foo(int *A, unsigned X) { + return A[X]; +} diff --git a/clang/test/CodeGen/2002-09-18-UnionProblem.c b/clang/test/CodeGen/2002-09-18-UnionProblem.c new file mode 100644 index 0000000..d299c19 --- /dev/null +++ b/clang/test/CodeGen/2002-09-18-UnionProblem.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +struct DWstruct { + char high, low; +}; + +typedef union { + struct DWstruct s; + short ll; +} DWunion; + +short __udivmodhi4 (char n1, char bm) { + DWunion rr; + + if (bm == 0) + { + rr.s.high = n1; + } + else + { + rr.s.high = bm; + } + + return rr.ll; +} diff --git a/clang/test/CodeGen/2002-09-19-StarInLabel.c b/clang/test/CodeGen/2002-09-19-StarInLabel.c new file mode 100644 index 0000000..e046e2b --- /dev/null +++ b/clang/test/CodeGen/2002-09-19-StarInLabel.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +extern void start() __asm__("start"); +extern void _start() __asm__("_start"); +extern void __start() __asm__("__start"); +void start() {} +void _start() {} +void __start() {} + diff --git a/clang/test/CodeGen/2002-10-12-TooManyArguments.c b/clang/test/CodeGen/2002-10-12-TooManyArguments.c new file mode 100644 index 0000000..2324c2a --- /dev/null +++ b/clang/test/CodeGen/2002-10-12-TooManyArguments.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +void foo() {} + +void bar() { + foo(1, 2, 3); /* Too many arguments passed */ +} diff --git a/clang/test/CodeGen/2002-12-15-GlobalBoolTest.c b/clang/test/CodeGen/2002-12-15-GlobalBoolTest.c new file mode 100644 index 0000000..3c4133f --- /dev/null +++ b/clang/test/CodeGen/2002-12-15-GlobalBoolTest.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +_Bool X = 0; + diff --git a/clang/test/CodeGen/2002-12-15-GlobalConstantTest.c b/clang/test/CodeGen/2002-12-15-GlobalConstantTest.c new file mode 100644 index 0000000..8203f56 --- /dev/null +++ b/clang/test/CodeGen/2002-12-15-GlobalConstantTest.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +const char *W = "foo"; +const int X = 7; +int Y = 8; +const char * const Z = "bar"; + diff --git a/clang/test/CodeGen/2002-12-15-GlobalRedefinition.c b/clang/test/CodeGen/2002-12-15-GlobalRedefinition.c new file mode 100644 index 0000000..646e91e --- /dev/null +++ b/clang/test/CodeGen/2002-12-15-GlobalRedefinition.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +extern char algbrfile[9]; +char algbrfile[9] = "abcdefgh"; + diff --git a/clang/test/CodeGen/2002-12-15-StructParameters.c b/clang/test/CodeGen/2002-12-15-StructParameters.c new file mode 100644 index 0000000..f6b59de --- /dev/null +++ b/clang/test/CodeGen/2002-12-15-StructParameters.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +typedef struct +{ + void *stack; + unsigned size; + unsigned avail; +} compile_stack_type; + +void foo(void*); +void bar(compile_stack_type T, unsigned); + +void test() { + compile_stack_type CST; + foo(&CST); + + bar(CST, 12); +} diff --git a/clang/test/CodeGen/2003-01-30-UnionInit.c b/clang/test/CodeGen/2003-01-30-UnionInit.c new file mode 100644 index 0000000..98aee72 --- /dev/null +++ b/clang/test/CodeGen/2003-01-30-UnionInit.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +union foo { + struct { char A, B; } X; + int C; +}; + +union foo V = { {1, 2} }; diff --git a/clang/test/CodeGen/2003-03-03-DeferredType.c b/clang/test/CodeGen/2003-03-03-DeferredType.c new file mode 100644 index 0000000..a7a4ce3 --- /dev/null +++ b/clang/test/CodeGen/2003-03-03-DeferredType.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + + + +struct foo A; + +struct foo { + int x; +double D; +}; + diff --git a/clang/test/CodeGen/2003-06-22-UnionCrash.c b/clang/test/CodeGen/2003-06-22-UnionCrash.c new file mode 100644 index 0000000..eb5014c --- /dev/null +++ b/clang/test/CodeGen/2003-06-22-UnionCrash.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct Blend_Map_Entry { + union { + float Colour[5]; + double Point_Slope[2]; + } Vals; +}; + +void test(struct Blend_Map_Entry* Foo) +{ +} + diff --git a/clang/test/CodeGen/2003-06-23-GCC-fold-infinite-recursion.c b/clang/test/CodeGen/2003-06-23-GCC-fold-infinite-recursion.c new file mode 100644 index 0000000..51d4824 --- /dev/null +++ b/clang/test/CodeGen/2003-06-23-GCC-fold-infinite-recursion.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +double Test(double A, double B, double C, double D) { + return -(A-B) - (C-D); +} + diff --git a/clang/test/CodeGen/2003-06-26-CFECrash.c b/clang/test/CodeGen/2003-06-26-CFECrash.c new file mode 100644 index 0000000..dd874b7 --- /dev/null +++ b/clang/test/CodeGen/2003-06-26-CFECrash.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +typedef struct min_info { + long offset; + unsigned file_attr; +} min_info; + +typedef struct Globals { + char answerbuf; + min_info info[1]; + min_info *pInfo; +} Uz_Globs; + +extern Uz_Globs G; + +int extract_or_test_files() { + G.pInfo = G.info; +} + diff --git a/clang/test/CodeGen/2003-06-29-MultipleFunctionDefinition.c b/clang/test/CodeGen/2003-06-29-MultipleFunctionDefinition.c new file mode 100644 index 0000000..99b3a7f --- /dev/null +++ b/clang/test/CodeGen/2003-06-29-MultipleFunctionDefinition.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -std=gnu89 -emit-llvm %s -o /dev/null + +/* This is apparently legal C. + */ +extern __inline__ void test() { } + +void test() { +} diff --git a/clang/test/CodeGen/2003-07-22-ArrayAccessTypeSafety.c b/clang/test/CodeGen/2003-07-22-ArrayAccessTypeSafety.c new file mode 100644 index 0000000..d0703ef --- /dev/null +++ b/clang/test/CodeGen/2003-07-22-ArrayAccessTypeSafety.c @@ -0,0 +1,7 @@ +/* RUN: %clang_cc1 %s -emit-llvm -o - | grep -v alloca | not grep bitcast + */ + +void test(int* array, long long N) { + array[N] = N[array] = 33; +} + diff --git a/clang/test/CodeGen/2003-08-06-BuiltinSetjmpLongjmp.c b/clang/test/CodeGen/2003-08-06-BuiltinSetjmpLongjmp.c new file mode 100644 index 0000000..12bce26 --- /dev/null +++ b/clang/test/CodeGen/2003-08-06-BuiltinSetjmpLongjmp.c @@ -0,0 +1,14 @@ +/* RUN: %clang_cc1 %s -emit-llvm -o - | not grep __builtin_ + * + * __builtin_longjmp/setjmp should get transformed into llvm.setjmp/longjmp + * just like explicit setjmp/longjmp calls are. + */ + +void jumpaway(int *ptr) { + __builtin_longjmp(ptr,1); +} + +int main(void) { + __builtin_setjmp(0); + jumpaway(0); +} diff --git a/clang/test/CodeGen/2003-08-17-DeadCodeShortCircuit.c b/clang/test/CodeGen/2003-08-17-DeadCodeShortCircuit.c new file mode 100644 index 0000000..031b530 --- /dev/null +++ b/clang/test/CodeGen/2003-08-17-DeadCodeShortCircuit.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -x c %s -emit-llvm -o /dev/null + +int test(_Bool pos, _Bool color) { + return 0; + return (pos && color); +} diff --git a/clang/test/CodeGen/2003-08-18-SigSetJmp.c b/clang/test/CodeGen/2003-08-18-SigSetJmp.c new file mode 100644 index 0000000..1b1b18f --- /dev/null +++ b/clang/test/CodeGen/2003-08-18-SigSetJmp.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o /dev/null + +#define _JBLEN ((9 * 2) + 3 + 16) +typedef int sigjmp_buf[_JBLEN + 1]; +int sigsetjmp(sigjmp_buf env, int savemask); +sigjmp_buf B; +int foo() { + sigsetjmp(B, 1); + bar(); +} diff --git a/clang/test/CodeGen/2003-08-18-StructAsValue.c b/clang/test/CodeGen/2003-08-18-StructAsValue.c new file mode 100644 index 0000000..9b8b5a2 --- /dev/null +++ b/clang/test/CodeGen/2003-08-18-StructAsValue.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +typedef struct { + int op; +} event_t; + +event_t test(int X) { + event_t foo = { 1 }, bar = { 2 }; + return X ? foo : bar; +} diff --git a/clang/test/CodeGen/2003-08-20-BadBitfieldRef.c b/clang/test/CodeGen/2003-08-20-BadBitfieldRef.c new file mode 100644 index 0000000..a001546 --- /dev/null +++ b/clang/test/CodeGen/2003-08-20-BadBitfieldRef.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +void foo() +{ + char *ap; + ap[1] == '-' && ap[2] == 0; +} + diff --git a/clang/test/CodeGen/2003-08-20-PrototypeMismatch.c b/clang/test/CodeGen/2003-08-20-PrototypeMismatch.c new file mode 100644 index 0000000..fa42ca5 --- /dev/null +++ b/clang/test/CodeGen/2003-08-20-PrototypeMismatch.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + + +static int foo(int); + +static int foo(C) +char C; +{ + return C; +} + +void test() { + foo(7); +} diff --git a/clang/test/CodeGen/2003-08-20-vfork-bug.c b/clang/test/CodeGen/2003-08-20-vfork-bug.c new file mode 100644 index 0000000..7ec0048 --- /dev/null +++ b/clang/test/CodeGen/2003-08-20-vfork-bug.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +extern int vfork(void); +test() { + vfork(); +} diff --git a/clang/test/CodeGen/2003-08-21-BinOp-Type-Mismatch.c b/clang/test/CodeGen/2003-08-21-BinOp-Type-Mismatch.c new file mode 100644 index 0000000..d86b024 --- /dev/null +++ b/clang/test/CodeGen/2003-08-21-BinOp-Type-Mismatch.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct bar; + +void foo() +{ + unsigned int frame, focus; + (struct bar *) focus == (focus ? ((struct bar *) frame) : 0); +} + diff --git a/clang/test/CodeGen/2003-08-21-StmtExpr.c b/clang/test/CodeGen/2003-08-21-StmtExpr.c new file mode 100644 index 0000000..39db694 --- /dev/null +++ b/clang/test/CodeGen/2003-08-21-StmtExpr.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +typedef struct { + unsigned long val; +} structty; + +void bar(structty new_mask); +static void foo() { + bar(({ structty mask; mask; })); +} + diff --git a/clang/test/CodeGen/2003-08-21-WideString.c b/clang/test/CodeGen/2003-08-21-WideString.c new file mode 100644 index 0000000..4071d17 --- /dev/null +++ b/clang/test/CodeGen/2003-08-21-WideString.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +// This bit is taken from Sema/wchar.c so we can avoid the wchar.h include. +typedef __WCHAR_TYPE__ wchar_t; +#if defined(_WIN32) || defined(_M_IX86) || defined(__CYGWIN__) \ + || defined(_M_X64) || defined(SHORT_WCHAR) + #define WCHAR_T_TYPE unsigned short +#elif defined(__sun) || defined(__AuroraUX__) + #define WCHAR_T_TYPE long +#else /* Solaris or AuroraUX. */ + #define WCHAR_T_TYPE int +#endif + +struct { + wchar_t *name; +} syms = { L"NUL" }; diff --git a/clang/test/CodeGen/2003-08-23-LocalUnionTest.c b/clang/test/CodeGen/2003-08-23-LocalUnionTest.c new file mode 100644 index 0000000..50b01e4 --- /dev/null +++ b/clang/test/CodeGen/2003-08-23-LocalUnionTest.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + + +union foo { int X; }; + +int test(union foo* F) { + { + union foo { float X; } A; + } +} diff --git a/clang/test/CodeGen/2003-08-29-BitFieldStruct.c b/clang/test/CodeGen/2003-08-29-BitFieldStruct.c new file mode 100644 index 0000000..d8995ea --- /dev/null +++ b/clang/test/CodeGen/2003-08-29-BitFieldStruct.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct Word { + short bar; + short baz; + int final:1; + short quux; +} *word_limit; + +void foo () +{ + word_limit->final = (word_limit->final && word_limit->final); +} diff --git a/clang/test/CodeGen/2003-08-29-HugeCharConst.c b/clang/test/CodeGen/2003-08-29-HugeCharConst.c new file mode 100644 index 0000000..cd3eb54 --- /dev/null +++ b/clang/test/CodeGen/2003-08-29-HugeCharConst.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +void foo() { + unsigned char int_latin1[] = "f\200\372b\200\343\200\340"; +} diff --git a/clang/test/CodeGen/2003-08-29-StructLayoutBug.c b/clang/test/CodeGen/2003-08-29-StructLayoutBug.c new file mode 100644 index 0000000..0f45fc9 --- /dev/null +++ b/clang/test/CodeGen/2003-08-29-StructLayoutBug.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct foo { + unsigned int I:1; + unsigned char J[1]; + unsigned int K:1; + }; + +void test(struct foo *X) {} + diff --git a/clang/test/CodeGen/2003-08-30-AggregateInitializer.c b/clang/test/CodeGen/2003-08-30-AggregateInitializer.c new file mode 100644 index 0000000..5beb14e --- /dev/null +++ b/clang/test/CodeGen/2003-08-30-AggregateInitializer.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct istruct { + unsigned char C; +}; + +struct foo { + unsigned int I:1; + struct istruct J; + unsigned char L[1]; + unsigned int K:1; +}; + +struct foo F = { 1, { 7 }, { 123 } , 1 }; + + diff --git a/clang/test/CodeGen/2003-08-30-LargeIntegerBitfieldMember.c b/clang/test/CodeGen/2003-08-30-LargeIntegerBitfieldMember.c new file mode 100644 index 0000000..483cb66 --- /dev/null +++ b/clang/test/CodeGen/2003-08-30-LargeIntegerBitfieldMember.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct foo { + unsigned int I:1; + unsigned char J[1][123]; + unsigned int K:1; + }; + +struct foo F; diff --git a/clang/test/CodeGen/2003-09-18-BitfieldTests.c b/clang/test/CodeGen/2003-09-18-BitfieldTests.c new file mode 100644 index 0000000..6807f5a --- /dev/null +++ b/clang/test/CodeGen/2003-09-18-BitfieldTests.c @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -w -emit-llvm %s -o /dev/null + + +typedef struct BF { + int A : 1; + char B; + int C : 13; +} BF; + +char *test1(BF *b) { + return &b->B; // Must be able to address non-bitfield +} + +void test2(BF *b) { // Increment and decrement operators + b->A++; + --b->C; +} + +void test3(BF *b) { + b->C = 12345; // Store +} + +int test4(BF *b) { + return b->C; // Load +} + +void test5(BF *b, int i) { // array ref + b[i].C = 12345; +} + diff --git a/clang/test/CodeGen/2003-09-30-StructLayout.c b/clang/test/CodeGen/2003-09-30-StructLayout.c new file mode 100644 index 0000000..45ef69c --- /dev/null +++ b/clang/test/CodeGen/2003-09-30-StructLayout.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +enum En { + ENUM_VAL +}; + +struct St { + unsigned char A; + enum En B; + unsigned char C; + enum En D; + float E; +}; + + +void func(struct St* A) { + A->D = ENUM_VAL; +} diff --git a/clang/test/CodeGen/2003-10-02-UnionLValueError.c b/clang/test/CodeGen/2003-10-02-UnionLValueError.c new file mode 100644 index 0000000..180eb10 --- /dev/null +++ b/clang/test/CodeGen/2003-10-02-UnionLValueError.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +int sprintf(char * restrict str, const char * restrict format, ...); +union U{ + int i[8]; + char s[80]; +}; + +void format_message(char *buffer, union U *u) { + sprintf(buffer, u->s); +} diff --git a/clang/test/CodeGen/2003-10-06-NegateExprType.c b/clang/test/CodeGen/2003-10-06-NegateExprType.c new file mode 100644 index 0000000..6d692c1 --- /dev/null +++ b/clang/test/CodeGen/2003-10-06-NegateExprType.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +extern int A[10]; +void Func(int *B) { + B - &A[5]; +} + diff --git a/clang/test/CodeGen/2003-10-09-UnionInitializerBug.c b/clang/test/CodeGen/2003-10-09-UnionInitializerBug.c new file mode 100644 index 0000000..a14fd08 --- /dev/null +++ b/clang/test/CodeGen/2003-10-09-UnionInitializerBug.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct Foo { + unsigned a; + unsigned b; + unsigned c; +}; + +struct Bar { + union { + void **a; + struct Foo b; + }u; +}; + +struct Bar test = {0}; + diff --git a/clang/test/CodeGen/2003-10-28-ident.c b/clang/test/CodeGen/2003-10-28-ident.c new file mode 100644 index 0000000..d1e5447 --- /dev/null +++ b/clang/test/CodeGen/2003-10-28-ident.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +#ident "foo" diff --git a/clang/test/CodeGen/2003-10-29-AsmRename.c b/clang/test/CodeGen/2003-10-29-AsmRename.c new file mode 100644 index 0000000..d0f19af --- /dev/null +++ b/clang/test/CodeGen/2003-10-29-AsmRename.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-apple-darwin -o /dev/null + + +struct foo { int X; }; +struct bar { int Y; }; + +extern int Func(struct foo*) __asm__("Func64"); +extern int Func64(struct bar*); + +int Func(struct foo *F) { + return 1; +} + +int Func64(struct bar* B) { + return 0; +} + + +int test() { + Func(0); /* should be renamed to call Func64 */ + Func64(0); +} diff --git a/clang/test/CodeGen/2003-11-01-C99-CompoundLiteral.c b/clang/test/CodeGen/2003-11-01-C99-CompoundLiteral.c new file mode 100644 index 0000000..f4d3824 --- /dev/null +++ b/clang/test/CodeGen/2003-11-01-C99-CompoundLiteral.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +typedef struct { int foo; } spinlock_t; +typedef struct wait_queue_head_t { spinlock_t lock; } wait_queue_head_t; +void call_usermodehelper(void) { + struct wait_queue_head_t work = { lock: (spinlock_t) { 0 }, }; +} + diff --git a/clang/test/CodeGen/2003-11-01-EmptyStructCrash.c b/clang/test/CodeGen/2003-11-01-EmptyStructCrash.c new file mode 100644 index 0000000..e0f231a --- /dev/null +++ b/clang/test/CodeGen/2003-11-01-EmptyStructCrash.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +typedef struct { } the_coolest_struct_in_the_world; +extern the_coolest_struct_in_the_world xyzzy; +void *foo() { return &xyzzy; } + diff --git a/clang/test/CodeGen/2003-11-01-GlobalUnionInit.c b/clang/test/CodeGen/2003-11-01-GlobalUnionInit.c new file mode 100644 index 0000000..8290379 --- /dev/null +++ b/clang/test/CodeGen/2003-11-01-GlobalUnionInit.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +union bdflush_param { + struct { int x; } b_un; + int y[1]; +} bdf_prm = {{30}}; + diff --git a/clang/test/CodeGen/2003-11-03-AddrArrayElement.c b/clang/test/CodeGen/2003-11-03-AddrArrayElement.c new file mode 100644 index 0000000..50e81d6 --- /dev/null +++ b/clang/test/CodeGen/2003-11-03-AddrArrayElement.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// This should be turned into a tasty getelementptr instruction, not a nasty +// series of casts and address arithmetic. + +char Global[100]; + +char *test1(unsigned i) { + // CHECK: getelementptr + return &Global[i]; +} diff --git a/clang/test/CodeGen/2003-11-04-EmptyStruct.c b/clang/test/CodeGen/2003-11-04-EmptyStruct.c new file mode 100644 index 0000000..e771b88 --- /dev/null +++ b/clang/test/CodeGen/2003-11-04-EmptyStruct.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +typedef struct { } rwlock_t; +struct fs_struct { rwlock_t lock; int umask; }; +void __copy_fs_struct(struct fs_struct *fs) { fs->lock = (rwlock_t) { }; } + diff --git a/clang/test/CodeGen/2003-11-04-OutOfMemory.c b/clang/test/CodeGen/2003-11-04-OutOfMemory.c new file mode 100644 index 0000000..579c93d --- /dev/null +++ b/clang/test/CodeGen/2003-11-04-OutOfMemory.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +void schedule_timeout(signed long timeout) +{ + switch (timeout) + { + case ((long)(~0UL>>1)): break; + } +} diff --git a/clang/test/CodeGen/2003-11-08-PointerSubNotGetelementptr.c b/clang/test/CodeGen/2003-11-08-PointerSubNotGetelementptr.c new file mode 100644 index 0000000..9a9c642 --- /dev/null +++ b/clang/test/CodeGen/2003-11-08-PointerSubNotGetelementptr.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +char *test(char* C) { + // CHECK: getelementptr + return C-1; // Should turn into a GEP +} + +int *test2(int* I) { + return I-1; +} diff --git a/clang/test/CodeGen/2003-11-12-VoidString.c b/clang/test/CodeGen/2003-11-12-VoidString.c new file mode 100644 index 0000000..d22e9f4 --- /dev/null +++ b/clang/test/CodeGen/2003-11-12-VoidString.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +void query_newnamebuf(void) { ((void)"query_newnamebuf"); } + diff --git a/clang/test/CodeGen/2003-11-13-TypeSafety.c b/clang/test/CodeGen/2003-11-13-TypeSafety.c new file mode 100644 index 0000000..b9add6c --- /dev/null +++ b/clang/test/CodeGen/2003-11-13-TypeSafety.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | grep getelementptr + +int *test(int *X, int Y) { + return X + Y; +} diff --git a/clang/test/CodeGen/2003-11-16-StaticArrayInit.c b/clang/test/CodeGen/2003-11-16-StaticArrayInit.c new file mode 100644 index 0000000..8a11c05 --- /dev/null +++ b/clang/test/CodeGen/2003-11-16-StaticArrayInit.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +void bar () { + static char x[10]; + static char *xend = x + 10; +} + + diff --git a/clang/test/CodeGen/2003-11-18-CondExprLValue.c b/clang/test/CodeGen/2003-11-18-CondExprLValue.c new file mode 100644 index 0000000..62968e5 --- /dev/null +++ b/clang/test/CodeGen/2003-11-18-CondExprLValue.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +typedef struct { unsigned long pgprot; } pgprot_t; + +void split_large_page(unsigned long addr, pgprot_t prot) +{ + (addr ? prot : ((pgprot_t) { 0x001 } )).pgprot; +} + diff --git a/clang/test/CodeGen/2003-11-19-AddressOfRegister.c b/clang/test/CodeGen/2003-11-19-AddressOfRegister.c new file mode 100644 index 0000000..e80ff65 --- /dev/null +++ b/clang/test/CodeGen/2003-11-19-AddressOfRegister.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null + +struct item { + short delta[4]; +}; + +int TEST(int nt) { + register struct item *aa; + aa[nt].delta; + return 1; +} diff --git a/clang/test/CodeGen/2003-11-19-BitFieldArray.c b/clang/test/CodeGen/2003-11-19-BitFieldArray.c new file mode 100644 index 0000000..8411563 --- /dev/null +++ b/clang/test/CodeGen/2003-11-19-BitFieldArray.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct _GIOChannel { + int write_buf; + char partial_write_buf[6]; + int d :1; +}; + +void g_io_channel_init (struct _GIOChannel *channel) { + channel->partial_write_buf[0]; +} + diff --git a/clang/test/CodeGen/2003-11-20-Bitfields.c b/clang/test/CodeGen/2003-11-20-Bitfields.c new file mode 100644 index 0000000..5284cde --- /dev/null +++ b/clang/test/CodeGen/2003-11-20-Bitfields.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct face_cachel { + unsigned int reverse :1; + unsigned char font_specified[1]; +}; + +void +ensure_face_cachel_contains_charset (struct face_cachel *cachel) { + cachel->font_specified[0] = 0; +} + diff --git a/clang/test/CodeGen/2003-11-20-ComplexDivision.c b/clang/test/CodeGen/2003-11-20-ComplexDivision.c new file mode 100644 index 0000000..ecd780b --- /dev/null +++ b/clang/test/CodeGen/2003-11-20-ComplexDivision.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +int test() { + __complex__ double C; + double D; + C / D; +} diff --git a/clang/test/CodeGen/2003-11-20-UnionBitfield.c b/clang/test/CodeGen/2003-11-20-UnionBitfield.c new file mode 100644 index 0000000..6ffe76a --- /dev/null +++ b/clang/test/CodeGen/2003-11-20-UnionBitfield.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct printf_spec { + unsigned int minus_flag:1; + char converter; +}; + +void parse_doprnt_spec () { + struct printf_spec spec; + spec.minus_flag = 1; +} + diff --git a/clang/test/CodeGen/2003-11-26-PointerShift.c b/clang/test/CodeGen/2003-11-26-PointerShift.c new file mode 100644 index 0000000..530759e --- /dev/null +++ b/clang/test/CodeGen/2003-11-26-PointerShift.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +unsigned long do_csum(const unsigned char *buff, int len, unsigned long result) { + if (2 & (unsigned long) buff) result += 1; + return result; +} diff --git a/clang/test/CodeGen/2003-11-27-ConstructorCast.c b/clang/test/CodeGen/2003-11-27-ConstructorCast.c new file mode 100644 index 0000000..f04fa21 --- /dev/null +++ b/clang/test/CodeGen/2003-11-27-ConstructorCast.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct i387_soft_struct { + long cwd; +}; +union i387_union { + struct i387_soft_struct soft; +}; +struct thread_struct { + union i387_union i387; +}; +void _init_task_union(void) { + struct thread_struct thread = (struct thread_struct) { {{0}} }; +} diff --git a/clang/test/CodeGen/2003-11-27-UnionCtorInitialization.c b/clang/test/CodeGen/2003-11-27-UnionCtorInitialization.c new file mode 100644 index 0000000..ca80173 --- /dev/null +++ b/clang/test/CodeGen/2003-11-27-UnionCtorInitialization.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct i387_soft_struct { + long cwd; + long twd; + long fip; +}; +union i387_union { + struct i387_soft_struct soft; +}; +struct thread_struct { + union i387_union i387; +}; +void _init_task_union(void) { + struct thread_struct thread = (struct thread_struct) { {{0}} }; +} diff --git a/clang/test/CodeGen/2003-12-14-ExternInlineSupport.c b/clang/test/CodeGen/2003-12-14-ExternInlineSupport.c new file mode 100644 index 0000000..eb3859c --- /dev/null +++ b/clang/test/CodeGen/2003-12-14-ExternInlineSupport.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -std=gnu89 %s -emit-llvm -o - | not grep dead_function + +extern __inline__ void dead_function() {} diff --git a/clang/test/CodeGen/2004-01-01-UnknownInitSize.c b/clang/test/CodeGen/2004-01-01-UnknownInitSize.c new file mode 100644 index 0000000..25ddebd --- /dev/null +++ b/clang/test/CodeGen/2004-01-01-UnknownInitSize.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +/* + * This regression test ensures that the C front end can compile initializers + * even when it cannot determine the size (as below). +*/ +struct one +{ + int a; + int values []; +}; + +struct one hobbit = {5, {1, 2, 3}}; + diff --git a/clang/test/CodeGen/2004-01-08-ExternInlineRedefine.c b/clang/test/CodeGen/2004-01-08-ExternInlineRedefine.c new file mode 100644 index 0000000..358a9c2 --- /dev/null +++ b/clang/test/CodeGen/2004-01-08-ExternInlineRedefine.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=gnu89 -emit-llvm %s -o /dev/null + + +extern __inline long int +__strtol_l (int a) +{ + return 0; +} + +long int +__strtol_l (int a) +{ + return 0; +} diff --git a/clang/test/CodeGen/2004-02-12-LargeAggregateCopy.c b/clang/test/CodeGen/2004-02-12-LargeAggregateCopy.c new file mode 100644 index 0000000..811ee8e --- /dev/null +++ b/clang/test/CodeGen/2004-02-12-LargeAggregateCopy.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +struct X { int V[10000]; }; +struct X Global1, Global2; +void test() { + // CHECK: llvm.memcpy + Global2 = Global1; +} diff --git a/clang/test/CodeGen/2004-02-13-BuiltinFrameReturnAddress.c b/clang/test/CodeGen/2004-02-13-BuiltinFrameReturnAddress.c new file mode 100644 index 0000000..8c0b7ba --- /dev/null +++ b/clang/test/CodeGen/2004-02-13-BuiltinFrameReturnAddress.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +void *test1() { + // CHECK: call i8* @llvm.returnaddress + return __builtin_return_address(1); +} +void *test2() { + // CHECK: call i8* @llvm.frameaddress + return __builtin_frame_address(0); +} diff --git a/clang/test/CodeGen/2004-02-13-IllegalVararg.c b/clang/test/CodeGen/2004-02-13-IllegalVararg.c new file mode 100644 index 0000000..cbc9151 --- /dev/null +++ b/clang/test/CodeGen/2004-02-13-IllegalVararg.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -w -emit-llvm -o - + +float test(int X, ...) { + __builtin_va_list ap; + float F; + __builtin_va_start(ap, X); + F = __builtin_va_arg(ap, float); + return F; +} diff --git a/clang/test/CodeGen/2004-02-13-Memset.c b/clang/test/CodeGen/2004-02-13-Memset.c new file mode 100644 index 0000000..23a4d3b --- /dev/null +++ b/clang/test/CodeGen/2004-02-13-Memset.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | grep llvm.memset | count 3 + +typedef __SIZE_TYPE__ size_t; +void *memset(void*, int, size_t); +void bzero(void*, size_t); + +void test(int* X, char *Y) { + // CHECK: call i8* llvm.memset + memset(X, 4, 1000); + // CHECK: call void bzero + bzero(Y, 100); +} diff --git a/clang/test/CodeGen/2004-02-14-ZeroInitializer.c b/clang/test/CodeGen/2004-02-14-ZeroInitializer.c new file mode 100644 index 0000000..3379a06 --- /dev/null +++ b/clang/test/CodeGen/2004-02-14-ZeroInitializer.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: zeroinitializer +int X[1000]; diff --git a/clang/test/CodeGen/2004-02-20-Builtins.c b/clang/test/CodeGen/2004-02-20-Builtins.c new file mode 100644 index 0000000..9be0523 --- /dev/null +++ b/clang/test/CodeGen/2004-02-20-Builtins.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | not grep builtin +double sqrt(double x); +void zsqrtxxx(float num) { + num = sqrt(num); +} diff --git a/clang/test/CodeGen/2004-03-07-ComplexDivEquals.c b/clang/test/CodeGen/2004-03-07-ComplexDivEquals.c new file mode 100644 index 0000000..e2cd539 --- /dev/null +++ b/clang/test/CodeGen/2004-03-07-ComplexDivEquals.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +void test(__complex__ double D, double X) { + D /= X; +} diff --git a/clang/test/CodeGen/2004-03-07-ExternalConstant.c b/clang/test/CodeGen/2004-03-07-ExternalConstant.c new file mode 100644 index 0000000..2de3a69 --- /dev/null +++ b/clang/test/CodeGen/2004-03-07-ExternalConstant.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: @a = external constan +extern const int a[]; // 'a' should be marked constant even though it's external! +int foo () { + return a[0]; +} diff --git a/clang/test/CodeGen/2004-03-09-LargeArrayInitializers.c b/clang/test/CodeGen/2004-03-09-LargeArrayInitializers.c new file mode 100644 index 0000000..b34af0d --- /dev/null +++ b/clang/test/CodeGen/2004-03-09-LargeArrayInitializers.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +// Test that these initializers are handled efficiently + +int test(int x) { + const int XX[1000] = { 0, 0 }; + const char S [1000] = "foo"; + + const int array[] = { + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, + }; + return array[x]; +} diff --git a/clang/test/CodeGen/2004-03-15-SimpleIndirectGoto.c b/clang/test/CodeGen/2004-03-15-SimpleIndirectGoto.c new file mode 100644 index 0000000..93fb59f --- /dev/null +++ b/clang/test/CodeGen/2004-03-15-SimpleIndirectGoto.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +int code[]={0,0,0,0,1}; +void foo(int x) { + volatile int b; + b = 0xffffffff; +} +void bar(int *pc) { + static const void *l[] = {&&lab0, &&end}; + + foo(0); + goto *l[*pc]; + lab0: + foo(0); + pc++; + goto *l[*pc]; + end: + return; +} +int main() { + bar(code); + return 0; +} diff --git a/clang/test/CodeGen/2004-03-16-AsmRegisterCrash.c b/clang/test/CodeGen/2004-03-16-AsmRegisterCrash.c new file mode 100644 index 0000000..515d243 --- /dev/null +++ b/clang/test/CodeGen/2004-03-16-AsmRegisterCrash.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +// XFAIL: * +// XTARGET: arm, i386, i686, x86_64 + +int foo() { +#ifdef __arm__ + register int X __asm__("r1"); +#else + register int X __asm__("ebx"); +#endif + return X; +} diff --git a/clang/test/CodeGen/2004-05-07-VarArrays.c b/clang/test/CodeGen/2004-05-07-VarArrays.c new file mode 100644 index 0000000..1ef5cf3 --- /dev/null +++ b/clang/test/CodeGen/2004-05-07-VarArrays.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +int foo(int len, char arr[][len], int X) { + return arr[X][0]; +} diff --git a/clang/test/CodeGen/2004-05-21-IncompleteEnum.c b/clang/test/CodeGen/2004-05-21-IncompleteEnum.c new file mode 100644 index 0000000..41652d1 --- /dev/null +++ b/clang/test/CodeGen/2004-05-21-IncompleteEnum.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -w -emit-llvm %s -o /dev/null + +void test(enum foo *X) { +} + diff --git a/clang/test/CodeGen/2004-06-08-OpaqueStructArg.c b/clang/test/CodeGen/2004-06-08-OpaqueStructArg.c new file mode 100644 index 0000000..cec4459 --- /dev/null +++ b/clang/test/CodeGen/2004-06-08-OpaqueStructArg.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + struct fu; + void foo(struct fu); + void bar() { + foo; + } diff --git a/clang/test/CodeGen/2004-06-17-UnorderedBuiltins.c b/clang/test/CodeGen/2004-06-17-UnorderedBuiltins.c new file mode 100644 index 0000000..90360c4 --- /dev/null +++ b/clang/test/CodeGen/2004-06-17-UnorderedBuiltins.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +_Bool A, B, C, D, E, F, G, H; +void TestF(float X, float Y) { + A = __builtin_isgreater(X, Y); + B = __builtin_isgreaterequal(X, Y); + C = __builtin_isless(X, Y); + D = __builtin_islessequal(X, Y); + E = __builtin_islessgreater(X, Y); + F = __builtin_isunordered(X, Y); + //G = __builtin_isordered(X, Y); // Our current snapshot of GCC doesn't include this builtin + H = __builtin_isunordered(X, Y); +} +void TestD(double X, double Y) { + A = __builtin_isgreater(X, Y); + B = __builtin_isgreaterequal(X, Y); + C = __builtin_isless(X, Y); + D = __builtin_islessequal(X, Y); + E = __builtin_islessgreater(X, Y); + F = __builtin_isunordered(X, Y); + //G = __builtin_isordered(X, Y); // Our current snapshot doesn't include this builtin. FIXME + H = __builtin_isunordered(X, Y); +} diff --git a/clang/test/CodeGen/2004-06-17-UnorderedCompares.c b/clang/test/CodeGen/2004-06-17-UnorderedCompares.c new file mode 100644 index 0000000..7d2ba96 --- /dev/null +++ b/clang/test/CodeGen/2004-06-17-UnorderedCompares.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c99 %s -emit-llvm -o - | grep -v llvm.isunordered | not grep call + +_Bool A, B, C, D, E, F; +void TestF(float X, float Y) { + A = __builtin_isgreater(X, Y); + B = __builtin_isgreaterequal(X, Y); + C = __builtin_isless(X, Y); + D = __builtin_islessequal(X, Y); + E = __builtin_islessgreater(X, Y); + F = __builtin_isunordered(X, Y); +} +void TestD(double X, double Y) { + A = __builtin_isgreater(X, Y); + B = __builtin_isgreaterequal(X, Y); + C = __builtin_isless(X, Y); + D = __builtin_islessequal(X, Y); + E = __builtin_islessgreater(X, Y); + F = __builtin_isunordered(X, Y); +} diff --git a/clang/test/CodeGen/2004-06-18-VariableLengthArrayOfStructures.c b/clang/test/CodeGen/2004-06-18-VariableLengthArrayOfStructures.c new file mode 100644 index 0000000..abf78fb --- /dev/null +++ b/clang/test/CodeGen/2004-06-18-VariableLengthArrayOfStructures.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +struct S { }; + +int xxxx(int a) { + struct S comps[a]; + comps[0]; +} + diff --git a/clang/test/CodeGen/2004-07-06-FunctionCast.c b/clang/test/CodeGen/2004-07-06-FunctionCast.c new file mode 100644 index 0000000..32931e2 --- /dev/null +++ b/clang/test/CodeGen/2004-07-06-FunctionCast.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +static int unused_func(void) { + return 1; +} + +int foo(void) { + (void)unused_func; /* avoid compiler warning */ + return 2; +} diff --git a/clang/test/CodeGen/2004-08-06-LargeStructTest.c b/clang/test/CodeGen/2004-08-06-LargeStructTest.c new file mode 100644 index 0000000..ee57f0b --- /dev/null +++ b/clang/test/CodeGen/2004-08-06-LargeStructTest.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + + +#define A(X) int X; +#define B(X) A(X##0) A(X##1) A(X##2) A(X##3) A(X##4) A(X##5) A(X##6) A(X##7) \ + A(X##8) A(X##9) A(X##A) A(X##B) A(X##C) A(X##D) A(X##E) A(X##F) +#define C(X) B(X##0) B(X##1) B(X##2) B(X##3) B(X##4) B(X##5) B(X##6) B(X##7) \ + B(X##8) B(X##9) B(X##A) B(X##B) B(X##C) B(X##D) B(X##E) B(X##F) + +struct foo { + C(x); // 256 + C(y); // 256 + C(z); +}; + + +int test(struct foo *F) { + return F->xA1 + F->yFF + F->zC4; +} diff --git a/clang/test/CodeGen/2004-11-25-UnnamedBitfieldPadding.c b/clang/test/CodeGen/2004-11-25-UnnamedBitfieldPadding.c new file mode 100644 index 0000000..a6af2a5 --- /dev/null +++ b/clang/test/CodeGen/2004-11-25-UnnamedBitfieldPadding.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +// This is a testcase for PR461 +typedef struct { + unsigned min_align: 1; + unsigned : 1; +} addr_diff_vec_flags; + +addr_diff_vec_flags X; diff --git a/clang/test/CodeGen/2004-11-27-InvalidConstantExpr.c b/clang/test/CodeGen/2004-11-27-InvalidConstantExpr.c new file mode 100644 index 0000000..431dccf --- /dev/null +++ b/clang/test/CodeGen/2004-11-27-InvalidConstantExpr.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | not grep {foo\\* sub} +// This should not produce a subtrace constantexpr of a pointer +struct foo { + int Y; + char X[100]; +} F; + +int test(char *Y) { + return Y - F.X; +} diff --git a/clang/test/CodeGen/2004-11-27-StaticFunctionRedeclare.c b/clang/test/CodeGen/2004-11-27-StaticFunctionRedeclare.c new file mode 100644 index 0000000..55efa86 --- /dev/null +++ b/clang/test/CodeGen/2004-11-27-StaticFunctionRedeclare.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | \ +// RUN: opt -std-compile-opts -emit-llvm | not grep {declare i32.*func} + +// There should not be an unresolved reference to func here. Believe it or not, +// the "expected result" is a function named 'func' which is internal and +// referenced by bar(). + +// This is PR244 + +static int func(); +void bar() { + int func(); + foo(func); +} +static int func(char** A, char ** B) {} diff --git a/clang/test/CodeGen/2005-01-02-ConstantInits.c b/clang/test/CodeGen/2005-01-02-ConstantInits.c new file mode 100644 index 0000000..d85f519 --- /dev/null +++ b/clang/test/CodeGen/2005-01-02-ConstantInits.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +// This tests all kinds of hard cases with initializers and +// array subscripts. This corresponds to PR487. + +struct X { int a[2]; }; + +int test() { + static int i23 = (int) &(((struct X *)0)->a[1]); + return i23; +} + +int i = (int) &( ((struct X *)0) -> a[1]); + +int Arr[100]; + +int foo(int i) { return bar(&Arr[49])+bar(&Arr[i]); } +int foo2(int i) { + static const int *X = &Arr[49]; + static int i23 = (int) &( ((struct X *)0) -> a[0]); + int *P = Arr; + ++P; + return bar(Arr+i); +} diff --git a/clang/test/CodeGen/2005-01-02-PointerDifference.c b/clang/test/CodeGen/2005-01-02-PointerDifference.c new file mode 100644 index 0000000..1114ef5 --- /dev/null +++ b/clang/test/CodeGen/2005-01-02-PointerDifference.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: sdiv exact +int Diff(int *P, int *Q) { return P-Q; } diff --git a/clang/test/CodeGen/2005-01-02-VAArgError-ICE.c b/clang/test/CodeGen/2005-01-02-VAArgError-ICE.c new file mode 100644 index 0000000..06377c2 --- /dev/null +++ b/clang/test/CodeGen/2005-01-02-VAArgError-ICE.c @@ -0,0 +1,9 @@ +// This file is erroneous, but should not cause the compiler to ICE. +// PR481 +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null + +int flags(int a, int b, ...) { + __builtin_va_list args; + __builtin_va_start(args,a); // not the last named arg + foo(args); +} diff --git a/clang/test/CodeGen/2005-02-20-AggregateSAVEEXPR.c b/clang/test/CodeGen/2005-02-20-AggregateSAVEEXPR.c new file mode 100644 index 0000000..99efb1b --- /dev/null +++ b/clang/test/CodeGen/2005-02-20-AggregateSAVEEXPR.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 %s -o /dev/null -emit-llvm + +int foo(__complex float c) { + return creal(c); +} diff --git a/clang/test/CodeGen/2005-02-27-MarkGlobalConstant.c b/clang/test/CodeGen/2005-02-27-MarkGlobalConstant.c new file mode 100644 index 0000000..dc2cdbf --- /dev/null +++ b/clang/test/CodeGen/2005-02-27-MarkGlobalConstant.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// PR10414 + +// The synthetic global made by the CFE for big initializer should be marked +// constant. + +void bar(); +void foo() { + // CHECK: private unnamed_addr constant + char Blah[] = "asdlfkajsdlfkajsd;lfkajds;lfkjasd;flkajsd;lkfja;sdlkfjasd"; + bar(Blah); +} diff --git a/clang/test/CodeGen/2005-03-05-OffsetOfHack.c b/clang/test/CodeGen/2005-03-05-OffsetOfHack.c new file mode 100644 index 0000000..4420981 --- /dev/null +++ b/clang/test/CodeGen/2005-03-05-OffsetOfHack.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +struct s { + unsigned long int field[0]; +}; + +#define OFFS \ + (((char *) &((struct s *) 0)->field[0]) - (char *) 0) + +int foo[OFFS]; + + diff --git a/clang/test/CodeGen/2005-03-06-OffsetOfStructCrash.c b/clang/test/CodeGen/2005-03-06-OffsetOfStructCrash.c new file mode 100644 index 0000000..46968bb --- /dev/null +++ b/clang/test/CodeGen/2005-03-06-OffsetOfStructCrash.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +struct Y {}; +struct XXX { + struct Y F; +}; + +void test1() { + (int)&((struct XXX*)(((void *)0)))->F; +} + +void test2() { + &((struct XXX*)(((void *)0)))->F; +} diff --git a/clang/test/CodeGen/2005-03-11-Prefetch.c b/clang/test/CodeGen/2005-03-11-Prefetch.c new file mode 100644 index 0000000..8d7d12e --- /dev/null +++ b/clang/test/CodeGen/2005-03-11-Prefetch.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +void foo(int *P) { + // CHECK: llvm.prefetch + __builtin_prefetch(P); + __builtin_prefetch(P, 1); +} diff --git a/clang/test/CodeGen/2005-04-09-ComplexOps.c b/clang/test/CodeGen/2005-04-09-ComplexOps.c new file mode 100644 index 0000000..23716d3 --- /dev/null +++ b/clang/test/CodeGen/2005-04-09-ComplexOps.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +#define I 1.0iF + +double __complex test(double X) { return ~-(X*I); } + +_Bool EQ(double __complex A, double __complex B) { return A == B; } +_Bool NE(double __complex A, double __complex B) { return A != B; } diff --git a/clang/test/CodeGen/2005-05-10-GlobalUnionInit.c b/clang/test/CodeGen/2005-05-10-GlobalUnionInit.c new file mode 100644 index 0000000..ddd7f5e --- /dev/null +++ b/clang/test/CodeGen/2005-05-10-GlobalUnionInit.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +union A { // { uint } + union B { double *C; } D; +} E = { { (double*)12312 } }; + diff --git a/clang/test/CodeGen/2005-06-15-ExpandGotoInternalProblem.c b/clang/test/CodeGen/2005-06-15-ExpandGotoInternalProblem.c new file mode 100644 index 0000000..dd1acc5 --- /dev/null +++ b/clang/test/CodeGen/2005-06-15-ExpandGotoInternalProblem.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c99 %s -emit-llvm -o - | \ +// RUN: opt -std-compile-opts -disable-output +// PR580 + +int X, Y; +int foo() { + int i; + for (i=0; i<100; i++ ) + { + break; + i = ( X || Y ) ; + } +} + diff --git a/clang/test/CodeGen/2005-07-20-SqrtNoErrno.c b/clang/test/CodeGen/2005-07-20-SqrtNoErrno.c new file mode 100644 index 0000000..f40f61d --- /dev/null +++ b/clang/test/CodeGen/2005-07-20-SqrtNoErrno.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// llvm.sqrt has undefined behavior on negative inputs, so it is +// inappropriate to translate C/C++ sqrt to this. +float sqrtf(float x); +float foo(float X) { + // CHECK: foo + // CHECK: call float @sqrtf(float % + // Check that this is marked readonly when errno is ignored. + return sqrtf(X); +} diff --git a/clang/test/CodeGen/2005-07-26-UnionInitCrash.c b/clang/test/CodeGen/2005-07-26-UnionInitCrash.c new file mode 100644 index 0000000..5572240 --- /dev/null +++ b/clang/test/CodeGen/2005-07-26-UnionInitCrash.c @@ -0,0 +1,3 @@ +// PR607 +// RUN: %clang_cc1 %s -emit-llvm -o - +union { char bytes[8]; double alignment; }EQ1 = {0,0,0,0,0,0,0,0}; diff --git a/clang/test/CodeGen/2005-07-28-IncorrectWeakGlobal.c b/clang/test/CodeGen/2005-07-28-IncorrectWeakGlobal.c new file mode 100644 index 0000000..cbacf22 --- /dev/null +++ b/clang/test/CodeGen/2005-07-28-IncorrectWeakGlobal.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | grep TheGlobal | not grep weak + +extern int TheGlobal; +int foo() { return TheGlobal; } +int TheGlobal = 1; diff --git a/clang/test/CodeGen/2005-09-20-ComplexConstants.c b/clang/test/CodeGen/2005-09-20-ComplexConstants.c new file mode 100644 index 0000000..a23ccee --- /dev/null +++ b/clang/test/CodeGen/2005-09-20-ComplexConstants.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null + +const double _Complex x[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + diff --git a/clang/test/CodeGen/2005-09-24-AsmUserPrefix.c b/clang/test/CodeGen/2005-09-24-AsmUserPrefix.c new file mode 100644 index 0000000..1628313 --- /dev/null +++ b/clang/test/CodeGen/2005-09-24-AsmUserPrefix.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | opt -std-compile-opts | llc | \ +// RUN: not grep _foo2 + +void foo() __asm__("foo2"); + +void bar() { + foo(); +} diff --git a/clang/test/CodeGen/2005-09-24-BitFieldCrash.c b/clang/test/CodeGen/2005-09-24-BitFieldCrash.c new file mode 100644 index 0000000..d687d2f --- /dev/null +++ b/clang/test/CodeGen/2005-09-24-BitFieldCrash.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +struct tree_common {}; + +struct tree_int_cst { + struct tree_common common; + struct tree_int_cst_lowhi { + unsigned long long low; + long long high; + } int_cst; +}; + +enum XXX { yyy }; + +struct tree_function_decl { + struct tree_common common; + long long locus, y; + __extension__ enum XXX built_in_class : 2; + +}; + + +union tree_node { + struct tree_int_cst int_cst; + struct tree_function_decl function_decl; +}; + + +void foo (union tree_node * decl) { + decl->function_decl.built_in_class != 0; +} + + diff --git a/clang/test/CodeGen/2005-12-04-AttributeUsed.c b/clang/test/CodeGen/2005-12-04-AttributeUsed.c new file mode 100644 index 0000000..4be6b79 --- /dev/null +++ b/clang/test/CodeGen/2005-12-04-AttributeUsed.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: @llvm.used = appending global [2 x i8*] [i8* bitcast (void ()* @foo to i8*), i8* bitcast (i32* @X to i8*)], section "llvm.metadata" +int X __attribute__((used)); +int Y; + +__attribute__((used)) void foo() {} diff --git a/clang/test/CodeGen/2005-12-04-DeclarationLineNumbers.c b/clang/test/CodeGen/2005-12-04-DeclarationLineNumbers.c new file mode 100644 index 0000000..596d3ee --- /dev/null +++ b/clang/test/CodeGen/2005-12-04-DeclarationLineNumbers.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 %s -emit-llvm -g -o - | grep DW_TAG_compile_unit | count 1 +// PR664: ensure that line #'s are emitted for declarations + + +short test(short br_data_0, +short br_data_1, +short br_data_2, +short br_data_3, +short br_data_4, +short br_data_5, +short br_data_6, +short br_data_7) { + +short sm07 = br_data_0 + br_data_7; +short sm16 = br_data_1 + br_data_6; +short sm25 = br_data_2 + br_data_5; +short sm34 = br_data_3 + br_data_4; +short s0734 = sm07 + sm34; +short s1625 = sm16 + sm25; + +return s0734 + s1625; +} + diff --git a/clang/test/CodeGen/2006-01-13-Includes.c b/clang/test/CodeGen/2006-01-13-Includes.c new file mode 100644 index 0000000..9cc45ce --- /dev/null +++ b/clang/test/CodeGen/2006-01-13-Includes.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -g -emit-llvm -o - | FileCheck %s +// PR676 + +int printf(const char * restrict format, ...); + +void test() { + printf("Hello World\n"); +} + +// CHECK: test{{[\\/]}}CodeGen diff --git a/clang/test/CodeGen/2006-01-13-StackSave.c b/clang/test/CodeGen/2006-01-13-StackSave.c new file mode 100644 index 0000000..7c506b3 --- /dev/null +++ b/clang/test/CodeGen/2006-01-13-StackSave.c @@ -0,0 +1,11 @@ +// PR691 +// RUN: %clang_cc1 %s -emit-llvm -o - | opt -std-compile-opts | \ +// RUN: llvm-dis | grep llvm.stacksave + +void test(int N) { + int i; + for (i = 0; i < N; ++i) { + int VLA[i]; + external(VLA); + } +} diff --git a/clang/test/CodeGen/2006-01-16-BitCountIntrinsicsUnsigned.c b/clang/test/CodeGen/2006-01-16-BitCountIntrinsicsUnsigned.c new file mode 100644 index 0000000..ba7820a --- /dev/null +++ b/clang/test/CodeGen/2006-01-16-BitCountIntrinsicsUnsigned.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +unsigned t2(unsigned X) { + // CHECK: t2 + // CHECK: llvm.ctlz.i32 + return __builtin_clz(X); +} +int t1(int X) { + // CHECK: t1 + // CHECK: llvm.ctlz.i32 + return __builtin_clz(X); +} diff --git a/clang/test/CodeGen/2006-01-23-FileScopeAsm.c b/clang/test/CodeGen/2006-01-23-FileScopeAsm.c new file mode 100644 index 0000000..472b464 --- /dev/null +++ b/clang/test/CodeGen/2006-01-23-FileScopeAsm.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: module asm "foo1" +__asm__ ("foo1"); +// CHECK: module asm "foo2" +__asm__ ("foo2"); +// CHECK: module asm "foo3" +__asm__ ("foo3"); +// CHECK: module asm "foo4" +__asm__ ("foo4"); +// CHECK: module asm "foo5" +__asm__ ("foo5"); diff --git a/clang/test/CodeGen/2006-03-03-MissingInitializer.c b/clang/test/CodeGen/2006-03-03-MissingInitializer.c new file mode 100644 index 0000000..d2317d3 --- /dev/null +++ b/clang/test/CodeGen/2006-03-03-MissingInitializer.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +struct X { int *XX; int Y;}; + +void foo() { + // CHECK: @foo.nate = internal global i32 0 + static int nate = 0; + struct X bob = { &nate, 14 }; + bar(&bob); +} diff --git a/clang/test/CodeGen/2006-03-16-VectorCtor.c b/clang/test/CodeGen/2006-03-16-VectorCtor.c new file mode 100644 index 0000000..c04d4b9 --- /dev/null +++ b/clang/test/CodeGen/2006-03-16-VectorCtor.c @@ -0,0 +1,10 @@ +// Test that basic generic vector support works +// RUN: %clang_cc1 %s -emit-llvm -o - + +typedef int v4si __attribute__ ((__vector_size__ (16))); +void test(v4si *P, v4si *Q, float X) { + *P = (v4si){ X, X, X, X } * *Q; +} + +v4si G = (v4si){ 0.1, 1.2, 4.2, 17.2 }; + diff --git a/clang/test/CodeGen/2006-03-17-KnRMismatch.c b/clang/test/CodeGen/2006-03-17-KnRMismatch.c new file mode 100644 index 0000000..f678e9f --- /dev/null +++ b/clang/test/CodeGen/2006-03-17-KnRMismatch.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +void regnode(int op); + +void regnode(op) +char op; +{ +} diff --git a/clang/test/CodeGen/2006-05-19-SingleEltReturn.c b/clang/test/CodeGen/2006-05-19-SingleEltReturn.c new file mode 100644 index 0000000..819237c --- /dev/null +++ b/clang/test/CodeGen/2006-05-19-SingleEltReturn.c @@ -0,0 +1,23 @@ +// Test returning a single element aggregate value containing a double. +// RUN: %clang_cc1 %s -emit-llvm -o - + +struct X { + double D; +}; + +struct Y { + struct X x; +}; + +struct Y bar(); + +void foo(struct Y *P) { + *P = bar(); +} + +struct Y bar() { + struct Y a; + a.x.D = 0; + return a; +} + diff --git a/clang/test/CodeGen/2006-07-31-PR854.c b/clang/test/CodeGen/2006-07-31-PR854.c new file mode 100644 index 0000000..b3b4d8e --- /dev/null +++ b/clang/test/CodeGen/2006-07-31-PR854.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple i686-linux-gnu -w %s -emit-llvm -o - + +// PR854 + struct kernel_symbol { + unsigned long value; + }; + unsigned long loops_per_jiffy = (1<<12); + static const char __kstrtab_loops_per_jiffy[] +__attribute__((section("__ksymtab_strings"))) = "loops_per_jiffy"; + static const struct kernel_symbol __ksymtab_loops_per_jiffy +__attribute__((__used__)) __attribute__((section("__ksymtab"))) = { (unsigned +long)&loops_per_jiffy, __kstrtab_loops_per_jiffy }; diff --git a/clang/test/CodeGen/2006-09-11-BitfieldRefCrash.c b/clang/test/CodeGen/2006-09-11-BitfieldRefCrash.c new file mode 100644 index 0000000..3d45d8b --- /dev/null +++ b/clang/test/CodeGen/2006-09-11-BitfieldRefCrash.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - +// PR906 + +struct state_struct { + unsigned long long phys_frame: 50; + unsigned valid : 2; +} s; + +int mem_access(struct state_struct *p) { + return p->valid; +} + diff --git a/clang/test/CodeGen/2006-09-18-fwrite-cast-crash.c b/clang/test/CodeGen/2006-09-18-fwrite-cast-crash.c new file mode 100644 index 0000000..a12fd0b --- /dev/null +++ b/clang/test/CodeGen/2006-09-18-fwrite-cast-crash.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null +// PR910 + +struct l_struct_2E_FILE { char x; }; +unsigned fwrite(signed char *, unsigned , unsigned , signed char *); +static signed char str301[39]; +static void Usage(signed char *ltmp_611_6) { + struct l_struct_2E_FILE *ltmp_6202_16; + unsigned ltmp_6203_92; + ltmp_6203_92 = /*tail*/ ((unsigned (*) (signed char *, unsigned , unsigned , +struct l_struct_2E_FILE *))(void*)fwrite)((&(str301[0u])), 38u, 1u, ltmp_6202_16); +} diff --git a/clang/test/CodeGen/2006-09-21-IncompleteElementType.c b/clang/test/CodeGen/2006-09-21-IncompleteElementType.c new file mode 100644 index 0000000..1c71ea1 --- /dev/null +++ b/clang/test/CodeGen/2006-09-21-IncompleteElementType.c @@ -0,0 +1,3 @@ +// RUN: not %clang_cc1 %s -emit-llvm -o /dev/null + +struct A X[(927 - 37) / sizeof(struct A)]; diff --git a/clang/test/CodeGen/2006-09-25-DebugFilename.c b/clang/test/CodeGen/2006-09-25-DebugFilename.c new file mode 100644 index 0000000..2edb63f --- /dev/null +++ b/clang/test/CodeGen/2006-09-25-DebugFilename.c @@ -0,0 +1,4 @@ +// RUN: not %clang_cc1 %s -emit-llvm -o /dev/null +#include "2006-09-25-DebugFilename.h" +int func1() { return hfunc1(); } +int func2() { fluffy; return hfunc1(); } // expected-error {{use of undeclared identifier 'fluffy'}} diff --git a/clang/test/CodeGen/2006-09-25-DebugFilename.h b/clang/test/CodeGen/2006-09-25-DebugFilename.h new file mode 100644 index 0000000..9b03666 --- /dev/null +++ b/clang/test/CodeGen/2006-09-25-DebugFilename.h @@ -0,0 +1,6 @@ +extern int exfunc(int a); + +static inline int hfunc1() +{ + return exfunc(1); +} diff --git a/clang/test/CodeGen/2006-09-28-SimpleAsm.c b/clang/test/CodeGen/2006-09-28-SimpleAsm.c new file mode 100644 index 0000000..c3983af --- /dev/null +++ b/clang/test/CodeGen/2006-09-28-SimpleAsm.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// PR924 + +void bar() { + // Extended asm + // CHECK: call void asm sideeffect "ext: xorl %eax, eax; movl eax, fs; movl eax, gs %blah + asm volatile ("ext: xorl %%eax, eax; movl eax, fs; movl eax, gs %%blah %= %\ +% " : : "r"(1)); + // CHECK: call void asm sideeffect "nonext: xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs %%blah %= %% + // Non-extended asm. + asm volatile ("nonext: xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs %%blah %= %% "); +} diff --git a/clang/test/CodeGen/2006-10-30-ArrayCrash.c b/clang/test/CodeGen/2006-10-30-ArrayCrash.c new file mode 100644 index 0000000..67446fd --- /dev/null +++ b/clang/test/CodeGen/2006-10-30-ArrayCrash.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -O3 -emit-llvm -o - %s +// PR954, PR911 + +extern void foo(); + +struct S { + short f1[3]; + unsigned int f2 : 1; +}; + +void bar() +{ + struct S *A; + + if (A->f2) + foo(); +} diff --git a/clang/test/CodeGen/2006-12-14-ordered_expr.c b/clang/test/CodeGen/2006-12-14-ordered_expr.c new file mode 100644 index 0000000..c46ba85 --- /dev/null +++ b/clang/test/CodeGen/2006-12-14-ordered_expr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -O3 -emit-llvm %s -o - | FileCheck %s + +int test2(float X, float Y) { + // CHECK: fcmp ord float %X, %Y + return !__builtin_isunordered(X, Y); +} diff --git a/clang/test/CodeGen/2007-01-06-KNR-Proto.c b/clang/test/CodeGen/2007-01-06-KNR-Proto.c new file mode 100644 index 0000000..d56a786 --- /dev/null +++ b/clang/test/CodeGen/2007-01-06-KNR-Proto.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s +// PR1083 + +int svc_register (void (*dispatch) (int)); + +int svc_register (dispatch) + void (*dispatch) (); +{ +} + diff --git a/clang/test/CodeGen/2007-01-20-VectorICE.c b/clang/test/CodeGen/2007-01-20-VectorICE.c new file mode 100644 index 0000000..286b8a1 --- /dev/null +++ b/clang/test/CodeGen/2007-01-20-VectorICE.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +typedef float __m128 __attribute__((__vector_size__(16))); +typedef long long __v2di __attribute__((__vector_size__(16))); +typedef int __v4si __attribute__((__vector_size__(16))); + +__v2di bar(void); +void foo(int X, __v4si *P) { + *P = X == 2 ? bar() : bar(); +} + diff --git a/clang/test/CodeGen/2007-01-24-InlineAsmCModifier.c b/clang/test/CodeGen/2007-01-24-InlineAsmCModifier.c new file mode 100644 index 0000000..5158898 --- /dev/null +++ b/clang/test/CodeGen/2007-01-24-InlineAsmCModifier.c @@ -0,0 +1,12 @@ +// Verify that the %c modifier works and strips off any prefixes from +// immediates. +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +void foo() { + // CHECK: i32 789514 + __asm__ volatile("/* " "pickANumber" ": %c0 */"::"i"(0xC0C0A)); + + // Check that non-c modifiers work also + // CHECK: i32 123 + __asm__ volatile("/* " "pickANumber2 " ": %0 */"::"i"(123)); +} diff --git a/clang/test/CodeGen/2007-02-04-AddrLValue-2.c b/clang/test/CodeGen/2007-02-04-AddrLValue-2.c new file mode 100644 index 0000000..bc44d14 --- /dev/null +++ b/clang/test/CodeGen/2007-02-04-AddrLValue-2.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -O3 -emit-llvm -o - +// PR1173 + +struct S { char s; }; +struct T { struct S t; }; + +struct S *const p = &((struct T * const) (0x4000))->t; + +void +foo (void) +{ + p->s = 0; +} diff --git a/clang/test/CodeGen/2007-02-04-AddrLValue.c b/clang/test/CodeGen/2007-02-04-AddrLValue.c new file mode 100644 index 0000000..400dcb6 --- /dev/null +++ b/clang/test/CodeGen/2007-02-04-AddrLValue.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 %s -O3 -emit-llvm -o - +// PR1176 + +typedef struct +{ + char *key; + char *value; +} T1; + +typedef struct +{ + long type; + char *value; +} T3; + +T1 a[] = +{ + { + "", + ((char *)&((T3) {1, (char *) 1})) + } +}; + diff --git a/clang/test/CodeGen/2007-02-04-EmptyStruct.c b/clang/test/CodeGen/2007-02-04-EmptyStruct.c new file mode 100644 index 0000000..2b2896f --- /dev/null +++ b/clang/test/CodeGen/2007-02-04-EmptyStruct.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -O3 -emit-llvm -o - +// PR1175 + +struct empty { }; + +void foo(struct empty *p) { + p++; +} + diff --git a/clang/test/CodeGen/2007-02-07-AddrLabel.c b/clang/test/CodeGen/2007-02-07-AddrLabel.c new file mode 100644 index 0000000..25eb894 --- /dev/null +++ b/clang/test/CodeGen/2007-02-07-AddrLabel.c @@ -0,0 +1,10 @@ +// PR947 +// RUN: %clang_cc1 %s -emit-llvm -o - + +void foo() { + void *ptr; + label: + ptr = &&label; + + goto *ptr; + } diff --git a/clang/test/CodeGen/2007-02-16-VoidPtrDiff.c b/clang/test/CodeGen/2007-02-16-VoidPtrDiff.c new file mode 100644 index 0000000..c9f6714 --- /dev/null +++ b/clang/test/CodeGen/2007-02-16-VoidPtrDiff.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +void foo(void *ptr, int test) { + (ptr - ((void *) test + 0x2000)); +} diff --git a/clang/test/CodeGen/2007-02-25-C-DotDotDot.c b/clang/test/CodeGen/2007-02-25-C-DotDotDot.c new file mode 100644 index 0000000..7b2e418 --- /dev/null +++ b/clang/test/CodeGen/2007-02-25-C-DotDotDot.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -O0 %s -emit-llvm -o - | FileCheck %s + +// Make sure the call to foo is compiled as: +// call float @foo() +// not +// call float (...)* bitcast (float ()* @foo to float (...)*)( ) + +static float foo() { return 0.0; } +// CHECK: call float @foo +float bar() { return foo()*10.0;} diff --git a/clang/test/CodeGen/2007-03-01-VarSizeArrayIdx.c b/clang/test/CodeGen/2007-03-01-VarSizeArrayIdx.c new file mode 100644 index 0000000..7a9f89a --- /dev/null +++ b/clang/test/CodeGen/2007-03-01-VarSizeArrayIdx.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -O3 -emit-llvm -o - | grep mul +// PR1233 + +float foo(int w, float A[][w], int g, int h) { + return A[g][0]; +} + diff --git a/clang/test/CodeGen/2007-03-05-DataLayout.c b/clang/test/CodeGen/2007-03-05-DataLayout.c new file mode 100644 index 0000000..7519624 --- /dev/null +++ b/clang/test/CodeGen/2007-03-05-DataLayout.c @@ -0,0 +1,55 @@ +// Testcase for PR1242 +// RUN: %clang_cc1 -emit-llvm %s -o - | grep datalayout | \ +// RUN: not grep {"\[Ee\]-p:\[36\]\[24\]:\[36\]\[24\]"} +// END. + +typedef __SIZE_TYPE__ size_t; +void * malloc(size_t size); +#define NDIM 3 +#define BODY 01 +typedef double vector[NDIM]; +typedef struct bnode* bodyptr; +// { i16, double, [3 x double], i32, i32, [3 x double], [3 x double], [3 x +// double], double, \2 *, \2 * } +struct bnode { + short int type; + double mass; + vector pos; + int proc; + int new_proc; + vector vel; + vector acc; + vector new_acc; + double phi; + bodyptr next; + bodyptr proc_next; +} body; + +#define Type(x) ((x)->type) +#define Mass(x) ((x)->mass) +#define Pos(x) ((x)->pos) +#define Proc(x) ((x)->proc) +#define New_Proc(x) ((x)->new_proc) +#define Vel(x) ((x)->vel) +#define Acc(x) ((x)->acc) +#define New_Acc(x) ((x)->new_acc) +#define Phi(x) ((x)->phi) +#define Next(x) ((x)->next) +#define Proc_Next(x) ((x)->proc_next) + +bodyptr ubody_alloc(int p) +{ + register bodyptr tmp; + tmp = (bodyptr)malloc(sizeof(body)); + + Type(tmp) = BODY; + Proc(tmp) = p; + Proc_Next(tmp) = NULL; + New_Proc(tmp) = p; + return tmp; +} + +int main(int argc, char** argv) { + bodyptr b = ubody_alloc(17); + return 0; +} diff --git a/clang/test/CodeGen/2007-03-26-BitfieldAfterZeroWidth.c b/clang/test/CodeGen/2007-03-26-BitfieldAfterZeroWidth.c new file mode 100644 index 0000000..b4a42d9 --- /dev/null +++ b/clang/test/CodeGen/2007-03-26-BitfieldAfterZeroWidth.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - +struct W {}; +struct Y { + struct W w; + int i:1; +} __attribute__ ((packed)) y; diff --git a/clang/test/CodeGen/2007-03-26-ZeroWidthBitfield.c b/clang/test/CodeGen/2007-03-26-ZeroWidthBitfield.c new file mode 100644 index 0000000..0bf42ad --- /dev/null +++ b/clang/test/CodeGen/2007-03-26-ZeroWidthBitfield.c @@ -0,0 +1,2 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - +struct Z { int :0; } z; diff --git a/clang/test/CodeGen/2007-03-27-VarLengthArray.c b/clang/test/CodeGen/2007-03-27-VarLengthArray.c new file mode 100644 index 0000000..ec11f55 --- /dev/null +++ b/clang/test/CodeGen/2007-03-27-VarLengthArray.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// CHECK: getelementptr inbounds i32* %{{vla|[0-9]}} +extern void f(int *); +int e(int m, int n) { + int x[n]; + f(x); + return x[m]; +} diff --git a/clang/test/CodeGen/2007-04-05-PackedBitFields-2.c b/clang/test/CodeGen/2007-04-05-PackedBitFields-2.c new file mode 100644 index 0000000..41e6b7d --- /dev/null +++ b/clang/test/CodeGen/2007-04-05-PackedBitFields-2.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +# define pck __attribute__((packed)) + + +struct pck F { + unsigned long long i : 12, + j : 23, + k : 27, + l; +}; +struct F f1; + +void foo() { + f1.l = 5; +} diff --git a/clang/test/CodeGen/2007-04-05-PackedBitFields.c b/clang/test/CodeGen/2007-04-05-PackedBitFields.c new file mode 100644 index 0000000..5c824a3 --- /dev/null +++ b/clang/test/CodeGen/2007-04-05-PackedBitFields.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +# define pck __attribute__((packed)) + + +struct pck E { + unsigned long long l, + i : 12, + j : 23, + k : 29; }; + +struct E e1; + +void foo() { + e1.k = 5; +} diff --git a/clang/test/CodeGen/2007-04-05-PackedStruct.c b/clang/test/CodeGen/2007-04-05-PackedStruct.c new file mode 100644 index 0000000..1e9171e --- /dev/null +++ b/clang/test/CodeGen/2007-04-05-PackedStruct.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +#pragma pack(push, 2) + +enum { + tA = 0, + tB = 1 +}; + +struct MyStruct { + unsigned long A; + char C; + void * B; +}; + +void bar(){ +struct MyStruct MS = { tB, 0 }; +} diff --git a/clang/test/CodeGen/2007-04-05-PadBeforeZeroLengthField.c b/clang/test/CodeGen/2007-04-05-PadBeforeZeroLengthField.c new file mode 100644 index 0000000..f3005b5 --- /dev/null +++ b/clang/test/CodeGen/2007-04-05-PadBeforeZeroLengthField.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - +struct c__ { unsigned int type:4; }; +union A { struct c__ c; } __attribute__((aligned(8))); +struct B { + unsigned int retainCount; + union A objects[]; +}; +void foo(union A * objects, struct B *array, unsigned long k) +{ array->objects[k] = objects[k]; } diff --git a/clang/test/CodeGen/2007-04-05-UnPackedStruct.c b/clang/test/CodeGen/2007-04-05-UnPackedStruct.c new file mode 100644 index 0000000..e7a8df6 --- /dev/null +++ b/clang/test/CodeGen/2007-04-05-UnPackedStruct.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + + +enum { + tA = 0, + tB = 1 +}; + +struct MyStruct { + unsigned long A; + void * B; +}; + +void bar(){ +struct MyStruct MS = { tB, 0 }; +} diff --git a/clang/test/CodeGen/2007-04-11-InlineAsmStruct.c b/clang/test/CodeGen/2007-04-11-InlineAsmStruct.c new file mode 100644 index 0000000..d617fee --- /dev/null +++ b/clang/test/CodeGen/2007-04-11-InlineAsmStruct.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +struct V { short X, Y; }; +int bar() { + struct V bar; + __asm__ volatile("foo %0\n" : "=r"(bar)); + return bar.X; +} diff --git a/clang/test/CodeGen/2007-04-11-InlineAsmUnion.c b/clang/test/CodeGen/2007-04-11-InlineAsmUnion.c new file mode 100644 index 0000000..6d24d93 --- /dev/null +++ b/clang/test/CodeGen/2007-04-11-InlineAsmUnion.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +union U { int x; float p; }; +void foo() { + union U bar; + __asm__ volatile("foo %0\n" : "=r"(bar)); +} diff --git a/clang/test/CodeGen/2007-04-11-PR1321.c b/clang/test/CodeGen/2007-04-11-PR1321.c new file mode 100644 index 0000000..6207ecc --- /dev/null +++ b/clang/test/CodeGen/2007-04-11-PR1321.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null + +struct X { + unsigned int e0 : 17; + unsigned int e1 : 17; + unsigned int e2 : 17; + unsigned int e3 : 17; + unsigned int e4 : 17; + unsigned int e5 : 17; + unsigned int e6 : 17; + unsigned int e7 : 17; +} __attribute__((packed)) x; diff --git a/clang/test/CodeGen/2007-04-13-InlineAsmStruct2.c b/clang/test/CodeGen/2007-04-13-InlineAsmStruct2.c new file mode 100644 index 0000000..c9a87ff --- /dev/null +++ b/clang/test/CodeGen/2007-04-13-InlineAsmStruct2.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +struct V { short X, Y; }; +int bar() { + struct V bar; + // CHECK: call void asm + __asm__ volatile("foo %0\n" :: "r"(bar)); + return bar.X; +} diff --git a/clang/test/CodeGen/2007-04-13-InlineAsmUnion2.c b/clang/test/CodeGen/2007-04-13-InlineAsmUnion2.c new file mode 100644 index 0000000..a8983b6 --- /dev/null +++ b/clang/test/CodeGen/2007-04-13-InlineAsmUnion2.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +union U { int x; char* p; }; +void foo() { + union U bar; + // CHECK: call void asm + __asm__ volatile("foo %0\n" :: "r"(bar)); +} diff --git a/clang/test/CodeGen/2007-04-14-FNoBuiltin.c b/clang/test/CodeGen/2007-04-14-FNoBuiltin.c new file mode 100644 index 0000000..a5fda63 --- /dev/null +++ b/clang/test/CodeGen/2007-04-14-FNoBuiltin.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -O2 -fno-builtin -o - | grep call.*printf +// Check that -fno-builtin is honored. + +extern int printf(const char*, ...); +void foo(const char *msg) { + printf("%s\n",msg); +} diff --git a/clang/test/CodeGen/2007-04-17-ZeroSizeBitFields.c b/clang/test/CodeGen/2007-04-17-ZeroSizeBitFields.c new file mode 100644 index 0000000..91b4582 --- /dev/null +++ b/clang/test/CodeGen/2007-04-17-ZeroSizeBitFields.c @@ -0,0 +1,4 @@ +// PR 1332 +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null + +struct Z { int a:1; int :0; int c:1; } z; diff --git a/clang/test/CodeGen/2007-04-24-VolatileStructCopy.c b/clang/test/CodeGen/2007-04-24-VolatileStructCopy.c new file mode 100644 index 0000000..5eeecce --- /dev/null +++ b/clang/test/CodeGen/2007-04-24-VolatileStructCopy.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// PR1352 + +struct foo { + int x; +}; + +void copy(volatile struct foo *p, struct foo *q) { + // CHECK: call void @llvm.memcpy + *p = *q; +} diff --git a/clang/test/CodeGen/2007-04-24-bit-not-expr.c b/clang/test/CodeGen/2007-04-24-bit-not-expr.c new file mode 100644 index 0000000..9d99caf --- /dev/null +++ b/clang/test/CodeGen/2007-04-24-bit-not-expr.c @@ -0,0 +1,7 @@ +// PR 1346 +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +extern bar(void *); + +void f(void *cd) { + bar(((void *)((unsigned long)(cd) ^ -1))); +} diff --git a/clang/test/CodeGen/2007-04-24-str-const.c b/clang/test/CodeGen/2007-04-24-str-const.c new file mode 100644 index 0000000..1d86d1c --- /dev/null +++ b/clang/test/CodeGen/2007-04-24-str-const.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +static char *str; + +static const struct { + const char *name; + unsigned type; +} scan_special[] = { + {"shift", 1}, + {0, 0} +}; + +static void +sb(void) +{ + while (*str == ' ' || *str == '\t') + str++; +} diff --git a/clang/test/CodeGen/2007-05-07-PaddingElements.c b/clang/test/CodeGen/2007-05-07-PaddingElements.c new file mode 100644 index 0000000..574a377 --- /dev/null +++ b/clang/test/CodeGen/2007-05-07-PaddingElements.c @@ -0,0 +1,12 @@ +// PR 1278 +// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | grep {struct.s} | not grep "4 x i8] zeroinitializer" +// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | not grep "i32 0, i32 2" +struct s { + double d1; + int s1; +}; + +struct s foo(void) { + struct s S = {1.1, 2}; + return S; +} diff --git a/clang/test/CodeGen/2007-05-08-PCH.c b/clang/test/CodeGen/2007-05-08-PCH.c new file mode 100644 index 0000000..c45d57c --- /dev/null +++ b/clang/test/CodeGen/2007-05-08-PCH.c @@ -0,0 +1,7 @@ +// PR 1400 +// RUN: %clang_cc1 -x c-header %s -o /dev/null + +int main() { + return 0; +} + diff --git a/clang/test/CodeGen/2007-05-11-str-const.c b/clang/test/CodeGen/2007-05-11-str-const.c new file mode 100644 index 0000000..731496d --- /dev/null +++ b/clang/test/CodeGen/2007-05-11-str-const.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o /dev/null + +static unsigned char out[]={0,1}; +static const unsigned char str1[]="1"; + diff --git a/clang/test/CodeGen/2007-05-15-PaddingElement.c b/clang/test/CodeGen/2007-05-15-PaddingElement.c new file mode 100644 index 0000000..5aa4f2e --- /dev/null +++ b/clang/test/CodeGen/2007-05-15-PaddingElement.c @@ -0,0 +1,23 @@ +// PR 1419 + +// RUN: %clang_cc1 -O2 %s -emit-llvm -o - | grep "ret i32 1" +struct A { + short x; + long long :0; +}; + +struct B { + char a; + char b; + unsigned char i; +}; + +union X { struct A a; struct B b; }; + +int check(void) { + union X x, y; + + y.b.i = 0xff; + x = y; + return (x.b.i == 0xff); +} diff --git a/clang/test/CodeGen/2007-05-16-EmptyStruct.c b/clang/test/CodeGen/2007-05-16-EmptyStruct.c new file mode 100644 index 0000000..14aaff0 --- /dev/null +++ b/clang/test/CodeGen/2007-05-16-EmptyStruct.c @@ -0,0 +1,5 @@ +// PR 1417 +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: global %struct.anon* null +struct { } *X; diff --git a/clang/test/CodeGen/2007-05-29-UnionCopy.c b/clang/test/CodeGen/2007-05-29-UnionCopy.c new file mode 100644 index 0000000..9f71687 --- /dev/null +++ b/clang/test/CodeGen/2007-05-29-UnionCopy.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | grep memcpy +// PR1421 + +struct A { + char c; + int i; +}; + +struct B { + int c; + unsigned char x; +}; + +union U { struct A a; struct B b; }; + +void check(union U *u, union U *v) { + *u = *v; +} diff --git a/clang/test/CodeGen/2007-06-05-NoInlineAttribute.c b/clang/test/CodeGen/2007-06-05-NoInlineAttribute.c new file mode 100644 index 0000000..26aad88 --- /dev/null +++ b/clang/test/CodeGen/2007-06-05-NoInlineAttribute.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -O2 -emit-llvm %s -o - | grep call + +static int bar(int x, int y) __attribute__((noinline)); + +static int bar(int x, int y) +{ + return x + y; +} + +int foo(int a, int b) { + return bar(b, a); +} + diff --git a/clang/test/CodeGen/2007-06-15-AnnotateAttribute.c b/clang/test/CodeGen/2007-06-15-AnnotateAttribute.c new file mode 100644 index 0000000..de34866 --- /dev/null +++ b/clang/test/CodeGen/2007-06-15-AnnotateAttribute.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | grep llvm.global.annotations +// RUN: %clang_cc1 -emit-llvm %s -o - | grep llvm.var.annotation | count 3 + +/* Global variable with attribute */ +int X __attribute__((annotate("GlobalValAnnotation"))); + +/* Function with attribute */ +int foo(int y) __attribute__((annotate("GlobalValAnnotation"))) + __attribute__((noinline)); + +int foo(int y __attribute__((annotate("LocalValAnnotation")))) { + int x __attribute__((annotate("LocalValAnnotation"))); + x = 34; + return y + x; +} + +int main() { + static int a __attribute__((annotate("GlobalValAnnotation"))); + a = foo(2); + return 0; +} diff --git a/clang/test/CodeGen/2007-06-18-SextAttrAggregate.c b/clang/test/CodeGen/2007-06-18-SextAttrAggregate.c new file mode 100644 index 0000000..27ae6a9 --- /dev/null +++ b/clang/test/CodeGen/2007-06-18-SextAttrAggregate.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -o - -emit-llvm | FileCheck %s +// PR1513 + +struct s{ +long a; +long b; +}; + +void f(struct s a, char *b, signed char C) { + // CHECK: i8 signext + +} diff --git a/clang/test/CodeGen/2007-07-29-RestrictPtrArg.c b/clang/test/CodeGen/2007-07-29-RestrictPtrArg.c new file mode 100644 index 0000000..b6d61a7 --- /dev/null +++ b/clang/test/CodeGen/2007-07-29-RestrictPtrArg.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | grep noalias + +void foo(int * __restrict myptr1, int * myptr2) { + myptr1[0] = 0; + myptr2[0] = 0; +} diff --git a/clang/test/CodeGen/2007-08-01-LoadStoreAlign.c b/clang/test/CodeGen/2007-08-01-LoadStoreAlign.c new file mode 100644 index 0000000..87cf163 --- /dev/null +++ b/clang/test/CodeGen/2007-08-01-LoadStoreAlign.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +struct p { + char a; + int b; +} __attribute__ ((packed)); + +struct p t = { 1, 10 }; +struct p u; + +int main () { + // CHECK: align 1 + // CHECK: align 1 + int tmp = t.b; + u.b = tmp; + return tmp; + +} diff --git a/clang/test/CodeGen/2007-08-21-ComplexCst.c b/clang/test/CodeGen/2007-08-21-ComplexCst.c new file mode 100644 index 0000000..cd9ceb1 --- /dev/null +++ b/clang/test/CodeGen/2007-08-21-ComplexCst.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -O2 -emit-llvm %s -o /dev/null +void f(_Complex float z); +void g() { f(1.0i); } diff --git a/clang/test/CodeGen/2007-08-22-CTTZ.c b/clang/test/CodeGen/2007-08-22-CTTZ.c new file mode 100644 index 0000000..9067c5a --- /dev/null +++ b/clang/test/CodeGen/2007-08-22-CTTZ.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +int bork(unsigned long long x) { + // CHECK: llvm.cttz.i64 + // CHECK: llvm.cttz.i64 + // CHECK-NOT: lshr + return __builtin_ctzll(x); +} diff --git a/clang/test/CodeGen/2007-09-05-ConstCtor.c b/clang/test/CodeGen/2007-09-05-ConstCtor.c new file mode 100644 index 0000000..138b818 --- /dev/null +++ b/clang/test/CodeGen/2007-09-05-ConstCtor.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -Os -emit-llvm %s -o /dev/null +// PR1641 + +struct A { + unsigned long l; +}; + +void bar(struct A *a); + +void bork() { + const unsigned long vcgt = 1234; + struct A a = { vcgt }; + bar(&a); +} diff --git a/clang/test/CodeGen/2007-09-12-PragmaPack.c b/clang/test/CodeGen/2007-09-12-PragmaPack.c new file mode 100644 index 0000000..71c7537 --- /dev/null +++ b/clang/test/CodeGen/2007-09-12-PragmaPack.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + +#pragma pack(push, 1) +typedef struct +{ + uint32_t a; +} foo; + +typedef struct { + uint8_t major; + uint8_t minor; + uint16_t build; +} VERSION; + +typedef struct { + uint8_t a[5]; + VERSION version; + uint8_t b; + foo d; + uint32_t guard; +} bar; +#pragma pack(pop) + + +unsigned barsize(void) { + // CHECK: ret i32 18 + return sizeof(bar); +} diff --git a/clang/test/CodeGen/2007-09-14-NegatePointer.c b/clang/test/CodeGen/2007-09-14-NegatePointer.c new file mode 100644 index 0000000..52367e6 --- /dev/null +++ b/clang/test/CodeGen/2007-09-14-NegatePointer.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR1662 + +int foo(unsigned char *test) { + return 0U - (unsigned int )test; +} + diff --git a/clang/test/CodeGen/2007-09-17-WeakRef.c b/clang/test/CodeGen/2007-09-17-WeakRef.c new file mode 100644 index 0000000..3047b7f --- /dev/null +++ b/clang/test/CodeGen/2007-09-17-WeakRef.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -O1 -emit-llvm %s -o - | grep icmp +// PR1678 + +extern void B (void); +static __typeof(B) A __attribute__ ((__weakref__("B"))); +int active (void) +{ + static void *const p = __extension__ (void *) &A; + return p != 0; +} diff --git a/clang/test/CodeGen/2007-09-26-Alignment.c b/clang/test/CodeGen/2007-09-26-Alignment.c new file mode 100644 index 0000000..8ab130b --- /dev/null +++ b/clang/test/CodeGen/2007-09-26-Alignment.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +extern p(int *); +int q(void) { + // CHECK: alloca i32, align 16 + int x __attribute__ ((aligned (16))); + p(&x); + return x; +} diff --git a/clang/test/CodeGen/2007-09-27-ComplexIntCompare.c b/clang/test/CodeGen/2007-09-27-ComplexIntCompare.c new file mode 100644 index 0000000..d07aa0c --- /dev/null +++ b/clang/test/CodeGen/2007-09-27-ComplexIntCompare.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR1708 + +void __attribute__((noreturn)) abort(void); + +struct s { _Complex unsigned short x; }; +struct s gs = { 100 + 200i }; +struct s __attribute__((noinline)) foo (void) { return gs; } + +int main () +{ + if (foo ().x != gs.x) + abort (); + exit (0); +} diff --git a/clang/test/CodeGen/2007-09-28-PackedUnionMember.c b/clang/test/CodeGen/2007-09-28-PackedUnionMember.c new file mode 100644 index 0000000..f018306 --- /dev/null +++ b/clang/test/CodeGen/2007-09-28-PackedUnionMember.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +#pragma pack(push, 2) +struct H { + unsigned long f1; + unsigned long f2; + union { + struct opaque1 *f3; + struct opaque2 *f4; + struct { + struct opaque3 *f5; + unsigned short f6; + } f7; + } f8; +}; +#pragma pack(pop) + +struct E { + unsigned long f1; + unsigned long f2; +}; + +typedef long (*FuncPtr) (); + +extern long bork(FuncPtr handler, const struct E *list); + +static long hndlr() +{ + struct H cmd = { 4, 412 }; + struct H cmd2 = { 4, 412, 0 }; + return 0; +} +void foo(void *inWindow) { + static const struct E events[] = { + { 123124, 1 } + }; + bork(hndlr, events); +} diff --git a/clang/test/CodeGen/2007-10-02-VolatileArray.c b/clang/test/CodeGen/2007-10-02-VolatileArray.c new file mode 100644 index 0000000..b1dcb7e --- /dev/null +++ b/clang/test/CodeGen/2007-10-02-VolatileArray.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | grep volatile +// PR1647 + +void foo(volatile int *p) +{ +p[0] = 0; +} diff --git a/clang/test/CodeGen/2007-10-15-VoidPtr.c b/clang/test/CodeGen/2007-10-15-VoidPtr.c new file mode 100644 index 0000000..0bbff3d --- /dev/null +++ b/clang/test/CodeGen/2007-10-15-VoidPtr.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +void bork(void **data) { + (*(unsigned short *) (&(data[37])[927]) = 0); +} diff --git a/clang/test/CodeGen/2007-10-30-Volatile.c b/clang/test/CodeGen/2007-10-30-Volatile.c new file mode 100644 index 0000000..17aac1a --- /dev/null +++ b/clang/test/CodeGen/2007-10-30-Volatile.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -Wall -Werror +void bork() { + char * volatile p = 0; + volatile int cc = 0; + p += cc; +} diff --git a/clang/test/CodeGen/2007-11-07-AlignedMemcpy.c b/clang/test/CodeGen/2007-11-07-AlignedMemcpy.c new file mode 100644 index 0000000..829b60c --- /dev/null +++ b/clang/test/CodeGen/2007-11-07-AlignedMemcpy.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +void bork() { + int Qux[33] = {0}; +} diff --git a/clang/test/CodeGen/2007-11-07-CopyAggregateAlign.c b/clang/test/CodeGen/2007-11-07-CopyAggregateAlign.c new file mode 100644 index 0000000..08d9770 --- /dev/null +++ b/clang/test/CodeGen/2007-11-07-CopyAggregateAlign.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +struct A { char s, t, u, v; short a; }; +// CHECK: %a = alloca %struct.A, align 2 +// CHECK: %b = alloca %struct.A, align 2 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.{{.*}}, i32 2, i1 false) + +void q() { struct A a, b; a = b; } diff --git a/clang/test/CodeGen/2007-11-07-ZeroAggregateAlign.c b/clang/test/CodeGen/2007-11-07-ZeroAggregateAlign.c new file mode 100644 index 0000000..b059607 --- /dev/null +++ b/clang/test/CodeGen/2007-11-07-ZeroAggregateAlign.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +struct A { short s; short t; int i; }; +// CHECK: %a = alloca %struct.A, align 4 +// CHECK: call void @llvm.memset.p0i8.{{.*}}i32 4, i1 false) +void q() { struct A a = {0}; } diff --git a/clang/test/CodeGen/2007-11-28-GlobalInitializer.c b/clang/test/CodeGen/2007-11-28-GlobalInitializer.c new file mode 100644 index 0000000..a79ccdd --- /dev/null +++ b/clang/test/CodeGen/2007-11-28-GlobalInitializer.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR1744 +typedef struct foo { int x; char *p; } FOO; +extern FOO yy[]; + +int *y = &((yy + 1)->x); +void *z = &((yy + 1)->x); + diff --git a/clang/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c b/clang/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c new file mode 100644 index 0000000..a1ec633 --- /dev/null +++ b/clang/test/CodeGen/2007-11-29-ArraySizeFromInitializer.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t + +int array[] = {1, 2, 3, 4, 5}; + diff --git a/clang/test/CodeGen/2007-12-16-AsmNoUnwind.c b/clang/test/CodeGen/2007-12-16-AsmNoUnwind.c new file mode 100644 index 0000000..de078a2 --- /dev/null +++ b/clang/test/CodeGen/2007-12-16-AsmNoUnwind.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | grep nounwind + +void bar() { asm (""); } diff --git a/clang/test/CodeGen/2008-01-04-WideBitfield.c b/clang/test/CodeGen/2008-01-04-WideBitfield.c new file mode 100644 index 0000000..e1c7a38 --- /dev/null +++ b/clang/test/CodeGen/2008-01-04-WideBitfield.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s +// PR1386 +typedef unsigned long long uint64_t; +struct X { + unsigned char pad : 4; + uint64_t a : 64; +} __attribute__((packed)) x; + +uint64_t f(void) +{ + return x.a; +} diff --git a/clang/test/CodeGen/2008-01-07-UnusualIntSize.c b/clang/test/CodeGen/2008-01-07-UnusualIntSize.c new file mode 100644 index 0000000..bf0ca55 --- /dev/null +++ b/clang/test/CodeGen/2008-01-07-UnusualIntSize.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// PR1721 + +struct s { + unsigned long long u33: 33; +} a, b; + +// This should have %0 and %1 truncated to 33 bits before any operation. +// This can be done using i33 or an explicit and. +_Bool test(void) { + // CHECK: and i64 %[[TMP1:[0-9]+]], 8589934591 + // CHECK-NOT: and i64 [[TMP1]], 8589934591 + // CHECK: and i64 %{{[0-9]}}, 8589934591 + return a.u33 + b.u33 != 0; +} diff --git a/clang/test/CodeGen/2008-01-11-ChainConsistency.c b/clang/test/CodeGen/2008-01-11-ChainConsistency.c new file mode 100644 index 0000000..9ae021f --- /dev/null +++ b/clang/test/CodeGen/2008-01-11-ChainConsistency.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -fnested-functions | not grep nest + +void n1(void) { void a(void) { a(); } a(); } diff --git a/clang/test/CodeGen/2008-01-21-PackedBitFields.c b/clang/test/CodeGen/2008-01-21-PackedBitFields.c new file mode 100644 index 0000000..a649475 --- /dev/null +++ b/clang/test/CodeGen/2008-01-21-PackedBitFields.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +typedef double Al1Double __attribute__((aligned(1))); +struct x { int a:23; Al1Double v; }; +struct x X = { 5, 3.0 }; +double foo() { return X.v; } + diff --git a/clang/test/CodeGen/2008-01-21-PackedStructField.c b/clang/test/CodeGen/2008-01-21-PackedStructField.c new file mode 100644 index 0000000..aa1bee4 --- /dev/null +++ b/clang/test/CodeGen/2008-01-21-PackedStructField.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +struct X { long double b; unsigned char c; double __attribute__((packed)) d; }; +struct X x = { 3.0L, 5, 3.0 }; + + +struct S2504 { + int e:17; + __attribute__((packed)) unsigned long long int f; +} ; +int fails; + extern struct S2504 s2504; +void check2504va (int z) { + struct S2504 arg, *p; + long long int i = 0; + arg.f = i; +} + diff --git a/clang/test/CodeGen/2008-01-24-StructAlignAndBitFields.c b/clang/test/CodeGen/2008-01-24-StructAlignAndBitFields.c new file mode 100644 index 0000000..eae48b3 --- /dev/null +++ b/clang/test/CodeGen/2008-01-24-StructAlignAndBitFields.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +struct U { char a; short b; int c:25; char d; } u; + diff --git a/clang/test/CodeGen/2008-01-25-ByValReadNone.c b/clang/test/CodeGen/2008-01-25-ByValReadNone.c new file mode 100644 index 0000000..06ad1ee --- /dev/null +++ b/clang/test/CodeGen/2008-01-25-ByValReadNone.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | not grep readonly +// RUN: %clang_cc1 -emit-llvm -o - %s | not grep readnone + +// XFAIL: arm + +// The struct being passed byval means that we cannot mark the +// function readnone. Readnone would allow stores to the arg to +// be deleted in the caller. We also don't allow readonly since +// the callee might write to the byval parameter. The inliner +// would have to assume the worse and introduce an explicit +// temporary when inlining such a function, which is costly for +// the common case in which the byval argument is not written. +struct S { int A[1000]; }; +int __attribute__ ((const)) f(struct S x) { x.A[1] = 0; return x.A[0]; } +int g(struct S x) __attribute__ ((pure)); +int h(struct S x) { return g(x); } diff --git a/clang/test/CodeGen/2008-01-25-ZeroSizedAggregate.c b/clang/test/CodeGen/2008-01-25-ZeroSizedAggregate.c new file mode 100644 index 0000000..d905985 --- /dev/null +++ b/clang/test/CodeGen/2008-01-25-ZeroSizedAggregate.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +// Aggregates of size zero should be dropped from argument list. +typedef long int Tlong; +struct S2411 { + __attribute__((aligned)) Tlong:0; +}; + +extern struct S2411 a2411[5]; +extern void checkx2411(struct S2411); +void test2411(void) { + checkx2411(a2411[0]); +} + +// Proper handling of zero sized fields during type conversion. +typedef unsigned long long int Tal2ullong __attribute__((aligned(2))); +struct S2525 { + Tal2ullong: 0; + struct { + } e; +}; +struct S2525 s2525; + +struct { + signed char f; + char :0; + struct{}h; + char * i[5]; +} data; + +// Taking address of a zero sized field. +struct Z {}; +struct Y { + int i; + struct Z z; +}; +void *f(struct Y *y) { + return &y->z; +} diff --git a/clang/test/CodeGen/2008-01-28-PragmaMark.c b/clang/test/CodeGen/2008-01-28-PragmaMark.c new file mode 100644 index 0000000..399af95 --- /dev/null +++ b/clang/test/CodeGen/2008-01-28-PragmaMark.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -Werror -emit-llvm %s -o /dev/null +#pragma mark LLVM's world +#ifdef DO_ERROR +#error LLVM's world +#endif +int i; diff --git a/clang/test/CodeGen/2008-01-28-UnionSize.c b/clang/test/CodeGen/2008-01-28-UnionSize.c new file mode 100644 index 0000000..14f363d --- /dev/null +++ b/clang/test/CodeGen/2008-01-28-UnionSize.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - +// PR 1861 + +typedef unsigned char __u8; +typedef unsigned int __u32; +typedef unsigned short u16; +typedef __u32 __le32; +struct bcm43xx_plcp_hdr6 { + union { + __le32 data; + __u8 raw[6]; + } + __attribute__((__packed__)); +} + __attribute__((__packed__)); +struct bcm43xx_txhdr { + union { + struct { + struct bcm43xx_plcp_hdr6 plcp; + }; + }; +} + __attribute__((__packed__)); +static void bcm43xx_generate_rts(struct bcm43xx_txhdr *txhdr ) { } diff --git a/clang/test/CodeGen/2008-02-07-bitfield-bug.c b/clang/test/CodeGen/2008-02-07-bitfield-bug.c new file mode 100644 index 0000000..73e31e7 --- /dev/null +++ b/clang/test/CodeGen/2008-02-07-bitfield-bug.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/2008-02-08-bitfield-bug.c b/clang/test/CodeGen/2008-02-08-bitfield-bug.c new file mode 100644 index 0000000..1549b72 --- /dev/null +++ b/clang/test/CodeGen/2008-02-08-bitfield-bug.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t + +struct test { + unsigned a:1; + unsigned b:1; +}; + +struct test *t; + diff --git a/clang/test/CodeGen/2008-02-26-inline-asm-bug.c b/clang/test/CodeGen/2008-02-26-inline-asm-bug.c new file mode 100644 index 0000000..1103e9b --- /dev/null +++ b/clang/test/CodeGen/2008-02-26-inline-asm-bug.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm < %s | grep "\$0,\$1" + +void f() { + int d1, d2; + asm("%0,%1": "=r" (d1) : "r" (d2)); +} diff --git a/clang/test/CodeGen/2008-03-03-CtorAttrType.c b/clang/test/CodeGen/2008-03-03-CtorAttrType.c new file mode 100644 index 0000000..dbd7bc0 --- /dev/null +++ b/clang/test/CodeGen/2008-03-03-CtorAttrType.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | grep llvm.global_ctors +int __attribute__((constructor)) foo(void) { + return 0; +} +void __attribute__((constructor)) bar(void) {} + diff --git a/clang/test/CodeGen/2008-03-05-syncPtr.c b/clang/test/CodeGen/2008-03-05-syncPtr.c new file mode 100644 index 0000000..784295c --- /dev/null +++ b/clang/test/CodeGen/2008-03-05-syncPtr.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +int* foo(int** a, int* b, int* c) { +return __sync_val_compare_and_swap (a, b, c); +} +// CHECK: define i32* @foo +// CHECK: cmpxchg + +int foo2(int** a, int* b, int* c) { +return __sync_bool_compare_and_swap (a, b, c); +} +// CHECK: define i32 @foo2 +// CHECK: cmpxchg + +int* foo3(int** a, int b) { + return __sync_fetch_and_add (a, b); +} +// CHECK: define i32* @foo3 +// CHECK: atomicrmw add + + +int* foo4(int** a, int b) { + return __sync_fetch_and_sub (a, b); +} +// CHECK: define i32* @foo4 +// CHECK: atomicrmw sub + + +int* foo5(int** a, int* b) { + return __sync_lock_test_and_set (a, b); +} +// CHECK: define i32* @foo5 +// CHECK: atomicrmw xchg + + +int* foo6(int** a, int*** b) { + return __sync_lock_test_and_set (a, b); +} +// CHECK: define i32* @foo6 +// CHECK: atomicrmw xchg diff --git a/clang/test/CodeGen/2008-03-24-BitField-And-Alloca.c b/clang/test/CodeGen/2008-03-24-BitField-And-Alloca.c new file mode 100644 index 0000000..cb80d76 --- /dev/null +++ b/clang/test/CodeGen/2008-03-24-BitField-And-Alloca.c @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -O2 -emit-llvm %s -o - | not grep alloca +// RUN: %clang_cc1 -m32 -O2 -emit-llvm %s -o - | not grep {store } + +enum { + PP_C, + PP_D, + PP_R, + PP_2D, + PP_1D, + PP_SR, + PP_S2D, + PP_S1D, + PP_SC +}; + +enum { + G_VP, + G_FP, + G_VS, + G_GS, + G_FS +}; + +enum { + G_NONE, + G_B, + G_R +}; + +typedef union _Key { + struct { + unsigned int count : 2; + unsigned int Aconst : 1; + unsigned int Bconst : 1; + unsigned int Cconst : 1; + unsigned int Xused : 1; + unsigned int Yused : 1; + unsigned int Zused : 1; + unsigned int Wused : 1; + unsigned int ttype : 3; + unsigned int scalar : 1; + unsigned int AType : 4; + unsigned int BType : 4; + unsigned int CType : 4; + unsigned int RType : 4; + unsigned int Size : 2; + unsigned int prec : 1; + + unsigned int ASize : 2; + unsigned int BSize : 2; + unsigned int CSize : 2; + unsigned int tTex : 4; + unsigned int proj : 1; + unsigned int lod : 2; + unsigned int dvts : 1; + unsigned int uipad : 18; + } key_io; + struct { + unsigned int key0; + unsigned int key1; + } key; + unsigned long long lkey; +} Key; + +static void foo(const Key iospec, int* ret) +{ + *ret=0; + if(((iospec.key_io.lod == G_B) && + (iospec.key_io.ttype != G_VS) && + (iospec.key_io.ttype != G_GS) && + (iospec.key_io.ttype != G_FS)) || + + (((iospec.key_io.tTex == PP_C) || + (iospec.key_io.tTex == PP_SC)) && + ((iospec.key_io.tTex == PP_SR) || + (iospec.key_io.tTex == PP_S2D) || + (iospec.key_io.tTex == PP_S1D) || + (iospec.key_io.tTex == PP_SC)))) + *ret=1; +} + + +extern int bar(unsigned long long key_token2) +{ + int ret; + __attribute__ ((unused)) Key iospec = (Key) key_token2; + foo(iospec, &ret); + return ret; +} diff --git a/clang/test/CodeGen/2008-03-26-PackedBitFields.c b/clang/test/CodeGen/2008-03-26-PackedBitFields.c new file mode 100644 index 0000000..72e5cb1 --- /dev/null +++ b/clang/test/CodeGen/2008-03-26-PackedBitFields.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + + +struct S1757 { + long double c; + long int __attribute__((packed)) e:28; +} x; diff --git a/clang/test/CodeGen/2008-04-08-NoExceptions.c b/clang/test/CodeGen/2008-04-08-NoExceptions.c new file mode 100644 index 0000000..6d5d20f --- /dev/null +++ b/clang/test/CodeGen/2008-04-08-NoExceptions.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +void f(void); +void g(void) { + // CHECK: define void @g() nounwind + // CHECK-NOT: call void @f() nounwind + f(); +} + +// CHECK-NOT: declare void @f() nounwind diff --git a/clang/test/CodeGen/2008-05-06-CFECrash.c b/clang/test/CodeGen/2008-05-06-CFECrash.c new file mode 100644 index 0000000..1177567 --- /dev/null +++ b/clang/test/CodeGen/2008-05-06-CFECrash.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm -O2 %s -o /dev/null +// PR2292. +__inline__ __attribute__ ((__pure__)) int g (void) {} +void f (int k) { k = g (); } diff --git a/clang/test/CodeGen/2008-05-12-TempUsedBeforeDef.c b/clang/test/CodeGen/2008-05-12-TempUsedBeforeDef.c new file mode 100644 index 0000000..bc2886e --- /dev/null +++ b/clang/test/CodeGen/2008-05-12-TempUsedBeforeDef.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -w -emit-llvm -o /dev/null %s +// PR2264. +unsigned foo = 8L; +unsigned bar = 0L; +volatile unsigned char baz = 6L; +int test() { + char qux = 1L; + for (; baz >= -29; baz--) + bork(bar && foo, qux); +} diff --git a/clang/test/CodeGen/2008-05-19-AlwaysInline.c b/clang/test/CodeGen/2008-05-19-AlwaysInline.c new file mode 100644 index 0000000..73a7691 --- /dev/null +++ b/clang/test/CodeGen/2008-05-19-AlwaysInline.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -fno-unit-at-a-time -O0 -o - | not grep sabrina +// RUN: %clang_cc1 %s -emit-llvm -funit-at-a-time -O0 -o - | not grep sabrina + +static inline int sabrina (void) __attribute__((always_inline)); +static inline int sabrina (void) +{ + return 13; +} +int bar (void) +{ + return sabrina () + 68; +} diff --git a/clang/test/CodeGen/2008-07-17-no-emit-on-error.c b/clang/test/CodeGen/2008-07-17-no-emit-on-error.c new file mode 100644 index 0000000..2cae57b --- /dev/null +++ b/clang/test/CodeGen/2008-07-17-no-emit-on-error.c @@ -0,0 +1,15 @@ +// RUN: rm -f %t1.bc +// RUN: %clang_cc1 -DPASS %s -emit-llvm-bc -o %t1.bc +// RUN: opt %t1.bc -disable-output +// RUN: rm -f %t1.bc +// RUN: not %clang_cc1 %s -emit-llvm-bc -o %t1.bc +// RUN: not opt %t1.bc -disable-output + +void f() { +} + +#ifndef PASS +void g() { + *10; +} +#endif diff --git a/clang/test/CodeGen/2008-07-21-mixed-var-fn-decl.c b/clang/test/CodeGen/2008-07-21-mixed-var-fn-decl.c new file mode 100644 index 0000000..ac13260 --- /dev/null +++ b/clang/test/CodeGen/2008-07-21-mixed-var-fn-decl.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +int g0, f0(); +int f1(), g1; + +// CHECK: @g0 = common global i32 0, align 4 +// CHECK: @g1 = common global i32 0, align 4 + diff --git a/clang/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c b/clang/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c new file mode 100644 index 0000000..33bd800 --- /dev/null +++ b/clang/test/CodeGen/2008-07-22-bitfield-init-after-zero-len-array.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm -o - %s | FileCheck %s + +struct et7 { + float lv7[0]; + char mv7:6; +} yv7 = { + {}, + 52, +}; + +// CHECK: @yv7 = global +// CHECK: i8 52, diff --git a/clang/test/CodeGen/2008-07-22-packed-bitfield-access.c b/clang/test/CodeGen/2008-07-22-packed-bitfield-access.c new file mode 100644 index 0000000..76b942d --- /dev/null +++ b/clang/test/CodeGen/2008-07-22-packed-bitfield-access.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/2008-07-29-override-alias-decl.c b/clang/test/CodeGen/2008-07-29-override-alias-decl.c new file mode 100644 index 0000000..0c2d0c6 --- /dev/null +++ b/clang/test/CodeGen/2008-07-29-override-alias-decl.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s + +int x() { return 1; } + +// CHECK: ret i32 1 + + +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(); +} + +// CHECK: [[call:%.*]] = call i32 (...)* @f() +// CHECK: ret i32 [[call]] + diff --git a/clang/test/CodeGen/2008-07-30-implicit-initialization.c b/clang/test/CodeGen/2008-07-30-implicit-initialization.c new file mode 100644 index 0000000..8c719bb --- /dev/null +++ b/clang/test/CodeGen/2008-07-30-implicit-initialization.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c b/clang/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c new file mode 100644 index 0000000..546590e --- /dev/null +++ b/clang/test/CodeGen/2008-07-30-redef-of-bitcasted-decl.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/2008-07-31-asm-labels.c b/clang/test/CodeGen/2008-07-31-asm-labels.c new file mode 100644 index 0000000..130ad6b --- /dev/null +++ b/clang/test/CodeGen/2008-07-31-asm-labels.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -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_cc1 -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/clang/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c b/clang/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c new file mode 100644 index 0000000..de06263 --- /dev/null +++ b/clang/test/CodeGen/2008-07-31-promotion-of-compound-pointer-arithmetic.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/2008-08-04-void-pointer-arithmetic.c b/clang/test/CodeGen/2008-08-04-void-pointer-arithmetic.c new file mode 100644 index 0000000..dbfc107 --- /dev/null +++ b/clang/test/CodeGen/2008-08-04-void-pointer-arithmetic.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s +// <rdar://problem/6122967> + +int f0(void *a, void *b) { + return a - b; +} diff --git a/clang/test/CodeGen/2008-08-07-AlignPadding1.c b/clang/test/CodeGen/2008-08-07-AlignPadding1.c new file mode 100644 index 0000000..2bb2e61 --- /dev/null +++ b/clang/test/CodeGen/2008-08-07-AlignPadding1.c @@ -0,0 +1,32 @@ +/* RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-darwin -o - | FileCheck %s + +The FE must generate padding here both at the end of each PyG_Head and +between array elements. Reduced from Python. */ + +typedef union _gc_head { + struct { + union _gc_head *gc_next; + union _gc_head *gc_prev; + long gc_refs; + } gc; + int dummy __attribute__((aligned(16))); +} PyGC_Head; + +struct gc_generation { + PyGC_Head head; + int threshold; + int count; +}; + +#define GEN_HEAD(n) (&generations[n].head) + +// The idea is that there are 6 undefs in this structure initializer to cover +// the padding between elements. +// CHECK: @generations = global [3 x %struct.gc_generation] [%struct.gc_generation { %union._gc_head { %struct.anon { %union._gc_head* getelementptr inbounds ([3 x %struct.gc_generation]* @generations, i32 0, i32 0, i32 0), %union._gc_head* getelementptr inbounds ([3 x %struct.gc_generation]* @generations, i32 0, i32 0, i32 0), i64 0 }, [8 x i8] undef }, i32 700, i32 0, [8 x i8] undef }, %struct.gc_generation { %union._gc_head { %struct.anon { %union._gc_head* bitcast (i8* getelementptr (i8* bitcast ([3 x %struct.gc_generation]* @generations to i8*), i64 48) to %union._gc_head*), %union._gc_head* bitcast (i8* getelementptr (i8* bitcast ([3 x %struct.gc_generation]* @generations to i8*), i64 48) to %union._gc_head*), i64 0 }, [8 x i8] undef }, i32 10, i32 0, [8 x i8] undef }, %struct.gc_generation { %union._gc_head { %struct.anon { %union._gc_head* bitcast (i8* getelementptr (i8* bitcast ([3 x %struct.gc_generation]* @generations to i8*), i64 96) to %union._gc_head*), %union._gc_head* bitcast (i8* getelementptr (i8* bitcast ([3 x %struct.gc_generation]* @generations to i8*), i64 96) to %union._gc_head*), i64 0 }, [8 x i8] undef }, i32 10, i32 0, [8 x i8] undef }] +/* linked lists of container objects */ +struct gc_generation generations[3] = { + /* 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/clang/test/CodeGen/2008-08-07-AlignPadding2.c b/clang/test/CodeGen/2008-08-07-AlignPadding2.c new file mode 100644 index 0000000..ecf28dd --- /dev/null +++ b/clang/test/CodeGen/2008-08-07-AlignPadding2.c @@ -0,0 +1,18 @@ +/* RUN: %clang_cc1 %s -emit-llvm -o - -O0 | grep zeroinitializer | count 1 + +The FE must not generate padding here between array elements. PR 2533. */ + +typedef struct { + const char *name; + int flags; + union { + int x; + } u; +} OptionDef; + +const OptionDef options[] = { + /* main options */ + { "a", 0, {3} }, + { "b", 0, {4} }, + { 0, }, +}; diff --git a/clang/test/CodeGen/2008-08-07-GEPIntToPtr.c b/clang/test/CodeGen/2008-08-07-GEPIntToPtr.c new file mode 100644 index 0000000..6892be0 --- /dev/null +++ b/clang/test/CodeGen/2008-08-07-GEPIntToPtr.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// PR2603 + +struct A { + char num_fields; +}; + +struct B { + char a, b[1]; +}; + +const struct A Foo = { + // CHECK: i8 1 + (char *)(&( (struct B *)(16) )->b[0]) - (char *)(16) +}; diff --git a/clang/test/CodeGen/2008-08-19-cast-of-typedef.c b/clang/test/CodeGen/2008-08-19-cast-of-typedef.c new file mode 100644 index 0000000..740f48a --- /dev/null +++ b/clang/test/CodeGen/2008-08-19-cast-of-typedef.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/2008-09-03-WeakAlias.c b/clang/test/CodeGen/2008-09-03-WeakAlias.c new file mode 100644 index 0000000..4712a01 --- /dev/null +++ b/clang/test/CodeGen/2008-09-03-WeakAlias.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm -O1 -o - %s | grep icmp +// PR1678 +extern void B (void); +static __typeof(B) A __attribute__ ((__weakref__("B"))); +int active (void) +{ + static void *const p = __extension__ (void *) &A; + return p != 0; +} diff --git a/clang/test/CodeGen/2008-09-22-bad-switch-type.c b/clang/test/CodeGen/2008-09-22-bad-switch-type.c new file mode 100644 index 0000000..853e6bd --- /dev/null +++ b/clang/test/CodeGen/2008-09-22-bad-switch-type.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/2008-10-13-FrontendCrash.c b/clang/test/CodeGen/2008-10-13-FrontendCrash.c new file mode 100644 index 0000000..cdd1229 --- /dev/null +++ b/clang/test/CodeGen/2008-10-13-FrontendCrash.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - +// PR2797 + +unsigned int +func_48 (signed char p_49) +{ + signed char l_340; + func_44 (1&((1 ^ 1 == (lshift_u_s (1)) != (l_340 < 1)) & 1L)); +} diff --git a/clang/test/CodeGen/2008-10-30-ZeroPlacement.c b/clang/test/CodeGen/2008-10-30-ZeroPlacement.c new file mode 100644 index 0000000..f3806d4 --- /dev/null +++ b/clang/test/CodeGen/2008-10-30-ZeroPlacement.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR2987 +struct S2045 +{ + unsigned short int a; + union { } b; + union __attribute__ ((aligned (4))) { } c[0]; +}; +struct S2045 s2045; diff --git a/clang/test/CodeGen/2008-11-02-WeakAlias.c b/clang/test/CodeGen/2008-11-02-WeakAlias.c new file mode 100644 index 0000000..63fd4e1 --- /dev/null +++ b/clang/test/CodeGen/2008-11-02-WeakAlias.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple=i686-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s +// PR2691 + +// CHECK: weak +void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); +void native_init_IRQ(void) {} diff --git a/clang/test/CodeGen/2008-11-08-InstCombineSelect.c b/clang/test/CodeGen/2008-11-08-InstCombineSelect.c new file mode 100644 index 0000000..3f4428e --- /dev/null +++ b/clang/test/CodeGen/2008-11-08-InstCombineSelect.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -emit-llvm -O2 -o - +// PR3028 + +int g_187; +int g_204; +int g_434; + +int func_89 (void) +{ + return 1; +} + +void func_20 (int p_22) +{ + if (1 & p_22 | g_204 & (1 < g_187) - func_89 ()) + g_434 = 1; +} diff --git a/clang/test/CodeGen/2008-12-23-AsmIntPointerTie.c b/clang/test/CodeGen/2008-12-23-AsmIntPointerTie.c new file mode 100644 index 0000000..df646b7 --- /dev/null +++ b/clang/test/CodeGen/2008-12-23-AsmIntPointerTie.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -O1 -o - + +typedef long intptr_t; +int test(void *b) { + intptr_t a; + __asm__ __volatile__ ("%0 %1 " : "=r" (a): "0" (b)); + return a; +} diff --git a/clang/test/CodeGen/2009-01-05-BlockInlining.c b/clang/test/CodeGen/2009-01-05-BlockInlining.c new file mode 100644 index 0000000..2ae9b70 --- /dev/null +++ b/clang/test/CodeGen/2009-01-05-BlockInlining.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 %s -emit-llvm -fblocks -o - | FileCheck %s +// rdar://5865221 + +// These will be inlined by the optimizers provided the block descriptors +// and block literals are internal constants. +// CHECK: @__block_descriptor_tmp = internal constant +// CHECK: @__block_literal_global = internal constant +// CHECK: @__block_descriptor_tmp1 = internal constant +// CHECK: @__block_literal_global2 = internal constant +static int fun(int x) { + return x+1; +} + +static int block(int x) { + return (^(int x){return x+1;})(x); +} + +static void print(int result) { + printf("%d\n", result); +} + +int main (int argc, const char * argv[]) { + int x = argc-1; + print(fun(x)); + print(block(x)); + int (^block_inline)(int) = ^(int x){return x+1;}; + print(block_inline(x)); + return 0; +} diff --git a/clang/test/CodeGen/2009-01-21-InvalidIterator.c b/clang/test/CodeGen/2009-01-21-InvalidIterator.c new file mode 100644 index 0000000..f857b4d --- /dev/null +++ b/clang/test/CodeGen/2009-01-21-InvalidIterator.c @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 %s -emit-llvm -g -o /dev/null + +typedef long unsigned int size_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long int uint64_t; +typedef uint16_t Elf64_Half; +typedef uint32_t Elf64_Word; +typedef uint64_t Elf64_Xword; +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; +typedef struct +{ + Elf64_Word p_type; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Xword p_align; +} +Elf64_Phdr; +struct dl_phdr_info +{ + const char *dlpi_name; + const Elf64_Phdr *dlpi_phdr; + Elf64_Half dlpi_phnum; + unsigned long long int dlpi_adds; +}; +typedef unsigned _Unwind_Ptr; +struct object +{ + union + { + const struct dwarf_fde *single; + struct dwarf_fde **array; + struct fde_vector *sort; + } + u; + union + { + struct + { + } + b; + } + s; + struct object *next; +}; +typedef int sword; +typedef unsigned int uword; +struct dwarf_fde +{ + uword length; + sword CIE_delta; + unsigned char pc_begin[]; +}; +typedef struct dwarf_fde fde; +struct unw_eh_callback_data +{ + const fde *ret; + struct frame_hdr_cache_element *link; +} +frame_hdr_cache[8]; + +_Unwind_Ptr +base_from_cb_data (struct unw_eh_callback_data *data) +{ +} + +void +_Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) +{ + const unsigned char *p; + const struct unw_eh_frame_hdr *hdr; + struct object ob; +} diff --git a/clang/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c b/clang/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c new file mode 100644 index 0000000..8787bd4 --- /dev/null +++ b/clang/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -triple powerpc-pc-linux -emit-llvm -o - | grep {i32 32} | count 3 +// XFAIL: * +// Every printf has 'i32 0' for the GEP of the string; no point counting those. +typedef unsigned int Foo __attribute__((aligned(32))); +typedef union{Foo:0;}a; +typedef union{int x; Foo:0;}b; +extern int printf(const char*, ...); +main() { + printf("%ld\n", sizeof(a)); + printf("%ld\n", __alignof__(a)); + printf("%ld\n", sizeof(b)); + printf("%ld\n", __alignof__(b)); +} diff --git a/clang/test/CodeGen/2009-02-13-zerosize-union-field.c b/clang/test/CodeGen/2009-02-13-zerosize-union-field.c new file mode 100644 index 0000000..b39a231 --- /dev/null +++ b/clang/test/CodeGen/2009-02-13-zerosize-union-field.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -triple i686-apple-darwin -emit-llvm -o - | FileCheck %s +// Every printf has 'i32 0' for the GEP of the string; no point counting those. +typedef unsigned int Foo __attribute__((aligned(32))); +typedef union{Foo:0;}a; +typedef union{int x; Foo:0;}b; +extern int printf(const char*, ...); +int main() { + // CHECK: getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 0 + printf("%ld\n", sizeof(a)); + // CHECK: getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 1 + printf("%ld\n", __alignof__(a)); + // CHECK: getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 4 + printf("%ld\n", sizeof(b)); + // CHECK: getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 4 + printf("%ld\n", __alignof__(b)); +} diff --git a/clang/test/CodeGen/2009-03-01-MallocNoAlias.c b/clang/test/CodeGen/2009-03-01-MallocNoAlias.c new file mode 100644 index 0000000..1c4878a --- /dev/null +++ b/clang/test/CodeGen/2009-03-01-MallocNoAlias.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | grep noalias + +void * __attribute__ ((malloc)) foo (void) { return 0; } diff --git a/clang/test/CodeGen/2009-03-08-ZeroEltStructCrash.c b/clang/test/CodeGen/2009-03-08-ZeroEltStructCrash.c new file mode 100644 index 0000000..b530eb7 --- /dev/null +++ b/clang/test/CodeGen/2009-03-08-ZeroEltStructCrash.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR3744 +struct Empty {}; +struct Union { + union { + int zero_arr[0]; + } contents; +}; +static inline void Foo(struct Union *u) { + int *array = u->contents.zero_arr; +} +static void Bar(struct Union *u) { + Foo(u); +} diff --git a/clang/test/CodeGen/2009-03-13-dbg.c b/clang/test/CodeGen/2009-03-13-dbg.c new file mode 100644 index 0000000..8f48830 --- /dev/null +++ b/clang/test/CodeGen/2009-03-13-dbg.c @@ -0,0 +1,2 @@ +// RUN: %clang_cc1 %s -emit-llvm -g -o /dev/null +void foo() {} diff --git a/clang/test/CodeGen/2009-03-22-increment-bitfield.c b/clang/test/CodeGen/2009-03-22-increment-bitfield.c new file mode 100644 index 0000000..407aea2 --- /dev/null +++ b/clang/test/CodeGen/2009-03-22-increment-bitfield.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm -O1 < %s | grep "ret i32 0" + +int a(void) { + return ++(struct x {unsigned x : 2;}){3}.x; +} + + diff --git a/clang/test/CodeGen/2009-04-23-dbg.c b/clang/test/CodeGen/2009-04-23-dbg.c new file mode 100644 index 0000000..704aba2 --- /dev/null +++ b/clang/test/CodeGen/2009-04-23-dbg.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -S -g -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/clang/test/CodeGen/2009-04-28-UnionArrayCrash.c b/clang/test/CodeGen/2009-04-28-UnionArrayCrash.c new file mode 100644 index 0000000..4296b91 --- /dev/null +++ b/clang/test/CodeGen/2009-04-28-UnionArrayCrash.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR4082 +union U { + int I; + double F; +}; + +union U arr[] = { { .I = 4 }, { .F = 123.} }; +union U *P = &arr[0]; + + diff --git a/clang/test/CodeGen/2009-05-04-EnumInreg.c b/clang/test/CodeGen/2009-05-04-EnumInreg.c new file mode 100644 index 0000000..2abc747 --- /dev/null +++ b/clang/test/CodeGen/2009-05-04-EnumInreg.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm -triple i686-apple-darwin -mregparm 3 %s -o - | FileCheck %s +// PR3967 + +enum kobject_action { + KOBJ_ADD, + KOBJ_REMOVE, + KOBJ_CHANGE, + KOBJ_MOVE, + KOBJ_ONLINE, + KOBJ_OFFLINE, + KOBJ_MAX +}; + +struct kobject; + +// CHECK: i32 inreg %action +int kobject_uevent(struct kobject *kobj, enum kobject_action action) {} diff --git a/clang/test/CodeGen/2009-05-22-callingconv.c b/clang/test/CodeGen/2009-05-22-callingconv.c new file mode 100644 index 0000000..3e616d9 --- /dev/null +++ b/clang/test/CodeGen/2009-05-22-callingconv.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple i386-unknown-unknown | 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/clang/test/CodeGen/2009-05-28-const-typedef.c b/clang/test/CodeGen/2009-05-28-const-typedef.c new file mode 100644 index 0000000..3464fde --- /dev/null +++ b/clang/test/CodeGen/2009-05-28-const-typedef.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/2009-06-01-addrofknr.c b/clang/test/CodeGen/2009-06-01-addrofknr.c new file mode 100644 index 0000000..17d6fdf --- /dev/null +++ b/clang/test/CodeGen/2009-06-01-addrofknr.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -o %t -emit-llvm -verify +// PR4289 + +struct funcptr { + int (*func)(); +}; + +static int func(f) + void *f; +{ + return 0; +} + +int +main(int argc, char *argv[]) +{ + struct funcptr fp; + + fp.func = &func; + fp.func = func; +} diff --git a/clang/test/CodeGen/2009-06-14-HighlyAligned.c b/clang/test/CodeGen/2009-06-14-HighlyAligned.c new file mode 100644 index 0000000..b5a7f5e --- /dev/null +++ b/clang/test/CodeGen/2009-06-14-HighlyAligned.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null +// PR4332 + +static int highly_aligned __attribute__((aligned(4096))); + +int f() { + return highly_aligned; +} diff --git a/clang/test/CodeGen/2009-06-14-anonymous-union-init.c b/clang/test/CodeGen/2009-06-14-anonymous-union-init.c new file mode 100644 index 0000000..8ccd7bc --- /dev/null +++ b/clang/test/CodeGen/2009-06-14-anonymous-union-init.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm < %s | grep "zeroinitializer, i16 16877" +// PR4390 +struct sysfs_dirent { + union { struct sysfs_elem_dir {} s_dir; }; + unsigned short s_mode; +}; +struct sysfs_dirent sysfs_root = { {}, 16877 }; diff --git a/clang/test/CodeGen/2009-06-18-StaticInitTailPadPack.c b/clang/test/CodeGen/2009-06-18-StaticInitTailPadPack.c new file mode 100644 index 0000000..be103ec --- /dev/null +++ b/clang/test/CodeGen/2009-06-18-StaticInitTailPadPack.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - +// rdar://6983634 + + typedef struct A *Foo; +#pragma pack(push, 2) + struct Bar { + Foo f1; + unsigned short f2; + float f3; + }; + struct Baz { + struct Bar f1; + struct Bar f2; + }; + struct Qux { + unsigned long f1; + struct Baz f2; + }; +extern const struct Qux Bork; +const struct Qux Bork = { + 0, + { + {0}, + {0} + } +}; diff --git a/clang/test/CodeGen/2009-07-14-VoidPtr.c b/clang/test/CodeGen/2009-07-14-VoidPtr.c new file mode 100644 index 0000000..5e8b23d --- /dev/null +++ b/clang/test/CodeGen/2009-07-14-VoidPtr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR4556 + +extern void foo; +void *bar = &foo; + diff --git a/clang/test/CodeGen/2009-07-15-pad-wchar_t-array.c b/clang/test/CodeGen/2009-07-15-pad-wchar_t-array.c new file mode 100644 index 0000000..df12cae --- /dev/null +++ b/clang/test/CodeGen/2009-07-15-pad-wchar_t-array.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +// This bit is taken from Sema/wchar.c so we can avoid the wchar.h include. +typedef __WCHAR_TYPE__ wchar_t; +#if defined(_WIN32) || defined(_M_IX86) || defined(__CYGWIN__) \ + || defined(_M_X64) || defined(SHORT_WCHAR) + #define WCHAR_T_TYPE unsigned short +#elif defined(__sun) || defined(__AuroraUX__) + #define WCHAR_T_TYPE long +#else /* Solaris or AuroraUX. */ + #define WCHAR_T_TYPE int +#endif + +signed short _iodbcdm_sqlerror( ) +{ + wchar_t _sqlState[6] = { L"\0" }; +} diff --git a/clang/test/CodeGen/2009-07-22-StructLayout.c b/clang/test/CodeGen/2009-07-22-StructLayout.c new file mode 100644 index 0000000..7b7b82c --- /dev/null +++ b/clang/test/CodeGen/2009-07-22-StructLayout.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 %s -triple i686-pc-linux-gnu -emit-llvm -o /dev/null +// PR4590 + +typedef unsigned char __u8; +typedef unsigned int __le32; +typedef unsigned int __u32; +typedef unsigned short __le16; +typedef unsigned short __u16; + +struct usb_cdc_ether_desc { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __u8 iMACAddress; + __le32 bmEthernetStatistics; + __le16 wMaxSegmentSize; + __le16 wNumberMCFilters; + __u8 bNumberPowerFilters; +} __attribute__ ((packed)); + + +static struct usb_cdc_ether_desc ecm_desc __attribute__ ((__section__(".init.data"))) = { + .bLength = sizeof ecm_desc, + .bDescriptorType = ((0x01 << 5) | 0x04), + .bDescriptorSubType = 0x0f, + + + + .bmEthernetStatistics = (( __le32)(__u32)(0)), + .wMaxSegmentSize = (( __le16)(__u16)(1514)), + .wNumberMCFilters = (( __le16)(__u16)(0)), + .bNumberPowerFilters = 0, +}; diff --git a/clang/test/CodeGen/2009-07-31-DbgDeclare.c b/clang/test/CodeGen/2009-07-31-DbgDeclare.c new file mode 100644 index 0000000..3ccb263 --- /dev/null +++ b/clang/test/CodeGen/2009-07-31-DbgDeclare.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -S -g -o %t.s %s +void foo() { + int i = 0; + i = 42; +} diff --git a/clang/test/CodeGen/2009-08-14-vararray-crash.c b/clang/test/CodeGen/2009-08-14-vararray-crash.c new file mode 100644 index 0000000..7f489bc --- /dev/null +++ b/clang/test/CodeGen/2009-08-14-vararray-crash.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm < %s + +void sum1(int rb) { + typedef unsigned char imgrow[rb]; + typedef imgrow img[rb]; + + const img *br; + int y; + + (*br)[y]; +} diff --git a/clang/test/CodeGen/2009-09-24-SqrtErrno.c b/clang/test/CodeGen/2009-09-24-SqrtErrno.c new file mode 100644 index 0000000..b4a04ff --- /dev/null +++ b/clang/test/CodeGen/2009-09-24-SqrtErrno.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -fmath-errno | FileCheck %s +// llvm.sqrt has undefined behavior on negative inputs, so it is +// inappropriate to translate C/C++ sqrt to this. + +float sqrtf(float x); +float foo(float X) { +// CHECK: foo +// CHECK-NOT: readonly +// CHECK: call float @sqrtf + // Check that this is not marked readonly when errno is used. + return sqrtf(X); +} diff --git a/clang/test/CodeGen/2009-10-20-GlobalDebug.c b/clang/test/CodeGen/2009-10-20-GlobalDebug.c new file mode 100644 index 0000000..8828eef --- /dev/null +++ b/clang/test/CodeGen/2009-10-20-GlobalDebug.c @@ -0,0 +1,10 @@ +// REQUIRES: x86-registered-target +// RUN: %clang -target i386-apple-darwin10 -flto -S -g %s -o - | FileCheck %s +int global; +int main() { + static int localstatic; + return 0; +} + +// CHECK: !14 = metadata !{i32 {{.*}}, i32 0, metadata !5, metadata !"localstatic", metadata !"localstatic", metadata !"", metadata !6, i32 5, metadata !9, i32 1, i32 1, i32* @main.localstatic} ; [ DW_TAG_variable ] +// CHECK: !15 = metadata !{i32 {{.*}}, i32 0, null, metadata !"global", metadata !"global", metadata !"", metadata !6, i32 3, metadata !9, i32 0, i32 1, i32* @global} ; [ DW_TAG_variable ] diff --git a/clang/test/CodeGen/2009-12-07-BitFieldAlignment.c b/clang/test/CodeGen/2009-12-07-BitFieldAlignment.c new file mode 100644 index 0000000..72c30e1 --- /dev/null +++ b/clang/test/CodeGen/2009-12-07-BitFieldAlignment.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple i686-apple-darwin %s -emit-llvm -o - | FileCheck %s +// Set alignment on bitfield accesses. + +struct S { + int a, b; + void *c; + unsigned d : 8; + unsigned e : 8; +}; + +void f0(struct S *a) { +// CHECK: load {{.*}}, align 4 +// CHECK: store {{.*}}, align 4 + a->e = 0; +} diff --git a/clang/test/CodeGen/2010-01-13-MemBarrier.c b/clang/test/CodeGen/2010-01-13-MemBarrier.c new file mode 100644 index 0000000..c2b0acd --- /dev/null +++ b/clang/test/CodeGen/2010-01-13-MemBarrier.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// XFAIL: sparc +// rdar://7536390 + +typedef unsigned __INT32_TYPE__ uint32_t; + +unsigned t(uint32_t *ptr, uint32_t val) { + // CHECK: @t + // CHECK: atomicrmw xchg i32* {{.*}} seq_cst + return __sync_lock_test_and_set(ptr, val); +} diff --git a/clang/test/CodeGen/2010-01-14-FnType-DebugInfo.c b/clang/test/CodeGen/2010-01-14-FnType-DebugInfo.c new file mode 100644 index 0000000..964c031 --- /dev/null +++ b/clang/test/CodeGen/2010-01-14-FnType-DebugInfo.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -emit-llvm -g -o /dev/null +typedef void (*sigcatch_t)( struct sigcontext *); +sigcatch_t sigcatch[50] = {(sigcatch_t) 0}; + diff --git a/clang/test/CodeGen/2010-01-18-Inlined-Debug.c b/clang/test/CodeGen/2010-01-18-Inlined-Debug.c new file mode 100644 index 0000000..cf00be7 --- /dev/null +++ b/clang/test/CodeGen/2010-01-18-Inlined-Debug.c @@ -0,0 +1,12 @@ +// PR: 6058 +// RUN: %clang_cc1 -g -emit-llvm %s -O0 -o /dev/null + +static inline int foo(double) __attribute__ ((always_inline)); +static inline int foo(double __x) { return __x; } + +void bar(double x) { + foo(x); +} + + + diff --git a/clang/test/CodeGen/2010-02-10-PointerName.c b/clang/test/CodeGen/2010-02-10-PointerName.c new file mode 100644 index 0000000..910dd30 --- /dev/null +++ b/clang/test/CodeGen/2010-02-10-PointerName.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -g -o - | grep DW_TAG_pointer_type | grep -v char + +char i = 1; +void foo() { + char *cp = &i; +} + diff --git a/clang/test/CodeGen/2010-02-15-DbgStaticVar.c b/clang/test/CodeGen/2010-02-15-DbgStaticVar.c new file mode 100644 index 0000000..facd14e --- /dev/null +++ b/clang/test/CodeGen/2010-02-15-DbgStaticVar.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -g -emit-llvm %s -o - | grep "metadata ..b., metadata ..b., metadata ...," +// Test to check intentionally empty linkage name for a static variable. +// Radar 7651244. +static int foo(int a) +{ + static int b = 1; + return b+a; +} + +int main() { + int j = foo(1); + return 0; +} diff --git a/clang/test/CodeGen/2010-02-16-DbgScopes.c b/clang/test/CodeGen/2010-02-16-DbgScopes.c new file mode 100644 index 0000000..b11f920 --- /dev/null +++ b/clang/test/CodeGen/2010-02-16-DbgScopes.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm -g < %s | grep lexical | count 5 +// Test to check number of lexical scope identified in debug info. + +extern int bar(); +extern void foobar(); +void foo(int s) { + unsigned loc = 0; + if (s) { + if (bar()) { + foobar(); + } + } else { + loc = 1; + if (bar()) { + loc = 2; + } + } +} diff --git a/clang/test/CodeGen/2010-02-18-Dbg-VectorType.c b/clang/test/CodeGen/2010-02-18-Dbg-VectorType.c new file mode 100644 index 0000000..eb17d11 --- /dev/null +++ b/clang/test/CodeGen/2010-02-18-Dbg-VectorType.c @@ -0,0 +1,9 @@ +// RUN: %clang -emit-llvm -S -O0 -g %s -o - | grep DW_TAG_typedef | grep float4 +typedef float float4 __attribute__((vector_size(16))); + +int main(){ + volatile float4 x = (float4) { 0.0f, 1.0f, 2.0f, 3.0f }; + x += x; + return 0; +} + diff --git a/clang/test/CodeGen/2010-03-09-DbgInfo.c b/clang/test/CodeGen/2010-03-09-DbgInfo.c new file mode 100644 index 0000000..3541e5f --- /dev/null +++ b/clang/test/CodeGen/2010-03-09-DbgInfo.c @@ -0,0 +1,2 @@ +// RUN: %clang -emit-llvm -S -O0 -g %s -o - | grep DW_TAG_variable +unsigned char ctable1[1] = { 0001 }; diff --git a/clang/test/CodeGen/2010-03-5-LexicalScope.c b/clang/test/CodeGen/2010-03-5-LexicalScope.c new file mode 100644 index 0000000..0f63ff6 --- /dev/null +++ b/clang/test/CodeGen/2010-03-5-LexicalScope.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -O0 -g %s -o - | grep DW_TAG_lexical_block | count 3 +int foo(int i) { + if (i) { + int j = 2; + } + else { + int j = 3; + } + return i; +} diff --git a/clang/test/CodeGen/2010-05-26-AsmSideEffect.c b/clang/test/CodeGen/2010-05-26-AsmSideEffect.c new file mode 100644 index 0000000..7dd86ae --- /dev/null +++ b/clang/test/CodeGen/2010-05-26-AsmSideEffect.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple arm-apple-darwin -o - | FileCheck %s +// Radar 8026855 + +int test (void *src) { + register int w0 asm ("0"); + // CHECK: call i32 asm "ldr $0, [$1]", "={r0}{{.*}}(i8* + asm ("ldr %0, [%1]": "=r" (w0): "r" (src)); + return w0; +} diff --git a/clang/test/CodeGen/2010-06-11-SaveExpr.c b/clang/test/CodeGen/2010-06-11-SaveExpr.c new file mode 100644 index 0000000..bfe0f35 --- /dev/null +++ b/clang/test/CodeGen/2010-06-11-SaveExpr.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// Test case by Eric Postpischil! +void foo(void) +{ + char a[1]; + int t = 1; + ((char (*)[t]) a)[0][0] = 0; +} diff --git a/clang/test/CodeGen/2010-06-17-asmcrash.c b/clang/test/CodeGen/2010-06-17-asmcrash.c new file mode 100644 index 0000000..8e9485b --- /dev/null +++ b/clang/test/CodeGen/2010-06-17-asmcrash.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | llc -mtriple=x86_64-apple-darwin | FileCheck %s +// XFAIL: * +// XTARGET: x86,i386,i686 + +typedef long long int64_t; +typedef unsigned char uint8_t; +typedef int64_t x86_reg; + +void avg_pixels8_mmx2(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm__ volatile("# %0 %1 %2 %3" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r" ((x86_reg)line_size) + :"%""rax", "memory"); +// CHECK: # %ecx %rsi %rdi %rdx + } diff --git a/clang/test/CodeGen/2010-07-08-DeclDebugLineNo.c b/clang/test/CodeGen/2010-07-08-DeclDebugLineNo.c new file mode 100644 index 0000000..1637a49 --- /dev/null +++ b/clang/test/CodeGen/2010-07-08-DeclDebugLineNo.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -O0 -g %s -o - | FileCheck %s +// Insure that dbg.declare lines for locals refer to correct line number records. +// Radar 8152866. +void foo() { + int l = 0; // line #4: CHECK: {{call.*llvm.dbg.declare.*%l.*\!dbg }}[[variable_l:![0-9]+]] + int p = 0; // line #5: CHECK: {{call.*llvm.dbg.declare.*%p.*\!dbg }}[[variable_p:![0-9]+]] +} +// Now match the line number records: +// CHECK: {{^}}[[variable_l]]{{ = metadata ![{]i32 5,}} +// CHECK: {{^}}[[variable_p]]{{ = metadata ![{]i32 6,}} diff --git a/clang/test/CodeGen/2010-07-14-overconservative-align.c b/clang/test/CodeGen/2010-07-14-overconservative-align.c new file mode 100644 index 0000000..5c8c056 --- /dev/null +++ b/clang/test/CodeGen/2010-07-14-overconservative-align.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s +// PR 5995 +struct s { + int word; + struct { + int filler __attribute__ ((aligned (8))); + }; +}; + +void func (struct s *s) +{ + // CHECK: load %struct.s**{{.*}}align 8 + s->word = 0; +} diff --git a/clang/test/CodeGen/2010-07-14-ref-off-end.c b/clang/test/CodeGen/2010-07-14-ref-off-end.c new file mode 100644 index 0000000..580ae88 --- /dev/null +++ b/clang/test/CodeGen/2010-07-14-ref-off-end.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple i386-apple-darwin -o - | FileCheck %s +extern void abort(); +extern void exit(int); +struct T +{ +unsigned i:8; +unsigned c:24; +}; +f(struct T t) +{ +struct T s[1]; +s[0]=t; +return(char)s->c; +} +main() +{ +// CHECK: getelementptr inbounds [1 x %struct.T]* %s, i32 0, i32 0 +// CHECK: getelementptr inbounds [1 x %struct.T]* %s, i32 0, i32 0 +struct T t; +t.i=0xff; +t.c=0xffff11; +if(f(t)!=0x11)abort(); +exit(0); +} diff --git a/clang/test/CodeGen/2010-08-10-DbgConstant.c b/clang/test/CodeGen/2010-08-10-DbgConstant.c new file mode 100644 index 0000000..5b8f064 --- /dev/null +++ b/clang/test/CodeGen/2010-08-10-DbgConstant.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -S -emit-llvm -g %s -o - | grep DW_TAG_variable + +static const unsigned int ro = 201; +void bar(int); +void foo() { bar(ro); } diff --git a/clang/test/CodeGen/2010-08-12-asm-aggr-arg.c b/clang/test/CodeGen/2010-08-12-asm-aggr-arg.c new file mode 100644 index 0000000..5ddc412 --- /dev/null +++ b/clang/test/CodeGen/2010-08-12-asm-aggr-arg.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | FileCheck %s +// Radar 8288710: A small aggregate can be passed as an integer. Make sure +// we don't get an error with "input constraint with a matching output +// constraint of incompatible type!" + +struct wrapper { + int i; +}; + +// CHECK: xyz +int test(int i) { + struct wrapper w; + w.i = i; + __asm__("xyz" : "=r" (w) : "0" (w)); + return w.i; +} diff --git a/clang/test/CodeGen/2010-12-01-CommonGlobal.c b/clang/test/CodeGen/2010-12-01-CommonGlobal.c new file mode 100644 index 0000000..5eadbae --- /dev/null +++ b/clang/test/CodeGen/2010-12-01-CommonGlobal.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +// Don't crash on a common-linkage constant global. +extern const int kABSourceTypeProperty; +int foo(void) { + return kABSourceTypeProperty; +} +const int kABSourceTypeProperty; diff --git a/clang/test/CodeGen/2011-02-21-DATA-common.c b/clang/test/CodeGen/2011-02-21-DATA-common.c new file mode 100644 index 0000000..5079561 --- /dev/null +++ b/clang/test/CodeGen/2011-02-21-DATA-common.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +struct rtxc_snapshot { + int a, b, c, d; +}; +__attribute__ ((section("__DATA, __common"))) static struct rtxc_snapshot rtxc_log_A[4]; diff --git a/clang/test/CodeGen/2011-03-02-UnionInitializer.c b/clang/test/CodeGen/2011-03-02-UnionInitializer.c new file mode 100644 index 0000000..3c112e0 --- /dev/null +++ b/clang/test/CodeGen/2011-03-02-UnionInitializer.c @@ -0,0 +1,2 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +union { int :3; double f; } u17_017 = {17.17}; diff --git a/clang/test/CodeGen/2011-03-08-ZeroFieldUnionInitializer.c b/clang/test/CodeGen/2011-03-08-ZeroFieldUnionInitializer.c new file mode 100644 index 0000000..ff570d8 --- /dev/null +++ b/clang/test/CodeGen/2011-03-08-ZeroFieldUnionInitializer.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +typedef struct { + union { + struct { } __attribute((packed)); + }; +} fenv_t; +const fenv_t _FE_DFL_ENV = {{{ 0, 0, 0, 0 }}}; diff --git a/clang/test/CodeGen/2011-03-31-ArrayRefFolding.c b/clang/test/CodeGen/2011-03-31-ArrayRefFolding.c new file mode 100644 index 0000000..31c0a68 --- /dev/null +++ b/clang/test/CodeGen/2011-03-31-ArrayRefFolding.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple i386-apple-darwin %s | FileCheck %s +// PR9571 + +struct t { + int x; +}; + +extern struct t *cfun; + +int f(void) { + if (!(cfun + 0)) + // CHECK: icmp ne %struct.t* + return 0; + return cfun->x; +} diff --git a/clang/test/CodeGen/3dnow-builtins.c b/clang/test/CodeGen/3dnow-builtins.c new file mode 100644 index 0000000..294fbc0 --- /dev/null +++ b/clang/test/CodeGen/3dnow-builtins.c @@ -0,0 +1,156 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-unknown-unknown -target-feature +3dnow -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +__m64 test_m_pavgusb(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pavgusb + // CHECK: @llvm.x86.3dnow.pavgusb + return _m_pavgusb(m1, m2); +} + +__m64 test_m_pf2id(__m64 m) { + // CHECK: define i64 @test_m_pf2id + // CHECK: @llvm.x86.3dnow.pf2id + return _m_pf2id(m); +} + +__m64 test_m_pfacc(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfacc + // CHECK: @llvm.x86.3dnow.pfacc + return _m_pfacc(m1, m2); +} + +__m64 test_m_pfadd(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfadd + // CHECK: @llvm.x86.3dnow.pfadd + return _m_pfadd(m1, m2); +} + +__m64 test_m_pfcmpeq(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfcmpeq + // CHECK: @llvm.x86.3dnow.pfcmpeq + return _m_pfcmpeq(m1, m2); +} + +__m64 test_m_pfcmpge(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfcmpge + // CHECK: @llvm.x86.3dnow.pfcmpge + return _m_pfcmpge(m1, m2); +} + +__m64 test_m_pfcmpgt(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfcmpgt + // CHECK: @llvm.x86.3dnow.pfcmpgt + return _m_pfcmpgt(m1, m2); +} + +__m64 test_m_pfmax(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfmax + // CHECK: @llvm.x86.3dnow.pfmax + return _m_pfmax(m1, m2); +} + +__m64 test_m_pfmin(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfmin + // CHECK: @llvm.x86.3dnow.pfmin + return _m_pfmin(m1, m2); +} + +__m64 test_m_pfmul(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfmul + // CHECK: @llvm.x86.3dnow.pfmul + return _m_pfmul(m1, m2); +} + +__m64 test_m_pfrcp(__m64 m) { + // CHECK: define i64 @test_m_pfrcp + // CHECK: @llvm.x86.3dnow.pfrcp + return _m_pfrcp(m); +} + +__m64 test_m_pfrcpit1(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfrcpit1 + // CHECK: @llvm.x86.3dnow.pfrcpit1 + return _m_pfrcpit1(m1, m2); +} + +__m64 test_m_pfrcpit2(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfrcpit2 + // CHECK: @llvm.x86.3dnow.pfrcpit2 + return _m_pfrcpit2(m1, m2); +} + +__m64 test_m_pfrsqrt(__m64 m) { + // CHECK: define i64 @test_m_pfrsqrt + // CHECK: @llvm.x86.3dnow.pfrsqrt + return _m_pfrsqrt(m); +} + +__m64 test_m_pfrsqrtit1(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfrsqrtit1 + // CHECK: @llvm.x86.3dnow.pfrsqit1 + return _m_pfrsqrtit1(m1, m2); +} + +__m64 test_m_pfsub(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfsub + // CHECK: @llvm.x86.3dnow.pfsub + return _m_pfsub(m1, m2); +} + +__m64 test_m_pfsubr(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfsubr + // CHECK: @llvm.x86.3dnow.pfsubr + return _m_pfsubr(m1, m2); +} + +__m64 test_m_pi2fd(__m64 m) { + // CHECK: define i64 @test_m_pi2fd + // CHECK: @llvm.x86.3dnow.pi2fd + return _m_pi2fd(m); +} + +__m64 test_m_pmulhrw(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pmulhrw + // CHECK: @llvm.x86.3dnow.pmulhrw + return _m_pmulhrw(m1, m2); +} + +__m64 test_m_pf2iw(__m64 m) { + // CHECK: define i64 @test_m_pf2iw + // CHECK: @llvm.x86.3dnowa.pf2iw + return _m_pf2iw(m); +} + +__m64 test_m_pfnacc(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfnacc + // CHECK: @llvm.x86.3dnowa.pfnacc + return _m_pfnacc(m1, m2); +} + +__m64 test_m_pfpnacc(__m64 m1, __m64 m2) { + // CHECK: define i64 @test_m_pfpnacc + // CHECK: @llvm.x86.3dnowa.pfpnacc + return _m_pfpnacc(m1, m2); +} + +__m64 test_m_pi2fw(__m64 m) { + // CHECK: define i64 @test_m_pi2fw + // CHECK: @llvm.x86.3dnowa.pi2fw + return _m_pi2fw(m); +} + +__m64 test_m_pswapdsf(__m64 m) { + // CHECK: define i64 @test_m_pswapdsf + // CHECK: @llvm.x86.3dnowa.pswapd + return _m_pswapdsf(m); +} + +__m64 test_m_pswapdsi(__m64 m) { + // CHECK: define i64 @test_m_pswapdsi + // CHECK: @llvm.x86.3dnowa.pswapd + return _m_pswapdsi(m); +} diff --git a/clang/test/CodeGen/Atomics.c b/clang/test/CodeGen/Atomics.c new file mode 100644 index 0000000..c440b6c --- /dev/null +++ b/clang/test/CodeGen/Atomics.c @@ -0,0 +1,203 @@ +// Test frontend handling of __sync builtins. +// Modified from a gcc testcase. +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +signed char sc; +unsigned char uc; +signed short ss; +unsigned short us; +signed int si; +unsigned int ui; +signed long long sll; +unsigned long long ull; + +void test_op_ignore (void) // CHECK: define void @test_op_ignore +{ + (void) __sync_fetch_and_add (&sc, 1); // CHECK: atomicrmw add i8 + (void) __sync_fetch_and_add (&uc, 1); // CHECK: atomicrmw add i8 + (void) __sync_fetch_and_add (&ss, 1); // CHECK: atomicrmw add i16 + (void) __sync_fetch_and_add (&us, 1); // CHECK: atomicrmw add i16 + (void) __sync_fetch_and_add (&si, 1); // CHECK: atomicrmw add i32 + (void) __sync_fetch_and_add (&ui, 1); // CHECK: atomicrmw add i32 + (void) __sync_fetch_and_add (&sll, 1); // CHECK: atomicrmw add i64 + (void) __sync_fetch_and_add (&ull, 1); // CHECK: atomicrmw add i64 + + (void) __sync_fetch_and_sub (&sc, 1); // CHECK: atomicrmw sub i8 + (void) __sync_fetch_and_sub (&uc, 1); // CHECK: atomicrmw sub i8 + (void) __sync_fetch_and_sub (&ss, 1); // CHECK: atomicrmw sub i16 + (void) __sync_fetch_and_sub (&us, 1); // CHECK: atomicrmw sub i16 + (void) __sync_fetch_and_sub (&si, 1); // CHECK: atomicrmw sub i32 + (void) __sync_fetch_and_sub (&ui, 1); // CHECK: atomicrmw sub i32 + (void) __sync_fetch_and_sub (&sll, 1); // CHECK: atomicrmw sub i64 + (void) __sync_fetch_and_sub (&ull, 1); // CHECK: atomicrmw sub i64 + + (void) __sync_fetch_and_or (&sc, 1); // CHECK: atomicrmw or i8 + (void) __sync_fetch_and_or (&uc, 1); // CHECK: atomicrmw or i8 + (void) __sync_fetch_and_or (&ss, 1); // CHECK: atomicrmw or i16 + (void) __sync_fetch_and_or (&us, 1); // CHECK: atomicrmw or i16 + (void) __sync_fetch_and_or (&si, 1); // CHECK: atomicrmw or i32 + (void) __sync_fetch_and_or (&ui, 1); // CHECK: atomicrmw or i32 + (void) __sync_fetch_and_or (&sll, 1); // CHECK: atomicrmw or i64 + (void) __sync_fetch_and_or (&ull, 1); // CHECK: atomicrmw or i64 + + (void) __sync_fetch_and_xor (&sc, 1); // CHECK: atomicrmw xor i8 + (void) __sync_fetch_and_xor (&uc, 1); // CHECK: atomicrmw xor i8 + (void) __sync_fetch_and_xor (&ss, 1); // CHECK: atomicrmw xor i16 + (void) __sync_fetch_and_xor (&us, 1); // CHECK: atomicrmw xor i16 + (void) __sync_fetch_and_xor (&si, 1); // CHECK: atomicrmw xor i32 + (void) __sync_fetch_and_xor (&ui, 1); // CHECK: atomicrmw xor i32 + (void) __sync_fetch_and_xor (&sll, 1); // CHECK: atomicrmw xor i64 + (void) __sync_fetch_and_xor (&ull, 1); // CHECK: atomicrmw xor i64 + + (void) __sync_fetch_and_and (&sc, 1); // CHECK: atomicrmw and i8 + (void) __sync_fetch_and_and (&uc, 1); // CHECK: atomicrmw and i8 + (void) __sync_fetch_and_and (&ss, 1); // CHECK: atomicrmw and i16 + (void) __sync_fetch_and_and (&us, 1); // CHECK: atomicrmw and i16 + (void) __sync_fetch_and_and (&si, 1); // CHECK: atomicrmw and i32 + (void) __sync_fetch_and_and (&ui, 1); // CHECK: atomicrmw and i32 + (void) __sync_fetch_and_and (&sll, 1); // CHECK: atomicrmw and i64 + (void) __sync_fetch_and_and (&ull, 1); // CHECK: atomicrmw and i64 + +} + +void test_fetch_and_op (void) // CHECK: define void @test_fetch_and_op +{ + sc = __sync_fetch_and_add (&sc, 11); // CHECK: atomicrmw add + uc = __sync_fetch_and_add (&uc, 11); // CHECK: atomicrmw add + ss = __sync_fetch_and_add (&ss, 11); // CHECK: atomicrmw add + us = __sync_fetch_and_add (&us, 11); // CHECK: atomicrmw add + si = __sync_fetch_and_add (&si, 11); // CHECK: atomicrmw add + ui = __sync_fetch_and_add (&ui, 11); // CHECK: atomicrmw add + sll = __sync_fetch_and_add (&sll, 11); // CHECK: atomicrmw add + ull = __sync_fetch_and_add (&ull, 11); // CHECK: atomicrmw add + + sc = __sync_fetch_and_sub (&sc, 11); // CHECK: atomicrmw sub + uc = __sync_fetch_and_sub (&uc, 11); // CHECK: atomicrmw sub + ss = __sync_fetch_and_sub (&ss, 11); // CHECK: atomicrmw sub + us = __sync_fetch_and_sub (&us, 11); // CHECK: atomicrmw sub + si = __sync_fetch_and_sub (&si, 11); // CHECK: atomicrmw sub + ui = __sync_fetch_and_sub (&ui, 11); // CHECK: atomicrmw sub + sll = __sync_fetch_and_sub (&sll, 11); // CHECK: atomicrmw sub + ull = __sync_fetch_and_sub (&ull, 11); // CHECK: atomicrmw sub + + sc = __sync_fetch_and_or (&sc, 11); // CHECK: atomicrmw or + uc = __sync_fetch_and_or (&uc, 11); // CHECK: atomicrmw or + ss = __sync_fetch_and_or (&ss, 11); // CHECK: atomicrmw or + us = __sync_fetch_and_or (&us, 11); // CHECK: atomicrmw or + si = __sync_fetch_and_or (&si, 11); // CHECK: atomicrmw or + ui = __sync_fetch_and_or (&ui, 11); // CHECK: atomicrmw or + sll = __sync_fetch_and_or (&sll, 11); // CHECK: atomicrmw or + ull = __sync_fetch_and_or (&ull, 11); // CHECK: atomicrmw or + + sc = __sync_fetch_and_xor (&sc, 11); // CHECK: atomicrmw xor + uc = __sync_fetch_and_xor (&uc, 11); // CHECK: atomicrmw xor + ss = __sync_fetch_and_xor (&ss, 11); // CHECK: atomicrmw xor + us = __sync_fetch_and_xor (&us, 11); // CHECK: atomicrmw xor + si = __sync_fetch_and_xor (&si, 11); // CHECK: atomicrmw xor + ui = __sync_fetch_and_xor (&ui, 11); // CHECK: atomicrmw xor + sll = __sync_fetch_and_xor (&sll, 11); // CHECK: atomicrmw xor + ull = __sync_fetch_and_xor (&ull, 11); // CHECK: atomicrmw xor + + sc = __sync_fetch_and_and (&sc, 11); // CHECK: atomicrmw and + uc = __sync_fetch_and_and (&uc, 11); // CHECK: atomicrmw and + ss = __sync_fetch_and_and (&ss, 11); // CHECK: atomicrmw and + us = __sync_fetch_and_and (&us, 11); // CHECK: atomicrmw and + si = __sync_fetch_and_and (&si, 11); // CHECK: atomicrmw and + ui = __sync_fetch_and_and (&ui, 11); // CHECK: atomicrmw and + sll = __sync_fetch_and_and (&sll, 11); // CHECK: atomicrmw and + ull = __sync_fetch_and_and (&ull, 11); // CHECK: atomicrmw and + +} + +void test_op_and_fetch (void) +{ + sc = __sync_add_and_fetch (&sc, uc); // CHECK: atomicrmw add + uc = __sync_add_and_fetch (&uc, uc); // CHECK: atomicrmw add + ss = __sync_add_and_fetch (&ss, uc); // CHECK: atomicrmw add + us = __sync_add_and_fetch (&us, uc); // CHECK: atomicrmw add + si = __sync_add_and_fetch (&si, uc); // CHECK: atomicrmw add + ui = __sync_add_and_fetch (&ui, uc); // CHECK: atomicrmw add + sll = __sync_add_and_fetch (&sll, uc); // CHECK: atomicrmw add + ull = __sync_add_and_fetch (&ull, uc); // CHECK: atomicrmw add + + sc = __sync_sub_and_fetch (&sc, uc); // CHECK: atomicrmw sub + uc = __sync_sub_and_fetch (&uc, uc); // CHECK: atomicrmw sub + ss = __sync_sub_and_fetch (&ss, uc); // CHECK: atomicrmw sub + us = __sync_sub_and_fetch (&us, uc); // CHECK: atomicrmw sub + si = __sync_sub_and_fetch (&si, uc); // CHECK: atomicrmw sub + ui = __sync_sub_and_fetch (&ui, uc); // CHECK: atomicrmw sub + sll = __sync_sub_and_fetch (&sll, uc); // CHECK: atomicrmw sub + ull = __sync_sub_and_fetch (&ull, uc); // CHECK: atomicrmw sub + + sc = __sync_or_and_fetch (&sc, uc); // CHECK: atomicrmw or + uc = __sync_or_and_fetch (&uc, uc); // CHECK: atomicrmw or + ss = __sync_or_and_fetch (&ss, uc); // CHECK: atomicrmw or + us = __sync_or_and_fetch (&us, uc); // CHECK: atomicrmw or + si = __sync_or_and_fetch (&si, uc); // CHECK: atomicrmw or + ui = __sync_or_and_fetch (&ui, uc); // CHECK: atomicrmw or + sll = __sync_or_and_fetch (&sll, uc); // CHECK: atomicrmw or + ull = __sync_or_and_fetch (&ull, uc); // CHECK: atomicrmw or + + sc = __sync_xor_and_fetch (&sc, uc); // CHECK: atomicrmw xor + uc = __sync_xor_and_fetch (&uc, uc); // CHECK: atomicrmw xor + ss = __sync_xor_and_fetch (&ss, uc); // CHECK: atomicrmw xor + us = __sync_xor_and_fetch (&us, uc); // CHECK: atomicrmw xor + si = __sync_xor_and_fetch (&si, uc); // CHECK: atomicrmw xor + ui = __sync_xor_and_fetch (&ui, uc); // CHECK: atomicrmw xor + sll = __sync_xor_and_fetch (&sll, uc); // CHECK: atomicrmw xor + ull = __sync_xor_and_fetch (&ull, uc); // CHECK: atomicrmw xor + + sc = __sync_and_and_fetch (&sc, uc); // CHECK: atomicrmw and + uc = __sync_and_and_fetch (&uc, uc); // CHECK: atomicrmw and + ss = __sync_and_and_fetch (&ss, uc); // CHECK: atomicrmw and + us = __sync_and_and_fetch (&us, uc); // CHECK: atomicrmw and + si = __sync_and_and_fetch (&si, uc); // CHECK: atomicrmw and + ui = __sync_and_and_fetch (&ui, uc); // CHECK: atomicrmw and + sll = __sync_and_and_fetch (&sll, uc); // CHECK: atomicrmw and + ull = __sync_and_and_fetch (&ull, uc); // CHECK: atomicrmw and + +} + +void test_compare_and_swap (void) +{ + sc = __sync_val_compare_and_swap (&sc, uc, sc); // CHECK: cmpxchg i8 + uc = __sync_val_compare_and_swap (&uc, uc, sc); // CHECK: cmpxchg i8 + ss = __sync_val_compare_and_swap (&ss, uc, sc); // CHECK: cmpxchg i16 + us = __sync_val_compare_and_swap (&us, uc, sc); // CHECK: cmpxchg i16 + si = __sync_val_compare_and_swap (&si, uc, sc); // CHECK: cmpxchg i32 + ui = __sync_val_compare_and_swap (&ui, uc, sc); // CHECK: cmpxchg i32 + sll = __sync_val_compare_and_swap (&sll, uc, sc); // CHECK: cmpxchg i64 + ull = __sync_val_compare_and_swap (&ull, uc, sc); // CHECK: cmpxchg i64 + + ui = __sync_bool_compare_and_swap (&sc, uc, sc); // CHECK: cmpxchg + ui = __sync_bool_compare_and_swap (&uc, uc, sc); // CHECK: cmpxchg + ui = __sync_bool_compare_and_swap (&ss, uc, sc); // CHECK: cmpxchg + ui = __sync_bool_compare_and_swap (&us, uc, sc); // CHECK: cmpxchg + ui = __sync_bool_compare_and_swap (&si, uc, sc); // CHECK: cmpxchg + ui = __sync_bool_compare_and_swap (&ui, uc, sc); // CHECK: cmpxchg + ui = __sync_bool_compare_and_swap (&sll, uc, sc); // CHECK: cmpxchg + ui = __sync_bool_compare_and_swap (&ull, uc, sc); // CHECK: cmpxchg +} + +void test_lock (void) +{ + sc = __sync_lock_test_and_set (&sc, 1); // CHECK: atomicrmw xchg i8 + uc = __sync_lock_test_and_set (&uc, 1); // CHECK: atomicrmw xchg i8 + ss = __sync_lock_test_and_set (&ss, 1); // CHECK: atomicrmw xchg i16 + us = __sync_lock_test_and_set (&us, 1); // CHECK: atomicrmw xchg i16 + si = __sync_lock_test_and_set (&si, 1); // CHECK: atomicrmw xchg i32 + ui = __sync_lock_test_and_set (&ui, 1); // CHECK: atomicrmw xchg i32 + sll = __sync_lock_test_and_set (&sll, 1); // CHECK: atomicrmw xchg i64 + ull = __sync_lock_test_and_set (&ull, 1); // CHECK: atomicrmw xchg i64 + + __sync_synchronize (); // CHECK: fence seq_cst + + __sync_lock_release (&sc); // CHECK: store atomic {{.*}} release, align 1 + __sync_lock_release (&uc); // CHECK: store atomic {{.*}} release, align 1 + __sync_lock_release (&ss); // CHECK: store atomic {{.*}} release, align 2 + __sync_lock_release (&us); /// CHECK: store atomic {{.*}} release, align 2 + __sync_lock_release (&si); // CHECK: store atomic {{.*}} release, align 4 + __sync_lock_release (&ui); // CHECK: store atomic {{.*}} release, align 4 + __sync_lock_release (&sll); // CHECK: store atomic {{.*}} release, align 8 + __sync_lock_release (&ull); // CHECK: store atomic {{.*}} release, align 8 +} diff --git a/clang/test/CodeGen/BasicInstrs.c b/clang/test/CodeGen/BasicInstrs.c new file mode 100644 index 0000000..2b8a6f6 --- /dev/null +++ b/clang/test/CodeGen/BasicInstrs.c @@ -0,0 +1,25 @@ +// This file can be used to see what a native C compiler is generating for a +// variety of interesting operations. +// +// RUN: %clang_cc1 -emit-llvm %s -o - + +unsigned int udiv(unsigned int X, unsigned int Y) { + return X/Y; +} +int sdiv(int X, int Y) { + return X/Y; +} +unsigned int urem(unsigned int X, unsigned int Y) { + return X%Y; +} +int srem(int X, int Y) { + return X%Y; +} + +_Bool setlt(int X, int Y) { + return X < Y; +} + +_Bool setgt(int X, int Y) { + return X > Y; +} diff --git a/clang/test/CodeGen/Inputs/stdio.h b/clang/test/CodeGen/Inputs/stdio.h new file mode 100644 index 0000000..cfe3595 --- /dev/null +++ b/clang/test/CodeGen/Inputs/stdio.h @@ -0,0 +1,9 @@ +struct FILE; +extern int vfprintf(struct FILE *s, const char *format, __builtin_va_list arg); +extern int vprintf(const char *format, __builtin_va_list arg); + +extern __inline __attribute__((gnu_inline,always_inline)) int +vprintf(const char *x, __builtin_va_list y) +{ + return vfprintf (0, 0, 0); +} diff --git a/clang/test/CodeGen/OpaqueStruct.c b/clang/test/CodeGen/OpaqueStruct.c new file mode 100644 index 0000000..fe96126 --- /dev/null +++ b/clang/test/CodeGen/OpaqueStruct.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t +typedef struct a b; + +b* x; + +struct a { + b* p; +}; + +void f() { + b* z = x->p; +} diff --git a/clang/test/CodeGen/PR2001-bitfield-reload.c b/clang/test/CodeGen/PR2001-bitfield-reload.c new file mode 100644 index 0000000..d05aef3 --- /dev/null +++ b/clang/test/CodeGen/PR2001-bitfield-reload.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm -o - %s | FileCheck %s +// 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() { + // CHECK: ret i32 1 + return foo(-5) == -1; +} diff --git a/clang/test/CodeGen/PR2413-void-address-cast-error.c b/clang/test/CodeGen/PR2413-void-address-cast-error.c new file mode 100644 index 0000000..3920dfd --- /dev/null +++ b/clang/test/CodeGen/PR2413-void-address-cast-error.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +void f() +{ + void *addr; + addr = (void *)( ((long int)addr + 7L) ); +} diff --git a/clang/test/CodeGen/PR2643-null-store-to-bitfield.c b/clang/test/CodeGen/PR2643-null-store-to-bitfield.c new file mode 100644 index 0000000..d6c2f36 --- /dev/null +++ b/clang/test/CodeGen/PR2643-null-store-to-bitfield.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s +// PR2643 + +void foo() { + struct { + int a : 1; + int b : 1; + } entry = {0}; +} + diff --git a/clang/test/CodeGen/PR2743-reference-missing-static.c b/clang/test/CodeGen/PR2743-reference-missing-static.c new file mode 100644 index 0000000..f32d6c5 --- /dev/null +++ b/clang/test/CodeGen/PR2743-reference-missing-static.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/PR3130-cond-constant.c b/clang/test/CodeGen/PR3130-cond-constant.c new file mode 100644 index 0000000..dbec650 --- /dev/null +++ b/clang/test/CodeGen/PR3130-cond-constant.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +int a = 2.0 ? 1 : 2; diff --git a/clang/test/CodeGen/PR3589-freestanding-libcalls.c b/clang/test/CodeGen/PR3589-freestanding-libcalls.c new file mode 100644 index 0000000..8b8282f --- /dev/null +++ b/clang/test/CodeGen/PR3589-freestanding-libcalls.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | grep 'declare i32 @printf' | count 1 +// RUN: %clang_cc1 -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 1 +// RUN: %clang_cc1 -ffreestanding -O2 -emit-llvm %s -o - | grep 'declare i32 @puts' | count 0 + +int printf(const char *, ...); + +void f0() { + printf("hello\n"); +} diff --git a/clang/test/CodeGen/PR3613-static-decl.c b/clang/test/CodeGen/PR3613-static-decl.c new file mode 100644 index 0000000..7f6d979 --- /dev/null +++ b/clang/test/CodeGen/PR3613-static-decl.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o %t %s +// RUN: grep '@g0 = internal global %.truct.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/clang/test/CodeGen/PR3709-int-to-pointer-sign.c b/clang/test/CodeGen/PR3709-int-to-pointer-sign.c new file mode 100644 index 0000000..f77737e --- /dev/null +++ b/clang/test/CodeGen/PR3709-int-to-pointer-sign.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/PR4611-bitfield-layout.c b/clang/test/CodeGen/PR4611-bitfield-layout.c new file mode 100644 index 0000000..3975ed0 --- /dev/null +++ b/clang/test/CodeGen/PR4611-bitfield-layout.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o %t +// RUN: grep "struct.object_entry = type { i8, \[2 x i8\], i8 }" %t + +struct object_entry { + unsigned int type:3, pack_id:16, depth:13; +} entries; diff --git a/clang/test/CodeGen/PR5060-align.c b/clang/test/CodeGen/PR5060-align.c new file mode 100644 index 0000000..efd8520 --- /dev/null +++ b/clang/test/CodeGen/PR5060-align.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -verify | FileCheck %s + +// CHECK: @foo.p = internal global i8 0, align 32 +char *foo(void) { + static char p __attribute__((aligned(32))); + return &p; +} + +void bar(long n) { + // CHECK: align 32 + char p[n] __attribute__((aligned(32))); +} + diff --git a/clang/test/CodeGen/_Bool-conversion.c b/clang/test/CodeGen/_Bool-conversion.c new file mode 100644 index 0000000..9e5e894 --- /dev/null +++ b/clang/test/CodeGen/_Bool-conversion.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple i386 -emit-llvm -O2 -o - %s | FileCheck %s + +// CHECK: define i32 @f0() +// CHECK: ret i32 1 +// CHECK: } + +static _Bool f0_0(void *a0) { return (_Bool) a0; } +int f0() { return f0_0((void*) 0x2); } + +_Bool f1(void) { + return (_Bool) ({ void (*x)(); x = 0; }); +} diff --git a/clang/test/CodeGen/address-safety-attr.cpp b/clang/test/CodeGen/address-safety-attr.cpp new file mode 100644 index 0000000..9d0fb95 --- /dev/null +++ b/clang/test/CodeGen/address-safety-attr.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - %s -faddress-sanitizer | FileCheck -check-prefix ASAN %s + +// The address_safety attribute should be attached to functions +// when AddressSanitizer is enabled, unless no_address_safety_analysis attribute +// is present. + +// CHECK-NOT: NoAddressSafety1{{.*}} address_safety +// ASAN-NOT: NoAddressSafety1{{.*}} address_safety +__attribute__((no_address_safety_analysis)) +int NoAddressSafety1(int *a) { return *a; } + +// CHECK-NOT: NoAddressSafety2{{.*}} address_safety +// ASAN-NOT: NoAddressSafety2{{.*}} address_safety +__attribute__((no_address_safety_analysis)) +int NoAddressSafety2(int *a); +int NoAddressSafety2(int *a) { return *a; } + +// CHECK-NOT: AddressSafetyOk{{.*}} address_safety +// ASAN: AddressSafetyOk{{.*}} address_safety +int AddressSafetyOk(int *a) { return *a; } + +// CHECK-NOT: TemplateNoAddressSafety{{.*}} address_safety +// ASAN-NOT: TemplateNoAddressSafety{{.*}} address_safety +template<int i> +__attribute__((no_address_safety_analysis)) +int TemplateNoAddressSafety() { return i; } + +// CHECK-NOT: TemplateAddressSafetyOk{{.*}} address_safety +// ASAN: TemplateAddressSafetyOk{{.*}} address_safety +template<int i> +int TemplateAddressSafetyOk() { return i; } + +int force_instance = TemplateAddressSafetyOk<42>() + + TemplateNoAddressSafety<42>(); diff --git a/clang/test/CodeGen/address-space-cast.c b/clang/test/CodeGen/address-space-cast.c new file mode 100644 index 0000000..076c2f1 --- /dev/null +++ b/clang/test/CodeGen/address-space-cast.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm < %s + +volatile unsigned char* const __attribute__((address_space(1))) serial_ctrl = 0x02; + diff --git a/clang/test/CodeGen/address-space-compound-literal.c b/clang/test/CodeGen/address-space-compound-literal.c new file mode 100644 index 0000000..37d9c7b --- /dev/null +++ b/clang/test/CodeGen/address-space-compound-literal.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm < %s | grep "internal addrspace(1) global i32 1" + +typedef int a __attribute__((address_space(1))); +a* x = &(a){1}; + diff --git a/clang/test/CodeGen/address-space-field1.c b/clang/test/CodeGen/address-space-field1.c new file mode 100644 index 0000000..e9c1871 --- /dev/null +++ b/clang/test/CodeGen/address-space-field1.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 < %s -o - | FileCheck %s +// CHECK:%struct.S = type { i32, i32 } +// CHECK:define void @test_addrspace(%struct.S addrspace(1)* %p1, %struct.S addrspace(2)* %p2) nounwind +// CHECK: [[p1addr:%.*]] = alloca %struct.S addrspace(1)* +// CHECK: [[p2addr:%.*]] = alloca %struct.S addrspace(2)* +// CHECK: store %struct.S addrspace(1)* %p1, %struct.S addrspace(1)** [[p1addr]] +// CHECK: store %struct.S addrspace(2)* %p2, %struct.S addrspace(2)** [[p2addr]] +// CHECK: [[t0:%.*]] = load %struct.S addrspace(2)** [[p2addr]], align 8 +// CHECK: [[t1:%.*]] = getelementptr inbounds %struct.S addrspace(2)* [[t0]], i32 0, i32 1 +// CHECK: [[t2:%.*]] = load i32 addrspace(2)* [[t1]], align 4 +// CHECK: [[t3:%.*]] = load %struct.S addrspace(1)** [[p1addr]], align 8 +// CHECK: [[t4:%.*]] = getelementptr inbounds %struct.S addrspace(1)* [[t3]], i32 0, i32 0 +// CHECK: store i32 [[t2]], i32 addrspace(1)* [[t4]], align 4 +// CHECK: [[t5:%.*]] = load %struct.S addrspace(2)** [[p2addr]], align 8 +// CHECK: [[t6:%.*]] = getelementptr inbounds %struct.S addrspace(2)* [[t5]], i32 0, i32 0 +// CHECK: [[t7:%.*]] = load i32 addrspace(2)* [[t6]], align 4 +// CHECK: [[t8:%.*]] = load %struct.S addrspace(1)** [[p1addr]], align 8 +// CHECK: [[t9:%.*]] = getelementptr inbounds %struct.S addrspace(1)* [[t8]], i32 0, i32 1 +// CHECK: store i32 [[t7]], i32 addrspace(1)* [[t9]], align 4 +// CHECK: ret void +// CHECK:} + +// Check that we don't lose the address space when accessing a member +// of a structure. + +#define __addr1 __attribute__((address_space(1))) +#define __addr2 __attribute__((address_space(2))) + +typedef struct S { + int a; + int b; +} S; + +void test_addrspace(__addr1 S* p1, __addr2 S*p2) { + // swap + p1->a = p2->b; + p1->b = p2->a; +} diff --git a/clang/test/CodeGen/address-space.c b/clang/test/CodeGen/address-space.c new file mode 100644 index 0000000..04f88dc --- /dev/null +++ b/clang/test/CodeGen/address-space.c @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm < %s | grep 'load.*addrspace(2).. @A' +// RUN: %clang_cc1 -emit-llvm < %s | grep 'load.*addrspace(2).. @B' + + +// CHECK: @foo = common addrspace(1) global +int foo __attribute__((address_space(1))); + +// CHECK: @ban = common addrspace(1) global +int ban[10] __attribute__((address_space(1))); + +// CHECK: define i32 @test1() +// CHECK: load i32 addrspace(1)* @foo +int test1() { return foo; } + +// CHECK: define i32 @test2(i32 %i) +// CHECK: load i32 addrspace(1)* +// CHECK-NEXT: ret i32 +int test2(int i) { return ban[i]; } + +// Both A and B point into addrspace(2). +__attribute__((address_space(2))) int *A, *B; + +// CHECK: define void @test3() +// CHECK: load i32 addrspace(2)** @B +// CHECK: load i32 addrspace(2)* +// CHECK: load i32 addrspace(2)** @A +// CHECK: store i32 {{.*}}, i32 addrspace(2)* +void test3() { + *A = *B; +} + +// PR7437 +typedef struct { + float aData[1]; +} MyStruct; + +// CHECK: define void @test4( +// CHECK: call void @llvm.memcpy.p0i8.p2i8 +// CHECK: call void @llvm.memcpy.p2i8.p0i8 +void test4(MyStruct __attribute__((address_space(2))) *pPtr) { + MyStruct s = pPtr[0]; + pPtr[0] = s; +} diff --git a/clang/test/CodeGen/alias.c b/clang/test/CodeGen/alias.c new file mode 100644 index 0000000..f2e87a5 --- /dev/null +++ b/clang/test/CodeGen/alias.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/align-local.c b/clang/test/CodeGen/align-local.c new file mode 100644 index 0000000..b839ee1 --- /dev/null +++ b/clang/test/CodeGen/align-local.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/align-param.c b/clang/test/CodeGen/align-param.c new file mode 100644 index 0000000..8907f66 --- /dev/null +++ b/clang/test/CodeGen/align-param.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm -triple i386-apple-macosx10.7.2 < %s | FileCheck %s + +// The preferred alignment for a long long on x86-32 is 8; make sure the +// alloca for x uses that alignment. +int test (long long x) { + return (int)x; +} +// CHECK: define i32 @test +// CHECK: alloca i64, align 8 + + +// Make sure we honor the aligned attribute. +struct X { int x,y,z,a; }; +int test2(struct X x __attribute((aligned(16)))) { + return x.z; +} +// CHECK: define i32 @test2 +// CHECK: alloca %struct.X, align 16 diff --git a/clang/test/CodeGen/alignment.c b/clang/test/CodeGen/alignment.c new file mode 100644 index 0000000..8882c91 --- /dev/null +++ b/clang/test/CodeGen/alignment.c @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +__attribute((aligned(16))) float a[128]; +union {int a[4]; __attribute((aligned(16))) float b[4];} b; + +// CHECK: @a = {{.*}}zeroinitializer, align 16 +// CHECK: @b = {{.*}}zeroinitializer, align 16 + + + +// PR5279 - Reduced alignment on typedef. +typedef int myint __attribute__((aligned(1))); + +void test1(myint *p) { + *p = 0; +} +// CHECK: @test1( +// CHECK: store i32 0, i32* {{.*}}, align 1 +// CHECK: ret void + +int test1a(myint *p) { + return *p; +} +// CHECK: @test1a( +// CHECK: load i32* {{.*}}, align 1 +// CHECK: ret i32 + + +// PR5279 - Reduced alignment on typedef. +typedef float __attribute__((vector_size(16), aligned(4))) packedfloat4; + +void test2(packedfloat4 *p) { + *p = (packedfloat4) { 3.2f, 2.3f, 0.1f, 0.0f }; +} +// CHECK: @test2( +// CHECK: store <4 x float> {{.*}}, align 4 +// CHECK: ret void + + +// PR5279 - Reduced alignment on typedef. +typedef float __attribute__((ext_vector_type(3), aligned(4))) packedfloat3; +void test3(packedfloat3 *p) { + *p = (packedfloat3) { 3.2f, 2.3f, 0.1f }; +} +// CHECK: @test3( +// CHECK: store <3 x float> {{.*}}, align 4 +// CHECK: ret void + + + +typedef float __attribute__((vector_size(16), aligned(64))) float4align64; + +// rdar://10639962 - Typedef alignment lost in p[]-style dereferencing +void test4(float4align64 *p) { + p[0] = (float4align64){ 3.2f, 2.3f, 0.1f, 0.0f }; +} +// CHECK: @test4( +// CHECK: store <4 x float> {{.*}}, <4 x float>* {{.*}}, align 64 + diff --git a/clang/test/CodeGen/alignof.c b/clang/test/CodeGen/alignof.c new file mode 100644 index 0000000..64d0c08 --- /dev/null +++ b/clang/test/CodeGen/alignof.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/altivec.c b/clang/test/CodeGen/altivec.c new file mode 100644 index 0000000..2982303 --- /dev/null +++ b/clang/test/CodeGen/altivec.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// Check initialization + +vector int test0 = (vector int)(1); // CHECK: @test0 = global <4 x i32> <i32 1, i32 1, i32 1, i32 1> +vector float test1 = (vector float)(1.0); // CHECK: @test1 = global <4 x float> <float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}> + +// CHECK: @v1 = global <16 x i8> <i8 0, i8 0, i8 0, i8 1, i8 0, i8 0, i8 0, i8 2, i8 0, i8 0, i8 0, i8 3, i8 0, i8 0, i8 0, i8 4> +vector char v1 = (vector char)((vector int)(1, 2, 3, 4)); +// CHECK: @v2 = global <16 x i8> <i8 63, i8 -128, i8 0, i8 0, i8 64, i8 0, i8 0, i8 0, i8 64, i8 64, i8 0, i8 0, i8 64, i8 -128, i8 0, i8 0> +vector char v2 = (vector char)((vector float)(1.0f, 2.0f, 3.0f, 4.0f)); +// CHECK: @v3 = global <16 x i8> <i8 0, i8 0, i8 0, i8 97, i8 0, i8 0, i8 0, i8 98, i8 0, i8 0, i8 0, i8 99, i8 0, i8 0, i8 0, i8 100> +vector char v3 = (vector char)((vector int)('a', 'b', 'c', 'd')); +// CHECK: @v4 = global <4 x i32> <i32 16909060, i32 0, i32 0, i32 0> +vector int v4 = (vector char){1, 2, 3, 4}; + +void test2() +{ + vector int vi; + vector float vf; + vi = (vector int)(1); // CHECK: <i32 1, i32 1, i32 1, i32 1> + vf = (vector float)(1.0); // CHECK: <float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}> + vi = (vector int)(1, 2, 3, 4); // CHECK: <i32 1, i32 2, i32 3, i32 4> + vi = (vector int)(1, 2, 3, 4, 5); // CHECK: <i32 1, i32 2, i32 3, i32 4> + + vi = (vector int){1}; // CHECK: <i32 1, i32 0, i32 0, i32 0> + vi = (vector int){1, 2}; // CHECK: <i32 1, i32 2, i32 0, i32 0> + vi = (vector int){1, 2, 3, 4}; // CHECK: <i32 1, i32 2, i32 3, i32 4> + +} + +// Check pre/post increment/decrement +void test3() { + vector int vi; + vi++; // CHECK: add <4 x i32> {{.*}} <i32 1, i32 1, i32 1, i32 1> + vector unsigned int vui; + --vui; // CHECK: add <4 x i32> {{.*}} <i32 -1, i32 -1, i32 -1, i32 -1> + vector float vf; + vf++; // CHECK: fadd <4 x float> {{.*}} <float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}, float 1.000000e+{{0+}}> +} diff --git a/clang/test/CodeGen/always-inline.c b/clang/test/CodeGen/always-inline.c new file mode 100644 index 0000000..dc74be5 --- /dev/null +++ b/clang/test/CodeGen/always-inline.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | grep call | not grep foo + +void bar() { +} + +inline void __attribute__((__always_inline__)) foo() { + bar(); +} + +void i_want_bar() { + foo(); +} diff --git a/clang/test/CodeGen/always_inline.c b/clang/test/CodeGen/always_inline.c new file mode 100644 index 0000000..c91fd43 --- /dev/null +++ b/clang/test/CodeGen/always_inline.c @@ -0,0 +1,20 @@ +// RUN: %clang -emit-llvm -S -o %t %s +// RUN: not grep '@f0' %t +// RUN: not grep 'call ' %t +// RUN: %clang -mllvm -disable-llvm-optzns -emit-llvm -S -o %t %s +// RUN: grep '@f0' %t | count 2 + +//static int f0() { +static int __attribute__((always_inline)) f0() { + return 1; +} + +int f1() { + return f0(); +} + +// PR4372 +inline int f2() __attribute__((always_inline)); +int f2() { return 7; } +int f3(void) { return f2(); } + diff --git a/clang/test/CodeGen/annotations-builtin.c b/clang/test/CodeGen/annotations-builtin.c new file mode 100644 index 0000000..42421a0 --- /dev/null +++ b/clang/test/CodeGen/annotations-builtin.c @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// END. + +static long long llfoo; +static int intfoo; +static short shortfoo; +static char charfoo; + +// CHECK: private unnamed_addr constant [13 x i8] {{.*}}annotation_a{{.*}} section "llvm.metadata" +// CHECK-NOT: {{.*}}annotation_a{{.*}} + +static int foo(int a) { + return a + 1; +} + +int main(int argc, char **argv) { + char barray[16]; + char *b = (char *) __builtin_annotation((int)barray, "annotation_a"); +// CHECK: ptrtoint i8* {{.*}} to i32 +// CHECK-NEXT: call i32 @llvm.annotation.i32 +// CHECK: inttoptr {{.*}} to i8* + + int call = __builtin_annotation(foo(argc), "annotation_a"); +// CHECK: call {{.*}} @foo +// CHECK: call i32 @llvm.annotation.i32 + + long long lla = __builtin_annotation(llfoo, "annotation_a"); +// CHECK: trunc i64 {{.*}} to i32 +// CHECK-NEXT: call i32 @llvm.annotation.i32 +// CHECK-NEXT: zext i32 {{.*}} to i64 + + int inta = __builtin_annotation(intfoo, "annotation_a"); +// CHECK: load i32* @intfoo +// CHECK-NEXT: call i32 @llvm.annotation.i32 +// CHECK-NEXT: store + + short shorta = __builtin_annotation(shortfoo, "annotation_a"); +// CHECK: sext i16 {{.*}} to i32 +// CHECK-NEXT: call i32 @llvm.annotation.i32 +// CHECK-NEXT: trunc i32 {{.*}} to i16 + + char chara = __builtin_annotation(charfoo, "annotation_a"); +// CHECK: sext i8 {{.*}} to i32 +// CHECK-NEXT: call i32 @llvm.annotation.i32 +// CHECK-NEXT: trunc i32 {{.*}} to i8 +// + char **arg = (char**) __builtin_annotation((int) argv, "annotation_a"); +// CHECK: ptrtoint i8** {{.*}} to +// CHECK: call i32 @llvm.annotation.i32 +// CHECK: inttoptr {{.*}} to i8** + return 0; +} diff --git a/clang/test/CodeGen/annotations-field.c b/clang/test/CodeGen/annotations-field.c new file mode 100644 index 0000000..6b44367 --- /dev/null +++ b/clang/test/CodeGen/annotations-field.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// END. + +// CHECK: private unnamed_addr constant [8 x i8] c"v_ann_{{.}}\00", section "llvm.metadata" +// CHECK: private unnamed_addr constant [8 x i8] c"v_ann_{{.}}\00", section "llvm.metadata" + +struct foo { + int v __attribute__((annotate("v_ann_0"))) __attribute__((annotate("v_ann_1"))); +}; + +static struct foo gf; + +int main(int argc, char **argv) { + struct foo f; + f.v = argc; +// CHECK: getelementptr inbounds %struct.foo* %f, i32 0, i32 0 +// CHECK-NEXT: bitcast i32* {{.*}} to i8* +// CHECK-NEXT: call i8* @llvm.ptr.annotation.p0i8({{.*}}str{{.*}}str{{.*}}i32 8) +// CHECK-NEXT: bitcast i8* {{.*}} to i32* +// CHECK-NEXT: bitcast i32* {{.*}} to i8* +// CHECK-NEXT: call i8* @llvm.ptr.annotation.p0i8({{.*}}str{{.*}}str{{.*}}i32 8) +// CHECK-NEXT: bitcast i8* {{.*}} to i32* + gf.v = argc; +// CHECK: bitcast i32* getelementptr inbounds (%struct.foo* @gf, i32 0, i32 0) to i8* +// CHECK-NEXT: call i8* @llvm.ptr.annotation.p0i8({{.*}}str{{.*}}str{{.*}}i32 8) + return 0; +} diff --git a/clang/test/CodeGen/annotations-global.c b/clang/test/CodeGen/annotations-global.c new file mode 100644 index 0000000..2782525 --- /dev/null +++ b/clang/test/CodeGen/annotations-global.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t1 +// RUN: FileCheck --check-prefix=FOO %s < %t1 +// RUN: FileCheck --check-prefix=A %s < %t1 +// RUN: FileCheck --check-prefix=BAR %s < %t1 +// RUN: FileCheck --check-prefix=FOOS %s < %t1 +// END. + +static __attribute((annotate("sfoo_0"))) __attribute((annotate("sfoo_1"))) char sfoo; +__attribute((annotate("foo_0"))) __attribute((annotate("foo_1"))) char foo; + +void __attribute((annotate("ann_a_0"))) __attribute((annotate("ann_a_1"))) __attribute((annotate("ann_a_2"))) __attribute((annotate("ann_a_3"))) a(char *a); +void __attribute((annotate("ann_a_0"))) __attribute((annotate("ann_a_1"))) a(char *a) { + __attribute__((annotate("bar_0"))) __attribute__((annotate("bar_1"))) static char bar; + sfoo = 0; +} + +// FOOS: target triple +// FOOS: private unnamed_addr constant [7 x i8] c"sfoo_{{.}}\00", section "llvm.metadata" +// FOOS: private unnamed_addr constant [7 x i8] c"sfoo_{{.}}\00", section "llvm.metadata" +// FOOS-NOT: sfoo_ +// FOOS: @llvm.global.annotations = appending global [10 x { i8*, i8*, i8*, i32 }] {{.*}}i8* @sfoo{{.*}}i8* @sfoo{{.*}}, section "llvm.metadata" + +// FOO: target triple +// FOO: private unnamed_addr constant [6 x i8] c"foo_{{.}}\00", section "llvm.metadata" +// FOO: private unnamed_addr constant [6 x i8] c"foo_{{.}}\00", section "llvm.metadata" +// FOO-NOT: foo_ +// FOO: @llvm.global.annotations = appending global [10 x { i8*, i8*, i8*, i32 }] {{.*}}i8* @foo{{.*}}i8* @foo{{.*}}, section "llvm.metadata" + +// A: target triple +// A: private unnamed_addr constant [8 x i8] c"ann_a_{{.}}\00", section "llvm.metadata" +// A: private unnamed_addr constant [8 x i8] c"ann_a_{{.}}\00", section "llvm.metadata" +// A: private unnamed_addr constant [8 x i8] c"ann_a_{{.}}\00", section "llvm.metadata" +// A: private unnamed_addr constant [8 x i8] c"ann_a_{{.}}\00", section "llvm.metadata" +// A-NOT: ann_a_ +// A: @llvm.global.annotations = appending global [10 x { i8*, i8*, i8*, i32 }] {{.*}}i8* bitcast (void (i8*)* @a to i8*){{.*}}i8* bitcast (void (i8*)* @a to i8*){{.*}}i8* bitcast (void (i8*)* @a to i8*){{.*}}i8* bitcast (void (i8*)* @a to i8*){{.*}}, section "llvm.metadata" + +// BAR: target triple +// BAR: private unnamed_addr constant [6 x i8] c"bar_{{.}}\00", section "llvm.metadata" +// BAR: private unnamed_addr constant [6 x i8] c"bar_{{.}}\00", section "llvm.metadata" +// BAR-NOT: bar_ +// BAR: @llvm.global.annotations = appending global [10 x { i8*, i8*, i8*, i32 }] {{.*}}i8* @a.bar{{.*}}i8* @a.bar{{.*}}, section "llvm.metadata" diff --git a/clang/test/CodeGen/annotations-loc.c b/clang/test/CodeGen/annotations-loc.c new file mode 100644 index 0000000..4644f0e --- /dev/null +++ b/clang/test/CodeGen/annotations-loc.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// END. +# 1 "t.c" +# 1 "<built-in>" +# 1 "<command-line>" +# 1 "t.c" +int __attribute((annotate("foo"))) foo(void) { return 0; } + +// CHECK: private unnamed_addr constant [4 x i8] c"t.c\00" +// CHECK: @llvm.global.annotations = {{.*}}, i32 1 } diff --git a/clang/test/CodeGen/annotations-var.c b/clang/test/CodeGen/annotations-var.c new file mode 100644 index 0000000..b8ada9f --- /dev/null +++ b/clang/test/CodeGen/annotations-var.c @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t1 %s +// RUN: FileCheck --check-prefix=LOCAL %s < %t1 +// RUN: FileCheck --check-prefix=UNDEF %s < %t1 +// RUN: FileCheck --check-prefix=PARAM %s < %t1 +// END. + +// LOCAL: private unnamed_addr constant [15 x i8] c"localvar_ann_{{.}}\00", section "llvm.metadata" +// LOCAL: private unnamed_addr constant [15 x i8] c"localvar_ann_{{.}}\00", section "llvm.metadata" + +// UNDEF: private unnamed_addr constant [15 x i8] c"undefvar_ann_0\00", section "llvm.metadata" + +// PARAM: private unnamed_addr constant [12 x i8] c"param_ann_{{.}}\00", section "llvm.metadata" +// PARAM: private unnamed_addr constant [12 x i8] c"param_ann_{{.}}\00", section "llvm.metadata" +// PARAM: private unnamed_addr constant [12 x i8] c"param_ann_{{.}}\00", section "llvm.metadata" +// PARAM: private unnamed_addr constant [12 x i8] c"param_ann_{{.}}\00", section "llvm.metadata" + +int foo(int v __attribute__((annotate("param_ann_2"))) __attribute__((annotate("param_ann_3")))); +int foo(int v __attribute__((annotate("param_ann_0"))) __attribute__((annotate("param_ann_1")))) { + return v + 1; +// PARAM: define {{.*}}@foo +// PARAM: [[V:%.*]] = alloca i32 +// PARAM: bitcast i32* [[V]] to i8* +// PARAM-NEXT: call void @llvm.var.annotation( +// PARAM-NEXT: bitcast i32* [[V]] to i8* +// PARAM-NEXT: call void @llvm.var.annotation( +// PARAM-NEXT: bitcast i32* [[V]] to i8* +// PARAM-NEXT: call void @llvm.var.annotation( +// PARAM-NEXT: bitcast i32* [[V]] to i8* +// PARAM-NEXT: call void @llvm.var.annotation( +} + +void local(void) { + int localvar __attribute__((annotate("localvar_ann_0"))) __attribute__((annotate("localvar_ann_1"))) = 3; +// LOCAL: define void @local() +// LOCAL: [[LOCALVAR:%.*]] = alloca i32, +// LOCAL-NEXT: [[T0:%.*]] = bitcast i32* [[LOCALVAR]] to i8* +// LOCAL-NEXT: call void @llvm.var.annotation(i8* [[T0]], i8* getelementptr inbounds ([15 x i8]* @{{.*}}), i8* getelementptr inbounds ({{.*}}), i32 33) +// LOCAL-NEXT: [[T0:%.*]] = bitcast i32* [[LOCALVAR]] to i8* +// LOCAL-NEXT: call void @llvm.var.annotation(i8* [[T0]], i8* getelementptr inbounds ([15 x i8]* @{{.*}}), i8* getelementptr inbounds ({{.*}}), i32 33) +} + +void undef(void) { + int undefvar __attribute__((annotate("undefvar_ann_0"))); +// UNDEF: define void @undef() +// UNDEF: [[UNDEFVAR:%.*]] = alloca i32, +// UNDEF-NEXT: [[T0:%.*]] = bitcast i32* [[UNDEFVAR]] to i8* +// UNDEF-NEXT: call void @llvm.var.annotation(i8* [[T0]], i8* getelementptr inbounds ([15 x i8]* @{{.*}}), i8* getelementptr inbounds ({{.*}}), i32 43) +} diff --git a/clang/test/CodeGen/arm-aapcs-vfp.c b/clang/test/CodeGen/arm-aapcs-vfp.c new file mode 100644 index 0000000..017c145 --- /dev/null +++ b/clang/test/CodeGen/arm-aapcs-vfp.c @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -triple thumbv7-apple-darwin9 \ +// RUN: -target-abi aapcs \ +// RUN: -target-cpu cortex-a8 \ +// RUN: -mfloat-abi hard \ +// RUN: -ffreestanding \ +// RUN: -emit-llvm -w -o - %s | FileCheck %s + +#include <arm_neon.h> + +struct homogeneous_struct { + float f[2]; + float f3; + float f4; +}; +// CHECK: define arm_aapcs_vfpcc %struct.homogeneous_struct @test_struct(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}}) +extern struct homogeneous_struct struct_callee(struct homogeneous_struct); +struct homogeneous_struct test_struct(struct homogeneous_struct arg) { + return struct_callee(arg); +} + +struct nested_array { + double d[4]; +}; +// CHECK: define arm_aapcs_vfpcc void @test_array(double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}}) +extern void array_callee(struct nested_array); +void test_array(struct nested_array arg) { + array_callee(arg); +} + +extern void complex_callee(__complex__ double); +// CHECK: define arm_aapcs_vfpcc void @test_complex(double %{{.*}}, double %{{.*}}) +void test_complex(__complex__ double cd) { + complex_callee(cd); +} + +// Structs with more than 4 elements of the base type are not treated +// as homogeneous aggregates. Test that. + +struct big_struct { + float f1; + float f[2]; + float f3; + float f4; +}; +// CHECK: define arm_aapcs_vfpcc void @test_big([5 x i32] %{{.*}}) +extern void big_callee(struct big_struct); +void test_big(struct big_struct arg) { + big_callee(arg); +} + +// Make sure that aggregates with multiple base types are not treated as +// homogeneous aggregates. + +struct heterogeneous_struct { + float f1; + int i2; +}; +// CHECK: define arm_aapcs_vfpcc void @test_hetero([2 x i32] %{{.*}}) +extern void hetero_callee(struct heterogeneous_struct); +void test_hetero(struct heterogeneous_struct arg) { + hetero_callee(arg); +} + +// Neon multi-vector types are homogeneous aggregates. +// CHECK: define arm_aapcs_vfpcc <16 x i8> @f0(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) +int8x16_t f0(int8x16x4_t v4) { + return vaddq_s8(v4.val[0], v4.val[3]); +} + +// ...and it doesn't matter whether the vectors are exactly the same, as long +// as they have the same size. + +struct neon_struct { + int8x8x2_t v12; + int32x2_t v3; + int16x4_t v4; +}; +// CHECK: define arm_aapcs_vfpcc void @test_neon(<8 x i8> %{{.*}}, <8 x i8> %{{.*}}, <2 x i32> %{{.*}}, <4 x i16> %{{.*}}) +extern void neon_callee(struct neon_struct); +void test_neon(struct neon_struct arg) { + neon_callee(arg); +} diff --git a/clang/test/CodeGen/arm-aapcs-zerolength-bitfield.c b/clang/test/CodeGen/arm-aapcs-zerolength-bitfield.c new file mode 100644 index 0000000..9fece19 --- /dev/null +++ b/clang/test/CodeGen/arm-aapcs-zerolength-bitfield.c @@ -0,0 +1,236 @@ +// RUN: %clang_cc1 -target-abi aapcs -triple armv7-apple-darwin10 %s -verify + +#include <stddef.h> + +struct t1 +{ + int foo : 1; + char : 0; + char bar; +}; +static int arr1_offset[(offsetof(struct t1, bar) == 1) ? 0 : -1]; +static int arr1_sizeof[(sizeof(struct t1) == 4) ? 0 : -1]; + +struct t2 +{ + int foo : 1; + short : 0; + char bar; +}; +static int arr2_offset[(offsetof(struct t2, bar) == 2) ? 0 : -1]; +static int arr2_sizeof[(sizeof(struct t2) == 4) ? 0 : -1]; + +struct t3 +{ + int foo : 1; + int : 0; + char bar; +}; +static int arr3_offset[(offsetof(struct t3, bar) == 4) ? 0 : -1]; +static int arr3_sizeof[(sizeof(struct t3) == 8) ? 0 : -1]; + +struct t4 +{ + int foo : 1; + long : 0; + char bar; +}; +static int arr4_offset[(offsetof(struct t4, bar) == 4) ? 0 : -1]; +static int arr4_sizeof[(sizeof(struct t4) == 8) ? 0 : -1]; + +struct t5 +{ + int foo : 1; + long long : 0; + char bar; +}; +static int arr5_offset[(offsetof(struct t5, bar) == 8) ? 0 : -1]; +static int arr5_sizeof[(sizeof(struct t5) == 16) ? 0 : -1]; + +struct t6 +{ + int foo : 1; + char : 0; + char bar : 1; + char bar2; +}; +static int arr6_offset[(offsetof(struct t6, bar2) == 2) ? 0 : -1]; +static int arr6_sizeof[(sizeof(struct t6) == 4) ? 0 : -1]; + +struct t7 +{ + int foo : 1; + short : 0; + char bar1 : 1; + char bar2; +}; +static int arr7_offset[(offsetof(struct t7, bar2) == 3) ? 0 : -1]; +static int arr7_sizeof[(sizeof(struct t7) == 4) ? 0 : -1]; + +struct t8 +{ + int foo : 1; + int : 0; + char bar1 : 1; + char bar2; +}; +static int arr8_offset[(offsetof(struct t8, bar2) == 5) ? 0 : -1]; +static int arr8_sizeof[(sizeof(struct t8) == 8) ? 0 : -1]; + +struct t9 +{ + int foo : 1; + long : 0; + char bar1 : 1; + char bar2; +}; +static int arr9_offset[(offsetof(struct t9, bar2) == 5) ? 0 : -1]; +static int arr9_sizeof[(sizeof(struct t9) == 8) ? 0 : -1]; + +struct t10 +{ + int foo : 1; + long long : 0; + char bar1 : 1; + char bar2; +}; +static int arr10_offset[(offsetof(struct t10, bar2) == 9) ? 0 : -1]; +static int arr10_sizeof[(sizeof(struct t10) == 16) ? 0 : -1]; + +struct t11 +{ + int foo : 1; + long long : 0; + char : 0; + char bar1 : 1; + char bar2; +}; +static int arr11_offset[(offsetof(struct t11, bar2) == 9) ? 0 : -1]; +static int arr11_sizeof[(sizeof(struct t11) == 16) ? 0 : -1]; + +struct t12 +{ + int foo : 1; + char : 0; + long long : 0; + char : 0; + char bar; +}; +static int arr12_offset[(offsetof(struct t12, bar) == 8) ? 0 : -1]; +static int arr12_sizeof[(sizeof(struct t12) == 16) ? 0 : -1]; + +struct t13 +{ + char foo; + long : 0; + char bar; +}; +static int arr13_offset[(offsetof(struct t13, bar) == 4) ? 0 : -1]; +static int arr13_sizeof[(sizeof(struct t13) == 8) ? 0 : -1]; + +struct t14 +{ + char foo1; + int : 0; + char foo2 : 1; + short foo3 : 16; + char : 0; + short foo4 : 16; + char bar1; + int : 0; + char bar2; +}; +static int arr14_bar1_offset[(offsetof(struct t14, bar1) == 10) ? 0 : -1]; +static int arr14_bar2_offset[(offsetof(struct t14, bar2) == 12) ? 0 : -1]; +static int arr14_sizeof[(sizeof(struct t14) == 16) ? 0 : -1]; + +struct t15 +{ + char foo; + char : 0; + int : 0; + char bar; + long : 0; + char : 0; +}; +static int arr15_offset[(offsetof(struct t15, bar) == 4) ? 0 : -1]; +static int arr15_sizeof[(sizeof(struct t15) == 8) ? 0 : -1]; + +struct t16 +{ + long : 0; + char bar; +}; +static int arr16_offset[(offsetof(struct t16, bar) == 0) ? 0 : -1]; +static int arr16_sizeof[(sizeof(struct t16) == 4) ? 0 : -1]; + +struct t17 +{ + char foo; + long : 0; + long : 0; + char : 0; + char bar; +}; +static int arr17_offset[(offsetof(struct t17, bar) == 4) ? 0 : -1]; +static int arr17_sizeof[(sizeof(struct t17) == 8) ? 0 : -1]; + +struct t18 +{ + long : 0; + long : 0; + char : 0; +}; +static int arr18_sizeof[(sizeof(struct t18) == 0) ? 0 : -1]; + +struct t19 +{ + char foo1; + long foo2 : 1; + char : 0; + long foo3 : 32; + char bar; +}; +static int arr19_offset[(offsetof(struct t19, bar) == 8) ? 0 : -1]; +static int arr19_sizeof[(sizeof(struct t19) == 12) ? 0 : -1]; + +struct t20 +{ + short : 0; + int foo : 1; + long : 0; + char bar; +}; +static int arr20_offset[(offsetof(struct t20, bar) == 4) ? 0 : -1]; +static int arr20_sizeof[(sizeof(struct t20) == 8) ? 0 : -1]; + +struct t21 +{ + short : 0; + int foo1 : 1; + char : 0; + int foo2 : 16; + long : 0; + char bar1; + int bar2; + long bar3; + char foo3 : 8; + char : 0; + long : 0; + int foo4 : 32; + short foo5: 1; + long bar4; + short foo6: 16; + short foo7: 16; + short foo8: 16; +}; +static int arr21_bar1_offset[(offsetof(struct t21, bar1) == 4) ? 0 : -1]; +static int arr21_bar2_offset[(offsetof(struct t21, bar2) == 8) ? 0 : -1]; +static int arr21_bar3_offset[(offsetof(struct t21, bar3) == 12) ? 0 : -1]; +static int arr21_bar4_offset[(offsetof(struct t21, bar4) == 28) ? 0 : -1]; +static int arr21_sizeof[(sizeof(struct t21) == 40) ? 0 : -1]; + +int main() { + return 0; +} + diff --git a/clang/test/CodeGen/arm-apcs-zerolength-bitfield.c b/clang/test/CodeGen/arm-apcs-zerolength-bitfield.c new file mode 100644 index 0000000..3f94525 --- /dev/null +++ b/clang/test/CodeGen/arm-apcs-zerolength-bitfield.c @@ -0,0 +1,240 @@ +// RUN: %clang_cc1 -target-abi apcs-gnu -triple armv7-apple-darwin10 %s -verify +// +// Note: gcc forces the alignment to 4 bytes, regardless of the type of the +// zero length bitfield. +// rdar://9859156 + +#include <stddef.h> + +struct t1 +{ + int foo : 1; + char : 0; + char bar; +}; +static int arr1_offset[(offsetof(struct t1, bar) == 4) ? 0 : -1]; +static int arr1_sizeof[(sizeof(struct t1) == 8) ? 0 : -1]; + +struct t2 +{ + int foo : 1; + short : 0; + char bar; +}; +static int arr2_offset[(offsetof(struct t2, bar) == 4) ? 0 : -1]; +static int arr2_sizeof[(sizeof(struct t2) == 8) ? 0 : -1]; + +struct t3 +{ + int foo : 1; + int : 0; + char bar; +}; +static int arr3_offset[(offsetof(struct t3, bar) == 4) ? 0 : -1]; +static int arr3_sizeof[(sizeof(struct t3) == 8) ? 0 : -1]; + +struct t4 +{ + int foo : 1; + long : 0; + char bar; +}; +static int arr4_offset[(offsetof(struct t4, bar) == 4) ? 0 : -1]; +static int arr4_sizeof[(sizeof(struct t4) == 8) ? 0 : -1]; + +struct t5 +{ + int foo : 1; + long long : 0; + char bar; +}; +static int arr5_offset[(offsetof(struct t5, bar) == 4) ? 0 : -1]; +static int arr5_sizeof[(sizeof(struct t5) == 8) ? 0 : -1]; + +struct t6 +{ + int foo : 1; + char : 0; + char bar : 1; + char bar2; +}; +static int arr6_offset[(offsetof(struct t6, bar2) == 5) ? 0 : -1]; +static int arr6_sizeof[(sizeof(struct t6) == 8) ? 0 : -1]; + +struct t7 +{ + int foo : 1; + short : 0; + char bar1 : 1; + char bar2; +}; +static int arr7_offset[(offsetof(struct t7, bar2) == 5) ? 0 : -1]; +static int arr7_sizeof[(sizeof(struct t7) == 8) ? 0 : -1]; + +struct t8 +{ + int foo : 1; + int : 0; + char bar1 : 1; + char bar2; +}; +static int arr8_offset[(offsetof(struct t8, bar2) == 5) ? 0 : -1]; +static int arr8_sizeof[(sizeof(struct t8) == 8) ? 0 : -1]; + +struct t9 +{ + int foo : 1; + long : 0; + char bar1 : 1; + char bar2; +}; +static int arr9_offset[(offsetof(struct t9, bar2) == 5) ? 0 : -1]; +static int arr9_sizeof[(sizeof(struct t9) == 8) ? 0 : -1]; + +struct t10 +{ + int foo : 1; + long long : 0; + char bar1 : 1; + char bar2; +}; +static int arr10_offset[(offsetof(struct t10, bar2) == 5) ? 0 : -1]; +static int arr10_sizeof[(sizeof(struct t10) == 8) ? 0 : -1]; + +struct t11 +{ + int foo : 1; + long long : 0; + char : 0; + char bar1 : 1; + char bar2; +}; +static int arr11_offset[(offsetof(struct t11, bar2) == 5) ? 0 : -1]; +static int arr11_sizeof[(sizeof(struct t11) == 8) ? 0 : -1]; + +struct t12 +{ + int foo : 1; + char : 0; + long long : 0; + char : 0; + char bar; +}; +static int arr12_offset[(offsetof(struct t12, bar) == 4) ? 0 : -1]; +static int arr12_sizeof[(sizeof(struct t12) == 8) ? 0 : -1]; + +struct t13 +{ + char foo; + long : 0; + char bar; +}; +static int arr13_offset[(offsetof(struct t13, bar) == 4) ? 0 : -1]; +static int arr13_sizeof[(sizeof(struct t13) == 8) ? 0 : -1]; + +struct t14 +{ + char foo1; + int : 0; + char foo2 : 1; + short foo3 : 16; + char : 0; + short foo4 : 16; + char bar1; + int : 0; + char bar2; +}; +static int arr14_bar1_offset[(offsetof(struct t14, bar1) == 10) ? 0 : -1]; +static int arr14_bar2_offset[(offsetof(struct t14, bar2) == 12) ? 0 : -1]; +static int arr14_sizeof[(sizeof(struct t14) == 16) ? 0 : -1]; + +struct t15 +{ + char foo; + char : 0; + int : 0; + char bar; + long : 0; + char : 0; +}; +static int arr15_offset[(offsetof(struct t15, bar) == 4) ? 0 : -1]; +static int arr15_sizeof[(sizeof(struct t15) == 8) ? 0 : -1]; + +struct t16 +{ + long : 0; + char bar; +}; +static int arr16_offset[(offsetof(struct t16, bar) == 0) ? 0 : -1]; +static int arr16_sizeof[(sizeof(struct t16) == 4) ? 0 : -1]; + +struct t17 +{ + char foo; + long : 0; + long : 0; + char : 0; + char bar; +}; +static int arr17_offset[(offsetof(struct t17, bar) == 4) ? 0 : -1]; +static int arr17_sizeof[(sizeof(struct t17) == 8) ? 0 : -1]; + +struct t18 +{ + long : 0; + long : 0; + char : 0; +}; +static int arr18_sizeof[(sizeof(struct t18) == 0) ? 0 : -1]; + +struct t19 +{ + char foo1; + long foo2 : 1; + char : 0; + long foo3 : 32; + char bar; +}; +static int arr19_offset[(offsetof(struct t19, bar) == 8) ? 0 : -1]; +static int arr19_sizeof[(sizeof(struct t19) == 12) ? 0 : -1]; + +struct t20 +{ + short : 0; + int foo : 1; + long : 0; + char bar; +}; +static int arr20_offset[(offsetof(struct t20, bar) == 4) ? 0 : -1]; +static int arr20_sizeof[(sizeof(struct t20) == 8) ? 0 : -1]; + +struct t21 +{ + short : 0; + int foo1 : 1; + char : 0; + int foo2 : 16; + long : 0; + char bar1; + int bar2; + long bar3; + char foo3 : 8; + char : 0; + long : 0; + int foo4 : 32; + short foo5: 1; + long bar4; + short foo6: 16; + short foo7: 16; + short foo8: 16; +}; +static int arr21_bar1_offset[(offsetof(struct t21, bar1) == 8) ? 0 : -1]; +static int arr21_bar2_offset[(offsetof(struct t21, bar2) == 12) ? 0 : -1]; +static int arr21_bar3_offset[(offsetof(struct t21, bar3) == 16) ? 0 : -1]; +static int arr21_bar4_offset[(offsetof(struct t21, bar4) == 32) ? 0 : -1]; +static int arr21_sizeof[(sizeof(struct t21) == 44) ? 0 : -1]; + +int main() { + return 0; +} + diff --git a/clang/test/CodeGen/arm-arguments.c b/clang/test/CodeGen/arm-arguments.c new file mode 100644 index 0000000..4686d4a --- /dev/null +++ b/clang/test/CodeGen/arm-arguments.c @@ -0,0 +1,167 @@ +// RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-abi apcs-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=APCS-GNU %s +// RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-abi aapcs -emit-llvm -w -o - %s | FileCheck -check-prefix=AAPCS %s + +// APCS-GNU: define signext i8 @f0() +// AAPCS: define arm_aapcscc signext i8 @f0() +char f0(void) { + return 0; +} + +// APCS-GNU: define i8 @f1() +// AAPCS: define arm_aapcscc i8 @f1() +struct s1 { char f0; }; +struct s1 f1(void) {} + +// APCS-GNU: define i16 @f2() +// AAPCS: define arm_aapcscc i16 @f2() +struct s2 { short f0; }; +struct s2 f2(void) {} + +// APCS-GNU: define i32 @f3() +// AAPCS: define arm_aapcscc i32 @f3() +struct s3 { int f0; }; +struct s3 f3(void) {} + +// APCS-GNU: define i32 @f4() +// AAPCS: define arm_aapcscc i32 @f4() +struct s4 { struct s4_0 { int f0; } f0; }; +struct s4 f4(void) {} + +// APCS-GNU: define void @f5( +// APCS-GNU: struct.s5* noalias sret +// AAPCS: define arm_aapcscc i32 @f5() +struct s5 { struct { } f0; int f1; }; +struct s5 f5(void) {} + +// APCS-GNU: define void @f6( +// APCS-GNU: struct.s6* noalias sret +// AAPCS: define arm_aapcscc i32 @f6() +struct s6 { int f0[1]; }; +struct s6 f6(void) {} + +// APCS-GNU: define void @f7() +// AAPCS: define arm_aapcscc void @f7() +struct s7 { struct { int : 0; } f0; }; +struct s7 f7(void) {} + +// APCS-GNU: define void @f8( +// APCS-GNU: struct.s8* noalias sret +// AAPCS: define arm_aapcscc void @f8() +struct s8 { struct { int : 0; } f0[1]; }; +struct s8 f8(void) {} + +// APCS-GNU: define i32 @f9() +// AAPCS: define arm_aapcscc i32 @f9() +struct s9 { int f0; int : 0; }; +struct s9 f9(void) {} + +// APCS-GNU: define i32 @f10() +// AAPCS: define arm_aapcscc i32 @f10() +struct s10 { int f0; int : 0; int : 0; }; +struct s10 f10(void) {} + +// APCS-GNU: define void @f11( +// APCS-GNU: struct.s11* noalias sret +// AAPCS: define arm_aapcscc i32 @f11() +struct s11 { int : 0; int f0; }; +struct s11 f11(void) {} + +// APCS-GNU: define i32 @f12() +// AAPCS: define arm_aapcscc i32 @f12() +union u12 { char f0; short f1; int f2; }; +union u12 f12(void) {} + +// APCS-GNU: define void @f13( +// APCS-GNU: struct.s13* noalias sret + +// FIXME: This should return a float. +// AAPCS-FIXME: darm_aapcscc efine float @f13() +struct s13 { float f0; }; +struct s13 f13(void) {} + +// APCS-GNU: define void @f14( +// APCS-GNU: union.u14* noalias sret +// AAPCS: define arm_aapcscc i32 @f14() +union u14 { float f0; }; +union u14 f14(void) {} + +// APCS-GNU: define void @f15() +// AAPCS: define arm_aapcscc void @f15() +void f15(struct s7 a0) {} + +// APCS-GNU: define void @f16() +// AAPCS: define arm_aapcscc void @f16() +void f16(struct s8 a0) {} + +// APCS-GNU: define i32 @f17() +// AAPCS: define arm_aapcscc i32 @f17() +struct s17 { short f0 : 13; char f1 : 4; }; +struct s17 f17(void) {} + +// APCS-GNU: define i32 @f18() +// AAPCS: define arm_aapcscc i32 @f18() +struct s18 { short f0; char f1 : 4; }; +struct s18 f18(void) {} + +// APCS-GNU: define void @f19( +// APCS-GNU: struct.s19* noalias sret +// AAPCS: define arm_aapcscc i32 @f19() +struct s19 { int f0; struct s8 f1; }; +struct s19 f19(void) {} + +// APCS-GNU: define void @f20( +// APCS-GNU: struct.s20* noalias sret +// AAPCS: define arm_aapcscc i32 @f20() +struct s20 { struct s8 f1; int f0; }; +struct s20 f20(void) {} + +// APCS-GNU: define i8 @f21() +// AAPCS: define arm_aapcscc i32 @f21() +struct s21 { struct {} f1; int f0 : 4; }; +struct s21 f21(void) {} + +// APCS-GNU: define i16 @f22() +// APCS-GNU: define i32 @f23() +// APCS-GNU: define i64 @f24() +// APCS-GNU: define i128 @f25() +// APCS-GNU: define i64 @f26() +// APCS-GNU: define i128 @f27() +// AAPCS: define arm_aapcscc i16 @f22() +// AAPCS: define arm_aapcscc i32 @f23() +// AAPCS: define arm_aapcscc void @f24({{.*}} noalias sret +// AAPCS: define arm_aapcscc void @f25({{.*}} noalias sret +// AAPCS: define arm_aapcscc void @f26({{.*}} noalias sret +// AAPCS: define arm_aapcscc void @f27({{.*}} noalias sret +_Complex char f22(void) {} +_Complex short f23(void) {} +_Complex int f24(void) {} +_Complex long long f25(void) {} +_Complex float f26(void) {} +_Complex double f27(void) {} + +// APCS-GNU: define i16 @f28() +// AAPCS: define arm_aapcscc i16 @f28() +struct s28 { _Complex char f0; }; +struct s28 f28() {} + +// APCS-GNU: define i32 @f29() +// AAPCS: define arm_aapcscc i32 @f29() +struct s29 { _Complex short f0; }; +struct s29 f29() {} + +// APCS-GNU: define void @f30({{.*}} noalias sret +// AAPCS: define arm_aapcscc void @f30({{.*}} noalias sret +struct s30 { _Complex int f0; }; +struct s30 f30() {} + +// PR11905 +struct s31 { char x; }; +void f31(struct s31 s) { } +// AAPCS: @f31([1 x i32] %s.coerce) +// AAPCS: %s = alloca %struct.s31, align 4 +// AAPCS: alloca [1 x i32] +// AAPCS: store [1 x i32] %s.coerce, [1 x i32]* +// APCS-GNU: @f31([1 x i32] %s.coerce) +// APCS-GNU: %s = alloca %struct.s31, align 4 +// APCS-GNU: alloca [1 x i32] +// APCS-GNU: store [1 x i32] %s.coerce, [1 x i32]* diff --git a/clang/test/CodeGen/arm-asm-variable.c b/clang/test/CodeGen/arm-asm-variable.c new file mode 100644 index 0000000..865d197 --- /dev/null +++ b/clang/test/CodeGen/arm-asm-variable.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -w -o - %s | FileCheck %s + +typedef long long int64_t; +typedef unsigned int uint32_t; + +int64_t foo(int64_t v, volatile int64_t *p) +{ + register uint32_t rl asm("r1"); + register uint32_t rh asm("r2"); + + int64_t r; + uint32_t t; + + __asm__ __volatile__( \ + "ldrexd%[_rl], %[_rh], [%[_p]]" \ + : [_rl] "=&r" (rl), [_rh] "=&r" (rh) \ + : [_p] "p" (p) : "memory"); + + // CHECK: call { i32, i32 } asm sideeffect "ldrexd$0, $1, [$2]", "={r1},={r2},r,~{memory}"(i64* + + return r; +} + +// Make sure we translate register names properly. +void bar (void) { + register unsigned int rn asm("r14"); + register unsigned int d asm("r2"); + + // CHECK: call i32 asm sideeffect "sub $1, $1, #32", "={r2},{lr}" + asm volatile ("sub %1, %1, #32" : "=r"(d) : "r"(rn)); +} diff --git a/clang/test/CodeGen/arm-asm.c b/clang/test/CodeGen/arm-asm.c new file mode 100644 index 0000000..9b1082a --- /dev/null +++ b/clang/test/CodeGen/arm-asm.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple thumb %s -emit-llvm -o - | FileCheck %s +int t1() { + static float k = 1.0f; + // CHECK: flds s15 + __asm__ volatile ("flds s15, %[k] \n" :: [k] "Uv" (k) : "s15"); + return 0; +} diff --git a/clang/test/CodeGen/arm-cc.c b/clang/test/CodeGen/arm-cc.c new file mode 100644 index 0000000..74eecc7 --- /dev/null +++ b/clang/test/CodeGen/arm-cc.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-abi apcs-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=DARWIN-APCS %s +// RUN: %clang_cc1 -triple armv7-apple-darwin9 -target-abi aapcs -emit-llvm -w -o - %s | FileCheck -check-prefix=DARWIN-AAPCS %s +// RUN: %clang_cc1 -triple arm-none-linux-gnueabi -target-abi apcs-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=LINUX-APCS %s +// RUN: %clang_cc1 -triple arm-none-linux-gnueabi -target-abi aapcs -emit-llvm -w -o - %s | FileCheck -check-prefix=LINUX-AAPCS %s + + +// DARWIN-APCS: define void @f() +// DARWIN-APCS: call void @g +// DARWIN-AAPCS: define arm_aapcscc void @f() +// DARWIN-AAPCS: call arm_aapcscc void @g +// LINUX-APCS: define arm_apcscc void @f() +// LINUX-APCS: call arm_apcscc void @g +// LINUX-AAPCS: define void @f() +// LINUX-AAPCS: call void @g +void g(void); +void f(void) { + g(); +} diff --git a/clang/test/CodeGen/arm-clear.c b/clang/test/CodeGen/arm-clear.c new file mode 100644 index 0000000..eda64ce --- /dev/null +++ b/clang/test/CodeGen/arm-clear.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -w -o - %s | FileCheck %s + +void clear0(void *ptr) { + // CHECK: clear0 + // CHECK-NOT: load i8** + __clear_cache(); +} + +void clear1(void *ptr) { + // CHECK: clear1 + // CHECK: load i8** + // CHECK-NOT: load i8** + __clear_cache(ptr); +} + +void clear2(void *ptr, void *ptr2) { + // CHECK: clear2 + // CHECK: load i8** + // CHECK: load i8** + __clear_cache(ptr, ptr2); +} diff --git a/clang/test/CodeGen/arm-homogenous.c b/clang/test/CodeGen/arm-homogenous.c new file mode 100644 index 0000000..eb3d5a6 --- /dev/null +++ b/clang/test/CodeGen/arm-homogenous.c @@ -0,0 +1,160 @@ +// RUN: %clang_cc1 -triple armv7---eabi -target-abi aapcs -mfloat-abi hard -emit-llvm %s -o - | FileCheck %s + +typedef long long int64_t; +typedef unsigned int uint32_t; + +/* This is not a homogenous aggregate - fundamental types are different */ +typedef union { + float f[4]; + uint32_t i[4]; +} union_with_first_floats; +union_with_first_floats g_u_f; + +extern void takes_union_with_first_floats(union_with_first_floats a); +extern union_with_first_floats returns_union_with_first_floats(void); + +void test_union_with_first_floats(void) { + takes_union_with_first_floats(g_u_f); +} +// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_first_floats([4 x i32]) + +void test_return_union_with_first_floats(void) { + g_u_f = returns_union_with_first_floats(); +} +// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(%union.union_with_first_floats* sret) + +/* This is not a homogenous aggregate - fundamental types are different */ +typedef union { + uint32_t i[4]; + float f[4]; +} union_with_non_first_floats; +union_with_non_first_floats g_u_nf_f; + +extern void takes_union_with_non_first_floats(union_with_non_first_floats a); +extern union_with_non_first_floats returns_union_with_non_first_floats(void); + +void test_union_with_non_first_floats(void) { + takes_union_with_non_first_floats(g_u_nf_f); +} +// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_non_first_floats([4 x i32]) + +void test_return_union_with_non_first_floats(void) { + g_u_nf_f = returns_union_with_non_first_floats(); +} +// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(%union.union_with_non_first_floats* sret) + +/* This is not a homogenous aggregate - fundamental types are different */ +typedef struct { + float a; + union_with_first_floats b; +} struct_with_union_with_first_floats; +struct_with_union_with_first_floats g_s_f; + +extern void takes_struct_with_union_with_first_floats(struct_with_union_with_first_floats a); +extern struct_with_union_with_first_floats returns_struct_with_union_with_first_floats(void); + +void test_struct_with_union_with_first_floats(void) { + takes_struct_with_union_with_first_floats(g_s_f); +} +// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_first_floats([5 x i32]) + +void test_return_struct_with_union_with_first_floats(void) { + g_s_f = returns_struct_with_union_with_first_floats(); +} +// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(%struct.struct_with_union_with_first_floats* sret) + +/* This is not a homogenous aggregate - fundamental types are different */ +typedef struct { + float a; + union_with_non_first_floats b; +} struct_with_union_with_non_first_floats; +struct_with_union_with_non_first_floats g_s_nf_f; + +extern void takes_struct_with_union_with_non_first_floats(struct_with_union_with_non_first_floats a); +extern struct_with_union_with_non_first_floats returns_struct_with_union_with_non_first_floats(void); + +void test_struct_with_union_with_non_first_floats(void) { + takes_struct_with_union_with_non_first_floats(g_s_nf_f); +} +// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_non_first_floats([5 x i32]) + +void test_return_struct_with_union_with_non_first_floats(void) { + g_s_nf_f = returns_struct_with_union_with_non_first_floats(); +} +// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(%struct.struct_with_union_with_non_first_floats* sret) + +/* Plain array is not a homogenous aggregate */ +extern void takes_array_of_floats(float a[4]); +void test_array_of_floats(void) { + float a[4] = {1.0, 2.0, 3.0, 4.0}; + takes_array_of_floats(a); +} +// CHECK: declare arm_aapcs_vfpcc void @takes_array_of_floats(float*) + +/* Struct-type homogenous aggregate */ +typedef struct { + float x, y, z, w; +} struct_with_fundamental_elems; +struct_with_fundamental_elems g_s; + +extern void takes_struct_with_fundamental_elems(struct_with_fundamental_elems a); +extern struct_with_fundamental_elems returns_struct_with_fundamental_elems(void); + +void test_struct_with_fundamental_elems(void) { + takes_struct_with_fundamental_elems(g_s); +// CHECK: call arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float{{.*}}, float {{.*}}) +} +// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(float, float, float, float) + +void test_return_struct_with_fundamental_elems(void) { + g_s = returns_struct_with_fundamental_elems(); +// CHECK: call arm_aapcs_vfpcc %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems() +} +// CHECK: declare arm_aapcs_vfpcc %struct.struct_with_fundamental_elems @returns_struct_with_fundamental_elems() + +/* Array-type homogenous aggregate */ +typedef struct { + float xyzw[4]; +} struct_with_array; +struct_with_array g_s_a; + +extern void takes_struct_with_array(struct_with_array a); +extern struct_with_array returns_struct_with_array(void); + +void test_struct_with_array(void) { + takes_struct_with_array(g_s_a); +// CHECK: call arm_aapcs_vfpcc void @takes_struct_with_array(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}}) +} +// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_array(float, float, float, float) + +void test_return_struct_with_array(void) { + g_s_a = returns_struct_with_array(); +// CHECK: call arm_aapcs_vfpcc %struct.struct_with_array @returns_struct_with_array() +} +// CHECK: declare arm_aapcs_vfpcc %struct.struct_with_array @returns_struct_with_array() + +/* This union is a homogenous aggregate. Check that it's passed properly */ +typedef union { + struct_with_fundamental_elems xyzw; + float a[3]; +} union_with_struct_with_fundamental_elems; +union_with_struct_with_fundamental_elems g_u_s_fe; + +extern void takes_union_with_struct_with_fundamental_elems(union_with_struct_with_fundamental_elems a); +extern union_with_struct_with_fundamental_elems returns_union_with_struct_with_fundamental_elems(void); + +void test_union_with_struct_with_fundamental_elems(void) { + takes_union_with_struct_with_fundamental_elems(g_u_s_fe); +// CHECK: call arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}}) +} +// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(float, float, float, float) + +void test_return_union_with_struct_with_fundamental_elems(void) { + g_u_s_fe = returns_union_with_struct_with_fundamental_elems(); +// CHECK: call arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems() +} +// CHECK: declare arm_aapcs_vfpcc %union.union_with_struct_with_fundamental_elems @returns_union_with_struct_with_fundamental_elems() + +// FIXME: Tests necessary: +// - Vectors +// - C++ stuff
\ No newline at end of file diff --git a/clang/test/CodeGen/arm-inline-asm.c b/clang/test/CodeGen/arm-inline-asm.c new file mode 100644 index 0000000..0152b05 --- /dev/null +++ b/clang/test/CodeGen/arm-inline-asm.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple armv7-apple-darwin9 -emit-llvm -w -o - %s | FileCheck %s + +void t1 (void *f, int g) { + // CHECK: call void asm "str $1, $0", "=*Q,r" + asm("str %1, %0" : "=Q"(f) : "r"(g)); +} diff --git a/clang/test/CodeGen/arm-pcs.c b/clang/test/CodeGen/arm-pcs.c new file mode 100644 index 0000000..d722f84 --- /dev/null +++ b/clang/test/CodeGen/arm-pcs.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple arm-none-linux-gnueabi -emit-llvm -w -o - < %s | FileCheck %s +typedef int __attribute__((pcs("aapcs"))) (*aapcs_fn)(void); +typedef int __attribute__((pcs("aapcs-vfp"))) (*aapcs_vfp_fn)(void); + +aapcs_fn bar; + +int foo(aapcs_vfp_fn baz) { +// CHECK: define i32 @foo +// CHECK: call arm_aapcscc +// CHECK: call arm_aapcs_vfpcc + return bar() + baz(); +} diff --git a/clang/test/CodeGen/arm-vaarg-align.c b/clang/test/CodeGen/arm-vaarg-align.c new file mode 100644 index 0000000..1187c02 --- /dev/null +++ b/clang/test/CodeGen/arm-vaarg-align.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple arm -target-abi aapcs %s -emit-llvm -o - | FileCheck -check-prefix=AAPCS %s +// RUN: %clang_cc1 -triple arm -target-abi apcs-gnu %s -emit-llvm -o - | FileCheck -check-prefix=APCS-GNU %s +/* + * Check that va_arg accesses stack according to ABI alignment + * long long and double require 8-byte alignment under AAPCS + * however, they only require 4-byte alignment under APCS + */ +long long t1(int i, ...) { + // AAPCS: t1 + // APCS-GNU: t1 + __builtin_va_list ap; + __builtin_va_start(ap, i); + // AAPCS: add i32 %{{.*}} 7 + // AAPCS: and i32 %{{.*}} -8 + // APCS-GNU-NOT: add i32 %{{.*}} 7 + // APCS-GNU-NOT: and i32 %{{.*}} -8 + long long ll = __builtin_va_arg(ap, long long); + __builtin_va_end(ap); + return ll; +} +double t2(int i, ...) { + // AAPCS: t2 + // APCS-GNU: t2 + __builtin_va_list ap; + __builtin_va_start(ap, i); + // AAPCS: add i32 %{{.*}} 7 + // AAPCS: and i32 %{{.*}} -8 + // APCS-GNU-NOT: add i32 %{{.*}} 7 + // APCS-GNU-NOT: and i32 %{{.*}} -8 + double ll = __builtin_va_arg(ap, double); + __builtin_va_end(ap); + return ll; +} diff --git a/clang/test/CodeGen/arm-vector-align.c b/clang/test/CodeGen/arm-vector-align.c new file mode 100644 index 0000000..b481a0c --- /dev/null +++ b/clang/test/CodeGen/arm-vector-align.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple thumbv7-apple-darwin \ +// RUN: -target-abi apcs-gnu \ +// RUN: -target-cpu cortex-a8 \ +// RUN: -mfloat-abi soft \ +// RUN: -target-feature +soft-float-abi \ +// RUN: -ffreestanding \ +// RUN: -emit-llvm -w -o - %s | FileCheck %s + +#include <arm_neon.h> + +// Radar 9311427: Check that alignment specifier is used in Neon load/store +// intrinsics. +typedef float AlignedAddr __attribute__ ((aligned (16))); +void t1(AlignedAddr *addr1, AlignedAddr *addr2) { +// CHECK: @t1 +// CHECK: call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* %{{.*}}, i32 16) + float32x4_t a = vld1q_f32(addr1); +// CHECK: call void @llvm.arm.neon.vst1.v4f32(i8* %{{.*}}, <4 x float> %{{.*}}, i32 16) + vst1q_f32(addr2, a); +} + +// Radar 10538555: Make sure unaligned load/stores do not gain alignment. +void t2(char *addr) { +// CHECK: @t2 +// CHECK: load i32* %{{.*}}, align 1 + int32x2_t vec = vld1_dup_s32(addr); +// CHECK: store i32 %{{.*}}, i32* {{.*}}, align 1 + vst1_lane_s32(addr, vec, 1); +} diff --git a/clang/test/CodeGen/arm-vector-arguments.c b/clang/test/CodeGen/arm-vector-arguments.c new file mode 100644 index 0000000..6bfb2f4 --- /dev/null +++ b/clang/test/CodeGen/arm-vector-arguments.c @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -triple thumbv7-apple-darwin9 \ +// RUN: -target-abi apcs-gnu \ +// RUN: -target-cpu cortex-a8 \ +// RUN: -mfloat-abi soft \ +// RUN: -target-feature +soft-float-abi \ +// RUN: -ffreestanding \ +// RUN: -emit-llvm -w -o - %s | FileCheck %s + +#include <arm_neon.h> + +// CHECK: define void @f0(%struct.int8x16x2_t* noalias sret %agg.result, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}) +int8x16x2_t f0(int8x16_t a0, int8x16_t a1) { + return vzipq_s8(a0, a1); +} + +// Test direct vector passing. + +typedef float T_float32x2 __attribute__ ((__vector_size__ (8))); +typedef float T_float32x4 __attribute__ ((__vector_size__ (16))); +typedef float T_float32x8 __attribute__ ((__vector_size__ (32))); +typedef float T_float32x16 __attribute__ ((__vector_size__ (64))); + +// CHECK: define <2 x float> @f1_0(<2 x float> %{{.*}}) +T_float32x2 f1_0(T_float32x2 a0) { return a0; } +// CHECK: define <4 x float> @f1_1(<4 x float> %{{.*}}) +T_float32x4 f1_1(T_float32x4 a0) { return a0; } +// CHECK: define void @f1_2(<8 x float>* noalias sret %{{.*}}, <8 x float> %{{.*}}) +T_float32x8 f1_2(T_float32x8 a0) { return a0; } +// CHECK: define void @f1_3(<16 x float>* noalias sret %{{.*}}, <16 x float> %{{.*}}) +T_float32x16 f1_3(T_float32x16 a0) { return a0; } diff --git a/clang/test/CodeGen/array.c b/clang/test/CodeGen/array.c new file mode 100644 index 0000000..0b401ea --- /dev/null +++ b/clang/test/CodeGen/array.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t + +void f() { + int a[2]; + a[0] = 0; +} + +void 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/clang/test/CodeGen/arrayderef.c b/clang/test/CodeGen/arrayderef.c new file mode 100644 index 0000000..effc0a6 --- /dev/null +++ b/clang/test/CodeGen/arrayderef.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -O1 -o - | FileCheck %s +// The load here was getting lost because this code was close +// enough to the traditional (wrong) implementation of offsetof +// to confuse the gcc FE. 8629268. + +struct foo { + int x; + int *y; +}; + +struct foo Foo[1]; + +int * bar(unsigned int ix) { +// CHECK: load + return &Foo->y[ix]; +} diff --git a/clang/test/CodeGen/asm-errors.c b/clang/test/CodeGen/asm-errors.c new file mode 100644 index 0000000..438c82b --- /dev/null +++ b/clang/test/CodeGen/asm-errors.c @@ -0,0 +1,11 @@ +// REQUIRES: x86-registered-target + +// RUN: true +// UN: not %clang_cc1 -triple i386-apple-darwin10 -emit-obj %s -o /dev/null > %t 2>&1 +// UN: FileCheck %s < %t + +int test1(int X) { +// CHECK: error: invalid instruction mnemonic 'abc' + __asm__ ("abc incl %0" : "+r" (X)); + return X; +} diff --git a/clang/test/CodeGen/asm-inout.c b/clang/test/CodeGen/asm-inout.c new file mode 100644 index 0000000..c7d1aec --- /dev/null +++ b/clang/test/CodeGen/asm-inout.c @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// PR3800 +int *foo(void); + +// CHECK: @test1 +void test1() { + // CHECK: [[REGCALLRESULT:%[a-zA-Z0-9\.]+]] = call i32* @foo() + // CHECK: call void asm "foobar", "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* [[REGCALLRESULT]], i32* [[REGCALLRESULT]]) + asm ("foobar" : "+m"(*foo())); +} + +// CHECK: @test2 +void test2() { + // CHECK: [[REGCALLRESULT:%[a-zA-Z0-9\.]+]] = call i32* @foo() + // CHECK: load i32* [[REGCALLRESULT]] + // CHECK: call i32 asm + // CHECK: store i32 {{%[a-zA-Z0-9\.]+}}, i32* [[REGCALLRESULT]] + asm ("foobar" : "+r"(*foo())); +} + +// PR7338 +// CHECK: @test3 +void test3(int *vout, int vin) +{ + // CHECK: call void asm "opr $0,$1", "=*r|m|r,r|m|r,~{edi},~{dirflag},~{fpsr},~{flags}" + asm ("opr %[vout],%[vin]" + : [vout] "=r,=m,=r" (*vout) + : [vin] "r,m,r" (vin) + : "edi"); +} + +// PR8959 - This should implicitly truncate the immediate to a byte. +// CHECK: @test4 +int test4(volatile int *addr) { + unsigned char oldval; + // CHECK: call i8 asm "frob $0", "=r,0{{.*}}"(i8 -1) + __asm__ ("frob %0" : "=r"(oldval) : "0"(0xff)); + return (int)oldval; +} + +// <rdar://problem/10919182> - This should have both inputs be of type x86_mmx. +// CHECK: @test5 +typedef long long __m64 __attribute__((__vector_size__(8))); +__m64 test5(__m64 __A, __m64 __B) { + // CHECK: call x86_mmx asm "pmulhuw $1, $0\0A\09", "=y,y,0,~{dirflag},~{fpsr},~{flags}"(x86_mmx %{{.*}}, x86_mmx %{{.*}}) + asm ("pmulhuw %1, %0\n\t" : "+y" (__A) : "y" (__B)); + return __A; +} diff --git a/clang/test/CodeGen/asm-label.c b/clang/test/CodeGen/asm-label.c new file mode 100644 index 0000000..c06f11f --- /dev/null +++ b/clang/test/CodeGen/asm-label.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple=i686-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 -triple=i686-apple-darwin9 -emit-llvm %s -o - | FileCheck %s --check-prefix=DARWIN + +char *strerror(int) asm("alias"); +int x __asm("foo"); + +int *test(void) { + static int y __asm("bar"); + strerror(-1); + return &y; +} + +// LINUX: @bar = internal global i32 0 +// LINUX: @foo = common global i32 0 +// LINUX: declare i8* @alias(i32) + +// DARWIN: @"\01bar" = internal global i32 0 +// DARWIN: @"\01foo" = common global i32 0 +// DARWIN: declare i8* @"\01alias"(i32) diff --git a/clang/test/CodeGen/asm-reg-var-local.c b/clang/test/CodeGen/asm-reg-var-local.c new file mode 100644 index 0000000..9060e12 --- /dev/null +++ b/clang/test/CodeGen/asm-reg-var-local.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s +// Exercise various use cases for local asm "register variables". + +int foo() { +// CHECK: [[A:%[a-zA-Z0-9]+]] = alloca i32 + + register int a asm("rsi")=5; +// CHECK: store i32 5, i32* [[A]] + + asm volatile("; %0 This asm defines rsi" : "=r"(a)); +// CHECK: [[Z:%[a-zA-Z0-9]+]] = call i32 asm sideeffect "; $0 This asm defines rsi", "={rsi},~{dirflag},~{fpsr},~{flags}"() +// CHECK: store i32 [[Z]], i32* [[A]] + + a = 42; +// CHECK: store i32 42, i32* [[A]] + + asm volatile("; %0 This asm uses rsi" : : "r"(a)); +// CHECK: [[TMP:%[a-zA-Z0-9]+]] = load i32* [[A]] +// CHECK: call void asm sideeffect "; $0 This asm uses rsi", "{rsi},~{dirflag},~{fpsr},~{flags}"(i32 [[TMP]]) + + return a; +// CHECK: [[TMP1:%[a-zA-Z0-9]+]] = load i32* [[A]] +// CHECK: ret i32 [[TMP1]] +} diff --git a/clang/test/CodeGen/asm-variable.c b/clang/test/CodeGen/asm-variable.c new file mode 100644 index 0000000..dc087bd --- /dev/null +++ b/clang/test/CodeGen/asm-variable.c @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +unsigned long long foo(unsigned long long addr, unsigned long long a0, + unsigned long long a1, unsigned long long a2, + unsigned long long a3, unsigned long long a4, + unsigned long long a5) { + register unsigned long long result asm("rax"); + register unsigned long long b0 asm("rdi"); + register unsigned long long b1 asm("rsi"); + register unsigned long long b2 asm("rdx"); + register unsigned long long b3 asm("rcx"); + register unsigned long long b4 asm("r8"); + register unsigned long long b5 asm("r9"); + + b0 = a0; + b1 = a1; + b2 = a2; + b3 = a3; + b4 = a4; + b5 = a5; + + asm("call *%1" : "=r" (result) + : "r"(addr), "r" (b0), "r" (b1), "r" (b2), "r" (b3), "r" (b4), "r" (b5)); + return result; +} + +// CHECK: call i64 asm "call *$1", "={rax},r,{rdi},{rsi},{rdx},{rcx},{r8},{r9},~{dirflag},~{fpsr},~{flags}" + +unsigned long long foo2(unsigned long long addr, double a0, + double a1, double a2, + double a3, double a4, + double a5, double a6, double a7) { + register double b0 asm("xmm0"); + register double b1 asm("xmm1"); + register double b2 asm("xmm2"); + register double b3 asm("xmm3"); + register double b4 asm("xmm4"); + register double b5 asm("xmm5"); + register double b6 asm("xmm6"); + register double b7 asm("xmm7"); + + register unsigned long long result asm("rax"); + + b0 = a0; + b1 = a1; + b2 = a2; + b3 = a3; + b4 = a4; + b5 = a5; + b6 = a6; + b7 = a7; + + asm("call *%1" : "=r" (result) + : "r"(addr), "x" (b0), "x" (b1), "x" (b2), "x" (b3), "x" (b4), "x" (b5), "x" (b6), + "x" (b7)); + return result; +} + +// CHECK: call i64 asm "call *$1", "={rax},r,{xmm0},{xmm1},{xmm2},{xmm3},{xmm4},{xmm5},{xmm6},{xmm7},~{dirflag},~{fpsr},~{flags} + +int randomvar asm("randomvar"); +void foo3() { + asm("vartest %0" : : "r"(randomvar)); +} +// CHECK: call void asm sideeffect "vartest $0", "r,~{dirflag},~{fpsr},~{flags}" diff --git a/clang/test/CodeGen/asm.c b/clang/test/CodeGen/asm.c new file mode 100644 index 0000000..84f26e1 --- /dev/null +++ b/clang/test/CodeGen/asm.c @@ -0,0 +1,222 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// PR10415 +__asm__ ("foo1"); +__asm__ ("foo2"); +__asm__ ("foo3"); +// CHECK: module asm "foo1" +// CHECK-NEXT: module asm "foo2" +// CHECK-NEXT: module asm "foo3" + +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)); +} + +void t7(int a) { + __asm__ volatile("T7 NAMED: %[input]" : "+r"(a): [input] "i" (4)); + // CHECK: @t7(i32 + // CHECK: T7 NAMED: $1 +} + +void t8() { + __asm__ volatile("T8 NAMED MODIFIER: %c[input]" :: [input] "i" (4)); + // CHECK: @t8() + // CHECK: T8 NAMED MODIFIER: ${0:c} +} + +// PR3682 +unsigned t9(unsigned int a) { + asm("bswap %0 %1" : "+r" (a)); + return a; +} + +// PR3908 +void t10(int r) { + __asm__("PR3908 %[lf] %[xx] %[li] %[r]" : [r] "+r" (r) : [lf] "mx" (0), [li] "mr" (0), [xx] "x" ((double)(0))); + +// CHECK: @t10( +// CHECK:PR3908 $1 $3 $2 $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) ); +} + +// PR4938 +int t16() { + int a,b; + asm ( "nop;" + :"=%c" (a) + : "r" (b) + ); + return 0; +} + +// PR6475 +void t17() { + int i; + __asm__ ( "nop": "=m"(i)); + +// CHECK: @t17() +// CHECK: call void asm "nop", "=*m, +} + +// <rdar://problem/6841383> +int t18(unsigned data) { + int a, b; + + asm("xyz" :"=a"(a), "=d"(b) : "a"(data)); + return a + b; +// CHECK: t18(i32 +// CHECK: = call {{.*}}asm "xyz" +// CHECK-NEXT: extractvalue +// CHECK-NEXT: extractvalue +} + +// PR6780 +int t19(unsigned data) { + int a, b; + + asm("x{abc|def|ghi}z" :"=r"(a): "r"(data)); + return a + b; + // CHECK: t19(i32 + // CHECK: = call {{.*}}asm "x$(abc$|def$|ghi$)z" +} + +// PR6845 - Mismatching source/dest fp types. +double t20(double x) { + register long double result; + __asm __volatile ("frndint" : "=t" (result) : "0" (x)); + return result; + + // CHECK: @t20 + // CHECK: fpext double {{.*}} to x86_fp80 + // CHECK-NEXT: call x86_fp80 asm sideeffect "frndint" + // CHECK: fptrunc x86_fp80 {{.*}} to double +} + +float t21(long double x) { + register float result; + __asm __volatile ("frndint" : "=t" (result) : "0" (x)); + return result; + // CHECK: @t21 + // CHECK: call x86_fp80 asm sideeffect "frndint" + // CHECK-NEXT: fptrunc x86_fp80 {{.*}} to float +} + +// <rdar://problem/8348447> - accept 'l' constraint +unsigned char t22(unsigned char a, unsigned char b) { + unsigned int la = a; + unsigned int lb = b; + unsigned int bigres; + unsigned char res; + __asm__ ("0:\n1:\n" : [bigres] "=la"(bigres) : [la] "0"(la), [lb] "c"(lb) : + "edx", "cc"); + res = bigres; + return res; +} + +// <rdar://problem/8348447> - accept 'l' constraint +unsigned char t23(unsigned char a, unsigned char b) { + unsigned int la = a; + unsigned int lb = b; + unsigned char res; + __asm__ ("0:\n1:\n" : [res] "=la"(res) : [la] "0"(la), [lb] "c"(lb) : + "edx", "cc"); + return res; +} + +void *t24(char c) { + void *addr; + // CHECK: @t24 + // CHECK: zext i8 {{.*}} to i32 + // CHECK-NEXT: call i8* asm "foobar" + __asm__ ("foobar" : "=a" (addr) : "0" (c)); + return addr; +} + +// PR10299 - fpsr, fpcr +void t25(void) +{ + __asm__ __volatile__( \ + "finit" \ + : \ + : \ + :"st","st(1)","st(2)","st(3)", \ + "st(4)","st(5)","st(6)","st(7)", \ + "fpsr","fpcr" \ + ); +} + +// rdar://10510405 - AVX registers +typedef long long __m256i __attribute__((__vector_size__(32))); +void t26 (__m256i *p) { + __asm__ volatile("vmovaps %0, %%ymm0" :: "m" (*(__m256i*)p) : "ymm0"); +} diff --git a/clang/test/CodeGen/asm_arm.c b/clang/test/CodeGen/asm_arm.c new file mode 100644 index 0000000..633bf55 --- /dev/null +++ b/clang/test/CodeGen/asm_arm.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -triple armv6-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +void test0(void) { + asm volatile("mov r0, r0" :: ); +} +void test1(void) { + asm volatile("mov r0, r0" ::: + "cc", "memory" ); +} +void test2(void) { + asm volatile("mov r0, r0" ::: + "r0", "r1", "r2", "r3"); + asm volatile("mov r0, r0" ::: + "r4", "r5", "r6", "r8"); +} +void test3(void) { + asm volatile("mov r0, r0" ::: + "a1", "a2", "a3", "a4"); + asm volatile("mov r0, r0" ::: + "v1", "v2", "v3", "v5"); +} + + +// {} should not be treated as asm variants. +void test4(float *a, float *b) { + // CHECK: @test4 + // CHECK: call void asm sideeffect "vld1.32 {d8[],d9[]}, + __asm__ volatile ( + "vld1.32 {d8[],d9[]}, [%1,:32] \n\t" + "vst1.32 {q4}, [%0,:128] \n\t" + :: "r"(a), "r"(b)); +} + +// {sp, lr, pc} are the canonical names for {r13, r14, r15}. +// +// CHECK: @test5 +// CHECK: call void asm sideeffect "", "~{sp},~{lr},~{pc},~{sp},~{lr},~{pc}"() +void test5() { + __asm__("" : : : "r13", "r14", "r15", "sp", "lr", "pc"); +} + +// CHECK: @test6 +// CHECK: call void asm sideeffect "", " +// CHECK: ~{s0},~{s1},~{s2},~{s3},~{s4},~{s5},~{s6},~{s7}, +// CHECK: ~{s8},~{s9},~{s10},~{s11},~{s12},~{s13},~{s14},~{s15}, +// CHECK: ~{s16},~{s17},~{s18},~{s19},~{s20},~{s21},~{s22},~{s23}, +// CHECK: ~{s24},~{s25},~{s26},~{s27},~{s28},~{s29},~{s30},~{s31}"() +void test6() { + __asm__("" : : : + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", + "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", + "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"); +} diff --git a/clang/test/CodeGen/assign.c b/clang/test/CodeGen/assign.c new file mode 100644 index 0000000..fc00896 --- /dev/null +++ b/clang/test/CodeGen/assign.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | FileCheck %s + +// Check that we don't generate unnecessary reloads. +// +// CHECK: define void @f0() +// CHECK: [[x_0:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[y_0:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 1, i32* [[x_0]] +// CHECK-NEXT: store i32 1, i32* [[x_0]] +// CHECK-NEXT: store i32 1, i32* [[y_0]] +// CHECK: } +void f0() { + int x, y; + x = 1; + y = (x = 1); +} + +// This used to test that we generate reloads for volatile access, +// but that does not appear to be correct behavior for C. +// +// CHECK: define void @f1() +// CHECK: [[x_1:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[y_1:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store volatile i32 1, i32* [[x_1]] +// CHECK-NEXT: store volatile i32 1, i32* [[x_1]] +// CHECK-NEXT: store volatile i32 1, i32* [[y_1]] +// CHECK: } +void f1() { + volatile int x, y; + x = 1; + y = (x = 1); +} diff --git a/clang/test/CodeGen/atomic-ops.c b/clang/test/CodeGen/atomic-ops.c new file mode 100644 index 0000000..1a9ed36 --- /dev/null +++ b/clang/test/CodeGen/atomic-ops.c @@ -0,0 +1,314 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s + +// Also test serialization of atomic operations here, to avoid duplicating the +// test. +// RUN: %clang_cc1 %s -emit-pch -o %t -triple=i686-apple-darwin9 +// RUN: %clang_cc1 %s -include-pch %t -triple=i686-apple-darwin9 -emit-llvm -o - | FileCheck %s +#ifndef ALREADY_INCLUDED +#define ALREADY_INCLUDED + +// Basic IRGen tests for __c11_atomic_* and GNU __atomic_* + +typedef enum memory_order { + memory_order_relaxed, memory_order_consume, memory_order_acquire, + memory_order_release, memory_order_acq_rel, memory_order_seq_cst +} memory_order; + +int fi1(_Atomic(int) *i) { + // CHECK: @fi1 + // CHECK: load atomic i32* {{.*}} seq_cst + return __c11_atomic_load(i, memory_order_seq_cst); +} + +int fi1a(int *i) { + // CHECK: @fi1a + // CHECK: load atomic i32* {{.*}} seq_cst + int v; + __atomic_load(i, &v, memory_order_seq_cst); + return v; +} + +int fi1b(int *i) { + // CHECK: @fi1b + // CHECK: load atomic i32* {{.*}} seq_cst + return __atomic_load_n(i, memory_order_seq_cst); +} + +void fi2(_Atomic(int) *i) { + // CHECK: @fi2 + // CHECK: store atomic i32 {{.*}} seq_cst + __c11_atomic_store(i, 1, memory_order_seq_cst); +} + +void fi2a(int *i) { + // CHECK: @fi2a + // CHECK: store atomic i32 {{.*}} seq_cst + int v = 1; + __atomic_store(i, &v, memory_order_seq_cst); +} + +void fi2b(int *i) { + // CHECK: @fi2b + // CHECK: store atomic i32 {{.*}} seq_cst + __atomic_store_n(i, 1, memory_order_seq_cst); +} + +int fi3(_Atomic(int) *i) { + // CHECK: @fi3 + // CHECK: atomicrmw and + // CHECK-NOT: and + return __c11_atomic_fetch_and(i, 1, memory_order_seq_cst); +} + +int fi3a(int *i) { + // CHECK: @fi3a + // CHECK: atomicrmw xor + // CHECK-NOT: xor + return __atomic_fetch_xor(i, 1, memory_order_seq_cst); +} + +int fi3b(int *i) { + // CHECK: @fi3b + // CHECK: atomicrmw add + // CHECK: add + return __atomic_add_fetch(i, 1, memory_order_seq_cst); +} + +int fi3c(int *i) { + // CHECK: @fi3c + // CHECK: atomicrmw nand + // CHECK-NOT: and + return __atomic_fetch_nand(i, 1, memory_order_seq_cst); +} + +int fi3d(int *i) { + // CHECK: @fi3d + // CHECK: atomicrmw nand + // CHECK: and + // CHECK: xor + return __atomic_nand_fetch(i, 1, memory_order_seq_cst); +} + +_Bool fi4(_Atomic(int) *i) { + // CHECK: @fi4 + // CHECK: cmpxchg i32* + int cmp = 0; + return __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire); +} + +_Bool fi4a(int *i) { + // CHECK: @fi4 + // CHECK: cmpxchg i32* + int cmp = 0; + int desired = 1; + return __atomic_compare_exchange(i, &cmp, &desired, 0, memory_order_acquire, memory_order_acquire); +} + +_Bool fi4b(int *i) { + // CHECK: @fi4 + // CHECK: cmpxchg i32* + int cmp = 0; + return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire); +} + +float ff1(_Atomic(float) *d) { + // CHECK: @ff1 + // CHECK: load atomic i32* {{.*}} monotonic + return __c11_atomic_load(d, memory_order_relaxed); +} + +void ff2(_Atomic(float) *d) { + // CHECK: @ff2 + // CHECK: store atomic i32 {{.*}} release + __c11_atomic_store(d, 1, memory_order_release); +} + +float ff3(_Atomic(float) *d) { + return __c11_atomic_exchange(d, 2, memory_order_seq_cst); +} + +int* fp1(_Atomic(int*) *p) { + // CHECK: @fp1 + // CHECK: load atomic i32* {{.*}} seq_cst + return __c11_atomic_load(p, memory_order_seq_cst); +} + +int* fp2(_Atomic(int*) *p) { + // CHECK: @fp2 + // CHECK: store i32 4 + // CHECK: atomicrmw add {{.*}} monotonic + return __c11_atomic_fetch_add(p, 1, memory_order_relaxed); +} + +int *fp2a(int **p) { + // CHECK: @fp2a + // CHECK: store i32 4 + // CHECK: atomicrmw sub {{.*}} monotonic + // Note, the GNU builtins do not multiply by sizeof(T)! + return __atomic_fetch_sub(p, 4, memory_order_relaxed); +} + +_Complex float fc(_Atomic(_Complex float) *c) { + // CHECK: @fc + // CHECK: atomicrmw xchg i64* + return __c11_atomic_exchange(c, 2, memory_order_seq_cst); +} + +typedef struct X { int x; } X; +X fs(_Atomic(X) *c) { + // CHECK: @fs + // CHECK: atomicrmw xchg i32* + return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst); +} + +X fsa(X *c, X *d) { + // CHECK: @fsa + // CHECK: atomicrmw xchg i32* + X ret; + __atomic_exchange(c, d, &ret, memory_order_seq_cst); + return ret; +} + +_Bool fsb(_Bool *c) { + // CHECK: @fsb + // CHECK: atomicrmw xchg i8* + return __atomic_exchange_n(c, 1, memory_order_seq_cst); +} + +char flag1; +volatile char flag2; +void test_and_set() { + // CHECK: atomicrmw xchg i8* @flag1, i8 1 seq_cst + __atomic_test_and_set(&flag1, memory_order_seq_cst); + // CHECK: atomicrmw volatile xchg i8* @flag2, i8 1 acquire + __atomic_test_and_set(&flag2, memory_order_acquire); + // CHECK: store atomic volatile i8 0, i8* @flag2 release + __atomic_clear(&flag2, memory_order_release); + // CHECK: store atomic i8 0, i8* @flag1 seq_cst + __atomic_clear(&flag1, memory_order_seq_cst); +} + +struct Sixteen { + char c[16]; +} sixteen; +struct Seventeen { + char c[17]; +} seventeen; + +int lock_free(struct Incomplete *incomplete) { + // CHECK: @lock_free + + // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null) + __c11_atomic_is_lock_free(3); + + // CHECK: call i32 @__atomic_is_lock_free(i32 16, i8* {{.*}}@sixteen{{.*}}) + __atomic_is_lock_free(16, &sixteen); + + // CHECK: call i32 @__atomic_is_lock_free(i32 17, i8* {{.*}}@seventeen{{.*}}) + __atomic_is_lock_free(17, &seventeen); + + // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + __atomic_is_lock_free(4, incomplete); + + char cs[20]; + // CHECK: call i32 @__atomic_is_lock_free(i32 4, {{.*}}) + __atomic_is_lock_free(4, cs+1); + + // CHECK-NOT: call + __atomic_always_lock_free(3, 0); + __atomic_always_lock_free(16, 0); + __atomic_always_lock_free(17, 0); + __atomic_always_lock_free(16, &sixteen); + __atomic_always_lock_free(17, &seventeen); + + int n; + __atomic_is_lock_free(4, &n); + + // CHECK: ret i32 1 + return __c11_atomic_is_lock_free(sizeof(_Atomic(int))); +} + +// Tests for atomic operations on big values. These should call the functions +// defined here: +// http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary#The_Library_interface + +struct foo { + int big[128]; +}; +struct bar { + char c[3]; +}; + +struct bar smallThing, thing1, thing2; +struct foo bigThing; +_Atomic(struct foo) bigAtomic; + +void structAtomicStore() { + // CHECK: @structAtomicStore + struct foo f = {0}; + __c11_atomic_store(&bigAtomic, f, 5); + // CHECK: call void @__atomic_store(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), + + struct bar b = {0}; + __atomic_store(&smallThing, &b, 5); + // CHECK: call void @__atomic_store(i32 3, i8* {{.*}} @smallThing + + __atomic_store(&bigThing, &f, 5); + // CHECK: call void @__atomic_store(i32 512, i8* {{.*}} @bigThing +} +void structAtomicLoad() { + // CHECK: @structAtomicLoad + struct foo f = __c11_atomic_load(&bigAtomic, 5); + // CHECK: call void @__atomic_load(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), + + struct bar b; + __atomic_load(&smallThing, &b, 5); + // CHECK: call void @__atomic_load(i32 3, i8* {{.*}} @smallThing + + __atomic_load(&bigThing, &f, 5); + // CHECK: call void @__atomic_load(i32 512, i8* {{.*}} @bigThing +} +struct foo structAtomicExchange() { + // CHECK: @structAtomicExchange + struct foo f = {0}; + struct foo old; + __atomic_exchange(&f, &bigThing, &old, 5); + // CHECK: call void @__atomic_exchange(i32 512, {{.*}}, i8* bitcast ({{.*}} @bigThing to i8*), + + return __c11_atomic_exchange(&bigAtomic, f, 5); + // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), +} +int structAtomicCmpExchange() { + // CHECK: @structAtomicCmpExchange + _Bool x = __atomic_compare_exchange(&smallThing, &thing1, &thing2, 1, 5, 5); + // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 3, {{.*}} @smallThing{{.*}} @thing1{{.*}} @thing2 + + struct foo f = {0}; + struct foo g = {0}; + g.big[12] = 12; + return x & __c11_atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5); + // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), +} + +// Check that no atomic operations are used in any initialisation of _Atomic +// types. +_Atomic(int) atomic_init_i = 42; + +// CHECK: @atomic_init_foo +void atomic_init_foo() +{ + // CHECK-NOT: } + // CHECK-NOT: atomic + // CHECK: store + _Atomic(int) j = 12; + + // CHECK-NOT: } + // CHECK-NOT: atomic + // CHECK: store + __c11_atomic_init(&j, 42); + + // CHECK-NOT: atomic + // CHECK: } +} + +#endif diff --git a/clang/test/CodeGen/atomic.c b/clang/test/CodeGen/atomic.c new file mode 100644 index 0000000..ac3848f --- /dev/null +++ b/clang/test/CodeGen/atomic.c @@ -0,0 +1,109 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s + +int atomic(void) { + // non-sensical test for sync functions + int old; + int val = 1; + char valc = 1; + _Bool valb = 0; + unsigned int uval = 1; + int cmp = 0; + int* ptrval; + + old = __sync_fetch_and_add(&val, 1); + // CHECK: atomicrmw add i32* %val, i32 1 seq_cst + + old = __sync_fetch_and_sub(&valc, 2); + // CHECK: atomicrmw sub i8* %valc, i8 2 seq_cst + + old = __sync_fetch_and_min(&val, 3); + // CHECK: atomicrmw min i32* %val, i32 3 seq_cst + + old = __sync_fetch_and_max(&val, 4); + // CHECK: atomicrmw max i32* %val, i32 4 seq_cst + + old = __sync_fetch_and_umin(&uval, 5u); + // CHECK: atomicrmw umin i32* %uval, i32 5 seq_cst + + old = __sync_fetch_and_umax(&uval, 6u); + // CHECK: atomicrmw umax i32* %uval, i32 6 seq_cst + + old = __sync_lock_test_and_set(&val, 7); + // CHECK: atomicrmw xchg i32* %val, i32 7 seq_cst + + old = __sync_swap(&val, 8); + // CHECK: atomicrmw xchg i32* %val, i32 8 seq_cst + + old = __sync_val_compare_and_swap(&val, 4, 1976); + // CHECK: cmpxchg i32* %val, i32 4, i32 1976 seq_cst + + old = __sync_bool_compare_and_swap(&val, 4, 1976); + // CHECK: cmpxchg i32* %val, i32 4, i32 1976 seq_cst + + old = __sync_fetch_and_and(&val, 0x9); + // CHECK: atomicrmw and i32* %val, i32 9 seq_cst + + old = __sync_fetch_and_or(&val, 0xa); + // CHECK: atomicrmw or i32* %val, i32 10 seq_cst + + old = __sync_fetch_and_xor(&val, 0xb); + // CHECK: atomicrmw xor i32* %val, i32 11 seq_cst + + old = __sync_add_and_fetch(&val, 1); + // CHECK: atomicrmw add i32* %val, i32 1 seq_cst + + old = __sync_sub_and_fetch(&val, 2); + // CHECK: atomicrmw sub i32* %val, i32 2 seq_cst + + old = __sync_and_and_fetch(&valc, 3); + // CHECK: atomicrmw and i8* %valc, i8 3 seq_cst + + old = __sync_or_and_fetch(&valc, 4); + // CHECK: atomicrmw or i8* %valc, i8 4 seq_cst + + old = __sync_xor_and_fetch(&valc, 5); + // CHECK: atomicrmw xor i8* %valc, i8 5 seq_cst + + __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0); + // CHECK: cmpxchg i32* null, i32 0, i32 0 seq_cst + + if ( __sync_val_compare_and_swap(&valb, 0, 1)) { + // CHECK: cmpxchg i8* %valb, i8 0, i8 1 seq_cst + old = 42; + } + + __sync_bool_compare_and_swap((void **)0, (void *)0, (void *)0); + // CHECK: cmpxchg i32* null, i32 0, i32 0 seq_cst + + __sync_lock_release(&val); + // CHECK: store atomic i32 0, {{.*}} release, align 4 + + __sync_lock_release(&ptrval); + // CHECK: store atomic i32 0, {{.*}} release, align 4 + + __sync_synchronize (); + // CHECK: fence seq_cst + + return old; +} + +// CHECK: @release_return +void release_return(int *lock) { + // Ensure this is actually returning void all the way through. + return __sync_lock_release(lock); + // CHECK: store atomic {{.*}} release, align 4 +} + + +// rdar://8461279 - Atomics with address spaces. +// CHECK: @addrspace +void addrspace(int __attribute__((address_space(256))) * P) { + __sync_bool_compare_and_swap(P, 0, 1); + // CHECK: cmpxchg i32 addrspace(256)*{{.*}}, i32 0, i32 1 seq_cst + + __sync_val_compare_and_swap(P, 0, 1); + // CHECK: cmpxchg i32 addrspace(256)*{{.*}}, i32 0, i32 1 seq_cst + + __sync_xor_and_fetch(P, 123); + // CHECK: atomicrmw xor i32 addrspace(256)*{{.*}}, i32 123 seq_cst +} diff --git a/clang/test/CodeGen/atomic_ops.c b/clang/test/CodeGen/atomic_ops.c new file mode 100644 index 0000000..9a18c9e --- /dev/null +++ b/clang/test/CodeGen/atomic_ops.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +void foo(void) +{ + _Atomic(int) i = 0; + // Check that multiply / divides on atomics produce a cmpxchg loop + i *= 2; // CHECK: cmpxchg + i /= 2; // CHECK: cmpxchg + // These should be emitting atomicrmw instructions, but they aren't yet + i += 2; // CHECK: cmpxchg + i -= 2; // CHECK: cmpxchg + i++; // CHECK: cmpxchg + i--; // CHECK: cmpxchg +} diff --git a/clang/test/CodeGen/attr-availability.c b/clang/test/CodeGen/attr-availability.c new file mode 100644 index 0000000..6f9c045 --- /dev/null +++ b/clang/test/CodeGen/attr-availability.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fvisibility hidden "-triple" "x86_64-apple-darwin8.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_4 %s +// RUN: %clang_cc1 -fvisibility hidden "-triple" "x86_64-apple-darwin9.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_5 %s +// RUN: %clang_cc1 -fvisibility hidden "-triple" "x86_64-apple-darwin10.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_6 %s + +// CHECK-10_4: define hidden void @f2 +// CHECK-10_5: define hidden void @f2 +// CHECK-10_6: define hidden void @f2 +void f2(); +void f2() { } + +// CHECK-10_4: define void @f3 +// CHECK-10_5: define void @f3 +// CHECK-10_6: define void @f3 +void f3() __attribute__((availability(macosx,introduced=10.5))); +void f3() { } + +// CHECK-10_4: declare extern_weak void @f0 +// CHECK-10_5: declare void @f0 +// CHECK-10_6: declare void @f0 +void f0() __attribute__((availability(macosx,introduced=10.5))); + +// CHECK-10_4: declare extern_weak void @f1 +// CHECK-10_5: declare extern_weak void @f1 +// CHECK-10_6: declare void @f1 +void f1() __attribute__((availability(macosx,introduced=10.6))); + +void test() { + f0(); + f1(); + f2(); +} diff --git a/clang/test/CodeGen/attr-cleanup.c b/clang/test/CodeGen/attr-cleanup.c new file mode 100644 index 0000000..7c2053d --- /dev/null +++ b/clang/test/CodeGen/attr-cleanup.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t + +// <rdar://problem/6827047> +void f(void* arg); +void g() { + __attribute__((cleanup(f))) void *g; +} + diff --git a/clang/test/CodeGen/attr-naked.c b/clang/test/CodeGen/attr-naked.c new file mode 100644 index 0000000..2387d28 --- /dev/null +++ b/clang/test/CodeGen/attr-naked.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -o - | FileCheck %s + +void t1() __attribute__((naked)); + +// Basic functionality check +// (Note that naked needs to imply noinline to work properly.) +// CHECK: define void @t1() nounwind noinline naked { +void t1() +{ +} + +// Make sure this doesn't explode in the verifier. +// (It doesn't really make sense, but it isn't invalid.) +// CHECK: define void @t2() nounwind noinline naked { +__attribute((naked, always_inline)) void t2() { +} diff --git a/clang/test/CodeGen/attr-nodebug.c b/clang/test/CodeGen/attr-nodebug.c new file mode 100644 index 0000000..66caa2b --- /dev/null +++ b/clang/test/CodeGen/attr-nodebug.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/attr-noinline.c b/clang/test/CodeGen/attr-noinline.c new file mode 100644 index 0000000..dbca71f --- /dev/null +++ b/clang/test/CodeGen/attr-noinline.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -g -emit-llvm -o %t %s +// RUN: grep 'noinline' %t + +void t1() __attribute__((noinline)); + +void t1() +{ +} + diff --git a/clang/test/CodeGen/attr-used.c b/clang/test/CodeGen/attr-used.c new file mode 100644 index 0000000..bc92b94 --- /dev/null +++ b/clang/test/CodeGen/attr-used.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/attr-weak-import.c b/clang/test/CodeGen/attr-weak-import.c new file mode 100644 index 0000000..0707f59 --- /dev/null +++ b/clang/test/CodeGen/attr-weak-import.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-darwin-apple -emit-llvm -o - %s | FileCheck %s +// rdar://9538608 + +extern int A __attribute__((weak_import)); +int A; + +extern int B __attribute__((weak_import)); +extern int B; + +int C; +extern int C __attribute__((weak_import)); + +extern int D __attribute__((weak_import)); +extern int D __attribute__((weak_import)); +int D; + +extern int E __attribute__((weak_import)); +int E; +extern int E __attribute__((weak_import)); + +// CHECK: @A = global i32 +// CHECK-NOT: @B = +// CHECK: @C = common global i32 +// CHECK: @D = global i32 +// CHECK: @E = global i32 + diff --git a/clang/test/CodeGen/attr-weakref.c b/clang/test/CodeGen/attr-weakref.c new file mode 100644 index 0000000..c1cc03b --- /dev/null +++ b/clang/test/CodeGen/attr-weakref.c @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu -o %t %s +// RUN: FileCheck --input-file=%t %s + +// CHECK: declare extern_weak void @test1_f() +void test1_f(void); +static void test1_g(void) __attribute__((weakref("test1_f"))); +void test1_h(void) { + test1_g(); +} + +// CHECK: define void @test2_f() +void test2_f(void) {} +static void test2_g(void) __attribute__((weakref("test2_f"))); +void test2_h(void) { + test2_g(); +} + +// CHECK: declare void @test3_f() +void test3_f(void); +static void test3_g(void) __attribute__((weakref("test3_f"))); +void test3_foo(void) { + test3_f(); +} +void test3_h(void) { + test3_g(); +} + +// CHECK: define void @test4_f() +void test4_f(void); +static void test4_g(void) __attribute__((weakref("test4_f"))); +void test4_h(void) { + test4_g(); +} +void test4_f(void) {} + +// CHECK: declare void @test5_f() +void test5_f(void); +static void test5_g(void) __attribute__((weakref("test5_f"))); +void test5_h(void) { + test5_g(); +} +void test5_foo(void) { + test5_f(); +} + +// CHECK: declare extern_weak void @test6_f() +void test6_f(void) __attribute__((weak)); +static void test6_g(void) __attribute__((weakref("test6_f"))); +void test6_h(void) { + test6_g(); +} +void test6_foo(void) { + test6_f(); +} + +// CHECK: declare extern_weak void @test7_f() +void test7_f(void); +static void test7_g(void) __attribute__((weakref("test7_f"))); +static void *const test7_zed = (void *) &test7_g; +void* test7_h(void) { + return test7_zed; +} diff --git a/clang/test/CodeGen/attr-weakref2.c b/clang/test/CodeGen/attr-weakref2.c new file mode 100644 index 0000000..9976063 --- /dev/null +++ b/clang/test/CodeGen/attr-weakref2.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu -o %t %s +// RUN: FileCheck --input-file=%t %s + +// CHECK: @test1_f = extern_weak global i32 +extern int test1_f; +static int test1_g __attribute__((weakref("test1_f"))); +int test1_h(void) { + return test1_g; +} + +// CHECK: @test2_f = common global i32 0, align 4 +int test2_f; +static int test2_g __attribute__((weakref("test2_f"))); +int test2_h(void) { + return test2_g; +} + +// CHECK: @test3_f = external global i32 +extern int test3_f; +static int test3_g __attribute__((weakref("test3_f"))); +int test3_foo(void) { + return test3_f; +} +int test3_h(void) { + return test3_g; +} + +// CHECK: @test4_f = common global i32 0, align 4 +extern int test4_f; +static int test4_g __attribute__((weakref("test4_f"))); +int test4_h(void) { + return test4_g; +} +int test4_f; + +// CHECK: @test5_f = external global i32 +extern int test5_f; +static int test5_g __attribute__((weakref("test5_f"))); +int test5_h(void) { + return test5_g; +} +int test5_foo(void) { + return test5_f; +} + +// CHECK: @test6_f = extern_weak global i32 +extern int test6_f __attribute__((weak)); +static int test6_g __attribute__((weakref("test6_f"))); +int test6_h(void) { + return test6_g; +} +int test6_foo(void) { + return test6_f; +} diff --git a/clang/test/CodeGen/attribute-section-data-common.c b/clang/test/CodeGen/attribute-section-data-common.c new file mode 100644 index 0000000..2393bfb --- /dev/null +++ b/clang/test/CodeGen/attribute-section-data-common.c @@ -0,0 +1,5 @@ +// RUN: %clang -S %s -o /dev/null +struct rtxc_snapshot { + int a, b, c, d; +}; +__attribute__ ((section("__DATA, __common"))) struct rtxc_snapshot rtxc_log_A[4]; diff --git a/clang/test/CodeGen/attribute_constructor.c b/clang/test/CodeGen/attribute_constructor.c new file mode 100644 index 0000000..c82c263 --- /dev/null +++ b/clang/test/CodeGen/attribute_constructor.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | grep llvm.global_ctors + +void foo() __attribute__((constructor)); +void foo() { + bar(); +} diff --git a/clang/test/CodeGen/attributes.c b/clang/test/CodeGen/attributes.c new file mode 100644 index 0000000..4e73af6 --- /dev/null +++ b/clang/test/CodeGen/attributes.c @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu -o %t %s +// RUN: FileCheck --input-file=%t %s + +// CHECK: @t5 = weak global i32 2 +int t5 __attribute__((weak)) = 2; + +// CHECK: @t13 = global %struct.s0 zeroinitializer, section "SECT" +struct s0 { int x; }; +struct s0 t13 __attribute__((section("SECT"))) = { 0 }; + +// CHECK: @t14.x = internal global i32 0, section "SECT" +void t14(void) { + static int x __attribute__((section("SECT"))) = 0; +} + +// CHECK: @t18 = global i32 1, align 4 +extern int t18 __attribute__((weak_import)); +int t18 = 1; + +// CHECK: @t16 = extern_weak global i32 +extern int t16 __attribute__((weak_import)); + +// CHECK: @t6 = common protected global i32 0 +int t6 __attribute__((visibility("protected"))); + +// CHECK: @t12 = global i32 0, section "SECT" +int t12 __attribute__((section("SECT"))); + +// CHECK: @t9 = alias weak bitcast (void ()* @__t8 to void (...)*) +void __t8() {} +void t9() __attribute__((weak, alias("__t8"))); + +// CHECK: declare extern_weak i32 @t15() +int __attribute__((weak_import)) t15(void); +int t17() { + return t15() + t16; +} + +// CHECK: define void @t1() noreturn nounwind { +void t1() __attribute__((noreturn)); +void t1() { while (1) {} } + +// CHECK: define void @t2() nounwind { +void t2() __attribute__((nothrow)); +void t2() {} + +// CHECK: define weak void @t3() nounwind { +void t3() __attribute__((weak)); +void t3() {} + +// CHECK: define hidden void @t4() nounwind { +void t4() __attribute__((visibility("hidden"))); +void t4() {} + +// CHECK: define void @t7() noreturn nounwind { +void t7() __attribute__((noreturn, nothrow)); +void t7() { while (1) {} } + +// CHECK: define void @t10() nounwind section "SECT" { +void t10(void) __attribute__((section("SECT"))); +void t10(void) {} +// CHECK: define void @t11() nounwind section "SECT" { +void __attribute__((section("SECT"))) t11(void) {} + +// CHECK: define i32 @t19() nounwind { +extern int t19(void) __attribute__((weak_import)); +int t19(void) { + return 10; +} + +// CHECK:define void @t20() nounwind { +// CHECK: call void @abort() +// CHECK-NEXT: unreachable +void t20(void) { + __builtin_abort(); +} + +void (__attribute__((fastcall)) *fptr)(int); +void t21(void) { + fptr(10); +} +// CHECK: [[FPTRVAR:%[a-z0-9]+]] = load void (i32)** @fptr +// CHECK-NEXT: call x86_fastcallcc void [[FPTRVAR]](i32 10) diff --git a/clang/test/CodeGen/available-externally-suppress.c b/clang/test/CodeGen/available-externally-suppress.c new file mode 100644 index 0000000..46b6e74 --- /dev/null +++ b/clang/test/CodeGen/available-externally-suppress.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -o - -O0 -triple x86_64-apple-darwin10 %s | FileCheck %s + +// Ensure that we don't emit available_externally functions at -O0. +int x; + +inline void f0(int y) { x = y; } + +// CHECK: define void @test() +// CHECK: declare void @f0(i32) +void test() { + f0(17); +} + +inline int __attribute__((always_inline)) f1(int x) { + int blarg = 0; + for (int i = 0; i < x; ++i) + blarg = blarg + x * i; + return blarg; +} + +// CHECK: @test1 +int test1(int x) { + // CHECK: br i1 + // CHECK-NOT: call {{.*}} @f1 + // CHECK: ret i32 + return f1(x); +} diff --git a/clang/test/CodeGen/avx-builtins.c b/clang/test/CodeGen/avx-builtins.c new file mode 100644 index 0000000..b963c97 --- /dev/null +++ b/clang/test/CodeGen/avx-builtins.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +avx -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <immintrin.h> + +// +// Test LLVM IR codegen of shuffle instructions +// + +__m256 test__mm256_loadu_ps(void* p) { + // CHECK: load <8 x float>* %{{.*}}, align 1 + return _mm256_loadu_ps(p); +} + +__m256d test__mm256_loadu_pd(void* p) { + // CHECK: load <4 x double>* %{{.*}}, align 1 + return _mm256_loadu_pd(p); +} + +__m256i test__mm256_loadu_si256(void* p) { + // CHECK: load <4 x i64>* %{{.+}}, align 1 + return _mm256_loadu_si256(p); +} diff --git a/clang/test/CodeGen/avx-cmp-builtins.c b/clang/test/CodeGen/avx-cmp-builtins.c new file mode 100644 index 0000000..1ac1c31 --- /dev/null +++ b/clang/test/CodeGen/avx-cmp-builtins.c @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +avx -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <immintrin.h> + +// +// Test LLVM IR codegen of cmpXY instructions +// + +__m128d test_cmp_pd(__m128d a, __m128d b) { + // Expects that the third argument in LLVM IR is immediate expression + // CHECK: @llvm.x86.sse2.cmp.pd({{.*}}, i8 13) + return _mm_cmp_pd(a, b, _CMP_GE_OS); +} + +__m128d test_cmp_ps(__m128 a, __m128 b) { + // Expects that the third argument in LLVM IR is immediate expression + // CHECK: @llvm.x86.sse.cmp.ps({{.*}}, i8 13) + return _mm_cmp_ps(a, b, _CMP_GE_OS); +} + +__m256d test_cmp_pd256(__m256d a, __m256d b) { + // Expects that the third argument in LLVM IR is immediate expression + // CHECK: @llvm.x86.avx.cmp.pd.256({{.*}}, i8 13) + return _mm256_cmp_pd(a, b, _CMP_GE_OS); +} + +__m256d test_cmp_ps256(__m256 a, __m256 b) { + // Expects that the third argument in LLVM IR is immediate expression + // CHECK: @llvm.x86.avx.cmp.ps.256({{.*}}, i8 13) + return _mm256_cmp_ps(a, b, _CMP_GE_OS); +} + +__m128d test_cmp_sd(__m128d a, __m128d b) { + // Expects that the third argument in LLVM IR is immediate expression + // CHECK: @llvm.x86.sse2.cmp.sd({{.*}}, i8 13) + return _mm_cmp_sd(a, b, _CMP_GE_OS); +} + +__m128d test_cmp_ss(__m128 a, __m128 b) { + // Expects that the third argument in LLVM IR is immediate expression + // CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 13) + return _mm_cmp_ss(a, b, _CMP_GE_OS); +} diff --git a/clang/test/CodeGen/avx-shuffle-builtins.c b/clang/test/CodeGen/avx-shuffle-builtins.c new file mode 100644 index 0000000..d071f82 --- /dev/null +++ b/clang/test/CodeGen/avx-shuffle-builtins.c @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +avx -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <immintrin.h> + +// +// Test LLVM IR codegen of shuffle instructions +// + +__m256 x(__m256 a, __m256 b) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 8, i32 11, i32 7, i32 6, i32 12, i32 15> + return _mm256_shuffle_ps(a, b, 203); +} + +__m128d test_mm_permute_pd(__m128d a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 1, i32 0> + return _mm_permute_pd(a, 1); +} + +__m256d test_mm256_permute_pd(__m256d a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 1, i32 0, i32 3, i32 2> + return _mm256_permute_pd(a, 5); +} + +__m128 test_mm_permute_ps(__m128 a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 1, i32 0> + return _mm_permute_ps(a, 0x1b); +} + +// Test case for PR12401 +__m128 test_mm_permute_ps2(__m128 a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 2, i32 1, i32 2, i32 3> + return _mm_permute_ps(a, 0xe6); +} + +__m256 test_mm256_permute_ps(__m256 a) { + // Check if the mask is correct + // CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4> + return _mm256_permute_ps(a, 0x1b); +} + +__m256d test_mm256_permute2f128_pd(__m256d a, __m256d b) { + // Check if the mask is correct + // CHECK: @llvm.x86.avx.vperm2f128.pd.256 + return _mm256_permute2f128_pd(a, b, 0x31); +} + +__m256 test_mm256_permute2f128_ps(__m256 a, __m256 b) { + // Check if the mask is correct + // CHECK: @llvm.x86.avx.vperm2f128.ps.256 + return _mm256_permute2f128_ps(a, b, 0x13); +} + +__m256i test_mm256_permute2f128_si256(__m256i a, __m256i b) { + // Check if the mask is correct + // CHECK: @llvm.x86.avx.vperm2f128.si.256 + return _mm256_permute2f128_si256(a, b, 0x20); +} diff --git a/clang/test/CodeGen/avx2-builtins.c b/clang/test/CodeGen/avx2-builtins.c new file mode 100644 index 0000000..7d166b5 --- /dev/null +++ b/clang/test/CodeGen/avx2-builtins.c @@ -0,0 +1,782 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +avx2 -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <immintrin.h> + +__m256i test_mm256_mpsadbw_epu8(__m256i x, __m256i y) { + // CHECK: @llvm.x86.avx2.mpsadbw({{.*}}, {{.*}}, i32 3) + return _mm256_mpsadbw_epu8(x, y, 3); +} + +__m256i test_mm256_abs_epi8(__m256i a) { + // CHECK: @llvm.x86.avx2.pabs.b + return _mm256_abs_epi8(a); +} + +__m256i test_mm256_abs_epi16(__m256i a) { + // CHECK: @llvm.x86.avx2.pabs.w + return _mm256_abs_epi16(a); +} + +__m256i test_mm256_abs_epi32(__m256i a) { + // CHECK: @llvm.x86.avx2.pabs.d + return _mm256_abs_epi32(a); +} + +__m256i test_mm256_packs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.packsswb + return _mm256_packs_epi16(a, b); +} + +__m256i test_mm256_packs_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.packssdw + return _mm256_packs_epi32(a, b); +} + +__m256i test_mm256_packs_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.packuswb + return _mm256_packus_epi16(a, b); +} + +__m256i test_mm256_packs_epu32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.packusdw + return _mm256_packus_epi32(a, b); +} + +__m256i test_mm256_add_epi8(__m256i a, __m256i b) { + // CHECK: add <32 x i8> + return _mm256_add_epi8(a, b); +} + +__m256i test_mm256_add_epi16(__m256i a, __m256i b) { + // CHECK: add <16 x i16> + return _mm256_add_epi16(a, b); +} + +__m256i test_mm256_add_epi32(__m256i a, __m256i b) { + // CHECK: add <8 x i32> + return _mm256_add_epi32(a, b); +} + +__m256i test_mm256_add_epi64(__m256i a, __m256i b) { + // CHECK: add <4 x i64> + return _mm256_add_epi64(a, b); +} + +__m256i test_mm256_adds_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.padds.b + return _mm256_adds_epi8(a, b); +} + +__m256i test_mm256_adds_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.padds.w + return _mm256_adds_epi16(a, b); +} + +__m256i test_mm256_adds_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.paddus.b + return _mm256_adds_epu8(a, b); +} + +__m256i test_mm256_adds_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.paddus.w + return _mm256_adds_epu16(a, b); +} + +__m256i test_mm256_alignr_epi8(__m256i a, __m256i b) { + // CHECK: shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <32 x i32> <i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 32, i32 33, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31, i32 48, i32 49> + return _mm256_alignr_epi8(a, b, 2); +} + +__m256i test2_mm256_alignr_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psrl.dq({{.*}}, i32 8) + return _mm256_alignr_epi8(a, b, 17); +} + +__m256i test_mm256_sub_epi8(__m256i a, __m256i b) { + // CHECK: sub <32 x i8> + return _mm256_sub_epi8(a, b); +} + +__m256i test_mm256_sub_epi16(__m256i a, __m256i b) { + // CHECK: sub <16 x i16> + return _mm256_sub_epi16(a, b); +} + +__m256i test_mm256_sub_epi32(__m256i a, __m256i b) { + // CHECK: sub <8 x i32> + return _mm256_sub_epi32(a, b); +} + +__m256i test_mm256_sub_epi64(__m256i a, __m256i b) { + // CHECK: sub <4 x i64> + return _mm256_sub_epi64(a, b); +} + +__m256i test_mm256_subs_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psubs.b + return _mm256_subs_epi8(a, b); +} + +__m256i test_mm256_subs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psubs.w + return _mm256_subs_epi16(a, b); +} + +__m256i test_mm256_subs_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psubus.b + return _mm256_subs_epu8(a, b); +} + +__m256i test_mm256_subs_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psubus.w + return _mm256_subs_epu16(a, b); +} + +__m256i test_mm256_and_si256(__m256i a, __m256i b) { + // CHECK: and <4 x i64> + return _mm256_and_si256(a, b); +} + +__m256i test_mm256_andnot_si256(__m256i a, __m256i b) { + // CHECK: xor <4 x i64> + // CHECK: and <4 x i64> + return _mm256_andnot_si256(a, b); +} + +__m256i test_mm256_or_si256(__m256i a, __m256i b) { + // CHECK: or <4 x i64> + return _mm256_or_si256(a, b); +} + +__m256i test_mm256_xor_si256(__m256i a, __m256i b) { + // CHECK: xor <4 x i64> + return _mm256_xor_si256(a, b); +} + +__m256i test_mm256_avg_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pavg.b + return _mm256_avg_epu8(a, b); +} + +__m256i test_mm256_avg_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pavg.w + return _mm256_avg_epu16(a, b); +} + +__m256i test_mm256_blendv_epi8(__m256i a, __m256i b, __m256i m) { + // CHECK: @llvm.x86.avx2.pblendvb + return _mm256_blendv_epi8(a, b, m); +} + +__m256i test_mm256_blend_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pblendw(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, i32 2) + return _mm256_blend_epi16(a, b, 2); +} + +__m256i test_mm256_cmpeq_epi8(__m256i a, __m256i b) { + // CHECK: icmp eq <32 x i8> + return _mm256_cmpeq_epi8(a, b); +} + +__m256i test_mm256_cmpeq_epi16(__m256i a, __m256i b) { + // CHECK: icmp eq <16 x i16> + return _mm256_cmpeq_epi16(a, b); +} + +__m256i test_mm256_cmpeq_epi32(__m256i a, __m256i b) { + // CHECK: icmp eq <8 x i32> + return _mm256_cmpeq_epi32(a, b); +} + +__m256i test_mm256_cmpeq_epi64(__m256i a, __m256i b) { + // CHECK: icmp eq <4 x i64> + return _mm256_cmpeq_epi64(a, b); +} + +__m256i test_mm256_cmpgt_epi8(__m256i a, __m256i b) { + // CHECK: icmp sgt <32 x i8> + return _mm256_cmpgt_epi8(a, b); +} + +__m256i test_mm256_cmpgt_epi16(__m256i a, __m256i b) { + // CHECK: icmp sgt <16 x i16> + return _mm256_cmpgt_epi16(a, b); +} + +__m256i test_mm256_cmpgt_epi32(__m256i a, __m256i b) { + // CHECK: icmp sgt <8 x i32> + return _mm256_cmpgt_epi32(a, b); +} + +__m256i test_mm256_cmpgt_epi64(__m256i a, __m256i b) { + // CHECK: icmp sgt <4 x i64> + return _mm256_cmpgt_epi64(a, b); +} + +__m256i test_mm256_hadd_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phadd.w + return _mm256_hadd_epi16(a, b); +} + +__m256i test_mm256_hadd_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phadd.d + return _mm256_hadd_epi32(a, b); +} + +__m256i test_mm256_hadds_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phadd.sw + return _mm256_hadds_epi16(a, b); +} + +__m256i test_mm256_hsub_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phsub.w + return _mm256_hsub_epi16(a, b); +} + +__m256i test_mm256_hsub_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phsub.d + return _mm256_hsub_epi32(a, b); +} + +__m256i test_mm256_hsubs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.phsub.sw + return _mm256_hsubs_epi16(a, b); +} + +__m256i test_mm256_maddubs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmadd.ub.sw + return _mm256_maddubs_epi16(a, b); +} + +__m256i test_mm256_madd_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmadd.wd + return _mm256_madd_epi16(a, b); +} + +__m256i test_mm256_max_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxs.b + return _mm256_max_epi8(a, b); +} + +__m256i test_mm256_max_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxs.w + return _mm256_max_epi16(a, b); +} + +__m256i test_mm256_max_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxs.d + return _mm256_max_epi32(a, b); +} + +__m256i test_mm256_max_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxu.b + return _mm256_max_epu8(a, b); +} + +__m256i test_mm256_max_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxu.w + return _mm256_max_epu16(a, b); +} + +__m256i test_mm256_max_epu32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmaxu.d + return _mm256_max_epu32(a, b); +} + +__m256i test_mm256_min_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmins.b + return _mm256_min_epi8(a, b); +} + +__m256i test_mm256_min_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmins.w + return _mm256_min_epi16(a, b); +} + +__m256i test_mm256_min_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmins.d + return _mm256_min_epi32(a, b); +} + +__m256i test_mm256_min_epu8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pminu.b + return _mm256_min_epu8(a, b); +} + +__m256i test_mm256_min_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pminu.w + return _mm256_min_epu16(a, b); +} + +__m256i test_mm256_min_epu32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pminu.d + return _mm256_min_epu32(a, b); +} + +int test_mm256_movemask_epi8(__m256i a) { + // CHECK: @llvm.x86.avx2.pmovmskb + return _mm256_movemask_epi8(a); +} + +__m256i test_mm256_cvtepi8_epi16(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxbw + return _mm256_cvtepi8_epi16(a); +} + +__m256i test_mm256_cvtepi8_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxbd + return _mm256_cvtepi8_epi32(a); +} + +__m256i test_mm256_cvtepi8_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxbq + return _mm256_cvtepi8_epi64(a); +} + +__m256i test_mm256_cvtepi16_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxwd + return _mm256_cvtepi16_epi32(a); +} + +__m256i test_mm256_cvtepi16_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxwq + return _mm256_cvtepi16_epi64(a); +} + +__m256i test_mm256_cvtepi32_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovsxdq + return _mm256_cvtepi32_epi64(a); +} + +__m256i test_mm256_cvtepu8_epi16(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxbw + return _mm256_cvtepu8_epi16(a); +} + +__m256i test_mm256_cvtepu8_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxbd + return _mm256_cvtepu8_epi32(a); +} + +__m256i test_mm256_cvtepu8_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxbq + return _mm256_cvtepu8_epi64(a); +} + +__m256i test_mm256_cvtepu16_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxwd + return _mm256_cvtepu16_epi32(a); +} + +__m256i test_mm256_cvtepu16_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxwq + return _mm256_cvtepu16_epi64(a); +} + +__m256i test_mm256_cvtepu32_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pmovzxdq + return _mm256_cvtepu32_epi64(a); +} + +__m256i test_mm256_mul_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmul.dq + return _mm256_mul_epi32(a, b); +} + +__m256i test_mm256_mulhrs_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmul.hr.sw + return _mm256_mulhrs_epi16(a, b); +} + +__m256i test_mm256_mulhi_epu16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmulhu.w + return _mm256_mulhi_epu16(a, b); +} + +__m256i test_mm256_mulhi_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmulh.w + return _mm256_mulhi_epi16(a, b); +} + +__m256i test_mm256_mullo_epi16(__m256i a, __m256i b) { + // CHECK: mul <16 x i16> + return _mm256_mullo_epi16(a, b); +} + +__m256i test_mm256_mullo_epi32(__m256i a, __m256i b) { + // CHECK: mul <8 x i32> + return _mm256_mullo_epi32(a, b); +} + +__m256i test_mm256_mul_epu32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pmulu.dq + return _mm256_mul_epu32(a, b); +} + +__m256i test_mm256_shuffle_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pshuf.b + return _mm256_shuffle_epi8(a, b); +} + +__m256i test_mm256_shuffle_epi32(__m256i a) { + // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> undef, <8 x i32> <i32 3, i32 3, i32 0, i32 0, i32 7, i32 7, i32 4, i32 4> + return _mm256_shuffle_epi32(a, 15); +} + +__m256i test_mm256_shufflehi_epi16(__m256i a) { + // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 7, i32 6, i32 6, i32 5, i32 8, i32 9, i32 10, i32 11, i32 15, i32 14, i32 14, i32 13> + return _mm256_shufflehi_epi16(a, 107); +} + +__m256i test_mm256_shufflelo_epi16(__m256i a) { + // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> undef, <16 x i32> <i32 3, i32 0, i32 1, i32 1, i32 4, i32 5, i32 6, i32 7, i32 11, i32 8, i32 9, i32 9, i32 12, i32 13, i32 14, i32 15> + return _mm256_shufflelo_epi16(a, 83); +} + +__m256i test_mm256_sign_epi8(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psign.b + return _mm256_sign_epi8(a, b); +} + +__m256i test_mm256_sign_epi16(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psign.w + return _mm256_sign_epi16(a, b); +} + +__m256i test_mm256_sign_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psign.d + return _mm256_sign_epi32(a, b); +} + +__m256i test_mm256_slli_si256(__m256i a) { + // CHECK: @llvm.x86.avx2.psll.dq + return _mm256_slli_si256(a, 3); +} + +__m256i test_mm256_slli_epi16(__m256i a) { + // CHECK: @llvm.x86.avx2.pslli.w + return _mm256_slli_epi16(a, 3); +} + +__m256i test_mm256_sll_epi16(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psll.w + return _mm256_sll_epi16(a, b); +} + +__m256i test_mm256_slli_epi32(__m256i a) { + // CHECK: @llvm.x86.avx2.pslli.d + return _mm256_slli_epi32(a, 3); +} + +__m256i test_mm256_sll_epi32(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psll.d + return _mm256_sll_epi32(a, b); +} + +__m256i test_mm256_slli_epi64(__m256i a) { + // CHECK: @llvm.x86.avx2.pslli.q + return _mm256_slli_epi64(a, 3); +} + +__m256i test_mm256_sll_epi64(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psll.q + return _mm256_sll_epi64(a, b); +} + +__m256i test_mm256_srai_epi16(__m256i a) { + // CHECK: @llvm.x86.avx2.psrai.w + return _mm256_srai_epi16(a, 3); +} + +__m256i test_mm256_sra_epi16(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psra.w + return _mm256_sra_epi16(a, b); +} + +__m256i test_mm256_srai_epi32(__m256i a) { + // CHECK: @llvm.x86.avx2.psrai.d + return _mm256_srai_epi32(a, 3); +} + +__m256i test_mm256_sra_epi32(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psra.d + return _mm256_sra_epi32(a, b); +} + +__m256i test_mm256_srli_si256(__m256i a) { + // CHECK: @llvm.x86.avx2.psrl.dq + return _mm256_srli_si256(a, 3); +} + +__m256i test_mm256_srli_epi16(__m256i a) { + // CHECK: @llvm.x86.avx2.psrli.w + return _mm256_srli_epi16(a, 3); +} + +__m256i test_mm256_srl_epi16(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrl.w + return _mm256_srl_epi16(a, b); +} + +__m256i test_mm256_srli_epi32(__m256i a) { + // CHECK: @llvm.x86.avx2.psrli.d + return _mm256_srli_epi32(a, 3); +} + +__m256i test_mm256_srl_epi32(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrl.d + return _mm256_srl_epi32(a, b); +} + +__m256i test_mm256_srli_epi64(__m256i a) { + // CHECK: @llvm.x86.avx2.psrli.q + return _mm256_srli_epi64(a, 3); +} + +__m256i test_mm256_srl_epi64(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrl.q + return _mm256_srl_epi64(a, b); +} + +__m256i test_mm256_unpackhi_epi8(__m256i a, __m256i b) { + // CHECK: shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <32 x i32> <i32 8, i32 40, i32 9, i32 41, i32 10, i32 42, i32 11, i32 43, i32 12, i32 44, i32 13, i32 45, i32 14, i32 46, i32 15, i32 47, i32 24, i32 56, i32 25, i32 57, i32 26, i32 58, i32 27, i32 59, i32 28, i32 60, i32 29, i32 61, i32 30, i32 62, i32 31, i32 63> + return _mm256_unpackhi_epi8(a, b); +} + +__m256i test_mm256_unpackhi_epi16(__m256i a, __m256i b) { + // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i32> <i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23, i32 12, i32 28, i32 13, i32 29, i32 14, i32 30, i32 15, i32 31> + return _mm256_unpackhi_epi16(a, b); +} + +__m256i test_mm256_unpackhi_epi32(__m256i a, __m256i b) { + // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> <i32 2, i32 10, i32 3, i32 11, i32 6, i32 14, i32 7, i32 15> + return _mm256_unpackhi_epi32(a, b); +} + +__m256i test_mm256_unpackhi_epi64(__m256i a, __m256i b) { + // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 1, i32 5, i32 3, i32 7> + return _mm256_unpackhi_epi64(a, b); +} + +__m256i test_mm256_unpacklo_epi8(__m256i a, __m256i b) { + // CHECK: shufflevector <32 x i8> %{{.*}}, <32 x i8> %{{.*}}, <32 x i32> <i32 0, i32 32, i32 1, i32 33, i32 2, i32 34, i32 3, i32 35, i32 4, i32 36, i32 5, i32 37, i32 6, i32 38, i32 7, i32 39, i32 16, i32 48, i32 17, i32 49, i32 18, i32 50, i32 19, i32 51, i32 20, i32 52, i32 21, i32 53, i32 22, i32 54, i32 23, i32 55> + return _mm256_unpacklo_epi8(a, b); +} + +__m256i test_mm256_unpacklo_epi16(__m256i a, __m256i b) { + // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i32> <i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 8, i32 24, i32 9, i32 25, i32 10, i32 26, i32 11, i32 27> + return _mm256_unpacklo_epi16(a, b); +} + +__m256i test_mm256_unpacklo_epi32(__m256i a, __m256i b) { + // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> <i32 0, i32 8, i32 1, i32 9, i32 4, i32 12, i32 5, i32 13> + return _mm256_unpacklo_epi32(a, b); +} + +__m256i test_mm256_unpacklo_epi64(__m256i a, __m256i b) { + // CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> %{{.*}}, <4 x i32> <i32 0, i32 4, i32 2, i32 6> + return _mm256_unpacklo_epi64(a, b); +} + +__m256i test_mm256_stream_load_si256(__m256i *a) { + // CHECK: @llvm.x86.avx2.movntdqa + return _mm256_stream_load_si256(a); +} + +__m128 test_mm_broadcastss_ps(__m128 a) { + // CHECK: @llvm.x86.avx2.vbroadcast.ss.ps + return _mm_broadcastss_ps(a); +} + +__m256 test_mm256_broadcastss_ps(__m128 a) { + // CHECK: @llvm.x86.avx2.vbroadcast.ss.ps.256 + return _mm256_broadcastss_ps(a); +} + +__m256d test_mm256_broadcastsd_pd(__m128d a) { + // check: @llvm.x86.avx2.vbroadcast.sd.pd.256 + return _mm256_broadcastsd_pd(a); +} + +__m256i test_mm_broadcastsi128_si256(__m128i *a) { + // CHECK: @llvm.x86.avx2.vbroadcasti128 + return _mm_broadcastsi128_si256(a); +} + +__m128i test_mm_blend_epi32(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.pblendd.128 + return _mm_blend_epi32(a, b, 57); +} + +__m256i test_mm256_blend_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.pblendd.256 + return _mm256_blend_epi32(a, b, 57); +} + +__m256i test_mm256_broadcastb_epi8(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastb.256 + return _mm256_broadcastb_epi8(a); +} + +__m256i test_mm256_broadcastw_epi16(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastw.256 + return _mm256_broadcastw_epi16(a); +} + +__m256i test_mm256_broadcastd_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastd.256 + return _mm256_broadcastd_epi32(a); +} + +__m256i test_mm256_broadcastq_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastq.256 + return _mm256_broadcastq_epi64(a); +} + +__m128i test_mm_broadcastb_epi8(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastb.128 + return _mm_broadcastb_epi8(a); +} + +__m128i test_mm_broadcastw_epi16(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastw.128 + return _mm_broadcastw_epi16(a); +} + +__m128i test_mm_broadcastd_epi32(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastd.128 + return _mm_broadcastd_epi32(a); +} + +__m128i test_mm_broadcastq_epi64(__m128i a) { + // CHECK: @llvm.x86.avx2.pbroadcastq.128 + return _mm_broadcastq_epi64(a); +} + +__m256i test_mm256_permutevar8x32_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.permd + return _mm256_permutevar8x32_epi32(a, b); +} + +__m256d test_mm256_permute4x64_pd(__m256d a) { + // CHECK: shufflevector{{.*}}<i32 1, i32 2, i32 1, i32 0> + return _mm256_permute4x64_pd(a, 25); +} + +__m256 test_mm256_permutevar8x32_ps(__m256 a, __m256 b) { + // CHECK: @llvm.x86.avx2.permps + return _mm256_permutevar8x32_ps(a, b); +} + +__m256i test_mm256_permute4x64_epi64(__m256i a) { + // CHECK: shufflevector{{.*}}<i32 3, i32 0, i32 2, i32 0> + return _mm256_permute4x64_epi64(a, 35); +} + +__m256i test_mm256_permute2x128_si256(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.vperm2i128 + return _mm256_permute2x128_si256(a, b, 0x31); +} + +__m128i test_mm256_extracti128_si256(__m256i a) { + // CHECK: @llvm.x86.avx2.vextracti128 + return _mm256_extracti128_si256(a, 1); +} + +__m256i test_mm256_inserti128_si256(__m256i a, __m128i b) { + // CHECK: @llvm.x86.avx2.vinserti128 + return _mm256_inserti128_si256(a, b, 1); +} + +__m256i test_mm256_maskload_epi32(int const *a, __m256i m) { + // CHECK: @llvm.x86.avx2.maskload.d.256 + return _mm256_maskload_epi32(a, m); +} + +__m256i test_mm256_maskload_epi64(long long const *a, __m256i m) { + // CHECK: @llvm.x86.avx2.maskload.q.256 + return _mm256_maskload_epi64(a, m); +} + +__m128i test_mm_maskload_epi32(int const *a, __m128i m) { + // CHECK: @llvm.x86.avx2.maskload.d + return _mm_maskload_epi32(a, m); +} + +__m128i test_mm_maskload_epi64(long long const *a, __m128i m) { + // CHECK: @llvm.x86.avx2.maskload.q + return _mm_maskload_epi64(a, m); +} + +void test_mm256_maskstore_epi32(int *a, __m256i m, __m256i b) { + // CHECK: @llvm.x86.avx2.maskstore.d.256 + _mm256_maskstore_epi32(a, m, b); +} + +void test_mm256_maskstore_epi64(long long *a, __m256i m, __m256i b) { + // CHECK: @llvm.x86.avx2.maskstore.q.256 + _mm256_maskstore_epi64(a, m, b); +} + +void test_mm_maskstore_epi32(int *a, __m128i m, __m128i b) { + // CHECK: @llvm.x86.avx2.maskstore.d + _mm_maskstore_epi32(a, m, b); +} + +void test_mm_maskstore_epi64(long long *a, __m128i m, __m128i b) { + // CHECK: @llvm.x86.avx2.maskstore.q + _mm_maskstore_epi64(a, m, b); +} + +__m256i test_mm256_sllv_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psllv.d.256 + return _mm256_sllv_epi32(a, b); +} + +__m128i test_mm_sllv_epi32(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psllv.d + return _mm_sllv_epi32(a, b); +} + +__m256i test_mm256_sllv_epi64(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psllv.q.256 + return _mm256_sllv_epi64(a, b); +} + +__m128i test_mm_sllv_epi64(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psllv.q + return _mm_sllv_epi64(a, b); +} + +__m256i test_mm256_srav_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psrav.d.256 + return _mm256_srav_epi32(a, b); +} + +__m128i test_mm_srav_epi32(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrav.d + return _mm_srav_epi32(a, b); +} + +__m256i test_mm256_srlv_epi32(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psrlv.d.256 + return _mm256_srlv_epi32(a, b); +} + +__m128i test_mm_srlv_epi32(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrlv.d + return _mm_srlv_epi32(a, b); +} + +__m256i test_mm256_srlv_epi64(__m256i a, __m256i b) { + // CHECK: @llvm.x86.avx2.psrlv.q.256 + return _mm256_srlv_epi64(a, b); +} + +__m128i test_mm_srlv_epi64(__m128i a, __m128i b) { + // CHECK: @llvm.x86.avx2.psrlv.q + return _mm_srlv_epi64(a, b); +} diff --git a/clang/test/CodeGen/bitfield-2.c b/clang/test/CodeGen/bitfield-2.c new file mode 100644 index 0000000..69ed5b1 --- /dev/null +++ b/clang/test/CodeGen/bitfield-2.c @@ -0,0 +1,368 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64 -O3 -o %t.opt.ll %s \ +// RUN: -fdump-record-layouts 2> %t.dump.txt +// RUN: FileCheck -check-prefix=CHECK-RECORD < %t.dump.txt %s +// RUN: FileCheck -check-prefix=CHECK-OPT < %t.opt.ll %s + +/****/ + +// Check that we don't read off the end a packed 24-bit structure. +// PR6176 + +// CHECK-RECORD: *** Dumping IRgen Record Layout +// CHECK-RECORD: Record: struct s0 +// CHECK-RECORD: Layout: <CGRecordLayout +// CHECK-RECORD: LLVMType:%struct.s0 = type <{ [3 x i8] }> +// CHECK-RECORD: IsZeroInitializable:1 +// CHECK-RECORD: BitFields:[ +// CHECK-RECORD: <CGBitFieldInfo Size:24 IsSigned:1 +// CHECK-RECORD: NumComponents:2 Components: [ +// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16 +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:16> +// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8 +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:16 TargetBitWidth:8> +struct __attribute((packed)) s0 { + int f0 : 24; +}; + +struct s0 g0 = { 0xdeadbeef }; + +int f0_load(struct s0 *a0) { + int size_check[sizeof(struct s0) == 3 ? 1 : -1]; + return a0->f0; +} +int f0_store(struct s0 *a0) { + return (a0->f0 = 1); +} +int f0_reload(struct s0 *a0) { + return (a0->f0 += 1); +} + +// CHECK-OPT: define i64 @test_0() +// CHECK-OPT: ret i64 1 +// CHECK-OPT: } +unsigned long long test_0() { + struct s0 g0 = { 0xdeadbeef }; + unsigned long long res = 0; + res ^= g0.f0; + res ^= f0_load(&g0) ^ f0_store(&g0) ^ f0_reload(&g0); + res ^= g0.f0; + return res; +} + +/****/ + +// PR5591 + +// CHECK-RECORD: *** Dumping IRgen Record Layout +// CHECK-RECORD: Record: struct s1 +// CHECK-RECORD: Layout: <CGRecordLayout +// CHECK-RECORD: LLVMType:%struct.s1 = type <{ [2 x i8], i8 }> +// CHECK-RECORD: IsZeroInitializable:1 +// CHECK-RECORD: BitFields:[ +// CHECK-RECORD: <CGBitFieldInfo Size:10 IsSigned:1 +// CHECK-RECORD: NumComponents:1 Components: [ +// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16 +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:10> +// CHECK-RECORD: ]> +// CHECK-RECORD: <CGBitFieldInfo Size:10 IsSigned:1 +// CHECK-RECORD: NumComponents:2 Components: [ +// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:10 AccessWidth:16 +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:6> +// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8 +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:6 TargetBitWidth:4> + +#pragma pack(push) +#pragma pack(1) +struct __attribute((packed)) s1 { + signed f0 : 10; + signed f1 : 10; +}; +#pragma pack(pop) + +struct s1 g1 = { 0xdeadbeef, 0xdeadbeef }; + +int f1_load(struct s1 *a0) { + int size_check[sizeof(struct s1) == 3 ? 1 : -1]; + return a0->f1; +} +int f1_store(struct s1 *a0) { + return (a0->f1 = 1234); +} +int f1_reload(struct s1 *a0) { + return (a0->f1 += 1234); +} + +// CHECK-OPT: define i64 @test_1() +// CHECK-OPT: ret i64 210 +// CHECK-OPT: } +unsigned long long test_1() { + struct s1 g1 = { 0xdeadbeef, 0xdeadbeef }; + unsigned long long res = 0; + res ^= g1.f0 ^ g1.f1; + res ^= f1_load(&g1) ^ f1_store(&g1) ^ f1_reload(&g1); + res ^= g1.f0 ^ g1.f1; + return res; +} + +/****/ + +// Check that we don't access beyond the bounds of a union. +// +// PR5567 + +// CHECK-RECORD: *** Dumping IRgen Record Layout +// CHECK-RECORD: Record: union u2 +// CHECK-RECORD: Layout: <CGRecordLayout +// CHECK-RECORD: LLVMType:%union.u2 = type <{ i8 }> +// CHECK-RECORD: IsZeroInitializable:1 +// CHECK-RECORD: BitFields:[ +// CHECK-RECORD: <CGBitFieldInfo Size:3 IsSigned:0 +// CHECK-RECORD: NumComponents:1 Components: [ +// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:8 +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:3> + +union __attribute__((packed)) u2 { + unsigned long long f0 : 3; +}; + +union u2 g2 = { 0xdeadbeef }; + +int f2_load(union u2 *a0) { + return a0->f0; +} +int f2_store(union u2 *a0) { + return (a0->f0 = 1234); +} +int f2_reload(union u2 *a0) { + return (a0->f0 += 1234); +} + +// CHECK-OPT: define i64 @test_2() +// CHECK-OPT: ret i64 2 +// CHECK-OPT: } +unsigned long long test_2() { + union u2 g2 = { 0xdeadbeef }; + unsigned long long res = 0; + res ^= g2.f0; + res ^= f2_load(&g2) ^ f2_store(&g2) ^ f2_reload(&g2); + res ^= g2.f0; + return res; +} + +/***/ + +// PR5039 + +struct s3 { + long long f0 : 32; + long long f1 : 32; +}; + +struct s3 g3 = { 0xdeadbeef, 0xdeadbeef }; + +int f3_load(struct s3 *a0) { + a0->f0 = 1; + return a0->f0; +} +int f3_store(struct s3 *a0) { + a0->f0 = 1; + return (a0->f0 = 1234); +} +int f3_reload(struct s3 *a0) { + a0->f0 = 1; + return (a0->f0 += 1234); +} + +// CHECK-OPT: define i64 @test_3() +// CHECK-OPT: ret i64 -559039940 +// CHECK-OPT: } +unsigned long long test_3() { + struct s3 g3 = { 0xdeadbeef, 0xdeadbeef }; + unsigned long long res = 0; + res ^= g3.f0 ^ g3.f1; + res ^= f3_load(&g3) ^ f3_store(&g3) ^ f3_reload(&g3); + res ^= g3.f0 ^ g3.f1; + return res; +} + +/***/ + +// This is a case where the bitfield access will straddle an alignment boundary +// of its underlying type. + +struct s4 { + unsigned f0 : 16; + unsigned f1 : 28 __attribute__ ((packed)); +}; + +struct s4 g4 = { 0xdeadbeef, 0xdeadbeef }; + +int f4_load(struct s4 *a0) { + return a0->f0 ^ a0->f1; +} +int f4_store(struct s4 *a0) { + return (a0->f0 = 1234) ^ (a0->f1 = 5678); +} +int f4_reload(struct s4 *a0) { + return (a0->f0 += 1234) ^ (a0->f1 += 5678); +} + +// CHECK-OPT: define i64 @test_4() +// CHECK-OPT: ret i64 4860 +// CHECK-OPT: } +unsigned long long test_4() { + struct s4 g4 = { 0xdeadbeef, 0xdeadbeef }; + unsigned long long res = 0; + res ^= g4.f0 ^ g4.f1; + res ^= f4_load(&g4) ^ f4_store(&g4) ^ f4_reload(&g4); + res ^= g4.f0 ^ g4.f1; + return res; +} + +/***/ + +struct s5 { + unsigned f0 : 2; + _Bool f1 : 1; + _Bool f2 : 1; +}; + +struct s5 g5 = { 0xdeadbeef, 0xdeadbeef }; + +int f5_load(struct s5 *a0) { + return a0->f0 ^ a0->f1; +} +int f5_store(struct s5 *a0) { + return (a0->f0 = 0xF) ^ (a0->f1 = 0xF) ^ (a0->f2 = 0xF); +} +int f5_reload(struct s5 *a0) { + return (a0->f0 += 0xF) ^ (a0->f1 += 0xF) ^ (a0->f2 += 0xF); +} + +// CHECK-OPT: define i64 @test_5() +// CHECK-OPT: ret i64 2 +// CHECK-OPT: } +unsigned long long test_5() { + struct s5 g5 = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }; + unsigned long long res = 0; + res ^= g5.f0 ^ g5.f1 ^ g5.f2; + res ^= f5_load(&g5) ^ f5_store(&g5) ^ f5_reload(&g5); + res ^= g5.f0 ^ g5.f1 ^ g5.f2; + return res; +} + +/***/ + +struct s6 { + _Bool f0 : 2; +}; + +struct s6 g6 = { 0xF }; + +int f6_load(struct s6 *a0) { + return a0->f0; +} +int f6_store(struct s6 *a0) { + return a0->f0 = 0x0; +} +int f6_reload(struct s6 *a0) { + return (a0->f0 += 0xF); +} + +// CHECK-OPT: define zeroext i1 @test_6() +// CHECK-OPT: ret i1 true +// CHECK-OPT: } +_Bool test_6() { + struct s6 g6 = { 0xF }; + unsigned long long res = 0; + res ^= g6.f0; + res ^= f6_load(&g6); + res ^= g6.f0; + return res; +} + +/***/ + +// Check that we compute the best alignment possible for each access. +// +// CHECK-RECORD: *** Dumping IRgen Record Layout +// CHECK-RECORD: Record: struct s7 +// CHECK-RECORD: Layout: <CGRecordLayout +// CHECK-RECORD: LLVMType:%struct.s7 = type { i32, i32, i32, i8, [3 x i8], [4 x i8], [12 x i8] } +// CHECK-RECORD: IsZeroInitializable:1 +// CHECK-RECORD: BitFields:[ +// CHECK-RECORD: <CGBitFieldInfo Size:5 IsSigned:1 +// CHECK-RECORD: NumComponents:1 Components: [ +// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:12 FieldBitStart:0 AccessWidth:32 +// CHECK-RECORD: AccessAlignment:4 TargetBitOffset:0 TargetBitWidth:5> +// CHECK-RECORD: ]> +// CHECK-RECORD: <CGBitFieldInfo Size:29 IsSigned:1 +// CHECK-RECORD: NumComponents:1 Components: [ +// CHECK-RECORD: <AccessInfo FieldIndex:0 FieldByteOffset:16 FieldBitStart:0 AccessWidth:32 +// CHECK-RECORD: AccessAlignment:16 TargetBitOffset:0 TargetBitWidth:29> + +struct __attribute__((aligned(16))) s7 { + int a, b, c; + int f0 : 5; + int f1 : 29; +}; + +int f7_load(struct s7 *a0) { + return a0->f0; +} + +/***/ + +// This is a case where we narrow the access width immediately. + +struct __attribute__((packed)) s8 { + char f0 : 4; + char f1; + int f2 : 4; + char f3 : 4; +}; + +struct s8 g8 = { 0xF }; + +int f8_load(struct s8 *a0) { + return a0->f0 ^ a0 ->f2 ^ a0->f3; +} +int f8_store(struct s8 *a0) { + return (a0->f0 = 0xFD) ^ (a0->f2 = 0xFD) ^ (a0->f3 = 0xFD); +} +int f8_reload(struct s8 *a0) { + return (a0->f0 += 0xFD) ^ (a0->f2 += 0xFD) ^ (a0->f3 += 0xFD); +} + +// CHECK-OPT: define i32 @test_8() +// CHECK-OPT: ret i32 -3 +// CHECK-OPT: } +unsigned test_8() { + struct s8 g8 = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }; + unsigned long long res = 0; + res ^= g8.f0 ^ g8.f2 ^ g8.f3; + res ^= f8_load(&g8) ^ f8_store(&g8) ^ f8_reload(&g8); + res ^= g8.f0 ^ g8.f2 ^ g8.f3; + return res; +} + +/***/ + +// This is another case where we narrow the access width immediately. +// +// <rdar://problem/7893760> + +struct __attribute__((packed)) s9 { + unsigned f0 : 7; + unsigned f1 : 7; + unsigned f2 : 7; + unsigned f3 : 7; + unsigned f4 : 7; + unsigned f5 : 7; + unsigned f6 : 7; + unsigned f7 : 7; +}; + +int f9_load(struct s9 *a0) { + return a0->f7; +} diff --git a/clang/test/CodeGen/bitfield-assign.c b/clang/test/CodeGen/bitfield-assign.c new file mode 100644 index 0000000..b8ab613 --- /dev/null +++ b/clang/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_cc1 -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_cc1 -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/clang/test/CodeGen/bitfield-init.c b/clang/test/CodeGen/bitfield-init.c new file mode 100644 index 0000000..bee4e7d --- /dev/null +++ b/clang/test/CodeGen/bitfield-init.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/bitfield-promote.c b/clang/test/CodeGen/bitfield-promote.c new file mode 100644 index 0000000..4c3292c --- /dev/null +++ b/clang/test/CodeGen/bitfield-promote.c @@ -0,0 +1,18 @@ +// 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 + +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/clang/test/CodeGen/bitfield.c b/clang/test/CodeGen/bitfield.c new file mode 100644 index 0000000..dea5e43 --- /dev/null +++ b/clang/test/CodeGen/bitfield.c @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/block-3.c b/clang/test/CodeGen/block-3.c new file mode 100644 index 0000000..95cb6a7 --- /dev/null +++ b/clang/test/CodeGen/block-3.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks -triple x86_64-apple-darwin10 +// rdar://10001085 + +int main() { + ^{ + __attribute__((__blocks__(byref))) int index = ({ int __a; int __b; __a < __b ? __b : __a; }); + }; +} diff --git a/clang/test/CodeGen/block-byref-aggr.c b/clang/test/CodeGen/block-byref-aggr.c new file mode 100644 index 0000000..3027df0 --- /dev/null +++ b/clang/test/CodeGen/block-byref-aggr.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks -triple x86_64-apple-darwin10 | FileCheck %s +// rdar://9309454 + +typedef struct { int v; } RetType; + +RetType func(); + +int main () { + __attribute__((__blocks__(byref))) RetType a = {100}; + + a = func(); +} +// CHECK: [[C1:%.*]] = call i32 (...)* @func() +// CHECK-NEXT: [[CO:%.*]] = getelementptr +// CHECK-NEXT: store i32 [[C1]], i32* [[CO]] +// CHECK-NEXT: [[FORWARDING:%.*]] = getelementptr inbounds [[BR:%.*]]* [[A:%.*]], i32 0, i32 1 +// CHECK-NEXT: [[O:%.*]] = load [[BR]]** [[FORWARDING]] diff --git a/clang/test/CodeGen/block-copy.c b/clang/test/CodeGen/block-copy.c new file mode 100644 index 0000000..fba76ad --- /dev/null +++ b/clang/test/CodeGen/block-copy.c @@ -0,0 +1,20 @@ +/* RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + + This should compile into a memcpy from a global, not 128 stores. */ + + + +void foo(); + +float bar() { + float lookupTable[] = {-1,-1,-1,0, -1,-1,0,-1, -1,-1,0,1, -1,-1,1,0, + -1,0,-1,-1, -1,0,-1,1, -1,0,1,-1, -1,0,1,1, + -1,1,-1,0, -1,1,0,-1, -1,1,0,1, -1,1,1,0, + 0,-1,-1,-1, 0,-1,-1,1, 0,-1,1,-1, 0,-1,1,1, + 1,-1,-1,0, 1,-1,0,-1, 1,-1,0,1, 1,-1,1,0, + 1,0,-1,-1, 1,0,-1,1, 1,0,1,-1, 1,0,1,1, + 1,1,-1,0, 1,1,0,-1, 1,1,0,1, 1,1,1,0, + 0,1,-1,-1, 0,1,-1,1, 0,1,1,-1, 0,1,1,1}; + // CHECK: memcpy + foo(lookupTable); +} diff --git a/clang/test/CodeGen/blocks-1.c b/clang/test/CodeGen/blocks-1.c new file mode 100644 index 0000000..350f7a3 --- /dev/null +++ b/clang/test/CodeGen/blocks-1.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t -fblocks +// RUN: grep "_Block_object_dispose" %t | count 17 +// RUN: grep "__copy_helper_block_" %t | count 14 +// RUN: grep "__destroy_helper_block_" %t | count 14 +// RUN: grep "__Block_byref_object_copy_" %t | count 2 +// RUN: grep "__Block_byref_object_dispose_" %t | count 2 +// RUN: grep "i32 135)" %t | count 2 +// RUN: grep "_Block_object_assign" %t | count 10 + +int printf(const char *, ...); + +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); }(); // needs copy/dispose + 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); + ^{ // needs copy/dispose + ^{ // needs copy/dispose + 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;}(); // needs copy/dispose +} + +int test4() { + extern int g; + static int i = 1; + ^(int j){ i = j; g = 0; }(0); // does not need copy/dispose + return i + g; +} + +int g; + +void test5() { + __block struct { int i; } i; + ^{ (void)i; }(); // needs copy/dispose +} + +void test6() { + __block int i; + ^{ i=1; }(); // needs copy/dispose + ^{}(); // does not need copy/dispose +} + +void test7() { + ^{ // does not need copy/dispose + __block int i; + ^{ i = 1; }(); // needs copy/dispose + }(); +} + +int main() { + int rv = 0; + test1(); + test2(); + test3(); + rv += test4(); + test5(); + return rv; +} diff --git a/clang/test/CodeGen/blocks-2.c b/clang/test/CodeGen/blocks-2.c new file mode 100644 index 0000000..4e574da --- /dev/null +++ b/clang/test/CodeGen/blocks-2.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -g %s -emit-llvm -o %t -fblocks +// RUN: grep "func.start" %t | count 4 +// RUN: %clang_cc1 -g %s -triple i386-unknown-unknown -emit-llvm -o %t -fblocks -fblock-introspection +// RUN: grep "v8@?0i4" %t | count 1 +// RUN: %clang_cc1 -g %s -triple i386-unknown-unknown -emit-llvm -o %t -fblocks +// RUN: grep "v8@?0i4" %t | count 0 +// 1 declaration, 1 bar, 1 test_block_dbg and 1 for the block. +// XFAIL: * + +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/clang/test/CodeGen/blocks-aligned-byref-variable.c b/clang/test/CodeGen/blocks-aligned-byref-variable.c new file mode 100644 index 0000000..07d683c --- /dev/null +++ b/clang/test/CodeGen/blocks-aligned-byref-variable.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-apple-darwin10 -fblocks %s +// RUN: %clang_cc1 -emit-llvm -o - -triple i386-apple-darwin10 -fblocks %s +typedef int __attribute__((aligned(32))) ai; + +void f() { + __block ai a = 10; + + ^{ + a = 20; + }(); +} + +void g() { + __block double a = 10; + + ^{ + a = 20; + }(); +} diff --git a/clang/test/CodeGen/blocks-seq.c b/clang/test/CodeGen/blocks-seq.c new file mode 100644 index 0000000..3557b48 --- /dev/null +++ b/clang/test/CodeGen/blocks-seq.c @@ -0,0 +1,18 @@ +// FIXME: We forcibly strip the names so that the test doesn't vary between +// builds with and without asserts. We need a better solution for this. + +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -emit-llvm-bc -o - %s | opt -strip | llvm-dis > %t +// RUN: grep '%6 = call i32 (...)\* @rhs()' %t | count 1 +// RUN: grep '%7 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 +// RUN: grep '%8 = load %0\*\* %7' %t | count 1 +// RUN: grep '%10 = call i32 (...)\* @rhs()' %t | count 1 +// RUN: grep '%11 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 +// RUN: grep '%12 = load %0\*\* %11' %t | count 1 + +int rhs(); + +void foo() { + __block int i; + i = rhs(); + i += rhs(); +} diff --git a/clang/test/CodeGen/blocks.c b/clang/test/CodeGen/blocks.c new file mode 100644 index 0000000..bef44c3 --- /dev/null +++ b/clang/test/CodeGen/blocks.c @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - -fblocks | FileCheck %s +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]; +}; + +// CHECK: define internal void @__f2_block_invoke_0(%struct.s0* noalias sret {{%.*}}, i8* {{%.*}}, %struct.s0* byval align 4 {{.*}}) +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; }(); +}; + +typedef double ftype(double); +// It's not clear that we *should* support this syntax, but until that decision +// is made, we should support it properly and not crash. +ftype ^test2 = ^ftype { + return 0; +}; + +// rdar://problem/8605032 +void f3_helper(void (^)(void)); +void f3() { + _Bool b = 0; + f3_helper(^{ if (b) {} }); +} diff --git a/clang/test/CodeGen/blocksignature.c b/clang/test/CodeGen/blocksignature.c new file mode 100644 index 0000000..63fe124 --- /dev/null +++ b/clang/test/CodeGen/blocksignature.c @@ -0,0 +1,96 @@ +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64 +// RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32 + +// X64: @.str = private unnamed_addr constant [6 x i8] c"v8@?0\00" +// X64: @__block_literal_global = internal constant {{.*}} { i8** @_NSConcreteGlobalBlock, i32 1342177280, +// X64: @.str1 = private unnamed_addr constant [12 x i8] c"i16@?0c8f12\00" +// X64: store i32 1073741824, i32* + +// X32: [[STR1:@.*]] = private unnamed_addr constant [6 x i8] c"v4@?0\00" +// X32: @__block_descriptor_tmp = internal constant [[FULL_DESCRIPTOR_T:.*]] { i32 0, i32 20, i8* getelementptr inbounds ([6 x i8]* [[STR1]], i32 0, i32 0), i8* null } +// X32: @__block_literal_global = internal constant [[GLOBAL_LITERAL_T:.*]] { i8** @_NSConcreteGlobalBlock, i32 1342177280, i32 0, i8* bitcast (void (i8*)* @__block_global_{{.*}} to i8*), [[DESCRIPTOR_T:%.*]]* bitcast ([[FULL_DESCRIPTOR_T]]* @__block_descriptor_tmp to {{%.*}}*) } +// X32: [[STR2:@.*]] = private unnamed_addr constant [11 x i8] c"i12@?0c4f8\00" +// X32: @__block_descriptor_tmp{{.*}} = internal constant [[FULL_DESCRIPTOR_T]] { i32 0, i32 24, i8* getelementptr inbounds ([11 x i8]* [[STR2]], i32 0, i32 0), i8* null } +// X32: store i32 1073741824, i32* + +// rdar://7635294 + + +int globalInt; +void (^global)(void) = ^{ ++globalInt; }; + + +void foo(int param) { + extern int rand(void); + extern void rand_r(int (^b)(char x, float y)); // name a function present at runtime + while (param--) + rand_r(^(char x, float y){ return x + (int)y + param + rand(); }); // generate a local block binding param +} + +#if 0 +#include <stdio.h> +enum { + BLOCK_HAS_COPY_DISPOSE = (1 << 25), + BLOCK_HAS_CXX_OBJ = (1 << 26), + BLOCK_IS_GLOBAL = (1 << 28), + BLOCK_HAS_DESCRIPTOR = (1 << 29), + BLOCK_HAS_OBJC_TYPE = (1 << 30) +}; + +struct block_descriptor_big { + unsigned long int reserved; + unsigned long int size; + void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE + void (*dispose)(void *); // conditional on BLOCK_HAS_COPY_DISPOSE + const char *signature; // conditional on BLOCK_HAS_OBJC + const char *layout; // conditional on BLOCK_HAS_OBJC +}; +struct block_descriptor_small { + unsigned long int reserved; + unsigned long int size; + const char *signature; // conditional on BLOCK_HAS_OBJC + const char *layout; // conditional on BLOCK_HAS_OBJC +}; + +struct block_layout_abi { // can't change + void *isa; + int flags; + int reserved; + void (*invoke)(void *, ...); + struct block_descriptor_big *descriptor; +}; + +const char *getBlockSignature(void *block) { + struct block_layout_abi *layout = (struct block_layout_abi *)block; + if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return NULL; + if (layout->flags & BLOCK_HAS_COPY_DISPOSE) + return layout->descriptor->signature; + else + return ((struct block_descriptor_small *)layout->descriptor)->signature; +} + + + +int main(int argc, char *argv[]) { + printf("desired global flags: %d\n", BLOCK_IS_GLOBAL | BLOCK_HAS_OBJC_TYPE); + printf("desired stack flags: %d\n", BLOCK_HAS_OBJC_TYPE); + + printf("types for global: %s\n", getBlockSignature(global)); + printf("types for local: %s\n", getBlockSignature(^int(char x, float y) { return (int)(y + x); })); + return 0; +} + +/* +x86_64 +desired global flags: 1342177280 +desired stack flags: 1073741824 +types for global: v8@?0 +types for local: i16@?0c8f12 + +i386 +desired global flags: 1342177280 +desired stack flags: 1073741824 +types for global: v4@?0 +types for local: i12@?0c4f8 +*/ +#endif diff --git a/clang/test/CodeGen/blockstret.c b/clang/test/CodeGen/blockstret.c new file mode 100644 index 0000000..d5dae6f --- /dev/null +++ b/clang/test/CodeGen/blockstret.c @@ -0,0 +1,106 @@ +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64 +// RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32 + +// X64: internal constant {{.*}} { i8** @_NSConcreteGlobalBlock, i32 1879048192 +// X64: store i32 1610612736, i32* %want + +// X32: @_NSConcreteGlobalBlock, i32 1879048192, i32 0, +// X32: store i32 1610612736, i32* %want + +// rdar://7677537 +int printf(const char *, ...); +void *malloc(__SIZE_TYPE__ size); + +typedef struct bigbig { + int array[512]; + char more[32]; +} BigStruct_t; + +BigStruct_t (^global)(void) = ^{ return *(BigStruct_t *)malloc(sizeof(struct bigbig)); }; + +const char * getBlockSignature(void *); + +BigStruct_t foo(int param) { + BigStruct_t x; + BigStruct_t (^f)(int) = ^(int param) { + BigStruct_t *result = malloc(sizeof(BigStruct_t)); + result->array[23] = param; + return *result; + }; + getBlockSignature(f); + return x; +} + +enum { + BLOCK_HAS_COPY_DISPOSE = (1 << 25), + BLOCK_HAS_CXX_OBJ = (1 << 26), + BLOCK_IS_GLOBAL = (1 << 28), + BLOCK_USE_STRET = (1 << 29), + BLOCK_HAS_OBJC_TYPE = (1 << 30) +}; + +struct block_descriptor_big { + unsigned long int reserved; + unsigned long int size; + void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE + void (*dispose)(void *); // conditional on BLOCK_HAS_COPY_DISPOSE + const char *signature; // conditional on BLOCK_HAS_OBJC + const char *layout; // conditional on BLOCK_HAS_OBJC +}; +struct block_descriptor_small { + unsigned long int reserved; + unsigned long int size; + const char *signature; // conditional on BLOCK_HAS_OBJC + const char *layout; // conditional on BLOCK_HAS_OBJC +}; + +struct block_layout_abi { // can't change + void *isa; + int flags; + int reserved; + void (*invoke)(void *, ...); + struct block_descriptor_big *descriptor; +}; + +const char *getBlockSignature(void *block) { + struct block_layout_abi *layout = (struct block_layout_abi *)block; + if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return 0; + if (layout->flags & BLOCK_HAS_COPY_DISPOSE) + return layout->descriptor->signature; + else + return ((struct block_descriptor_small *)layout->descriptor)->signature; +} + +int usesStruct(void *block) { + struct block_layout_abi *layout = (struct block_layout_abi *)block; + int want = BLOCK_HAS_OBJC_TYPE | BLOCK_USE_STRET; + return (layout->flags & want) == want; +} + + +int main(int argc, char *argv[]) { + printf("desired global flags: %d\n", BLOCK_USE_STRET | BLOCK_IS_GLOBAL | BLOCK_HAS_OBJC_TYPE); + printf("desired stack flags: %d\n", BLOCK_USE_STRET | BLOCK_HAS_OBJC_TYPE); + + printf("should be non-zero: %d\n", usesStruct(global)); + BigStruct_t x; + BigStruct_t (^local)(int) = ^(int param) { + BigStruct_t *result = (BigStruct_t *)malloc(sizeof(BigStruct_t)); + result->array[23] = argc; + return *result; + }; + printf("should be non-zero: %d\n", usesStruct(global)); + printf("should be non-zero: %d\n", usesStruct(local)); + printf("should be zero: %d\n", usesStruct(^void(int x){ })); + return 0; +} + +/* +desired global flags: 1879048192 +desired stack flags: 1610612736 +should be non-zero: 1 +should be non-zero: 1 +should be non-zero: 1 +should be zero: 0 + +*/ diff --git a/clang/test/CodeGen/blockwithlocalstatic.c b/clang/test/CodeGen/blockwithlocalstatic.c new file mode 100644 index 0000000..1fdaaf3 --- /dev/null +++ b/clang/test/CodeGen/blockwithlocalstatic.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -emit-llvm -o - %s | FileCheck %s +// pr8707 + +// CHECK: @__block_global_0.test = internal global i32 +int (^block)(void) = ^ { + static int test=0; + return test; +}; +// CHECK: @__block_global_1.test = internal global i32 +void (^block1)(void) = ^ { + static int test = 2; + return; +}; +// CHECK: @__block_global_2.test = internal global i32 +int (^block2)(void) = ^ { + static int test = 5; + return test; +}; + diff --git a/clang/test/CodeGen/bmi-builtins.c b/clang/test/CodeGen/bmi-builtins.c new file mode 100644 index 0000000..47b0da2 --- /dev/null +++ b/clang/test/CodeGen/bmi-builtins.c @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +bmi -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +unsigned short test__tzcnt16(unsigned short __X) { + // CHECK: @llvm.cttz.i16 + return __tzcnt16(__X); +} + +unsigned int test__andn_u32(unsigned int __X, unsigned int __Y) { + // CHECK: [[DEST:%.*]] = xor i32 %{{.*}}, -1 + // CHECK-NEXT: %{{.*}} = and i32 %{{.*}}, [[DEST]] + return __andn_u32(__X, __Y); +} + +unsigned int test__bextr_u32(unsigned int __X, unsigned int __Y) { + // CHECK: @llvm.x86.bmi.bextr.32 + return __bextr_u32(__X, __Y); +} + +unsigned int test__blsi_u32(unsigned int __X) { + // CHECK: [[DEST:%.*]] = sub i32 0, [[SRC:%.*]] + // CHECK-NEXT: %{{.*}} = and i32 [[SRC]], [[DEST]] + return __blsi_u32(__X); +} + +unsigned int test__blsmsk_u32(unsigned int __X) { + // CHECK: [[DEST:%.*]] = add i32 [[SRC:%.*]], -1 + // CHECK-NEXT: %{{.*}} = xor i32 [[DEST]], [[SRC]] + return __blsmsk_u32(__X); +} + +unsigned int test__blsr_u32(unsigned int __X) { + // CHECK: [[DEST:%.*]] = add i32 [[SRC:%.*]], -1 + // CHECK-NEXT: %{{.*}} = and i32 [[DEST]], [[SRC]] + return __blsr_u32(__X); +} + +unsigned int test_tzcnt32(unsigned int __X) { + // CHECK: @llvm.cttz.i32 + return __tzcnt32(__X); +} + +unsigned long long test__andn_u64(unsigned long __X, unsigned long __Y) { + // CHECK: [[DEST:%.*]] = xor i64 %{{.*}}, -1 + // CHECK-NEXT: %{{.*}} = and i64 %{{.*}}, [[DEST]] + return __andn_u64(__X, __Y); +} + +unsigned long long test__bextr_u64(unsigned long __X, unsigned long __Y) { + // CHECK: @llvm.x86.bmi.bextr.64 + return __bextr_u64(__X, __Y); +} + +unsigned long long test__blsi_u64(unsigned long long __X) { + // CHECK: [[DEST:%.*]] = sub i64 0, [[SRC:%.*]] + // CHECK-NEXT: %{{.*}} = and i64 [[SRC]], [[DEST]] + return __blsi_u64(__X); +} + +unsigned long long test__blsmsk_u64(unsigned long long __X) { + // CHECK: [[DEST:%.*]] = add i64 [[SRC:%.*]], -1 + // CHECK-NEXT: %{{.*}} = xor i64 [[DEST]], [[SRC]] + return __blsmsk_u64(__X); +} + +unsigned long long test__blsr_u64(unsigned long long __X) { + // CHECK: [[DEST:%.*]] = add i64 [[SRC:%.*]], -1 + // CHECK-NEXT: %{{.*}} = and i64 [[DEST]], [[SRC]] + return __blsr_u64(__X); +} + +unsigned long long test__tzcnt64(unsigned long long __X) { + // CHECK: @llvm.cttz.i64 + return __tzcnt64(__X); +} diff --git a/clang/test/CodeGen/bmi2-builtins.c b/clang/test/CodeGen/bmi2-builtins.c new file mode 100644 index 0000000..18b2319 --- /dev/null +++ b/clang/test/CodeGen/bmi2-builtins.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +bmi2 -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +unsigned int test_bzhi_u32(unsigned int __X, unsigned int __Y) { + // CHECK: @llvm.x86.bmi.bzhi.32 + return _bzhi_u32(__X, __Y); +} + +unsigned int test_pdep_u32(unsigned int __X, unsigned int __Y) { + // CHECK: @llvm.x86.bmi.pdep.32 + return _pdep_u32(__X, __Y); +} + +unsigned int test_pext_u32(unsigned int __X, unsigned int __Y) { + // CHECK: @llvm.x86.bmi.pext.32 + return _pext_u32(__X, __Y); +} + +unsigned long long test_bzhi_u64(unsigned long long __X, unsigned long long __Y) { + // CHECK: @llvm.x86.bmi.bzhi.64 + return _bzhi_u64(__X, __Y); +} + +unsigned long long test_pdep_u64(unsigned long long __X, unsigned long long __Y) { + // CHECK: @llvm.x86.bmi.pdep.64 + return _pdep_u64(__X, __Y); +} + +unsigned long long test_pext_u64(unsigned long long __X, unsigned long long __Y) { + // CHECK: @llvm.x86.bmi.pext.64 + return _pext_u64(__X, __Y); +} diff --git a/clang/test/CodeGen/bool-bitfield.c b/clang/test/CodeGen/bool-bitfield.c new file mode 100644 index 0000000..cb2d1db --- /dev/null +++ b/clang/test/CodeGen/bool-bitfield.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/bool-convert.c b/clang/test/CodeGen/bool-convert.c new file mode 100644 index 0000000..8bde837 --- /dev/null +++ b/clang/test/CodeGen/bool-convert.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/bool-init.c b/clang/test/CodeGen/bool-init.c new file mode 100644 index 0000000..1a8f127 --- /dev/null +++ b/clang/test/CodeGen/bool-init.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm < %s | grep i1 | count 1 + +// Check that the type of this global isn't i1 +_Bool test = &test; diff --git a/clang/test/CodeGen/bool_test.c b/clang/test/CodeGen/bool_test.c new file mode 100644 index 0000000..ffaaef8 --- /dev/null +++ b/clang/test/CodeGen/bool_test.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple powerpc-apple-darwin -emit-llvm -o - %s| FileCheck -check-prefix=DARWINPPC-CHECK %s + +int boolsize = sizeof(_Bool); +//DARWINPPC-CHECK: boolsize = global i32 4, align 4 + diff --git a/clang/test/CodeGen/boolassign.c b/clang/test/CodeGen/boolassign.c new file mode 100644 index 0000000..8c56319 --- /dev/null +++ b/clang/test/CodeGen/boolassign.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t + +int testBoolAssign(void) { + int ss; + if ((ss = ss && ss)) {} + return 1; +} diff --git a/clang/test/CodeGen/builtin-attributes.c b/clang/test/CodeGen/builtin-attributes.c new file mode 100644 index 0000000..3781eba --- /dev/null +++ b/clang/test/CodeGen/builtin-attributes.c @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -triple arm-unknown-linux-gnueabi -emit-llvm -o - %s | FileCheck %s + +// CHECK: declare i32 @printf(i8*, ...) +void f0() { + printf("a\n"); +} + +// CHECK: call void @exit +// CHECK: unreachable +void f1() { + exit(1); +} + +// CHECK: call i8* @strstr{{.*}} nounwind +char* f2(char* a, char* b) { + return __builtin_strstr(a, b); +} + +// frexp is NOT readnone. It writes to its pointer argument. +// <rdar://problem/10070234> +// +// CHECK: f3 +// CHECK: call double @frexp(double % +// CHECK-NOT: readnone +// CHECK: call float @frexpf(float % +// CHECK-NOT: readnone +// CHECK: call double @frexpl(double % +// CHECK-NOT: readnone +// +// Same thing for modf and friends. +// +// CHECK: call double @modf(double % +// CHECK-NOT: readnone +// CHECK: call float @modff(float % +// CHECK-NOT: readnone +// CHECK: call double @modfl(double % +// CHECK-NOT: readnone +// +// CHECK: call double @remquo(double % +// CHECK-NOT: readnone +// CHECK: call float @remquof(float % +// CHECK-NOT: readnone +// CHECK: call double @remquol(double % +// CHECK-NOT: readnone +// CHECK: ret +int f3(double x) { + int e; + __builtin_frexp(x, &e); + __builtin_frexpf(x, &e); + __builtin_frexpl(x, &e); + __builtin_modf(x, &e); + __builtin_modff(x, &e); + __builtin_modfl(x, &e); + __builtin_remquo(x, x, &e); + __builtin_remquof(x, x, &e); + __builtin_remquol(x, x, &e); + return e; +} diff --git a/clang/test/CodeGen/builtin-count-zeros.c b/clang/test/CodeGen/builtin-count-zeros.c new file mode 100644 index 0000000..acd22e6 --- /dev/null +++ b/clang/test/CodeGen/builtin-count-zeros.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple arm-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-ARM + +int a(int a) {return __builtin_ctz(a) + __builtin_clz(a);} +// CHECK: call i32 @llvm.cttz.i32({{.*}}, i1 true) +// CHECK: call i32 @llvm.ctlz.i32({{.*}}, i1 true) +// CHECK-ARM: call i32 @llvm.cttz.i32({{.*}}, i1 false) +// CHECK-ARM: call i32 @llvm.ctlz.i32({{.*}}, i1 false) diff --git a/clang/test/CodeGen/builtin-expect.c b/clang/test/CodeGen/builtin-expect.c new file mode 100644 index 0000000..664c6b6 --- /dev/null +++ b/clang/test/CodeGen/builtin-expect.c @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +int x; +int y(void); +void foo(); +void FUNC() { +// CHECK: [[call:%.*]] = call i32 @y + if (__builtin_expect (x, y())) + foo (); +} + +// rdar://9330105 +void isigprocmask(void); +long bar(); + +int main() { + (void) __builtin_expect((isigprocmask(), 0), bar()); +} + +// CHECK: call void @isigprocmask() +// CHECK: [[C:%.*]] = call i64 (...)* @bar() + + +// CHECK: @test1 +int test1(int x) { +// CHECK: @llvm.expect + if (__builtin_expect (x, 1)) + return 0; + return x; +} + +// CHECK: @test2 +int test2(int x) { +// CHECK: @llvm.expect + switch(__builtin_expect(x, 5)) { + default: + return 0; + case 0: + case 1: + case 2: + return 1; + case 5: + return 5; + }; + + return 0; +} diff --git a/clang/test/CodeGen/builtin-memfns.c b/clang/test/CodeGen/builtin-memfns.c new file mode 100644 index 0000000..72d3406 --- /dev/null +++ b/clang/test/CodeGen/builtin-memfns.c @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm < %s| FileCheck %s + +// CHECK: @test1 +// CHECK: call void @llvm.memset.p0i8.i32 +// CHECK: call void @llvm.memset.p0i8.i32 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32 +// CHECK: call void @llvm.memmove.p0i8.p0i8.i32 +// CHECK-NOT: __builtin +// CHECK: ret +int test1(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; +} + +// rdar://9289468 + +// CHECK: @test2 +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32 +char* test2(char* a, char* b) { + return __builtin_memcpy(a, b, 4); +} + +// CHECK: @test3 +// CHECK: call void @llvm.memset +void test3(char *P) { + __builtin___memset_chk(P, 42, 128, 128); +} + +// CHECK: @test4 +// CHECK: call void @llvm.memcpy +void test4(char *P, char *Q) { + __builtin___memcpy_chk(P, Q, 128, 128); +} + +// CHECK: @test5 +// CHECK: call void @llvm.memmove +void test5(char *P, char *Q) { + __builtin___memmove_chk(P, Q, 128, 128); +} + +// CHECK: @test6 +// CHECK: call void @llvm.memcpy +int test6(char *X) { + return __builtin___memcpy_chk(X, X, 42, 42) != 0; +} + +// CHECK: @test7 +// PR12094 +int test7(int *p) { + struct snd_pcm_hw_params_t* hwparams; // incomplete type. + + // CHECK: call void @llvm.memset{{.*}}256, i32 4, i1 false) + __builtin_memset(p, 0, 256); // Should be alignment = 4 + + // CHECK: call void @llvm.memset{{.*}}256, i32 1, i1 false) + __builtin_memset((char*)p, 0, 256); // Should be alignment = 1 + + __builtin_memset(hwparams, 0, 256); // No crash alignment = 1 + // CHECK: call void @llvm.memset{{.*}}256, i32 1, i1 false) +} diff --git a/clang/test/CodeGen/builtin-nanf.c b/clang/test/CodeGen/builtin-nanf.c new file mode 100644 index 0000000..ae37c9d --- /dev/null +++ b/clang/test/CodeGen/builtin-nanf.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/builtin-recursive.cc b/clang/test/CodeGen/builtin-recursive.cc new file mode 100644 index 0000000..81e9b9a --- /dev/null +++ b/clang/test/CodeGen/builtin-recursive.cc @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -nostdsysteminc -nobuiltininc -isystem Inputs -emit-llvm-only %s + +// This used to cause a read past the end of a global variable. + +#include <stdio.h> + +void testcase(void) { + vprintf(0, 0); +} + diff --git a/clang/test/CodeGen/builtin-rename.c b/clang/test/CodeGen/builtin-rename.c new file mode 100644 index 0000000..0b71d88 --- /dev/null +++ b/clang/test/CodeGen/builtin-rename.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | grep 'declare.*printf' | count 1 +// PR3612 + +int printf(const char *, ...); + +int foo(void) { + return printf(printf); +} diff --git a/clang/test/CodeGen/builtin-stackaddress.c b/clang/test/CodeGen/builtin-stackaddress.c new file mode 100644 index 0000000..f13b90e --- /dev/null +++ b/clang/test/CodeGen/builtin-stackaddress.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm < %s | grep "llvm.returnaddress" +// RUN: %clang_cc1 -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/clang/test/CodeGen/builtin-unwind-init.c b/clang/test/CodeGen/builtin-unwind-init.c new file mode 100644 index 0000000..6fa7766 --- /dev/null +++ b/clang/test/CodeGen/builtin-unwind-init.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm < %s -o - | FileCheck %s + +void a() { __builtin_unwind_init(); } + +// CHECK: call void @llvm.eh.unwind.init() diff --git a/clang/test/CodeGen/builtins-arm.c b/clang/test/CodeGen/builtins-arm.c new file mode 100644 index 0000000..09df1ef --- /dev/null +++ b/clang/test/CodeGen/builtins-arm.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -Wall -Werror -triple thumbv7-eabi -target-cpu cortex-a8 -O3 -emit-llvm -o - %s | FileCheck %s + +void *f0() +{ + return __builtin_thread_pointer(); +} + +void f1(char *a, char *b) { + __clear_cache(a,b); +} + +// CHECK: call {{.*}} @__clear_cache diff --git a/clang/test/CodeGen/builtins-ppc-altivec.c b/clang/test/CodeGen/builtins-ppc-altivec.c new file mode 100644 index 0000000..b12ff01 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-altivec.c @@ -0,0 +1,3115 @@ +// RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +vector bool char vbc = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }; +vector signed char vsc = { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16 }; +vector unsigned char vuc = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; +vector bool short vbs = { 1, 0, 1, 0, 1, 0, 1, 0 }; +vector short vs = { -1, 2, -3, 4, -5, 6, -7, 8 }; +vector unsigned short vus = { 1, 2, 3, 4, 5, 6, 7, 8 }; +vector pixel vp = { 1, 2, 3, 4, 5, 6, 7, 8 }; +vector bool int vbi = { 1, 0, 1, 0 }; +vector int vi = { -1, 2, -3, 4 }; +vector unsigned int vui = { 1, 2, 3, 4 }; +vector float vf = { -1.5, 2.5, -3.5, 4.5 }; + +vector bool char res_vbc; +vector signed char res_vsc; +vector unsigned char res_vuc; +vector bool short res_vbs; +vector short res_vs; +vector unsigned short res_vus; +vector pixel res_vp; +vector bool int res_vbi; +vector int res_vi; +vector unsigned int res_vui; +vector float res_vf; + +signed char param_sc; +unsigned char param_uc; +short param_s; +unsigned short param_us; +int param_i; +unsigned int param_ui; +float param_f; + +int res_sc; +int res_uc; +int res_s; +int res_us; +int res_i; +int res_ui; +int res_f; + +// CHECK: define void @test1 +void test1() { + + /* vec_abs */ + vsc = vec_abs(vsc); // CHECK: sub <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vmaxsb + + vs = vec_abs(vs); // CHECK: sub <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vmaxsh + + vi = vec_abs(vi); // CHECK: sub <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vmaxsw + + vf = vec_abs(vf); // CHECK: and <4 x i32> + + /* vec_abs */ + vsc = vec_abss(vsc); // CHECK: @llvm.ppc.altivec.vsubsbs + // CHECK: @llvm.ppc.altivec.vmaxsb + + vs = vec_abss(vs); // CHECK: @llvm.ppc.altivec.vsubshs + // CHECK: @llvm.ppc.altivec.vmaxsh + + vi = vec_abss(vi); // CHECK: @llvm.ppc.altivec.vsubsws + // CHECK: @llvm.ppc.altivec.vmaxsw + + /* vec_add */ + res_vsc = vec_add(vsc, vsc); // CHECK: add <16 x i8> + res_vsc = vec_add(vbc, vsc); // CHECK: add <16 x i8> + res_vsc = vec_add(vsc, vbc); // CHECK: add <16 x i8> + res_vuc = vec_add(vuc, vuc); // CHECK: add <16 x i8> + res_vuc = vec_add(vbc, vuc); // CHECK: add <16 x i8> + res_vuc = vec_add(vuc, vbc); // CHECK: add <16 x i8> + res_vs = vec_add(vs, vs); // CHECK: add <8 x i16> + res_vs = vec_add(vbs, vs); // CHECK: add <8 x i16> + res_vs = vec_add(vs, vbs); // CHECK: add <8 x i16> + res_vus = vec_add(vus, vus); // CHECK: add <8 x i16> + res_vus = vec_add(vbs, vus); // CHECK: add <8 x i16> + res_vus = vec_add(vus, vbs); // CHECK: add <8 x i16> + res_vi = vec_add(vi, vi); // CHECK: add <4 x i32> + res_vi = vec_add(vbi, vi); // CHECK: add <4 x i32> + res_vi = vec_add(vi, vbi); // CHECK: add <4 x i32> + res_vui = vec_add(vui, vui); // CHECK: add <4 x i32> + res_vui = vec_add(vbi, vui); // CHECK: add <4 x i32> + res_vui = vec_add(vui, vbi); // CHECK: add <4 x i32> + res_vf = vec_add(vf, vf); // CHECK: fadd <4 x float> + res_vsc = vec_vaddubm(vsc, vsc); // CHECK: add <16 x i8> + res_vsc = vec_vaddubm(vbc, vsc); // CHECK: add <16 x i8> + res_vsc = vec_vaddubm(vsc, vbc); // CHECK: add <16 x i8> + res_vuc = vec_vaddubm(vuc, vuc); // CHECK: add <16 x i8> + res_vuc = vec_vaddubm(vbc, vuc); // CHECK: add <16 x i8> + res_vuc = vec_vaddubm(vuc, vbc); // CHECK: add <16 x i8> + res_vs = vec_vadduhm(vs, vs); // CHECK: add <8 x i16> + res_vs = vec_vadduhm(vbs, vs); // CHECK: add <8 x i16> + res_vs = vec_vadduhm(vs, vbs); // CHECK: add <8 x i16> + res_vus = vec_vadduhm(vus, vus); // CHECK: add <8 x i16> + res_vus = vec_vadduhm(vbs, vus); // CHECK: add <8 x i16> + res_vus = vec_vadduhm(vus, vbs); // CHECK: add <8 x i16> + res_vi = vec_vadduwm(vi, vi); // CHECK: add <4 x i32> + res_vi = vec_vadduwm(vbi, vi); // CHECK: add <4 x i32> + res_vi = vec_vadduwm(vi, vbi); // CHECK: add <4 x i32> + res_vui = vec_vadduwm(vui, vui); // CHECK: add <4 x i32> + res_vui = vec_vadduwm(vbi, vui); // CHECK: add <4 x i32> + res_vui = vec_vadduwm(vui, vbi); // CHECK: add <4 x i32> + res_vf = vec_vaddfp(vf, vf); // CHECK: fadd <4 x float> + + /* vec_addc */ + res_vui = vec_addc(vui, vui); // HECK: @llvm.ppc.altivec.vaddcuw + res_vui = vec_vaddcuw(vui, vui); // HECK: @llvm.ppc.altivec.vaddcuw + + /* vec_adds */ + res_vsc = vec_adds(vsc, vsc); // CHECK: @llvm.ppc.altivec.vaddsbs + res_vsc = vec_adds(vbc, vsc); // CHECK: @llvm.ppc.altivec.vaddsbs + res_vsc = vec_adds(vsc, vbc); // CHECK: @llvm.ppc.altivec.vaddsbs + res_vuc = vec_adds(vuc, vuc); // CHECK: @llvm.ppc.altivec.vaddubs + res_vuc = vec_adds(vbc, vuc); // CHECK: @llvm.ppc.altivec.vaddubs + res_vuc = vec_adds(vuc, vbc); // CHECK: @llvm.ppc.altivec.vaddubs + res_vs = vec_adds(vs, vs); // CHECK: @llvm.ppc.altivec.vaddshs + res_vs = vec_adds(vbs, vs); // CHECK: @llvm.ppc.altivec.vaddshs + res_vs = vec_adds(vs, vbs); // CHECK: @llvm.ppc.altivec.vaddshs + res_vus = vec_adds(vus, vus); // CHECK: @llvm.ppc.altivec.vadduhs + res_vus = vec_adds(vbs, vus); // CHECK: @llvm.ppc.altivec.vadduhs + res_vus = vec_adds(vus, vbs); // CHECK: @llvm.ppc.altivec.vadduhs + res_vi = vec_adds(vi, vi); // CHECK: @llvm.ppc.altivec.vaddsws + res_vi = vec_adds(vbi, vi); // CHECK: @llvm.ppc.altivec.vaddsws + res_vi = vec_adds(vi, vbi); // CHECK: @llvm.ppc.altivec.vaddsws + res_vui = vec_adds(vui, vui); // CHECK: @llvm.ppc.altivec.vadduws + res_vui = vec_adds(vbi, vui); // CHECK: @llvm.ppc.altivec.vadduws + res_vui = vec_adds(vui, vbi); // CHECK: @llvm.ppc.altivec.vadduws + res_vsc = vec_vaddsbs(vsc, vsc); // CHECK: @llvm.ppc.altivec.vaddsbs + res_vsc = vec_vaddsbs(vbc, vsc); // CHECK: @llvm.ppc.altivec.vaddsbs + res_vsc = vec_vaddsbs(vsc, vbc); // CHECK: @llvm.ppc.altivec.vaddsbs + res_vuc = vec_vaddubs(vuc, vuc); // CHECK: @llvm.ppc.altivec.vaddubs + res_vuc = vec_vaddubs(vbc, vuc); // CHECK: @llvm.ppc.altivec.vaddubs + res_vuc = vec_vaddubs(vuc, vbc); // CHECK: @llvm.ppc.altivec.vaddubs + res_vs = vec_vaddshs(vs, vs); // CHECK: @llvm.ppc.altivec.vaddshs + res_vs = vec_vaddshs(vbs, vs); // CHECK: @llvm.ppc.altivec.vaddshs + res_vs = vec_vaddshs(vs, vbs); // CHECK: @llvm.ppc.altivec.vaddshs + res_vus = vec_vadduhs(vus, vus); // CHECK: @llvm.ppc.altivec.vadduhs + res_vus = vec_vadduhs(vbs, vus); // CHECK: @llvm.ppc.altivec.vadduhs + res_vus = vec_vadduhs(vus, vbs); // CHECK: @llvm.ppc.altivec.vadduhs + res_vi = vec_vaddsws(vi, vi); // CHECK: @llvm.ppc.altivec.vaddsws + res_vi = vec_vaddsws(vbi, vi); // CHECK: @llvm.ppc.altivec.vaddsws + res_vi = vec_vaddsws(vi, vbi); // CHECK: @llvm.ppc.altivec.vaddsws + res_vui = vec_vadduws(vui, vui); // CHECK: @llvm.ppc.altivec.vadduws + res_vui = vec_vadduws(vbi, vui); // CHECK: @llvm.ppc.altivec.vadduws + res_vui = vec_vadduws(vui, vbi); // CHECK: @llvm.ppc.altivec.vadduws + + /* vec_and */ + res_vsc = vec_and(vsc, vsc); // CHECK: and <16 x i8> + res_vsc = vec_and(vbc, vsc); // CHECK: and <16 x i8> + res_vsc = vec_and(vsc, vbc); // CHECK: and <16 x i8> + res_vuc = vec_and(vuc, vuc); // CHECK: and <16 x i8> + res_vuc = vec_and(vbc, vuc); // CHECK: and <16 x i8> + res_vuc = vec_and(vuc, vbc); // CHECK: and <16 x i8> + res_vbc = vec_and(vbc, vbc); // CHECK: and <16 x i8> + res_vs = vec_and(vs, vs); // CHECK: and <8 x i16> + res_vs = vec_and(vbs, vs); // CHECK: and <8 x i16> + res_vs = vec_and(vs, vbs); // CHECK: and <8 x i16> + res_vus = vec_and(vus, vus); // CHECK: and <8 x i16> + res_vus = vec_and(vbs, vus); // CHECK: and <8 x i16> + res_vus = vec_and(vus, vbs); // CHECK: and <8 x i16> + res_vbs = vec_and(vbs, vbs); // CHECK: and <8 x i16> + res_vi = vec_and(vi, vi); // CHECK: and <4 x i32> + res_vi = vec_and(vbi, vi); // CHECK: and <4 x i32> + res_vi = vec_and(vi, vbi); // CHECK: and <4 x i32> + res_vui = vec_and(vui, vui); // CHECK: and <4 x i32> + res_vui = vec_and(vbi, vui); // CHECK: and <4 x i32> + res_vui = vec_and(vui, vbi); // CHECK: and <4 x i32> + res_vbi = vec_and(vbi, vbi); // CHECK: and <4 x i32> + res_vsc = vec_vand(vsc, vsc); // CHECK: and <16 x i8> + res_vsc = vec_vand(vbc, vsc); // CHECK: and <16 x i8> + res_vsc = vec_vand(vsc, vbc); // CHECK: and <16 x i8> + res_vuc = vec_vand(vuc, vuc); // CHECK: and <16 x i8> + res_vuc = vec_vand(vbc, vuc); // CHECK: and <16 x i8> + res_vuc = vec_vand(vuc, vbc); // CHECK: and <16 x i8> + res_vbc = vec_vand(vbc, vbc); // CHECK: and <16 x i8> + res_vs = vec_vand(vs, vs); // CHECK: and <8 x i16> + res_vs = vec_vand(vbs, vs); // CHECK: and <8 x i16> + res_vs = vec_vand(vs, vbs); // CHECK: and <8 x i16> + res_vus = vec_vand(vus, vus); // CHECK: and <8 x i16> + res_vus = vec_vand(vbs, vus); // CHECK: and <8 x i16> + res_vus = vec_vand(vus, vbs); // CHECK: and <8 x i16> + res_vbs = vec_vand(vbs, vbs); // CHECK: and <8 x i16> + res_vi = vec_vand(vi, vi); // CHECK: and <4 x i32> + res_vi = vec_vand(vbi, vi); // CHECK: and <4 x i32> + res_vi = vec_vand(vi, vbi); // CHECK: and <4 x i32> + res_vui = vec_vand(vui, vui); // CHECK: and <4 x i32> + res_vui = vec_vand(vbi, vui); // CHECK: and <4 x i32> + res_vui = vec_vand(vui, vbi); // CHECK: and <4 x i32> + res_vbi = vec_vand(vbi, vbi); // CHECK: and <4 x i32> + + /* vec_andc */ + res_vsc = vec_andc(vsc, vsc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vsc = vec_andc(vbc, vsc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vsc = vec_andc(vsc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vuc = vec_andc(vuc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vuc = vec_andc(vbc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vuc = vec_andc(vuc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vbc = vec_andc(vbc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vs = vec_andc(vs, vs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vs = vec_andc(vbs, vs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vs = vec_andc(vs, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vus = vec_andc(vus, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vus = vec_andc(vbs, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vus = vec_andc(vus, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vbs = vec_andc(vbs, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vi = vec_andc(vi, vi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vi = vec_andc(vbi, vi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vi = vec_andc(vi, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vui = vec_andc(vui, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vui = vec_andc(vbi, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vui = vec_andc(vui, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vf = vec_andc(vf, vf); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vf = vec_andc(vbi, vf); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vf = vec_andc(vf, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vsc = vec_vandc(vsc, vsc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vsc = vec_vandc(vbc, vsc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vsc = vec_vandc(vsc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vuc = vec_vandc(vuc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vuc = vec_vandc(vbc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vuc = vec_vandc(vuc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vbc = vec_vandc(vbc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + + res_vs = vec_vandc(vs, vs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vs = vec_vandc(vbs, vs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vs = vec_vandc(vs, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vus = vec_vandc(vus, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vus = vec_vandc(vbs, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vus = vec_vandc(vus, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vbs = vec_vandc(vbs, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + + res_vi = vec_vandc(vi, vi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vi = vec_vandc(vbi, vi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vi = vec_vandc(vi, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vui = vec_vandc(vui, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vui = vec_vandc(vbi, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vui = vec_vandc(vui, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vf = vec_vandc(vf, vf); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vf = vec_vandc(vbi, vf); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + + res_vf = vec_vandc(vf, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + +} + +// CHECK: define void @test2 +void test2() { + /* vec_avg */ + res_vsc = vec_avg(vsc, vsc); // CHECK: @llvm.ppc.altivec.vavgsb + res_vuc = vec_avg(vuc, vuc); // CHECK: @llvm.ppc.altivec.vavgub + res_vs = vec_avg(vs, vs); // CHECK: @llvm.ppc.altivec.vavgsh + res_vus = vec_avg(vus, vus); // CHECK: @llvm.ppc.altivec.vavguh + res_vi = vec_avg(vi, vi); // CHECK: @llvm.ppc.altivec.vavgsw + res_vui = vec_avg(vui, vui); // CHECK: @llvm.ppc.altivec.vavguw + res_vsc = vec_vavgsb(vsc, vsc); // CHECK: @llvm.ppc.altivec.vavgsb + res_vuc = vec_vavgub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vavgub + res_vs = vec_vavgsh(vs, vs); // CHECK: @llvm.ppc.altivec.vavgsh + res_vus = vec_vavguh(vus, vus); // CHECK: @llvm.ppc.altivec.vavguh + res_vi = vec_vavgsw(vi, vi); // CHECK: @llvm.ppc.altivec.vavgsw + res_vui = vec_vavguw(vui, vui); // CHECK: @llvm.ppc.altivec.vavguw + + /* vec_ceil */ + res_vf = vec_ceil(vf); // CHECK: @llvm.ppc.altivec.vrfip + res_vf = vec_vrfip(vf); // CHECK: @llvm.ppc.altivec.vrfip + + /* vec_cmpb */ + res_vi = vec_cmpb(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpbfp + res_vi = vec_vcmpbfp(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpbfp + + /* vec_cmpeq */ + res_vbc = vec_cmpeq(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb + res_vbc = vec_cmpeq(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb + res_vbs = vec_cmpeq(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh + res_vbs = vec_cmpeq(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh + res_vbi = vec_cmpeq(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw + res_vbi = vec_cmpeq(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw + res_vbi = vec_cmpeq(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp + + /* vec_cmpge */ + res_vbi = vec_cmpge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp + res_vbi = vec_vcmpgefp(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp +} + +// CHECK: define void @test5 +void test5() { + + /* vec_cmpgt */ + res_vbc = vec_cmpgt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb + res_vbc = vec_cmpgt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub + res_vbs = vec_cmpgt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh + res_vbs = vec_cmpgt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh + res_vbi = vec_cmpgt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw + res_vbi = vec_cmpgt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw + res_vbi = vec_cmpgt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp + res_vbc = vec_vcmpgtsb(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb + res_vbc = vec_vcmpgtub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub + res_vbs = vec_vcmpgtsh(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh + res_vbs = vec_vcmpgtuh(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh + res_vbi = vec_vcmpgtsw(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw + res_vbi = vec_vcmpgtuw(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw + res_vbi = vec_vcmpgtfp(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp + + /* vec_cmple */ + res_vbi = vec_cmple(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp +} + +// CHECK: define void @test6 +void test6() { + /* vec_cmplt */ + res_vbc = vec_cmplt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb + res_vbc = vec_cmplt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub + res_vbs = vec_cmplt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh + res_vbs = vec_cmplt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh + res_vbi = vec_cmplt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw + res_vbi = vec_cmplt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw + res_vbi = vec_cmplt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp + + /* vec_ctf */ + res_vf = vec_ctf(vi, param_i); // CHECK: @llvm.ppc.altivec.vcfsx + res_vf = vec_ctf(vui, 0); // CHECK: @llvm.ppc.altivec.vcfux + res_vf = vec_vcfsx(vi, 0); // CHECK: @llvm.ppc.altivec.vcfsx + res_vf = vec_vcfux(vui, 0); // CHECK: @llvm.ppc.altivec.vcfux + + /* vec_cts */ + res_vi = vec_cts(vf, 0); // CHECK: @llvm.ppc.altivec.vctsxs + res_vi = vec_vctsxs(vf, 0); // CHECK: @llvm.ppc.altivec.vctsxs + + /* vec_ctu */ + res_vui = vec_ctu(vf, 0); // CHECK: @llvm.ppc.altivec.vctuxs + res_vui = vec_vctuxs(vf, 0); // CHECK: @llvm.ppc.altivec.vctuxs + + /* vec_dss */ + vec_dss(param_i); // CHECK: @llvm.ppc.altivec.dss + + /* vec_dssall */ + vec_dssall(); // CHECK: @llvm.ppc.altivec.dssall + + /* vec_dst */ + vec_dst(&vsc, 0, 0); // CHECK: @llvm.ppc.altivec.dst + + /* vec_dstst */ + vec_dstst(&vs, 0, 0); // CHECK: @llvm.ppc.altivec.dstst + + /* vec_dststt */ + vec_dststt(¶m_i, 0, 0); // CHECK: @llvm.ppc.altivec.dststt + + /* vec_dstt */ + vec_dstt(&vf, 0, 0); // CHECK: @llvm.ppc.altivec.dstt + + /* vec_expte */ + res_vf = vec_expte(vf); // CHECK: @llvm.ppc.altivec.vexptefp + res_vf = vec_vexptefp(vf); // CHECK: @llvm.ppc.altivec.vexptefp + + /* vec_floor */ + res_vf = vec_floor(vf); // CHECK: @llvm.ppc.altivec.vrfim + res_vf = vec_vrfim(vf); // CHECK: @llvm.ppc.altivec.vrfim + + /* vec_ld */ + res_vsc = vec_ld(0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + res_vsc = vec_ld(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + res_vuc = vec_ld(0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + res_vuc = vec_ld(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + res_vbc = vec_ld(0, &vbc); // CHECK: @llvm.ppc.altivec.lvx + res_vs = vec_ld(0, &vs); // CHECK: @llvm.ppc.altivec.lvx + res_vs = vec_ld(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + res_vus = vec_ld(0, &vus); // CHECK: @llvm.ppc.altivec.lvx + res_vus = vec_ld(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + res_vbs = vec_ld(0, &vbs); // CHECK: @llvm.ppc.altivec.lvx + res_vp = vec_ld(0, &vp); // CHECK: @llvm.ppc.altivec.lvx + res_vi = vec_ld(0, &vi); // CHECK: @llvm.ppc.altivec.lvx + res_vi = vec_ld(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + res_vui = vec_ld(0, &vui); // CHECK: @llvm.ppc.altivec.lvx + res_vui = vec_ld(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + res_vbi = vec_ld(0, &vbi); // CHECK: @llvm.ppc.altivec.lvx + res_vf = vec_ld(0, &vf); // CHECK: @llvm.ppc.altivec.lvx + res_vf = vec_ld(0, ¶m_f); // CHECK: @llvm.ppc.altivec.lvx + res_vsc = vec_lvx(0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + res_vsc = vec_lvx(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + res_vuc = vec_lvx(0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + res_vuc = vec_lvx(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + res_vbc = vec_lvx(0, &vbc); // CHECK: @llvm.ppc.altivec.lvx + res_vs = vec_lvx(0, &vs); // CHECK: @llvm.ppc.altivec.lvx + res_vs = vec_lvx(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + res_vus = vec_lvx(0, &vus); // CHECK: @llvm.ppc.altivec.lvx + res_vus = vec_lvx(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + res_vbs = vec_lvx(0, &vbs); // CHECK: @llvm.ppc.altivec.lvx + res_vp = vec_lvx(0, &vp); // CHECK: @llvm.ppc.altivec.lvx + res_vi = vec_lvx(0, &vi); // CHECK: @llvm.ppc.altivec.lvx + res_vi = vec_lvx(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + res_vui = vec_lvx(0, &vui); // CHECK: @llvm.ppc.altivec.lvx + res_vui = vec_lvx(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + res_vbi = vec_lvx(0, &vbi); // CHECK: @llvm.ppc.altivec.lvx + res_vf = vec_lvx(0, &vf); // CHECK: @llvm.ppc.altivec.lvx + res_vf = vec_lvx(0, ¶m_f); // CHECK: @llvm.ppc.altivec.lvx + + /* vec_lde */ + res_vsc = vec_lde(0, &vsc); // CHECK: @llvm.ppc.altivec.lvebx + res_vuc = vec_lde(0, &vuc); // CHECK: @llvm.ppc.altivec.lvebx + res_vs = vec_lde(0, &vs); // CHECK: @llvm.ppc.altivec.lvehx + res_vus = vec_lde(0, &vus); // CHECK: @llvm.ppc.altivec.lvehx + res_vi = vec_lde(0, &vi); // CHECK: @llvm.ppc.altivec.lvewx + res_vui = vec_lde(0, &vui); // CHECK: @llvm.ppc.altivec.lvewx + res_vf = vec_lde(0, &vf); // CHECK: @llvm.ppc.altivec.lvewx + res_vsc = vec_lvebx(0, &vsc); // CHECK: @llvm.ppc.altivec.lvebx + res_vuc = vec_lvebx(0, &vuc); // CHECK: @llvm.ppc.altivec.lvebx + res_vs = vec_lvehx(0, &vs); // CHECK: @llvm.ppc.altivec.lvehx + res_vus = vec_lvehx(0, &vus); // CHECK: @llvm.ppc.altivec.lvehx + res_vi = vec_lvewx(0, &vi); // CHECK: @llvm.ppc.altivec.lvewx + res_vui = vec_lvewx(0, &vui); // CHECK: @llvm.ppc.altivec.lvewx + res_vf = vec_lvewx(0, &vf); // CHECK: @llvm.ppc.altivec.lvewx + + /* vec_ldl */ + res_vsc = vec_ldl(0, &vsc); // CHECK: @llvm.ppc.altivec.lvxl + res_vsc = vec_ldl(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvxl + res_vuc = vec_ldl(0, &vuc); // CHECK: @llvm.ppc.altivec.lvxl + res_vuc = vec_ldl(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvxl + res_vbc = vec_ldl(0, &vbc); // CHECK: @llvm.ppc.altivec.lvxl + res_vs = vec_ldl(0, &vs); // CHECK: @llvm.ppc.altivec.lvxl + res_vs = vec_ldl(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvxl + res_vus = vec_ldl(0, &vus); // CHECK: @llvm.ppc.altivec.lvxl + res_vus = vec_ldl(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvxl + res_vbs = vec_ldl(0, &vbs); // CHECK: @llvm.ppc.altivec.lvxl + res_vp = vec_ldl(0, &vp); // CHECK: @llvm.ppc.altivec.lvxl + res_vi = vec_ldl(0, &vi); // CHECK: @llvm.ppc.altivec.lvxl + res_vi = vec_ldl(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvxl + res_vui = vec_ldl(0, &vui); // CHECK: @llvm.ppc.altivec.lvxl + res_vui = vec_ldl(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvxl + res_vbi = vec_ldl(0, &vbi); // CHECK: @llvm.ppc.altivec.lvxl + res_vf = vec_ldl(0, &vf); // CHECK: @llvm.ppc.altivec.lvxl + res_vf = vec_ldl(0, ¶m_f); // CHECK: @llvm.ppc.altivec.lvxl + res_vsc = vec_lvxl(0, &vsc); // CHECK: @llvm.ppc.altivec.lvxl + res_vsc = vec_lvxl(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvxl + res_vuc = vec_lvxl(0, &vuc); // CHECK: @llvm.ppc.altivec.lvxl + res_vbc = vec_lvxl(0, &vbc); // CHECK: @llvm.ppc.altivec.lvxl + res_vuc = vec_lvxl(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvxl + res_vs = vec_lvxl(0, &vs); // CHECK: @llvm.ppc.altivec.lvxl + res_vs = vec_lvxl(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvxl + res_vus = vec_lvxl(0, &vus); // CHECK: @llvm.ppc.altivec.lvxl + res_vus = vec_lvxl(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvxl + res_vbs = vec_lvxl(0, &vbs); // CHECK: @llvm.ppc.altivec.lvxl + res_vp = vec_lvxl(0, &vp); // CHECK: @llvm.ppc.altivec.lvxl + res_vi = vec_lvxl(0, &vi); // CHECK: @llvm.ppc.altivec.lvxl + res_vi = vec_lvxl(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvxl + res_vui = vec_lvxl(0, &vui); // CHECK: @llvm.ppc.altivec.lvxl + res_vui = vec_lvxl(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvxl + res_vbi = vec_lvxl(0, &vbi); // CHECK: @llvm.ppc.altivec.lvxl + res_vf = vec_lvxl(0, &vf); // CHECK: @llvm.ppc.altivec.lvxl + res_vf = vec_lvxl(0, ¶m_f); // CHECK: @llvm.ppc.altivec.lvxl + + /* vec_loge */ + res_vf = vec_loge(vf); // CHECK: @llvm.ppc.altivec.vlogefp + res_vf = vec_vlogefp(vf); // CHECK: @llvm.ppc.altivec.vlogefp + + /* vec_lvsl */ + res_vuc = vec_lvsl(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvsl + + /* vec_lvsr */ + res_vuc = vec_lvsr(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvsr + + /* vec_madd */ + res_vf =vec_madd(vf, vf, vf); // CHECK: @llvm.ppc.altivec.vmaddfp + res_vf = vec_vmaddfp(vf, vf, vf); // CHECK: @llvm.ppc.altivec.vmaddfp + + /* vec_madds */ + res_vs = vec_madds(vs, vs, vs); // CHECK: @llvm.ppc.altivec.vmhaddshs + res_vs = vec_vmhaddshs(vs, vs, vs); // CHECK: @llvm.ppc.altivec.vmhaddshs + + /* vec_max */ + res_vsc = vec_max(vsc, vsc); // CHECK: @llvm.ppc.altivec.vmaxsb + res_vsc = vec_max(vbc, vsc); // CHECK: @llvm.ppc.altivec.vmaxsb + res_vsc = vec_max(vsc, vbc); // CHECK: @llvm.ppc.altivec.vmaxsb + res_vuc = vec_max(vuc, vuc); // CHECK: @llvm.ppc.altivec.vmaxub + res_vuc = vec_max(vbc, vuc); // CHECK: @llvm.ppc.altivec.vmaxub + res_vuc = vec_max(vuc, vbc); // CHECK: @llvm.ppc.altivec.vmaxub + res_vs = vec_max(vs, vs); // CHECK: @llvm.ppc.altivec.vmaxsh + res_vs = vec_max(vbs, vs); // CHECK: @llvm.ppc.altivec.vmaxsh + res_vs = vec_max(vs, vbs); // CHECK: @llvm.ppc.altivec.vmaxsh + res_vus = vec_max(vus, vus); // CHECK: @llvm.ppc.altivec.vmaxuh + res_vus = vec_max(vbs, vus); // CHECK: @llvm.ppc.altivec.vmaxuh + res_vus = vec_max(vus, vbs); // CHECK: @llvm.ppc.altivec.vmaxuh + res_vi = vec_max(vi, vi); // CHECK: @llvm.ppc.altivec.vmaxsw + res_vi = vec_max(vbi, vi); // CHECK: @llvm.ppc.altivec.vmaxsw + res_vi = vec_max(vi, vbi); // CHECK: @llvm.ppc.altivec.vmaxsw + res_vui = vec_max(vui, vui); // CHECK: @llvm.ppc.altivec.vmaxuw + res_vui = vec_max(vbi, vui); // CHECK: @llvm.ppc.altivec.vmaxuw + res_vui = vec_max(vui, vbi); // CHECK: @llvm.ppc.altivec.vmaxuw + res_vf = vec_max(vf, vf); // CHECK: @llvm.ppc.altivec.vmaxfp + res_vsc = vec_vmaxsb(vsc, vsc); // CHECK: @llvm.ppc.altivec.vmaxsb + res_vsc = vec_vmaxsb(vbc, vsc); // CHECK: @llvm.ppc.altivec.vmaxsb + res_vsc = vec_vmaxsb(vsc, vbc); // CHECK: @llvm.ppc.altivec.vmaxsb + res_vuc = vec_vmaxub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vmaxub + res_vuc = vec_vmaxub(vbc, vuc); // CHECK: @llvm.ppc.altivec.vmaxub + res_vuc = vec_vmaxub(vuc, vbc); // CHECK: @llvm.ppc.altivec.vmaxub + res_vs = vec_vmaxsh(vs, vs); // CHECK: @llvm.ppc.altivec.vmaxsh + res_vs = vec_vmaxsh(vbs, vs); // CHECK: @llvm.ppc.altivec.vmaxsh + res_vs = vec_vmaxsh(vs, vbs); // CHECK: @llvm.ppc.altivec.vmaxsh + res_vus = vec_vmaxuh(vus, vus); // CHECK: @llvm.ppc.altivec.vmaxuh + res_vus = vec_vmaxuh(vbs, vus); // CHECK: @llvm.ppc.altivec.vmaxuh + res_vus = vec_vmaxuh(vus, vbs); // CHECK: @llvm.ppc.altivec.vmaxuh + res_vi = vec_vmaxsw(vi, vi); // CHECK: @llvm.ppc.altivec.vmaxsw + res_vi = vec_vmaxsw(vbi, vi); // CHECK: @llvm.ppc.altivec.vmaxsw + res_vi = vec_vmaxsw(vi, vbi); // CHECK: @llvm.ppc.altivec.vmaxsw + res_vui = vec_vmaxuw(vui, vui); // CHECK: @llvm.ppc.altivec.vmaxuw + res_vui = vec_vmaxuw(vbi, vui); // CHECK: @llvm.ppc.altivec.vmaxuw + res_vui = vec_vmaxuw(vui, vbi); // CHECK: @llvm.ppc.altivec.vmaxuw + res_vf = vec_vmaxfp(vf, vf); // CHECK: @llvm.ppc.altivec.vmaxfp + + /* vec_mergeh */ + res_vsc = vec_mergeh(vsc, vsc); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_mergeh(vuc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_mergeh(vbc, vbc); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_mergeh(vs, vs); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_mergeh(vp, vp); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_mergeh(vus, vus); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_mergeh(vbs, vbs); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_mergeh(vi, vi); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_mergeh(vui, vui); // CHECK: @llvm.ppc.altivec.vperm + res_vbi = vec_mergeh(vbi, vbi); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_mergeh(vf, vf); // CHECK: @llvm.ppc.altivec.vperm + res_vsc = vec_vmrghb(vsc, vsc); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_vmrghb(vuc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_vmrghb(vbc, vbc); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_vmrghh(vs, vs); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_vmrghh(vp, vp); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_vmrghh(vus, vus); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_vmrghh(vbs, vbs); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_vmrghw(vi, vi); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_vmrghw(vui, vui); // CHECK: @llvm.ppc.altivec.vperm + res_vbi = vec_vmrghw(vbi, vbi); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_vmrghw(vf, vf); // CHECK: @llvm.ppc.altivec.vperm + + /* vec_mergel */ + res_vsc = vec_mergel(vsc, vsc); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_mergel(vuc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_mergel(vbc, vbc); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_mergel(vs, vs); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_mergeh(vp, vp); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_mergel(vus, vus); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_mergel(vbs, vbs); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_mergel(vi, vi); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_mergel(vui, vui); // CHECK: @llvm.ppc.altivec.vperm + res_vbi = vec_mergel(vbi, vbi); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_mergel(vf, vf); // CHECK: @llvm.ppc.altivec.vperm + res_vsc = vec_vmrglb(vsc, vsc); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_vmrglb(vuc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_vmrglb(vbc, vbc); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_vmrglh(vs, vs); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_vmrglh(vp, vp); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_vmrglh(vus, vus); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_vmrglh(vbs, vbs); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_vmrglw(vi, vi); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_vmrglw(vui, vui); // CHECK: @llvm.ppc.altivec.vperm + res_vbi = vec_vmrglw(vbi, vbi); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_vmrglw(vf, vf); // CHECK: @llvm.ppc.altivec.vperm + + /* vec_mfvscr */ + vus = vec_mfvscr(); // CHECK: @llvm.ppc.altivec.mfvscr + + /* vec_min */ + res_vsc = vec_min(vsc, vsc); // CHECK: @llvm.ppc.altivec.vminsb + res_vsc = vec_min(vbc, vsc); // CHECK: @llvm.ppc.altivec.vminsb + res_vsc = vec_min(vsc, vbc); // CHECK: @llvm.ppc.altivec.vminsb + res_vuc = vec_min(vuc, vuc); // CHECK: @llvm.ppc.altivec.vminub + res_vuc = vec_min(vbc, vuc); // CHECK: @llvm.ppc.altivec.vminub + res_vuc = vec_min(vuc, vbc); // CHECK: @llvm.ppc.altivec.vminub + res_vs = vec_min(vs, vs); // CHECK: @llvm.ppc.altivec.vminsh + res_vs = vec_min(vbs, vs); // CHECK: @llvm.ppc.altivec.vminsh + res_vs = vec_min(vs, vbs); // CHECK: @llvm.ppc.altivec.vminsh + res_vus = vec_min(vus, vus); // CHECK: @llvm.ppc.altivec.vminuh + res_vus = vec_min(vbs, vus); // CHECK: @llvm.ppc.altivec.vminuh + res_vus = vec_min(vus, vbs); // CHECK: @llvm.ppc.altivec.vminuh + res_vi = vec_min(vi, vi); // CHECK: @llvm.ppc.altivec.vminsw + res_vi = vec_min(vbi, vi); // CHECK: @llvm.ppc.altivec.vminsw + res_vi = vec_min(vi, vbi); // CHECK: @llvm.ppc.altivec.vminsw + res_vui = vec_min(vui, vui); // CHECK: @llvm.ppc.altivec.vminuw + res_vui = vec_min(vbi, vui); // CHECK: @llvm.ppc.altivec.vminuw + res_vui = vec_min(vui, vbi); // CHECK: @llvm.ppc.altivec.vminuw + res_vf = vec_min(vf, vf); // CHECK: @llvm.ppc.altivec.vminfp + res_vsc = vec_vminsb(vsc, vsc); // CHECK: @llvm.ppc.altivec.vminsb + res_vsc = vec_vminsb(vbc, vsc); // CHECK: @llvm.ppc.altivec.vminsb + res_vsc = vec_vminsb(vsc, vbc); // CHECK: @llvm.ppc.altivec.vminsb + res_vuc = vec_vminub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vminub + res_vuc = vec_vminub(vbc, vuc); // CHECK: @llvm.ppc.altivec.vminub + res_vuc = vec_vminub(vuc, vbc); // CHECK: @llvm.ppc.altivec.vminub + res_vs = vec_vminsh(vs, vs); // CHECK: @llvm.ppc.altivec.vminsh + res_vs = vec_vminsh(vbs, vs); // CHECK: @llvm.ppc.altivec.vminsh + res_vs = vec_vminsh(vs, vbs); // CHECK: @llvm.ppc.altivec.vminsh + res_vus = vec_vminuh(vus, vus); // CHECK: @llvm.ppc.altivec.vminuh + res_vus = vec_vminuh(vbs, vus); // CHECK: @llvm.ppc.altivec.vminuh + res_vus = vec_vminuh(vus, vbs); // CHECK: @llvm.ppc.altivec.vminuh + res_vi = vec_vminsw(vi, vi); // CHECK: @llvm.ppc.altivec.vminsw + res_vi = vec_vminsw(vbi, vi); // CHECK: @llvm.ppc.altivec.vminsw + res_vi = vec_vminsw(vi, vbi); // CHECK: @llvm.ppc.altivec.vminsw + res_vui = vec_vminuw(vui, vui); // CHECK: @llvm.ppc.altivec.vminuw + res_vui = vec_vminuw(vbi, vui); // CHECK: @llvm.ppc.altivec.vminuw + res_vui = vec_vminuw(vui, vbi); // CHECK: @llvm.ppc.altivec.vminuw + res_vf = vec_vminfp(vf, vf); // CHECK: @llvm.ppc.altivec.vminfp + + /* vec_mladd */ + res_vus = vec_mladd(vus, vus, vus); // CHECK: mul <8 x i16> + // CHECK: add <8 x i16> + + res_vs = vec_mladd(vus, vs, vs); // CHECK: mul <8 x i16> + // CHECK: add <8 x i16> + + res_vs = vec_mladd(vs, vus, vus); // CHECK: mul <8 x i16> + // CHECK: add <8 x i16> + + res_vs = vec_mladd(vs, vs, vs); // CHECK: mul <8 x i16> + // CHECK: add <8 x i16> + + /* vec_mradds */ + res_vs = vec_mradds(vs, vs, vs); // CHECK: @llvm.ppc.altivec.vmhraddshs + res_vs = vec_vmhraddshs(vs, vs, vs); // CHECK: @llvm.ppc.altivec.vmhraddshs + + /* vec_msum */ + res_vi = vec_msum(vsc, vuc, vi); // CHECK: @llvm.ppc.altivec.vmsummbm + res_vui = vec_msum(vuc, vuc, vui); // CHECK: @llvm.ppc.altivec.vmsumubm + res_vi = vec_msum(vs, vs, vi); // CHECK: @llvm.ppc.altivec.vmsumshm + res_vui = vec_msum(vus, vus, vui); // CHECK: @llvm.ppc.altivec.vmsumuhm + res_vi = vec_vmsummbm(vsc, vuc, vi); // CHECK: @llvm.ppc.altivec.vmsummbm + res_vui = vec_vmsumubm(vuc, vuc, vui); // CHECK: @llvm.ppc.altivec.vmsumubm + res_vi = vec_vmsumshm(vs, vs, vi); // CHECK: @llvm.ppc.altivec.vmsumshm + res_vui = vec_vmsumuhm(vus, vus, vui); // CHECK: @llvm.ppc.altivec.vmsumuhm + + /* vec_msums */ + res_vi = vec_msums(vs, vs, vi); // CHECK: @llvm.ppc.altivec.vmsumshs + res_vui = vec_msums(vus, vus, vui); // CHECK: @llvm.ppc.altivec.vmsumuhs + res_vi = vec_vmsumshs(vs, vs, vi); // CHECK: @llvm.ppc.altivec.vmsumshs + res_vui = vec_vmsumuhs(vus, vus, vui); // CHECK: @llvm.ppc.altivec.vmsumuhs + + /* vec_mtvscr */ + vec_mtvscr(vsc); // CHECK: @llvm.ppc.altivec.mtvscr + vec_mtvscr(vuc); // CHECK: @llvm.ppc.altivec.mtvscr + vec_mtvscr(vbc); // CHECK: @llvm.ppc.altivec.mtvscr + vec_mtvscr(vs); // CHECK: @llvm.ppc.altivec.mtvscr + vec_mtvscr(vus); // CHECK: @llvm.ppc.altivec.mtvscr + vec_mtvscr(vbs); // CHECK: @llvm.ppc.altivec.mtvscr + vec_mtvscr(vp); // CHECK: @llvm.ppc.altivec.mtvscr + vec_mtvscr(vi); // CHECK: @llvm.ppc.altivec.mtvscr + vec_mtvscr(vui); // CHECK: @llvm.ppc.altivec.mtvscr + vec_mtvscr(vbi); // CHECK: @llvm.ppc.altivec.mtvscr + + /* vec_mule */ + res_vs = vec_mule(vsc, vsc); // CHECK: @llvm.ppc.altivec.vmulesb + res_vus = vec_mule(vuc, vuc); // CHECK: @llvm.ppc.altivec.vmuleub + res_vi = vec_mule(vs, vs); // CHECK: @llvm.ppc.altivec.vmulesh + res_vui = vec_mule(vus, vus); // CHECK: @llvm.ppc.altivec.vmuleuh + res_vs = vec_vmulesb(vsc, vsc); // CHECK: @llvm.ppc.altivec.vmulesb + res_vus = vec_vmuleub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vmuleub + res_vi = vec_vmulesh(vs, vs); // CHECK: @llvm.ppc.altivec.vmulesh + res_vui = vec_vmuleuh(vus, vus); // CHECK: @llvm.ppc.altivec.vmuleuh + + /* vec_mulo */ + res_vs = vec_mulo(vsc, vsc); // CHECK: @llvm.ppc.altivec.vmulosb + res_vus = vec_mulo(vuc, vuc); // CHECK: @llvm.ppc.altivec.vmuloub + res_vi = vec_mulo(vs, vs); // CHECK: @llvm.ppc.altivec.vmulosh + res_vui = vec_mulo(vus, vus); // CHECK: @llvm.ppc.altivec.vmulouh + res_vs = vec_vmulosb(vsc, vsc); // CHECK: @llvm.ppc.altivec.vmulosb + res_vus = vec_vmuloub(vuc, vuc); // CHECK: @llvm.ppc.altivec.vmuloub + res_vi = vec_vmulosh(vs, vs); // CHECK: @llvm.ppc.altivec.vmulosh + res_vui = vec_vmulouh(vus, vus); // CHECK: @llvm.ppc.altivec.vmulouh + + /* vec_nmsub */ + res_vf = vec_nmsub(vf, vf, vf); // CHECK: @llvm.ppc.altivec.vnmsubfp + res_vf = vec_vnmsubfp(vf, vf, vf); // CHECK: @llvm.ppc.altivec.vnmsubfp + + /* vec_nor */ + res_vsc = vec_nor(vsc, vsc); // CHECK: or <16 x i8> + // CHECK: xor <16 x i8> + + res_vuc = vec_nor(vuc, vuc); // CHECK: or <16 x i8> + // CHECK: xor <16 x i8> + + res_vuc = vec_nor(vbc, vbc); // CHECK: or <16 x i8> + // CHECK: xor <16 x i8> + + res_vs = vec_nor(vs, vs); // CHECK: or <8 x i16> + // CHECK: xor <8 x i16> + + res_vus = vec_nor(vus, vus); // CHECK: or <8 x i16> + // CHECK: xor <8 x i16> + + res_vus = vec_nor(vbs, vbs); // CHECK: or <8 x i16> + // CHECK: xor <8 x i16> + + res_vi = vec_nor(vi, vi); // CHECK: or <4 x i32> + // CHECK: xor <4 x i32> + + res_vui = vec_nor(vui, vui); // CHECK: or <4 x i32> + // CHECK: xor <4 x i32> + + res_vui = vec_nor(vbi, vbi); // CHECK: or <4 x i32> + // CHECK: xor <4 x i32> + + res_vf = vec_nor(vf, vf); // CHECK: or <4 x i32> + // CHECK: xor <4 x i32> + + res_vsc = vec_vnor(vsc, vsc); // CHECK: or <16 x i8> + // CHECK: xor <16 x i8> + + res_vuc = vec_vnor(vuc, vuc); // CHECK: or <16 x i8> + // CHECK: xor <16 x i8> + + res_vuc = vec_vnor(vbc, vbc); // CHECK: or <16 x i8> + // CHECK: xor <16 x i8> + + res_vs = vec_vnor(vs, vs); // CHECK: or <8 x i16> + // CHECK: xor <8 x i16> + + res_vus = vec_vnor(vus, vus); // CHECK: or <8 x i16> + // CHECK: xor <8 x i16> + + res_vus = vec_vnor(vbs, vbs); // CHECK: or <8 x i16> + // CHECK: xor <8 x i16> + + res_vi = vec_vnor(vi, vi); // CHECK: or <4 x i32> + // CHECK: xor <4 x i32> + + res_vui = vec_vnor(vui, vui); // CHECK: or <4 x i32> + // CHECK: xor <4 x i32> + + res_vui = vec_vnor(vbi, vbi); // CHECK: or <4 x i32> + // CHECK: xor <4 x i32> + + res_vf = vec_vnor(vf, vf); // CHECK: or <4 x i32> + // CHECK: xor <4 x i32> + + /* vec_or */ + res_vsc = vec_or(vsc, vsc); // CHECK: or <16 x i8> + res_vsc = vec_or(vbc, vsc); // CHECK: or <16 x i8> + res_vsc = vec_or(vsc, vbc); // CHECK: or <16 x i8> + res_vuc = vec_or(vuc, vuc); // CHECK: or <16 x i8> + res_vuc = vec_or(vbc, vuc); // CHECK: or <16 x i8> + res_vuc = vec_or(vuc, vbc); // CHECK: or <16 x i8> + res_vbc = vec_or(vbc, vbc); // CHECK: or <16 x i8> + res_vs = vec_or(vs, vs); // CHECK: or <8 x i16> + res_vs = vec_or(vbs, vs); // CHECK: or <8 x i16> + res_vs = vec_or(vs, vbs); // CHECK: or <8 x i16> + res_vus = vec_or(vus, vus); // CHECK: or <8 x i16> + res_vus = vec_or(vbs, vus); // CHECK: or <8 x i16> + res_vus = vec_or(vus, vbs); // CHECK: or <8 x i16> + res_vbs = vec_or(vbs, vbs); // CHECK: or <8 x i16> + res_vi = vec_or(vi, vi); // CHECK: or <4 x i32> + res_vi = vec_or(vbi, vi); // CHECK: or <4 x i32> + res_vi = vec_or(vi, vbi); // CHECK: or <4 x i32> + res_vui = vec_or(vui, vui); // CHECK: or <4 x i32> + res_vui = vec_or(vbi, vui); // CHECK: or <4 x i32> + res_vui = vec_or(vui, vbi); // CHECK: or <4 x i32> + res_vbi = vec_or(vbi, vbi); // CHECK: or <4 x i32> + res_vf = vec_or(vf, vf); // CHECK: or <4 x i32> + res_vf = vec_or(vbi, vf); // CHECK: or <4 x i32> + res_vf = vec_or(vf, vbi); // CHECK: or <4 x i32> + res_vsc = vec_vor(vsc, vsc); // CHECK: or <16 x i8> + res_vsc = vec_vor(vbc, vsc); // CHECK: or <16 x i8> + res_vsc = vec_vor(vsc, vbc); // CHECK: or <16 x i8> + res_vuc = vec_vor(vuc, vuc); // CHECK: or <16 x i8> + res_vuc = vec_vor(vbc, vuc); // CHECK: or <16 x i8> + res_vuc = vec_vor(vuc, vbc); // CHECK: or <16 x i8> + res_vbc = vec_vor(vbc, vbc); // CHECK: or <16 x i8> + res_vs = vec_vor(vs, vs); // CHECK: or <8 x i16> + res_vs = vec_vor(vbs, vs); // CHECK: or <8 x i16> + res_vs = vec_vor(vs, vbs); // CHECK: or <8 x i16> + res_vus = vec_vor(vus, vus); // CHECK: or <8 x i16> + res_vus = vec_vor(vbs, vus); // CHECK: or <8 x i16> + res_vus = vec_vor(vus, vbs); // CHECK: or <8 x i16> + res_vbs = vec_vor(vbs, vbs); // CHECK: or <8 x i16> + res_vi = vec_vor(vi, vi); // CHECK: or <4 x i32> + res_vi = vec_vor(vbi, vi); // CHECK: or <4 x i32> + res_vi = vec_vor(vi, vbi); // CHECK: or <4 x i32> + res_vui = vec_vor(vui, vui); // CHECK: or <4 x i32> + res_vui = vec_vor(vbi, vui); // CHECK: or <4 x i32> + res_vui = vec_vor(vui, vbi); // CHECK: or <4 x i32> + res_vbi = vec_vor(vbi, vbi); // CHECK: or <4 x i32> + res_vf = vec_vor(vf, vf); // CHECK: or <4 x i32> + res_vf = vec_vor(vbi, vf); // CHECK: or <4 x i32> + res_vf = vec_vor(vf, vbi); // CHECK: or <4 x i32> + + /* vec_pack */ + res_vsc = vec_pack(vs, vs); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_pack(vus, vus); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_pack(vbs, vbs); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_pack(vi, vi); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_pack(vui, vui); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_pack(vbi, vbi); // CHECK: @llvm.ppc.altivec.vperm + res_vsc = vec_vpkuhum(vs, vs); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_vpkuhum(vus, vus); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_vpkuhum(vbs, vbs); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_vpkuwum(vi, vi); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_vpkuwum(vui, vui); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_vpkuwum(vbi, vbi); // CHECK: @llvm.ppc.altivec.vperm + + /* vec_packpx */ + res_vp = vec_packpx(vui, vui); // CHECK: @llvm.ppc.altivec.vpkpx + res_vp = vec_vpkpx(vui, vui); // CHECK: @llvm.ppc.altivec.vpkpx + + /* vec_packs */ + res_vsc = vec_packs(vs, vs); // CHECK: @llvm.ppc.altivec.vpkshss + res_vuc = vec_packs(vus, vus); // CHECK: @llvm.ppc.altivec.vpkuhus + res_vs = vec_packs(vi, vi); // CHECK: @llvm.ppc.altivec.vpkswss + res_vus = vec_packs(vui, vui); // CHECK: @llvm.ppc.altivec.vpkuwus + res_vsc = vec_vpkshss(vs, vs); // CHECK: @llvm.ppc.altivec.vpkshss + res_vuc = vec_vpkuhus(vus, vus); // CHECK: @llvm.ppc.altivec.vpkuhus + res_vs = vec_vpkswss(vi, vi); // CHECK: @llvm.ppc.altivec.vpkswss + res_vus = vec_vpkuwus(vui, vui); // CHECK: @llvm.ppc.altivec.vpkuwus + + /* vec_packsu */ + res_vuc = vec_packsu(vs, vs); // CHECK: @llvm.ppc.altivec.vpkshus + res_vuc = vec_packsu(vus, vus); // CHECK: @llvm.ppc.altivec.vpkuhus + res_vus = vec_packsu(vi, vi); // CHECK: @llvm.ppc.altivec.vpkswus + res_vus = vec_packsu(vui, vui); // CHECK: @llvm.ppc.altivec.vpkuwus + res_vuc = vec_vpkshus(vs, vs); // CHECK: @llvm.ppc.altivec.vpkshus + res_vuc = vec_vpkshus(vus, vus); // CHECK: @llvm.ppc.altivec.vpkuhus + res_vus = vec_vpkswus(vi, vi); // CHECK: @llvm.ppc.altivec.vpkswus + res_vus = vec_vpkswus(vui, vui); // CHECK: @llvm.ppc.altivec.vpkuwus + + /* vec_perm */ + res_vsc = vec_perm(vsc, vsc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_perm(vuc, vuc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_perm(vbc, vbc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_perm(vs, vs, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_perm(vus, vus, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_perm(vbs, vbs, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_perm(vp, vp, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_perm(vi, vi, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_perm(vui, vui, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbi = vec_perm(vbi, vbi, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_perm(vf, vf, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vsc = vec_vperm(vsc, vsc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_vperm(vuc, vuc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_vperm(vbc, vbc, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_vperm(vs, vs, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_vperm(vus, vus, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_vperm(vbs, vbs, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_vperm(vp, vp, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_vperm(vi, vi, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_vperm(vui, vui, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vbi = vec_vperm(vbi, vbi, vuc); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_vperm(vf, vf, vuc); // CHECK: @llvm.ppc.altivec.vperm + + /* vec_re */ + res_vf = vec_re(vf); // CHECK: @llvm.ppc.altivec.vrefp + res_vf = vec_vrefp(vf); // CHECK: @llvm.ppc.altivec.vrefp + + /* vec_rl */ + res_vsc = vec_rl(vsc, vuc); // CHECK: @llvm.ppc.altivec.vrlb + res_vuc = vec_rl(vuc, vuc); // CHECK: @llvm.ppc.altivec.vrlb + res_vs = vec_rl(vs, vus); // CHECK: @llvm.ppc.altivec.vrlh + res_vus = vec_rl(vus, vus); // CHECK: @llvm.ppc.altivec.vrlh + res_vi = vec_rl(vi, vui); // CHECK: @llvm.ppc.altivec.vrlw + res_vui = vec_rl(vui, vui); // CHECK: @llvm.ppc.altivec.vrlw + res_vsc = vec_vrlb(vsc, vuc); // CHECK: @llvm.ppc.altivec.vrlb + res_vuc = vec_vrlb(vuc, vuc); // CHECK: @llvm.ppc.altivec.vrlb + res_vs = vec_vrlh(vs, vus); // CHECK: @llvm.ppc.altivec.vrlh + res_vus = vec_vrlh(vus, vus); // CHECK: @llvm.ppc.altivec.vrlh + res_vi = vec_vrlw(vi, vui); // CHECK: @llvm.ppc.altivec.vrlw + res_vui = vec_vrlw(vui, vui); // CHECK: @llvm.ppc.altivec.vrlw + + /* vec_round */ + res_vf = vec_round(vf); // CHECK: @llvm.ppc.altivec.vrfin + res_vf = vec_vrfin(vf); // CHECK: @llvm.ppc.altivec.vrfin + + /* vec_rsqrte */ + res_vf = vec_rsqrte(vf); // CHECK: @llvm.ppc.altivec.vrsqrtefp + res_vf = vec_vrsqrtefp(vf); // CHECK: @llvm.ppc.altivec.vrsqrtefp + + /* vec_sel */ + res_vsc = vec_sel(vsc, vsc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vsc = vec_sel(vsc, vsc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vuc = vec_sel(vuc, vuc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vuc = vec_sel(vuc, vuc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vbc = vec_sel(vbc, vbc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vbc = vec_sel(vbc, vbc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vs = vec_sel(vs, vs, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vs = vec_sel(vs, vs, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vus = vec_sel(vus, vus, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vus = vec_sel(vus, vus, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vbs = vec_sel(vbs, vbs, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vbs = vec_sel(vbs, vbs, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vi = vec_sel(vi, vi, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vi = vec_sel(vi, vi, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vui = vec_sel(vui, vui, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vui = vec_sel(vui, vui, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vbi = vec_sel(vbi, vbi, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vbi = vec_sel(vbi, vbi, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vf = vec_sel(vf, vf, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vf = vec_sel(vf, vf, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vsc = vec_vsel(vsc, vsc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vsc = vec_vsel(vsc, vsc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vuc = vec_vsel(vuc, vuc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vuc = vec_vsel(vuc, vuc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vbc = vec_vsel(vbc, vbc, vuc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vbc = vec_vsel(vbc, vbc, vbc); // CHECK: xor <16 x i8> + // CHECK: and <16 x i8> + // CHECK: and <16 x i8> + // CHECK: or <16 x i8> + + res_vs = vec_vsel(vs, vs, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vs = vec_vsel(vs, vs, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vus = vec_vsel(vus, vus, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vus = vec_vsel(vus, vus, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vbs = vec_vsel(vbs, vbs, vus); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vbs = vec_vsel(vbs, vbs, vbs); // CHECK: xor <8 x i16> + // CHECK: and <8 x i16> + // CHECK: and <8 x i16> + // CHECK: or <8 x i16> + + res_vi = vec_vsel(vi, vi, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vi = vec_vsel(vi, vi, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vui = vec_vsel(vui, vui, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vui = vec_vsel(vui, vui, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vbi = vec_vsel(vbi, vbi, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vbi = vec_vsel(vbi, vbi, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vf = vec_vsel(vf, vf, vui); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + res_vf = vec_vsel(vf, vf, vbi); // CHECK: xor <4 x i32> + // CHECK: and <4 x i32> + // CHECK: and <4 x i32> + // CHECK: or <4 x i32> + + /* vec_sl */ + res_vsc = vec_sl(vsc, vuc); // CHECK: shl <16 x i8> + res_vuc = vec_sl(vuc, vuc); // CHECK: shl <16 x i8> + res_vs = vec_sl(vs, vus); // CHECK: shl <8 x i16> + res_vus = vec_sl(vus, vus); // CHECK: shl <8 x i16> + res_vi = vec_sl(vi, vui); // CHECK: shl <4 x i32> + res_vui = vec_sl(vui, vui); // CHECK: shl <4 x i32> + res_vsc = vec_vslb(vsc, vuc); // CHECK: shl <16 x i8> + res_vuc = vec_vslb(vuc, vuc); // CHECK: shl <16 x i8> + res_vs = vec_vslh(vs, vus); // CHECK: shl <8 x i16> + res_vus = vec_vslh(vus, vus); // CHECK: shl <8 x i16> + res_vi = vec_vslw(vi, vui); // CHECK: shl <4 x i32> + res_vui = vec_vslw(vui, vui); // CHECK: shl <4 x i32> + + /* vec_sld */ + res_vsc = vec_sld(vsc, vsc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_sld(vuc, vuc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_sld(vs, vs, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_sld(vus, vus, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_sld(vp, vp, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_sld(vi, vi, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_sld(vui, vui, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_sld(vf, vf, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vsc = vec_vsldoi(vsc, vsc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_vsldoi(vuc, vuc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_vsldoi(vs, vs, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_vsldoi(vus, vus, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_vsldoi(vp, vp, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_vsldoi(vi, vi, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_vsldoi(vui, vui, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_vsldoi(vf, vf, 0); // CHECK: @llvm.ppc.altivec.vperm + + /* vec_sll */ + res_vsc = vec_sll(vsc, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vsc = vec_sll(vsc, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vsc = vec_sll(vsc, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vuc = vec_sll(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vuc = vec_sll(vuc, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vuc = vec_sll(vuc, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vbc = vec_sll(vbc, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vbc = vec_sll(vbc, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vbc = vec_sll(vbc, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vs = vec_sll(vs, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vs = vec_sll(vs, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vs = vec_sll(vs, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vus = vec_sll(vus, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vus = vec_sll(vus, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vus = vec_sll(vus, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vbs = vec_sll(vbs, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vbs = vec_sll(vbs, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vbs = vec_sll(vbs, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vp = vec_sll(vp, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vp = vec_sll(vp, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vp = vec_sll(vp, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vi = vec_sll(vi, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vi = vec_sll(vi, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vi = vec_sll(vi, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vui = vec_sll(vui, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vui = vec_sll(vui, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vui = vec_sll(vui, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vbi = vec_sll(vbi, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vbi = vec_sll(vbi, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vbi = vec_sll(vbi, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vsc = vec_vsl(vsc, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vsc = vec_vsl(vsc, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vsc = vec_vsl(vsc, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vuc = vec_vsl(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vuc = vec_vsl(vuc, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vuc = vec_vsl(vuc, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vbc = vec_vsl(vbc, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vbc = vec_vsl(vbc, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vbc = vec_vsl(vbc, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vs = vec_vsl(vs, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vs = vec_vsl(vs, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vs = vec_vsl(vs, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vus = vec_vsl(vus, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vus = vec_vsl(vus, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vus = vec_vsl(vus, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vbs = vec_vsl(vbs, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vbs = vec_vsl(vbs, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vbs = vec_vsl(vbs, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vp = vec_vsl(vp, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vp = vec_vsl(vp, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vp = vec_vsl(vp, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vi = vec_vsl(vi, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vi = vec_vsl(vi, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vi = vec_vsl(vi, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vui = vec_vsl(vui, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vui = vec_vsl(vui, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vui = vec_vsl(vui, vui); // CHECK: @llvm.ppc.altivec.vsl + res_vbi = vec_vsl(vbi, vuc); // CHECK: @llvm.ppc.altivec.vsl + res_vbi = vec_vsl(vbi, vus); // CHECK: @llvm.ppc.altivec.vsl + res_vbi = vec_vsl(vbi, vui); // CHECK: @llvm.ppc.altivec.vsl + + /* vec_slo */ + res_vsc = vec_slo(vsc, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vsc = vec_slo(vsc, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vuc = vec_slo(vuc, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vuc = vec_slo(vuc, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vs = vec_slo(vs, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vs = vec_slo(vs, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vus = vec_slo(vus, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vus = vec_slo(vus, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vp = vec_slo(vp, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vp = vec_slo(vp, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vi = vec_slo(vi, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vi = vec_slo(vi, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vui = vec_slo(vui, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vui = vec_slo(vui, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vf = vec_slo(vf, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vf = vec_slo(vf, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vsc = vec_vslo(vsc, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vsc = vec_vslo(vsc, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vuc = vec_vslo(vuc, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vuc = vec_vslo(vuc, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vs = vec_vslo(vs, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vs = vec_vslo(vs, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vus = vec_vslo(vus, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vus = vec_vslo(vus, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vp = vec_vslo(vp, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vp = vec_vslo(vp, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vi = vec_vslo(vi, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vi = vec_vslo(vi, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vui = vec_vslo(vui, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vui = vec_vslo(vui, vuc); // CHECK: @llvm.ppc.altivec.vslo + res_vf = vec_vslo(vf, vsc); // CHECK: @llvm.ppc.altivec.vslo + res_vf = vec_vslo(vf, vuc); // CHECK: @llvm.ppc.altivec.vslo + + /* vec_splat */ + res_vsc = vec_splat(vsc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_splat(vuc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_splat(vbc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_splat(vs, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_splat(vus, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_splat(vbs, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_splat(vp, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_splat(vi, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_splat(vui, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vbi = vec_splat(vbi, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_splat(vf, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vsc = vec_vspltb(vsc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vuc = vec_vspltb(vuc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vbc = vec_vspltb(vbc, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vs = vec_vsplth(vs, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vus = vec_vsplth(vus, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vbs = vec_vsplth(vbs, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vp = vec_vsplth(vp, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vi = vec_vspltw(vi, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vui = vec_vspltw(vui, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vbi = vec_vspltw(vbi, 0); // CHECK: @llvm.ppc.altivec.vperm + res_vf = vec_vspltw(vf, 0); // CHECK: @llvm.ppc.altivec.vperm + + /* vec_splat_s8 */ + res_vsc = vec_splat_s8(0x09); // TODO: add check + res_vsc = vec_vspltisb(0x09); // TODO: add check + + /* vec_splat_s16 */ + res_vs = vec_splat_s16(0x09); // TODO: add check + res_vs = vec_vspltish(0x09); // TODO: add check + + /* vec_splat_s32 */ + res_vi = vec_splat_s32(0x09); // TODO: add check + res_vi = vec_vspltisw(0x09); // TODO: add check + + /* vec_splat_u8 */ + res_vuc = vec_splat_u8(0x09); // TODO: add check + + /* vec_splat_u16 */ + res_vus = vec_splat_u16(0x09); // TODO: add check + + /* vec_splat_u32 */ + res_vui = vec_splat_u32(0x09); // TODO: add check + + /* vec_sr */ + res_vsc = vec_sr(vsc, vuc); // CHECK: shr <16 x i8> + res_vuc = vec_sr(vuc, vuc); // CHECK: shr <16 x i8> + res_vs = vec_sr(vs, vus); // CHECK: shr <8 x i16> + res_vus = vec_sr(vus, vus); // CHECK: shr <8 x i16> + res_vi = vec_sr(vi, vui); // CHECK: shr <4 x i32> + res_vui = vec_sr(vui, vui); // CHECK: shr <4 x i32> + res_vsc = vec_vsrb(vsc, vuc); // CHECK: shr <16 x i8> + res_vuc = vec_vsrb(vuc, vuc); // CHECK: shr <16 x i8> + res_vs = vec_vsrh(vs, vus); // CHECK: shr <8 x i16> + res_vus = vec_vsrh(vus, vus); // CHECK: shr <8 x i16> + res_vi = vec_vsrw(vi, vui); // CHECK: shr <4 x i32> + res_vui = vec_vsrw(vui, vui); // CHECK: shr <4 x i32> + + /* vec_sra */ + res_vsc = vec_sra(vsc, vuc); // CHECK: @llvm.ppc.altivec.vsrab + res_vuc = vec_sra(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsrab + res_vs = vec_sra(vs, vus); // CHECK: @llvm.ppc.altivec.vsrah + res_vus = vec_sra(vus, vus); // CHECK: @llvm.ppc.altivec.vsrah + res_vi = vec_sra(vi, vui); // CHECK: @llvm.ppc.altivec.vsraw + res_vui = vec_sra(vui, vui); // CHECK: @llvm.ppc.altivec.vsraw + res_vsc = vec_vsrab(vsc, vuc); // CHECK: @llvm.ppc.altivec.vsrab + res_vuc = vec_vsrab(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsrab + res_vs = vec_vsrah(vs, vus); // CHECK: @llvm.ppc.altivec.vsrah + res_vus = vec_vsrah(vus, vus); // CHECK: @llvm.ppc.altivec.vsrah + res_vi = vec_vsraw(vi, vui); // CHECK: @llvm.ppc.altivec.vsraw + res_vui = vec_vsraw(vui, vui); // CHECK: @llvm.ppc.altivec.vsraw + + /* vec_srl */ + res_vsc = vec_srl(vsc, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vsc = vec_srl(vsc, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vsc = vec_srl(vsc, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vuc = vec_srl(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vuc = vec_srl(vuc, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vuc = vec_srl(vuc, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vbc = vec_srl(vbc, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vbc = vec_srl(vbc, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vbc = vec_srl(vbc, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vs = vec_srl(vs, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vs = vec_srl(vs, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vs = vec_srl(vs, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vus = vec_srl(vus, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vus = vec_srl(vus, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vus = vec_srl(vus, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vbs = vec_srl(vbs, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vbs = vec_srl(vbs, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vbs = vec_srl(vbs, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vp = vec_srl(vp, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vp = vec_srl(vp, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vp = vec_srl(vp, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vi = vec_srl(vi, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vi = vec_srl(vi, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vi = vec_srl(vi, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vui = vec_srl(vui, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vui = vec_srl(vui, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vui = vec_srl(vui, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vbi = vec_srl(vbi, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vbi = vec_srl(vbi, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vbi = vec_srl(vbi, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vsc = vec_vsr(vsc, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vsc = vec_vsr(vsc, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vsc = vec_vsr(vsc, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vuc = vec_vsr(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vuc = vec_vsr(vuc, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vuc = vec_vsr(vuc, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vbc = vec_vsr(vbc, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vbc = vec_vsr(vbc, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vbc = vec_vsr(vbc, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vs = vec_vsr(vs, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vs = vec_vsr(vs, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vs = vec_vsr(vs, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vus = vec_vsr(vus, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vus = vec_vsr(vus, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vus = vec_vsr(vus, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vbs = vec_vsr(vbs, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vbs = vec_vsr(vbs, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vbs = vec_vsr(vbs, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vp = vec_vsr(vp, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vp = vec_vsr(vp, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vp = vec_vsr(vp, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vi = vec_vsr(vi, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vi = vec_vsr(vi, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vi = vec_vsr(vi, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vui = vec_vsr(vui, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vui = vec_vsr(vui, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vui = vec_vsr(vui, vui); // CHECK: @llvm.ppc.altivec.vsr + res_vbi = vec_vsr(vbi, vuc); // CHECK: @llvm.ppc.altivec.vsr + res_vbi = vec_vsr(vbi, vus); // CHECK: @llvm.ppc.altivec.vsr + res_vbi = vec_vsr(vbi, vui); // CHECK: @llvm.ppc.altivec.vsr + + /* vec_sro */ + res_vsc = vec_sro(vsc, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vsc = vec_sro(vsc, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vuc = vec_sro(vuc, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vuc = vec_sro(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vs = vec_sro(vs, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vs = vec_sro(vs, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vus = vec_sro(vus, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vus = vec_sro(vus, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vp = vec_sro(vp, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vp = vec_sro(vp, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vi = vec_sro(vi, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vi = vec_sro(vi, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vui = vec_sro(vui, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vui = vec_sro(vui, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vf = vec_sro(vf, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vf = vec_sro(vf, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vsc = vec_vsro(vsc, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vsc = vec_vsro(vsc, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vuc = vec_vsro(vuc, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vuc = vec_vsro(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vs = vec_vsro(vs, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vs = vec_vsro(vs, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vus = vec_vsro(vus, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vus = vec_vsro(vus, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vp = vec_vsro(vp, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vp = vec_vsro(vp, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vi = vec_vsro(vi, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vi = vec_vsro(vi, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vui = vec_vsro(vui, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vui = vec_vsro(vui, vuc); // CHECK: @llvm.ppc.altivec.vsro + res_vf = vec_vsro(vf, vsc); // CHECK: @llvm.ppc.altivec.vsro + res_vf = vec_vsro(vf, vuc); // CHECK: @llvm.ppc.altivec.vsro + + /* vec_st */ + vec_st(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vbc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vbc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vbc, 0, &vbc); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vbs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vbs, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vbs, 0, &vbs); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vp, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vp, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vp, 0, &vp); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vbi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vbi, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vbi, 0, &vbi); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.stvx + vec_st(vf, 0, ¶m_f); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vbc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vbc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vbc, 0, &vbc); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vbs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vbs, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vbs, 0, &vbs); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vp, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vp, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vp, 0, &vp); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vbi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vbi, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vbi, 0, &vbi); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.stvx + vec_stvx(vf, 0, ¶m_f); // CHECK: @llvm.ppc.altivec.stvx + + /* vec_ste */ + vec_ste(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvebx + vec_ste(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvebx + vec_ste(vbc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvebx + vec_ste(vbc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvebx + vec_ste(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvehx + vec_ste(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvehx + vec_ste(vbs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvehx + vec_ste(vbs, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvehx + vec_ste(vp, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvehx + vec_ste(vp, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvehx + vec_ste(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvewx + vec_ste(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvewx + vec_ste(vbi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvewx + vec_ste(vbi, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvewx + vec_ste(vf, 0, ¶m_f); // CHECK: @llvm.ppc.altivec.stvewx + vec_stvebx(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvebx + vec_stvebx(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvebx + vec_stvebx(vbc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvebx + vec_stvebx(vbc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvebx + vec_stvehx(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvehx + vec_stvehx(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvehx + vec_stvehx(vbs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvehx + vec_stvehx(vbs, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvehx + vec_stvehx(vp, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvehx + vec_stvehx(vp, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvehx + vec_stvewx(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvewx + vec_stvewx(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvewx + vec_stvewx(vbi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvewx + vec_stvewx(vbi, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvewx + vec_stvewx(vf, 0, ¶m_f); // CHECK: @llvm.ppc.altivec.stvewx + + /* vec_stl */ + vec_stl(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vbc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vbc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vbc, 0, &vbc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vbs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vbs, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vbs, 0, &vbs); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vp, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vp, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vp, 0, &vp); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vbi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vbi, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vbi, 0, &vbi); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.stvxl + vec_stl(vf, 0, ¶m_f); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vbc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vbc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vbc, 0, &vbc); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vbs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vbs, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vbs, 0, &vbs); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vp, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vp, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vp, 0, &vp); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vbi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vbi, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vbi, 0, &vbi); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.stvxl + vec_stvxl(vf, 0, ¶m_f); // CHECK: @llvm.ppc.altivec.stvxl + + /* vec_sub */ + res_vsc = vec_sub(vsc, vsc); // CHECK: sub <16 x i8> + res_vsc = vec_sub(vbc, vsc); // CHECK: sub <16 x i8> + res_vsc = vec_sub(vsc, vbc); // CHECK: sub <16 x i8> + res_vuc = vec_sub(vuc, vuc); // CHECK: sub <16 x i8> + res_vuc = vec_sub(vbc, vuc); // CHECK: sub <16 x i8> + res_vuc = vec_sub(vuc, vbc); // CHECK: sub <16 x i8> + res_vs = vec_sub(vs, vs); // CHECK: sub <8 x i16> + res_vs = vec_sub(vbs, vs); // CHECK: sub <8 x i16> + res_vs = vec_sub(vs, vbs); // CHECK: sub <8 x i16> + res_vus = vec_sub(vus, vus); // CHECK: sub <8 x i16> + res_vus = vec_sub(vbs, vus); // CHECK: sub <8 x i16> + res_vus = vec_sub(vus, vbs); // CHECK: sub <8 x i16> + res_vi = vec_sub(vi, vi); // CHECK: sub <4 x i32> + res_vi = vec_sub(vbi, vi); // CHECK: sub <4 x i32> + res_vi = vec_sub(vi, vbi); // CHECK: sub <4 x i32> + res_vui = vec_sub(vui, vui); // CHECK: sub <4 x i32> + res_vui = vec_sub(vbi, vui); // CHECK: sub <4 x i32> + res_vui = vec_sub(vui, vbi); // CHECK: sub <4 x i32> + res_vf = vec_sub(vf, vf); // CHECK: fsub <4 x float> + res_vsc = vec_vsububm(vsc, vsc); // CHECK: sub <16 x i8> + res_vsc = vec_vsububm(vbc, vsc); // CHECK: sub <16 x i8> + res_vsc = vec_vsububm(vsc, vbc); // CHECK: sub <16 x i8> + res_vuc = vec_vsububm(vuc, vuc); // CHECK: sub <16 x i8> + res_vuc = vec_vsububm(vbc, vuc); // CHECK: sub <16 x i8> + res_vuc = vec_vsububm(vuc, vbc); // CHECK: sub <16 x i8> + res_vs = vec_vsubuhm(vs, vs); // CHECK: sub <8 x i16> + res_vs = vec_vsubuhm(vbs, vus); // CHECK: sub <8 x i16> + res_vs = vec_vsubuhm(vus, vbs); // CHECK: sub <8 x i16> + res_vus = vec_vsubuhm(vus, vus); // CHECK: sub <8 x i16> + res_vus = vec_vsubuhm(vbs, vus); // CHECK: sub <8 x i16> + res_vus = vec_vsubuhm(vus, vbs); // CHECK: sub <8 x i16> + res_vi = vec_vsubuwm(vi, vi); // CHECK: sub <4 x i32> + res_vi = vec_vsubuwm(vbi, vi); // CHECK: sub <4 x i32> + res_vi = vec_vsubuwm(vi, vbi); // CHECK: sub <4 x i32> + res_vui = vec_vsubuwm(vui, vui); // CHECK: sub <4 x i32> + res_vui = vec_vsubuwm(vbi, vui); // CHECK: sub <4 x i32> + res_vui = vec_vsubuwm(vui, vbi); // CHECK: sub <4 x i32> + res_vf = vec_vsubfp(vf, vf); // CHECK: fsub <4 x float> + + /* vec_subc */ + res_vui = vec_subc(vui, vui); // CHECK: @llvm.ppc.altivec.vsubcuw + res_vui = vec_vsubcuw(vui, vui); // CHECK: @llvm.ppc.altivec.vsubcuw + + /* vec_subs */ + res_vsc = vec_subs(vsc, vsc); // CHECK: @llvm.ppc.altivec.vsubsbs + res_vsc = vec_subs(vbc, vsc); // CHECK: @llvm.ppc.altivec.vsubsbs + res_vsc = vec_subs(vsc, vbc); // CHECK: @llvm.ppc.altivec.vsubsbs + res_vuc = vec_subs(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsububs + res_vuc = vec_subs(vbc, vuc); // CHECK: @llvm.ppc.altivec.vsububs + res_vuc = vec_subs(vuc, vbc); // CHECK: @llvm.ppc.altivec.vsububs + res_vs = vec_subs(vs, vs); // CHECK: @llvm.ppc.altivec.vsubshs + res_vs = vec_subs(vbs, vs); // CHECK: @llvm.ppc.altivec.vsubshs + res_vs = vec_subs(vs, vbs); // CHECK: @llvm.ppc.altivec.vsubshs + res_vus = vec_subs(vus, vus); // CHECK: @llvm.ppc.altivec.vsubuhs + res_vus = vec_subs(vbs, vus); // CHECK: @llvm.ppc.altivec.vsubuhs + res_vus = vec_subs(vus, vbs); // CHECK: @llvm.ppc.altivec.vsubuhs + res_vi = vec_subs(vi, vi); // CHECK: @llvm.ppc.altivec.vsubsws + res_vi = vec_subs(vbi, vi); // CHECK: @llvm.ppc.altivec.vsubsws + res_vi = vec_subs(vi, vbi); // CHECK: @llvm.ppc.altivec.vsubsws + res_vui = vec_subs(vui, vui); // CHECK: @llvm.ppc.altivec.vsubuws + res_vui = vec_subs(vbi, vui); // CHECK: @llvm.ppc.altivec.vsubuws + res_vui = vec_subs(vui, vbi); // CHECK: @llvm.ppc.altivec.vsubuws + res_vsc = vec_vsubsbs(vsc, vsc); // CHECK: @llvm.ppc.altivec.vsubsbs + res_vsc = vec_vsubsbs(vbc, vsc); // CHECK: @llvm.ppc.altivec.vsubsbs + res_vsc = vec_vsubsbs(vsc, vbc); // CHECK: @llvm.ppc.altivec.vsubsbs + res_vuc = vec_vsububs(vuc, vuc); // CHECK: @llvm.ppc.altivec.vsububs + res_vuc = vec_vsububs(vbc, vuc); // CHECK: @llvm.ppc.altivec.vsububs + res_vuc = vec_vsububs(vuc, vbc); // CHECK: @llvm.ppc.altivec.vsububs + res_vs = vec_vsubshs(vs, vs); // CHECK: @llvm.ppc.altivec.vsubshs + res_vs = vec_vsubshs(vbs, vs); // CHECK: @llvm.ppc.altivec.vsubshs + res_vs = vec_vsubshs(vs, vbs); // CHECK: @llvm.ppc.altivec.vsubshs + res_vus = vec_vsubuhs(vus, vus); // CHECK: @llvm.ppc.altivec.vsubuhs + res_vus = vec_vsubuhs(vbs, vus); // CHECK: @llvm.ppc.altivec.vsubuhs + res_vus = vec_vsubuhs(vus, vbs); // CHECK: @llvm.ppc.altivec.vsubuhs + res_vi = vec_vsubsws(vi, vi); // CHECK: @llvm.ppc.altivec.vsubsws + res_vi = vec_vsubsws(vbi, vi); // CHECK: @llvm.ppc.altivec.vsubsws + res_vi = vec_vsubsws(vi, vbi); // CHECK: @llvm.ppc.altivec.vsubsws + res_vui = vec_vsubuws(vui, vui); // CHECK: @llvm.ppc.altivec.vsubuws + res_vui = vec_vsubuws(vbi, vui); // CHECK: @llvm.ppc.altivec.vsubuws + res_vui = vec_vsubuws(vui, vbi); // CHECK: @llvm.ppc.altivec.vsubuws + + /* vec_sum4s */ + res_vi = vec_sum4s(vsc, vi); // CHECK: @llvm.ppc.altivec.vsum4sbs + res_vui = vec_sum4s(vuc, vui); // CHECK: @llvm.ppc.altivec.vsum4ubs + res_vi = vec_sum4s(vs, vi); // CHECK: @llvm.ppc.altivec.vsum4shs + res_vi = vec_vsum4sbs(vsc, vi); // CHECK: @llvm.ppc.altivec.vsum4sbs + res_vui = vec_vsum4ubs(vuc, vui); // CHECK: @llvm.ppc.altivec.vsum4ubs + res_vi = vec_vsum4shs(vs, vi); // CHECK: @llvm.ppc.altivec.vsum4shs + + /* vec_sum2s */ + res_vi = vec_sum2s(vi, vi); // CHECK: @llvm.ppc.altivec.vsum2sws + res_vi = vec_vsum2sws(vi, vi); // CHECK: @llvm.ppc.altivec.vsum2sws + + /* vec_sums */ + res_vi = vec_sums(vi, vi); // CHECK: @llvm.ppc.altivec.vsumsws + res_vi = vec_vsumsws(vi, vi); // CHECK: @llvm.ppc.altivec.vsumsws + + /* vec_trunc */ + res_vf = vec_trunc(vf); // CHECK: @llvm.ppc.altivec.vrfiz + res_vf = vec_vrfiz(vf); // CHECK: @llvm.ppc.altivec.vrfiz + + /* vec_unpackh */ + res_vs = vec_unpackh(vsc); // CHECK: @llvm.ppc.altivec.vupkhsb + res_vbs = vec_unpackh(vbc); // CHECK: @llvm.ppc.altivec.vupkhsb + res_vi = vec_unpackh(vs); // CHECK: @llvm.ppc.altivec.vupkhsh + res_vbi = vec_unpackh(vbs); // CHECK: @llvm.ppc.altivec.vupkhsh + res_vui = vec_unpackh(vp); // CHECK: @llvm.ppc.altivec.vupkhsh + res_vs = vec_vupkhsb(vsc); // CHECK: @llvm.ppc.altivec.vupkhsb + res_vbs = vec_vupkhsb(vbc); // CHECK: @llvm.ppc.altivec.vupkhsb + res_vi = vec_vupkhsh(vs); // CHECK: @llvm.ppc.altivec.vupkhsh + res_vbi = vec_vupkhsh(vbs); // CHECK: @llvm.ppc.altivec.vupkhsh + res_vui = vec_vupkhsh(vp); // CHECK: @llvm.ppc.altivec.vupkhsh + + /* vec_unpackl */ + res_vs = vec_unpackl(vsc); // CHECK: @llvm.ppc.altivec.vupklsb + res_vbs = vec_unpackl(vbc); // CHECK: @llvm.ppc.altivec.vupklsb + res_vi = vec_unpackl(vs); // CHECK: @llvm.ppc.altivec.vupklsh + res_vbi = vec_unpackl(vbs); // CHECK: @llvm.ppc.altivec.vupklsh + res_vui = vec_unpackl(vp); // CHECK: @llvm.ppc.altivec.vupklsh + res_vs = vec_vupklsb(vsc); // CHECK: @llvm.ppc.altivec.vupklsb + res_vbs = vec_vupklsb(vbc); // CHECK: @llvm.ppc.altivec.vupklsb + res_vi = vec_vupklsh(vs); // CHECK: @llvm.ppc.altivec.vupklsh + res_vbi = vec_vupklsh(vbs); // CHECK: @llvm.ppc.altivec.vupklsh + res_vui = vec_vupklsh(vp); // CHECK: @llvm.ppc.altivec.vupklsh + + /* vec_xor */ + res_vsc = vec_xor(vsc, vsc); // CHECK: xor <16 x i8> + res_vsc = vec_xor(vbc, vsc); // CHECK: xor <16 x i8> + res_vsc = vec_xor(vsc, vbc); // CHECK: xor <16 x i8> + res_vuc = vec_xor(vuc, vuc); // CHECK: xor <16 x i8> + res_vuc = vec_xor(vbc, vuc); // CHECK: xor <16 x i8> + res_vuc = vec_xor(vuc, vbc); // CHECK: xor <16 x i8> + res_vbc = vec_xor(vbc, vbc); // CHECK: xor <16 x i8> + res_vs = vec_xor(vs, vs); // CHECK: xor <8 x i16> + res_vs = vec_xor(vbs, vs); // CHECK: xor <8 x i16> + res_vs = vec_xor(vs, vbs); // CHECK: xor <8 x i16> + res_vus = vec_xor(vus, vus); // CHECK: xor <8 x i16> + res_vus = vec_xor(vbs, vus); // CHECK: xor <8 x i16> + res_vus = vec_xor(vus, vbs); // CHECK: xor <8 x i16> + res_vbs = vec_xor(vbs, vbs); // CHECK: xor <8 x i16> + res_vi = vec_xor(vi, vi); // CHECK: xor <4 x i32> + res_vi = vec_xor(vbi, vi); // CHECK: xor <4 x i32> + res_vi = vec_xor(vi, vbi); // CHECK: xor <4 x i32> + res_vui = vec_xor(vui, vui); // CHECK: xor <4 x i32> + res_vui = vec_xor(vbi, vui); // CHECK: xor <4 x i32> + res_vui = vec_xor(vui, vbi); // CHECK: xor <4 x i32> + res_vbi = vec_xor(vbi, vbi); // CHECK: xor <4 x i32> + res_vf = vec_xor(vf, vf); // CHECK: xor <4 x i32> + res_vf = vec_xor(vbi, vf); // CHECK: xor <4 x i32> + res_vf = vec_xor(vf, vbi); // CHECK: xor <4 x i32> + res_vsc = vec_vxor(vsc, vsc); // CHECK: xor <16 x i8> + res_vsc = vec_vxor(vbc, vsc); // CHECK: xor <16 x i8> + res_vsc = vec_vxor(vsc, vbc); // CHECK: xor <16 x i8> + res_vuc = vec_vxor(vuc, vuc); // CHECK: xor <16 x i8> + res_vuc = vec_vxor(vbc, vuc); // CHECK: xor <16 x i8> + res_vuc = vec_vxor(vuc, vbc); // CHECK: xor <16 x i8> + res_vbc = vec_vxor(vbc, vbc); // CHECK: xor <16 x i8> + res_vs = vec_vxor(vs, vs); // CHECK: xor <8 x i16> + res_vs = vec_vxor(vbs, vs); // CHECK: xor <8 x i16> + res_vs = vec_vxor(vs, vbs); // CHECK: xor <8 x i16> + res_vus = vec_vxor(vus, vus); // CHECK: xor <8 x i16> + res_vus = vec_vxor(vbs, vus); // CHECK: xor <8 x i16> + res_vus = vec_vxor(vus, vbs); // CHECK: xor <8 x i16> + res_vbs = vec_vxor(vbs, vbs); // CHECK: xor <8 x i16> + res_vi = vec_vxor(vi, vi); // CHECK: xor <4 x i32> + res_vi = vec_vxor(vbi, vi); // CHECK: xor <4 x i32> + res_vi = vec_vxor(vi, vbi); // CHECK: xor <4 x i32> + res_vui = vec_vxor(vui, vui); // CHECK: xor <4 x i32> + res_vui = vec_vxor(vbi, vui); // CHECK: xor <4 x i32> + res_vui = vec_vxor(vui, vbi); // CHECK: xor <4 x i32> + res_vbi = vec_vxor(vbi, vbi); // CHECK: xor <4 x i32> + res_vf = vec_vxor(vf, vf); // CHECK: xor <4 x i32> + res_vf = vec_vxor(vbi, vf); // CHECK: xor <4 x i32> + res_vf = vec_vxor(vf, vbi); // CHECK: xor <4 x i32> + + /* ------------------------------ extensions -------------------------------------- */ + + /* vec_extract */ + res_sc = vec_extract(vsc, param_i); // CHECK: extractelement <16 x i8> + res_uc = vec_extract(vuc, param_i); // CHECK: extractelement <16 x i8> + res_s = vec_extract(vs, param_i); // CHECK: extractelement <8 x i16> + res_us = vec_extract(vus, param_i); // CHECK: extractelement <8 x i16> + res_i = vec_extract(vi, param_i); // CHECK: extractelement <4 x i32> + res_ui = vec_extract(vui, param_i); // CHECK: extractelement <4 x i32> + res_f = vec_extract(vf, param_i); // CHECK: extractelement <4 x float> + + /* vec_insert */ + res_vsc = vec_insert(param_sc, vsc, param_i); // CHECK: insertelement <16 x i8> + res_vuc = vec_insert(param_uc, vuc, param_i); // CHECK: insertelement <16 x i8> + res_vs = vec_insert(param_s, vs, param_i); // CHECK: insertelement <8 x i16> + res_vus = vec_insert(param_us, vus, param_i); // CHECK: insertelement <8 x i16> + res_vi = vec_insert(param_i, vi, param_i); // CHECK: insertelement <4 x i32> + res_vui = vec_insert(param_ui, vui, param_i); // CHECK: insertelement <4 x i32> + res_vf = vec_insert(param_f, vf, param_i); // CHECK: insertelement <4 x float> + + /* vec_lvlx */ + res_vsc = vec_lvlx(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vsc = vec_lvlx(0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvlx(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvlx(0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbc = vec_lvlx(0, &vbc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvlx(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvlx(0, &vs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvlx(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvlx(0, &vus); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbs = vec_lvlx(0, &vbs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vp = vec_lvlx(0, &vp); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvlx(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvlx(0, &vi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvlx(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvlx(0, &vui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbi = vec_lvlx(0, &vbi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vf = vec_lvlx(0, &vf); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + /* vec_lvlxl */ + res_vsc = vec_lvlxl(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vsc = vec_lvlxl(0, &vsc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvlxl(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvlxl(0, &vuc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbc = vec_lvlxl(0, &vbc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvlxl(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvlxl(0, &vs); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvlxl(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvlxl(0, &vus); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbs = vec_lvlxl(0, &vbs); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vp = vec_lvlxl(0, &vp); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvlxl(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvlxl(0, &vi); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvlxl(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvlxl(0, &vui); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbi = vec_lvlxl(0, &vbi); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vf = vec_lvlxl(0, &vf); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + /* vec_lvrx */ + res_vsc = vec_lvrx(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vsc = vec_lvrx(0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvrx(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvrx(0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbc = vec_lvrx(0, &vbc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvrx(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvrx(0, &vs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvrx(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvrx(0, &vus); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbs = vec_lvrx(0, &vbs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vp = vec_lvrx(0, &vp); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvrx(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvrx(0, &vi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvrx(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvrx(0, &vui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbi = vec_lvrx(0, &vbi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vf = vec_lvrx(0, &vf); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + /* vec_lvrxl */ + res_vsc = vec_lvrxl(0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vsc = vec_lvrxl(0, &vsc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvrxl(0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vuc = vec_lvrxl(0, &vuc); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbc = vec_lvrxl(0, &vbc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvrxl(0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vs = vec_lvrxl(0, &vs); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvrxl(0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vus = vec_lvrxl(0, &vus); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbs = vec_lvrxl(0, &vbs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vp = vec_lvrxl(0, &vp); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvrxl(0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vi = vec_lvrxl(0, &vi); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvrxl(0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vui = vec_lvrxl(0, &vui); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + res_vbi = vec_lvrxl(0, &vbi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + + res_vf = vec_lvrxl(0, &vf); // CHECK: @llvm.ppc.altivec.lvxl + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + + /* vec_stvlx */ + vec_stvlx(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vbc, 0, &vbc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vbs, 0, &vbs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vp, 0, &vp); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vbi, 0, &vbi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvlx(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + /* vec_stvlxl */ + vec_stvlxl(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vbc, 0, &vbc); // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vbs, 0, &vbs); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vp, 0, &vp); // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vbi, 0, &vbi); // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvlxl(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + /* vec_stvrx */ + vec_stvrx(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vbc, 0, &vbc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vbs, 0, &vbs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vp, 0, &vp); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vbi, 0, &vbi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + vec_stvrx(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvx + + /* vec_stvrxl */ + vec_stvrxl(vsc, 0, ¶m_sc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vsc, 0, &vsc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vuc, 0, ¶m_uc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vuc, 0, &vuc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vbc, 0, &vbc); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <16 x i8> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vs, 0, ¶m_s); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vs, 0, &vs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vus, 0, ¶m_us); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vus, 0, &vus); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vbs, 0, &vbs); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vp, 0, &vp); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <8 x i16> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vi, 0, ¶m_i); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vi, 0, &vi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vui, 0, ¶m_ui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vui, 0, &vui); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vbi, 0, &vbi); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: store <4 x i32> zeroinitializer + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + vec_stvrxl(vf, 0, &vf); // CHECK: @llvm.ppc.altivec.lvx + // CHECK: @llvm.ppc.altivec.lvsl + // CHECK: store <4 x float> zeroinitializer + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.lvsr + // CHECK: @llvm.ppc.altivec.vperm + // CHECK: @llvm.ppc.altivec.stvxl + + /* vec_promote */ + res_vsc = vec_promote(param_sc, 0); // CHECK: store <16 x i8> zeroinitializer + // CHECK: insertelement <16 x i8> + + res_vuc = vec_promote(param_uc, 0); // CHECK: store <16 x i8> zeroinitializer + // CHECK: insertelement <16 x i8> + + res_vs = vec_promote(param_s, 0); // CHECK: store <8 x i16> zeroinitializer + // CHECK: insertelement <8 x i16> + + res_vus = vec_promote(param_us, 0); // CHECK: store <8 x i16> zeroinitializer + // CHECK: insertelement <8 x i16> + + res_vi = vec_promote(param_i, 0); // CHECK: store <4 x i32> zeroinitializer + // CHECK: insertelement <4 x i32> + + res_vui = vec_promote(param_ui, 0); // CHECK: store <4 x i32> zeroinitializer + // CHECK: insertelement <4 x i32> + + res_vf = vec_promote(param_f, 0); // CHECK: store <4 x float> zeroinitializer + // CHECK: insertelement <4 x float> + + /* vec_splats */ + res_vsc = vec_splats(param_sc); // CHECK: insertelement <16 x i8> + + res_vuc = vec_splats(param_uc); // CHECK: insertelement <16 x i8> + + res_vs = vec_splats(param_s); // CHECK: insertelement <8 x i16> + + res_vus = vec_splats(param_us); // CHECK: insertelement <8 x i16> + + res_vi = vec_splats(param_i); // CHECK: insertelement <4 x i32> + + res_vui = vec_splats(param_ui); // CHECK: insertelement <4 x i32> + + res_vf = vec_splats(param_f); // CHECK: insertelement <4 x float> + + /* ------------------------------ predicates -------------------------------------- */ + + /* vec_all_eq */ + res_i = vec_all_eq(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_eq(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_eq(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_eq(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_eq(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_eq(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_eq(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_eq(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_eq(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_eq(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_eq(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_eq(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_eq(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_eq(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_eq(vp, vp); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_eq(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_eq(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_eq(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_eq(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_eq(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_eq(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_eq(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_eq(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p + + /* vec_all_ge */ + res_i = vec_all_ge(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_all_ge(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_all_ge(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_ge(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_ge(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_ge(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_ge(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_ge(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_all_ge(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_all_ge(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_ge(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_ge(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_ge(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_ge(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_ge(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_all_ge(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_all_ge(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_ge(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_ge(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_ge(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_ge(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_ge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p + + /* vec_all_gt */ + res_i = vec_all_gt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_all_gt(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_all_gt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_gt(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_gt(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_gt(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_gt(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_gt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_all_gt(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_all_gt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_gt(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_gt(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_gt(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_gt(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_gt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_all_gt(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_all_gt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_gt(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_gt(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_gt(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_gt(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_gt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p + + /* vec_all_in */ + res_i = vec_all_in(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpbfp.p + + /* vec_all_le */ + res_i = vec_all_le(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_all_le(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_all_le(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_le(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_le(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_le(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_le(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_le(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_all_le(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_all_le(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_le(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_le(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_le(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_le(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_le(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_all_le(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_all_le(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_le(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_le(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_le(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_le(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_le(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p + + /* vec_all_lt */ + res_i = vec_all_lt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_all_lt(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_all_lt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_lt(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_lt(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_lt(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_lt(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_all_lt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_all_lt(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_all_lt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_lt(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_lt(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_lt(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_lt(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_all_lt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_all_lt(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_all_lt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_lt(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_lt(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_lt(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_lt(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_all_lt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p + + /* vec_all_nan */ + res_i = vec_all_nan(vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p + + /* vec_all_ne */ + res_i = vec_all_ne(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_ne(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_ne(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_ne(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_ne(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_ne(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_ne(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_all_ne(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_ne(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_ne(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_ne(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_ne(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_ne(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_ne(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_ne(vp, vp); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_all_ne(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_ne(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_ne(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_ne(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_ne(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_ne(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_ne(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_all_ne(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p + + /* vec_all_nge */ + res_i = vec_all_nge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p + + /* vec_all_ngt */ + res_i = vec_all_ngt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p + + /* vec_all_nle */ + res_i = vec_all_nle(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p + + /* vec_all_nlt */ + res_i = vec_all_nlt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p + + /* vec_all_numeric */ + res_i = vec_all_numeric(vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p + + /* vec_any_eq */ + res_i = vec_any_eq(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_eq(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_eq(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_eq(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_eq(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_eq(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_eq(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_eq(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_eq(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_eq(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_eq(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_eq(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_eq(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_eq(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_eq(vp, vp); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_eq(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_eq(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_eq(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_eq(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_eq(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_eq(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_eq(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_eq(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p + + /* vec_any_ge */ + res_i = vec_any_ge(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_any_ge(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_any_ge(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_ge(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_ge(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_ge(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_ge(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_ge(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_any_ge(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_any_ge(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_ge(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_ge(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_ge(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_ge(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_ge(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_any_ge(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_any_ge(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_ge(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_ge(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_ge(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_ge(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_ge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p + + /* vec_any_gt */ + res_i = vec_any_gt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_any_gt(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_any_gt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_gt(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_gt(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_gt(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_gt(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_gt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_any_gt(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_any_gt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_gt(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_gt(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_gt(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_gt(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_gt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_any_gt(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_any_gt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_gt(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_gt(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_gt(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_gt(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_gt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p + + /* vec_any_le */ + res_i = vec_any_le(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_any_le(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_any_le(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_le(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_le(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_le(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_le(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_le(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_any_le(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_any_le(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_le(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_le(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_le(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_le(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_le(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_any_le(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_any_le(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_le(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_le(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_le(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_le(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_le(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p + + /* vec_any_lt */ + res_i = vec_any_lt(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_any_lt(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p + res_i = vec_any_lt(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_lt(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_lt(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_lt(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_lt(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpgtub.p + res_i = vec_any_lt(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_any_lt(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p + res_i = vec_any_lt(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_lt(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_lt(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_lt(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_lt(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p + res_i = vec_any_lt(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_any_lt(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p + res_i = vec_any_lt(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_lt(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_lt(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_lt(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_lt(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p + res_i = vec_any_lt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p + + /* vec_any_nan */ + res_i = vec_any_nan(vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p + + /* vec_any_ne */ + res_i = vec_any_ne(vsc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_ne(vsc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_ne(vuc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_ne(vuc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_ne(vbc, vsc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_ne(vbc, vuc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_ne(vbc, vbc); // CHECK: @llvm.ppc.altivec.vcmpequb.p + res_i = vec_any_ne(vs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_ne(vs, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_ne(vus, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_ne(vus, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_ne(vbs, vs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_ne(vbs, vus); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_ne(vbs, vbs); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_ne(vp, vp); // CHECK: @llvm.ppc.altivec.vcmpequh.p + res_i = vec_any_ne(vi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_ne(vi, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_ne(vui, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_ne(vui, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_ne(vbi, vi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_ne(vbi, vui); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_ne(vbi, vbi); // CHECK: @llvm.ppc.altivec.vcmpequw.p + res_i = vec_any_ne(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p + + /* vec_any_nge */ + res_i = vec_any_nge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p + + /* vec_any_ngt */ + res_i = vec_any_ngt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p + + /* vec_any_nle */ + res_i = vec_any_nle(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp.p + + /* vec_any_nlt */ + res_i = vec_any_nlt(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p + + /* vec_any_numeric */ + res_i = vec_any_numeric(vf); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p + + /* vec_any_out */ + res_i = vec_any_out(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpbfp.p +} + +/* ------------------------------ Relational Operators ------------------------------ */ +// CHECK: define void @test7 +void test7() { + vector signed char vsc1 = (vector signed char)(-1); + vector signed char vsc2 = (vector signed char)(-2); + res_i = (vsc1 == vsc2); // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2 + res_i = (vsc1 != vsc2); // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0 + res_i = (vsc1 < vsc2); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2 + res_i = (vsc1 > vsc2); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2 + res_i = (vsc1 <= vsc2); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0 + res_i = (vsc1 >= vsc2); // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0 + vector unsigned char vuc1 = (vector unsigned char)(1); + vector unsigned char vuc2 = (vector unsigned char)(2); + res_i = (vuc1 == vuc2); // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2 + res_i = (vuc1 != vuc2); // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0 + res_i = (vuc1 < vuc2); // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2 + res_i = (vuc1 > vuc2); // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2 + res_i = (vuc1 <= vuc2); // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0 + res_i = (vuc1 >= vuc2); // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0 + vector short vs1 = (vector short)(-1); + vector short vs2 = (vector short)(-2); + res_i = (vs1 == vs2); // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2 + res_i = (vs1 != vs2); // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0 + res_i = (vs1 < vs2); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2 + res_i = (vs1 > vs2); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2 + res_i = (vs1 <= vs2); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0 + res_i = (vs1 >= vs2); // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0 + vector unsigned short vus1 = (vector unsigned short)(1); + vector unsigned short vus2 = (vector unsigned short)(2); + res_i = (vus1 == vus2); // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2 + res_i = (vus1 != vus2); // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0 + res_i = (vus1 < vus2); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2 + res_i = (vus1 > vus2); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2 + res_i = (vus1 <= vus2); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0 + res_i = (vus1 >= vus2); // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0 + vector int vi1 = (vector int)(-1); + vector int vi2 = (vector int)(-2); + res_i = (vi1 == vi2); // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2 + res_i = (vi1 != vi2); // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0 + res_i = (vi1 < vi2); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2 + res_i = (vi1 > vi2); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2 + res_i = (vi1 <= vi2); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0 + res_i = (vi1 >= vi2); // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0 + vector unsigned int vui1 = (vector unsigned int)(1); + vector unsigned int vui2 = (vector unsigned int)(2); + res_i = (vui1 == vui2); // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2 + res_i = (vui1 != vui2); // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0 + res_i = (vui1 < vui2); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2 + res_i = (vui1 > vui2); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2 + res_i = (vui1 <= vui2); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0 + res_i = (vui1 >= vui2); // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0 + vector float vf1 = (vector float)(1.0); + vector float vf2 = (vector float)(2.0); + res_i = (vf1 == vf2); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 2 + res_i = (vf1 != vf2); // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 0 + res_i = (vf1 < vf2); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2 + res_i = (vf1 > vf2); // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2 + res_i = (vf1 <= vf2); // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2 + res_i = (vf1 >= vf2); // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2 +} diff --git a/clang/test/CodeGen/builtins-ptx.c b/clang/test/CodeGen/builtins-ptx.c new file mode 100644 index 0000000..6dd1018 --- /dev/null +++ b/clang/test/CodeGen/builtins-ptx.c @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -triple ptx32-unknown-unknown -emit-llvm -o %t %s +// RUN: %clang_cc1 -triple ptx64-unknown-unknown -emit-llvm -o %t %s + + +int read_tid() { + + int x = __builtin_ptx_read_tid_x(); + int y = __builtin_ptx_read_tid_y(); + int z = __builtin_ptx_read_tid_z(); + int w = __builtin_ptx_read_tid_w(); + + return x + y + z + w; + +} + +int read_ntid() { + + int x = __builtin_ptx_read_ntid_x(); + int y = __builtin_ptx_read_ntid_y(); + int z = __builtin_ptx_read_ntid_z(); + int w = __builtin_ptx_read_ntid_w(); + + return x + y + z + w; + +} + +int read_ctaid() { + + int x = __builtin_ptx_read_ctaid_x(); + int y = __builtin_ptx_read_ctaid_y(); + int z = __builtin_ptx_read_ctaid_z(); + int w = __builtin_ptx_read_ctaid_w(); + + return x + y + z + w; + +} + +int read_nctaid() { + + int x = __builtin_ptx_read_nctaid_x(); + int y = __builtin_ptx_read_nctaid_y(); + int z = __builtin_ptx_read_nctaid_z(); + int w = __builtin_ptx_read_nctaid_w(); + + return x + y + z + w; + +} + +int read_ids() { + + int a = __builtin_ptx_read_laneid(); + int b = __builtin_ptx_read_warpid(); + int c = __builtin_ptx_read_nwarpid(); + int d = __builtin_ptx_read_smid(); + int e = __builtin_ptx_read_nsmid(); + int f = __builtin_ptx_read_gridid(); + + return a + b + c + d + e + f; + +} + +int read_lanemasks() { + + int a = __builtin_ptx_read_lanemask_eq(); + int b = __builtin_ptx_read_lanemask_le(); + int c = __builtin_ptx_read_lanemask_lt(); + int d = __builtin_ptx_read_lanemask_ge(); + int e = __builtin_ptx_read_lanemask_gt(); + + return a + b + c + d + e; + +} + + +long read_clocks() { + + int a = __builtin_ptx_read_clock(); + long b = __builtin_ptx_read_clock64(); + + return (long)a + b; + +} + +int read_pms() { + + int a = __builtin_ptx_read_pm0(); + int b = __builtin_ptx_read_pm1(); + int c = __builtin_ptx_read_pm2(); + int d = __builtin_ptx_read_pm3(); + + return a + b + c + d; + +} + +void sync() { + + __builtin_ptx_bar_sync(0); + +} diff --git a/clang/test/CodeGen/builtins-x86.c b/clang/test/CodeGen/builtins-x86.c new file mode 100644 index 0000000..acb5554 --- /dev/null +++ b/clang/test/CodeGen/builtins-x86.c @@ -0,0 +1,496 @@ +// RUN: %clang_cc1 -DUSE_64 -triple x86_64-unknown-unknown -emit-llvm -o %t %s +// RUN: %clang_cc1 -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))); + +// 256-bit +typedef char V32c __attribute__((vector_size(32))); +typedef signed int V8i __attribute__((vector_size(32))); +typedef signed long long V4LLi __attribute__((vector_size(32))); + +typedef double V4d __attribute__((vector_size(32))); +typedef float V8f __attribute__((vector_size(32))); + +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; + V2d* tmp_V2dp; + V4f* tmp_V4fp; + const V2d* tmp_V2dCp; + const V4f* tmp_V4fCp; + + // 256-bit + V32c tmp_V32c; + V4d tmp_V4d; + V8f tmp_V8f; + V4LLi tmp_V4LLi; + V8i tmp_V8i; + V4LLi* tmp_V4LLip; + V4d* tmp_V4dp; + V8f* tmp_V8fp; + const V4d* tmp_V4dCp; + const V8f* tmp_V8fCp; + + 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_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_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_pmulhw(tmp_V4s, tmp_V4s); + tmp_V4s = __builtin_ia32_pmulhuw(tmp_V4s, tmp_V4s); + 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_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_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_pmulhw128(tmp_V8s, tmp_V8s); + tmp_V16c = __builtin_ia32_pavgb128(tmp_V16c, tmp_V16c); + tmp_V8s = __builtin_ia32_pavgw128(tmp_V8s, tmp_V8s); + 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_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); + 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); + tmp_i = __builtin_ia32_vec_ext_v2si(tmp_V2i, 0); + + (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_i = __builtin_ia32_cvtss2si(tmp_V4f); +#ifdef USE_64 + tmp_LLi = __builtin_ia32_cvtss2si64(tmp_V4f); +#endif + tmp_V2i = __builtin_ia32_cvttps2pi(tmp_V4f); + (void) __builtin_ia32_maskmovq(tmp_V8c, tmp_V8c, tmp_cp); + (void) __builtin_ia32_storeups(tmp_fp, tmp_V4f); + (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); + (void) __builtin_ia32_maskmovdqu(tmp_V16c, tmp_V16c, tmp_cp); + (void) __builtin_ia32_storeupd(tmp_dp, tmp_V2d); + 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_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_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); +#ifdef USE_64 + tmp_LLi = __builtin_ia32_cvtsd2si64(tmp_V2d); +#endif + tmp_V4i = __builtin_ia32_cvtps2dq(tmp_V4f); + tmp_V2d = __builtin_ia32_cvtps2pd(tmp_V4f); + tmp_V4i = __builtin_ia32_cvttps2dq(tmp_V4f); + (void) __builtin_ia32_clflush(tmp_vCp); + (void) __builtin_ia32_lfence(); + (void) __builtin_ia32_mfence(); + (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); + 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); + (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_V4f = __builtin_ia32_insertps128(tmp_V4f, tmp_V4f, tmp_i); +#endif + + tmp_V4d = __builtin_ia32_addsubpd256(tmp_V4d, tmp_V4d); + tmp_V8f = __builtin_ia32_addsubps256(tmp_V8f, tmp_V8f); + tmp_V4d = __builtin_ia32_haddpd256(tmp_V4d, tmp_V4d); + tmp_V8f = __builtin_ia32_hsubps256(tmp_V8f, tmp_V8f); + tmp_V4d = __builtin_ia32_hsubpd256(tmp_V4d, tmp_V4d); + tmp_V8f = __builtin_ia32_haddps256(tmp_V8f, tmp_V8f); + tmp_V4d = __builtin_ia32_maxpd256(tmp_V4d, tmp_V4d); + tmp_V8f = __builtin_ia32_maxps256(tmp_V8f, tmp_V8f); + tmp_V4d = __builtin_ia32_minpd256(tmp_V4d, tmp_V4d); + tmp_V8f = __builtin_ia32_minps256(tmp_V8f, tmp_V8f); + tmp_V2d = __builtin_ia32_vpermilvarpd(tmp_V2d, tmp_V2LLi); + tmp_V4f = __builtin_ia32_vpermilvarps(tmp_V4f, tmp_V4i); + tmp_V4d = __builtin_ia32_vpermilvarpd256(tmp_V4d, tmp_V4LLi); + tmp_V8f = __builtin_ia32_vpermilvarps256(tmp_V8f, tmp_V8i); + tmp_V4d = __builtin_ia32_blendpd256(tmp_V4d, tmp_V4d, 0x7); + tmp_V8f = __builtin_ia32_blendps256(tmp_V8f, tmp_V8f, 0x7); + tmp_V4d = __builtin_ia32_blendvpd256(tmp_V4d, tmp_V4d, tmp_V4d); + tmp_V8f = __builtin_ia32_blendvps256(tmp_V8f, tmp_V8f, tmp_V8f); + tmp_V8f = __builtin_ia32_dpps256(tmp_V8f, tmp_V8f, 0x7); + tmp_V4d = __builtin_ia32_cmppd256(tmp_V4d, tmp_V4d, 0); + tmp_V8f = __builtin_ia32_cmpps256(tmp_V8f, tmp_V8f, 0); + tmp_V2d = __builtin_ia32_vextractf128_pd256(tmp_V4d, 0x7); + tmp_V4f = __builtin_ia32_vextractf128_ps256(tmp_V8f, 0x7); + tmp_V4i = __builtin_ia32_vextractf128_si256(tmp_V8i, 0x7); + tmp_V4d = __builtin_ia32_cvtdq2pd256(tmp_V4i); + tmp_V8f = __builtin_ia32_cvtdq2ps256(tmp_V8i); + tmp_V4f = __builtin_ia32_cvtpd2ps256(tmp_V4d); + tmp_V8i = __builtin_ia32_cvtps2dq256(tmp_V8f); + tmp_V4d = __builtin_ia32_cvtps2pd256(tmp_V4f); + tmp_V4i = __builtin_ia32_cvttpd2dq256(tmp_V4d); + tmp_V4i = __builtin_ia32_cvtpd2dq256(tmp_V4d); + tmp_V8i = __builtin_ia32_cvttps2dq256(tmp_V8f); + tmp_V4d = __builtin_ia32_vperm2f128_pd256(tmp_V4d, tmp_V4d, 0x7); + tmp_V8f = __builtin_ia32_vperm2f128_ps256(tmp_V8f, tmp_V8f, 0x7); + tmp_V8i = __builtin_ia32_vperm2f128_si256(tmp_V8i, tmp_V8i, 0x7); + tmp_V4d = __builtin_ia32_vinsertf128_pd256(tmp_V4d, tmp_V2d, 0x7); + tmp_V8f = __builtin_ia32_vinsertf128_ps256(tmp_V8f, tmp_V4f, 0x7); + tmp_V8i = __builtin_ia32_vinsertf128_si256(tmp_V8i, tmp_V4i, 0x7); + tmp_V4d = __builtin_ia32_sqrtpd256(tmp_V4d); + tmp_V8f = __builtin_ia32_sqrtps256(tmp_V8f); + tmp_V8f = __builtin_ia32_rsqrtps256(tmp_V8f); + tmp_V8f = __builtin_ia32_rcpps256(tmp_V8f); + tmp_V4d = __builtin_ia32_roundpd256(tmp_V4d, 0x1); + tmp_V8f = __builtin_ia32_roundps256(tmp_V8f, 0x1); + tmp_i = __builtin_ia32_vtestzpd(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_vtestcpd(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_vtestnzcpd(tmp_V2d, tmp_V2d); + tmp_i = __builtin_ia32_vtestzps(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_vtestcps(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_vtestnzcps(tmp_V4f, tmp_V4f); + tmp_i = __builtin_ia32_vtestzpd256(tmp_V4d, tmp_V4d); + tmp_i = __builtin_ia32_vtestcpd256(tmp_V4d, tmp_V4d); + tmp_i = __builtin_ia32_vtestnzcpd256(tmp_V4d, tmp_V4d); + tmp_i = __builtin_ia32_vtestzps256(tmp_V8f, tmp_V8f); + tmp_i = __builtin_ia32_vtestcps256(tmp_V8f, tmp_V8f); + tmp_i = __builtin_ia32_vtestnzcps256(tmp_V8f, tmp_V8f); + tmp_i = __builtin_ia32_ptestz256(tmp_V4LLi, tmp_V4LLi); + tmp_i = __builtin_ia32_ptestc256(tmp_V4LLi, tmp_V4LLi); + tmp_i = __builtin_ia32_ptestnzc256(tmp_V4LLi, tmp_V4LLi); + tmp_i = __builtin_ia32_movmskpd256(tmp_V4d); + tmp_i = __builtin_ia32_movmskps256(tmp_V8f); + __builtin_ia32_vzeroall(); + __builtin_ia32_vzeroupper(); + tmp_V4f = __builtin_ia32_vbroadcastss(tmp_fCp); + tmp_V4d = __builtin_ia32_vbroadcastsd256(tmp_dCp); + tmp_V8f = __builtin_ia32_vbroadcastss256(tmp_fCp); + tmp_V4d = __builtin_ia32_vbroadcastf128_pd256(tmp_V2dCp); + tmp_V8f = __builtin_ia32_vbroadcastf128_ps256(tmp_V4fCp); + __builtin_ia32_storeupd256(tmp_dp, tmp_V4d); + __builtin_ia32_storeups256(tmp_fp, tmp_V8f); + __builtin_ia32_storedqu256(tmp_cp, tmp_V32c); + tmp_V32c = __builtin_ia32_lddqu256(tmp_cCp); + __builtin_ia32_movntdq256(tmp_V4LLip, tmp_V4LLi); + __builtin_ia32_movntpd256(tmp_dp, tmp_V4d); + __builtin_ia32_movntps256(tmp_fp, tmp_V8f); + tmp_V2d = __builtin_ia32_maskloadpd(tmp_V2dCp, tmp_V2d); + tmp_V4f = __builtin_ia32_maskloadps(tmp_V4fCp, tmp_V4f); + tmp_V4d = __builtin_ia32_maskloadpd256(tmp_V4dCp, tmp_V4d); + tmp_V8f = __builtin_ia32_maskloadps256(tmp_V8fCp, tmp_V8f); + __builtin_ia32_maskstorepd(tmp_V2dp, tmp_V2d, tmp_V2d); + __builtin_ia32_maskstoreps(tmp_V4fp, tmp_V4f, tmp_V4f); + __builtin_ia32_maskstorepd256(tmp_V4dp, tmp_V4d, tmp_V4d); + __builtin_ia32_maskstoreps256(tmp_V8fp, tmp_V8f, tmp_V8f); + +#ifdef USE_3DNOW + 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); + 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 +} diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c new file mode 100644 index 0000000..fca087e --- /dev/null +++ b/clang/test/CodeGen/builtins.c @@ -0,0 +1,205 @@ +// RUN: %clang_cc1 -emit-llvm -o %t %s +// RUN: not grep __builtin %t +// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple | FileCheck %s + +int printf(const char *, ...); + +void p(char *str, int x) { + printf("%s: %d\n", str, x); +} +void q(char *str, double x) { + printf("%s: %f\n", str, x); +} +void r(char *str, void *ptr) { + printf("%s: %p\n", str, ptr); +} + +int random(void); + +int main() { + int N = random(); +#define P(n,args) p(#n #args, __builtin_##n args) +#define Q(n,args) q(#n #args, __builtin_##n args) +#define R(n,args) r(#n #args, __builtin_##n args) +#define V(n,args) p(#n #args, (__builtin_##n args, 0)) + P(types_compatible_p, (int, float)); + P(choose_expr, (0, 10, 20)); + 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, ()); + + P(fpclassify, (0, 1, 2, 3, 4, 1.0)); + P(fpclassify, (0, 1, 2, 3, 4, 1.0f)); + P(fpclassify, (0, 1, 2, 3, 4, 1.0l)); + // FIXME: + // 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.)); + + P(isnan, (1.)); + + // 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, ()); + R(extract_return_addr, (&N)); + P(signbit, (1.0)); + + return 0; +} + + + +void foo() { + __builtin_strcat(0, 0); +} + +// CHECK: define void @bar( +void bar() { + float f; + double d; + long double ld; + + // LLVM's hex representation of float constants is really unfortunate; + // basically it does a float-to-double "conversion" and then prints the + // hex form of that. That gives us weird artifacts like exponents + // that aren't numerically similar to the original exponent and + // significand bit-patterns that are offset by three bits (because + // the exponent was expanded from 8 bits to 11). + // + // 0xAE98 == 1010111010011000 + // 0x15D3 == 1010111010011 + + f = __builtin_huge_valf(); // CHECK: float 0x7FF0000000000000 + d = __builtin_huge_val(); // CHECK: double 0x7FF0000000000000 + ld = __builtin_huge_vall(); // CHECK: x86_fp80 0xK7FFF8000000000000000 + f = __builtin_nanf(""); // CHECK: float 0x7FF8000000000000 + d = __builtin_nan(""); // CHECK: double 0x7FF8000000000000 + ld = __builtin_nanl(""); // CHECK: x86_fp80 0xK7FFFC000000000000000 + f = __builtin_nanf("0xAE98"); // CHECK: float 0x7FF815D300000000 + d = __builtin_nan("0xAE98"); // CHECK: double 0x7FF800000000AE98 + ld = __builtin_nanl("0xAE98"); // CHECK: x86_fp80 0xK7FFFC00000000000AE98 + f = __builtin_nansf(""); // CHECK: float 0x7FF4000000000000 + d = __builtin_nans(""); // CHECK: double 0x7FF4000000000000 + ld = __builtin_nansl(""); // CHECK: x86_fp80 0xK7FFFA000000000000000 + f = __builtin_nansf("0xAE98"); // CHECK: float 0x7FF015D300000000 + d = __builtin_nans("0xAE98"); // CHECK: double 0x7FF000000000AE98 + ld = __builtin_nansl("0xAE98");// CHECK: x86_fp80 0xK7FFF800000000000AE98 + +} +// CHECK: } + + +// CHECK: define void @test_float_builtins +void test_float_builtins(float F, double D, long double LD) { + volatile int res; + res = __builtin_isinf(F); + // CHECK: call float @fabsf(float + // CHECK: fcmp oeq float {{.*}}, 0x7FF0000000000000 + + res = __builtin_isinf(D); + // CHECK: call double @fabs(double + // CHECK: fcmp oeq double {{.*}}, 0x7FF0000000000000 + + res = __builtin_isinf(LD); + // CHECK: call x86_fp80 @fabsl(x86_fp80 + // CHECK: fcmp oeq x86_fp80 {{.*}}, 0xK7FFF8000000000000000 + + res = __builtin_isfinite(F); + // CHECK: fcmp oeq float + // CHECK: call float @fabsf + // CHECK: fcmp une float {{.*}}, 0x7FF0000000000000 + // CHECK: and i1 + + res = __builtin_isnormal(F); + // CHECK: fcmp oeq float + // CHECK: call float @fabsf + // CHECK: fcmp ult float {{.*}}, 0x7FF0000000000000 + // CHECK: fcmp uge float {{.*}}, 0x3810000000000000 + // CHECK: and i1 + // CHECK: and i1 +} + +// CHECK: define void @test_builtin_longjmp +void test_builtin_longjmp(void **buffer) { + // CHECK: [[BITCAST:%.*]] = bitcast + // CHECK-NEXT: call void @llvm.eh.sjlj.longjmp(i8* [[BITCAST]]) + __builtin_longjmp(buffer, 1); + // CHECK-NEXT: unreachable +} diff --git a/clang/test/CodeGen/builtinshufflevector.c b/clang/test/CodeGen/builtinshufflevector.c new file mode 100644 index 0000000..5c647df --- /dev/null +++ b/clang/test/CodeGen/builtinshufflevector.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm < %s | grep 'shufflevector' | count 1 +// RUN: %clang_cc1 -emit-llvm -ftrapv < %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, (2*3)+1);} + diff --git a/clang/test/CodeGen/builtinshufflevector2.c b/clang/test/CodeGen/builtinshufflevector2.c new file mode 100644 index 0000000..faf7a3e --- /dev/null +++ b/clang/test/CodeGen/builtinshufflevector2.c @@ -0,0 +1,35 @@ +// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s + +typedef float float4 __attribute__((ext_vector_type(4))); +typedef unsigned int uint4 __attribute__((ext_vector_type(4))); + +// CHECK: define void @clang_shufflevector_v_v( +void clang_shufflevector_v_v( float4* A, float4 x, uint4 mask ) { +// CHECK: [[MASK:%.*]] = and <4 x i32> {{%.*}}, <i32 3, i32 3, i32 3, i32 3> +// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 0 +// CHECK: [[E:%.*]] = extractelement <4 x float> [[X:%.*]], i32 [[I]] +// +// Here is where ToT Clang code generation makes a mistake. +// It uses [[I]] as the insertion index instead of 0. +// Similarly on the remaining insertelement. +// CHECK: [[V:%[a-zA-Z0-9._]+]] = insertelement <4 x float> undef, float [[E]], i32 0 + +// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 1 +// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]] +// CHECK: [[V:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 1 +// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 2 +// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]] +// CHECK: [[V:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 2 +// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 3 +// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]] +// CHECK: [[V:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 3 +// CHECK: store <4 x float> [[V]], <4 x float>* {{%.*}}, + *A = __builtin_shufflevector( x, mask ); +} + +// CHECK: define void @clang_shufflevector_v_v_c( +void clang_shufflevector_v_v_c( float4* A, float4 x, float4 y, uint4 mask ) { +// CHECK: [[V:%.*]] = shufflevector <4 x float> {{%.*}}, <4 x float> {{%.*}}, <4 x i32> <i32 0, i32 4, i32 1, i32 5> +// CHECK: store <4 x float> [[V]], <4 x float>* {{%.*}} + *A = __builtin_shufflevector( x, y, 0, 4, 1, 5 ); +} diff --git a/clang/test/CodeGen/byval-memcpy-elim.c b/clang/test/CodeGen/byval-memcpy-elim.c new file mode 100644 index 0000000..76cdafb --- /dev/null +++ b/clang/test/CodeGen/byval-memcpy-elim.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 < %s | FileCheck %s + +struct Test1S { + long NumDecls; + long X; + long Y; +}; +struct Test2S { + long NumDecls; + long X; +}; + +// Make sure we don't generate extra memcpy for lvalues +void test1a(struct Test1S, struct Test2S); +// CHECK: define void @test1( +// CHECK-NOT: memcpy +// CHECK: call void @test1a +void test1(struct Test1S *A, struct Test2S *B) { + test1a(*A, *B); +} + +// The above gets tricker when the byval argument requires higher alignment +// than the natural alignment of the type in question. +// rdar://9483886 + +// Make sure we do generate a memcpy when we cannot guarantee alignment. +struct Test3S { + int a,b,c,d,e,f,g,h,i,j,k,l; +}; +void test2a(struct Test3S q); +// CHECK: define void @test2( +// CHECK: alloca %struct.Test3S, align 8 +// CHECK: memcpy +// CHECK: call void @test2a +void test2(struct Test3S *q) { + test2a(*q); +} + +// But make sure we don't generate a memcpy when we can guarantee alignment. +void fooey(void); +// CHECK: define void @test3( +// CHECK: alloca %struct.Test3S, align 8 +// CHECK: call void @fooey +// CHECK-NOT: memcpy +// CHECK: call void @test2a +// CHECK-NOT: memcpy +// CHECK: call void @test2a +void test3(struct Test3S a) { + struct Test3S b = a; + fooey(); + test2a(a); + test2a(b); +} diff --git a/clang/test/CodeGen/c-strings.c b/clang/test/CodeGen/c-strings.c new file mode 100644 index 0000000..4fbeb7b --- /dev/null +++ b/clang/test/CodeGen/c-strings.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/call.c b/clang/test/CodeGen/call.c new file mode 100644 index 0000000..ef32775 --- /dev/null +++ b/clang/test/CodeGen/call.c @@ -0,0 +1,39 @@ +// RUN: %clang %s -O0 -emit-llvm -S -o - | FileCheck %s + +// This should call rb_define_global_function, not rb_f_chop. +void rb_define_global_function (const char*,void(*)(),int); +static void rb_f_chop(); +void Init_String() { + rb_define_global_function("chop", rb_f_chop, 0); +} +static void rb_f_chop() { +} + +// CHECK: call{{.*}}rb_define_global_function + +// PR10335 +typedef void (* JSErrorCallback)(void); +void js_GetErrorMessage(void); +void JS_ReportErrorNumber(JSErrorCallback errorCallback, ...); +void Interpret() { + JS_ReportErrorNumber(js_GetErrorMessage, 0); + + // CHECK: call void ({{.*}}, ...)* @JS_ReportErrorNumber({{.*}}@js_GetErrorMessage +} + + + + +// PR10337 +struct sigaction { int (*_sa_handler)(int); }; +typedef int SigHandler (); +typedef struct sigaction sighandler_cxt; +SigHandler *rl_set_sighandler(ohandler) +sighandler_cxt *ohandler; { + return 0; +} + +void rl_set_signals() { + SigHandler *oh; + oh = rl_set_sighandler(0); +} diff --git a/clang/test/CodeGen/capture-complex-expr-in-block.c b/clang/test/CodeGen/capture-complex-expr-in-block.c new file mode 100644 index 0000000..9ce7570 --- /dev/null +++ b/clang/test/CodeGen/capture-complex-expr-in-block.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks -triple x86_64-apple-darwin10 | FileCheck %s +// rdar://10033986 + +typedef void (^BLOCK)(void); +int main () +{ + _Complex double c; + BLOCK b = ^() { + _Complex double z; + z = z + c; + }; + b(); +} + +// CHECK: define internal void @__main_block_invoke_0 +// CHECK: [[C1:%.*]] = alloca { double, double }, align 8 +// CHECK: [[RP:%.*]] = getelementptr inbounds { double, double }* [[C1]], i32 0, i32 0 +// CHECK-NEXT: [[R:%.*]] = load double* [[RP]] +// CHECK-NEXT: [[IP:%.*]] = getelementptr inbounds { double, double }* [[C1]], i32 0, i32 1 +// CHECK-NEXT: [[I:%.*]] = load double* [[IP]] diff --git a/clang/test/CodeGen/cast-emit.c b/clang/test/CodeGen/cast-emit.c new file mode 100644 index 0000000..4e33fa3 --- /dev/null +++ b/clang/test/CodeGen/cast-emit.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +typedef union { + int i; + float f; +} MyUnion; +void unionf(MyUnion a); +void uniontest(float a) { + f((MyUnion)1.0f); +// CHECK: store float 1.000000e+00 +} + diff --git a/clang/test/CodeGen/cast.c b/clang/test/CodeGen/cast.c new file mode 100644 index 0000000..5f340c5 --- /dev/null +++ b/clang/test/CodeGen/cast.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/catch-undef-behavior.c b/clang/test/CodeGen/catch-undef-behavior.c new file mode 100644 index 0000000..fef1587 --- /dev/null +++ b/clang/test/CodeGen/catch-undef-behavior.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fcatch-undefined-behavior -emit-llvm-only %s + +// PR6805 +void foo() { + union { int i; } u; + u.i=1; +} diff --git a/clang/test/CodeGen/cfstring.c b/clang/test/CodeGen/cfstring.c new file mode 100644 index 0000000..9d98b56 --- /dev/null +++ b/clang/test/CodeGen/cfstring.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t + +// <rdar://problem/10657500>: Check that the backing store of CFStrings are +// constant with the -fwritable-strings flag. +// +// RUN: %clang_cc1 -fwritable-strings -emit-llvm %s -o - | FileCheck %s +// +// CHECK: @.str = linker_private unnamed_addr constant [14 x i8] c"Hello, World!\00", align 1 +// CHECK: @.str1 = linker_private unnamed_addr constant [7 x i8] c"yo joe\00", align 1 +// CHECK: @.str3 = linker_private unnamed_addr constant [16 x i8] c"Goodbye, World!\00", align 1 + +#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/clang/test/CodeGen/cfstring2.c b/clang/test/CodeGen/cfstring2.c new file mode 100644 index 0000000..c760f5d --- /dev/null +++ b/clang/test/CodeGen/cfstring2.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/char-literal.c b/clang/test/CodeGen/char-literal.c new file mode 100644 index 0000000..237d4b2 --- /dev/null +++ b/clang/test/CodeGen/char-literal.c @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=C %s +// RUN: %clang_cc1 -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=C %s +// RUN: %clang_cc1 -x c++ -std=c++11 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CPP0X %s + +#include <stddef.h> + +int main() { + // CHECK-C: store i8 97 + // CHECK-CPP0X: store i8 97 + char a = 'a'; + + // Should truncate value (equal to last character). + // CHECK-C: store i8 98 + // CHECK-CPP0X: store i8 98 + char b = 'ab'; + + // Should get concatenated characters + // CHECK-C: store i32 24930 + // CHECK-CPP0X: store i32 24930 + int b1 = 'ab'; + + // Should get concatenated characters + // CHECK-C: store i32 808464432 + // CHECK-CPP0X: store i32 808464432 + int b2 = '0000'; + + // Should get truncated value (last four characters concatenated) + // CHECK-C: store i32 1919512167 + // CHECK-CPP0X: store i32 1919512167 + int b3 = 'somesillylongstring'; + + // CHECK-C: store i32 97 + // CHECK-CPP0X: store i32 97 + wchar_t wa = L'a'; + + // Should pick second character. + // CHECK-C: store i32 98 + // CHECK-CPP0X: store i32 98 + wchar_t wb = L'ab'; + +#if __cplusplus >= 201103L + // CHECK-CPP0X: store i16 97 + char16_t ua = u'a'; + + // CHECK-CPP0X: store i32 97 + char32_t Ua = U'a'; + + // CHECK-CPP0X: store i16 1047 + char16_t ua1 = u'З'; + // CHECK-CPP0X: store i16 12538 + char16_t ua2 = u'ヺ'; + // CHECK-CPP0X: store i16 -27177 + char16_t ua3 = u'é——'; + + // CHECK-CPP0X: store i32 181 + char32_t Ua1 = U'µ'; + // CHECK-CPP0X: store i32 38359 + char32_t Ua2 = U'é——'; + // CHECK-CPP0X: store i32 128128 + char32_t Ua3 = U'💀'; + +#endif + + // CHECK-C: store i32 61451 + // CHECK-CPP0X: store i32 61451 + wchar_t wc = L'\uF00B'; + +#if __cplusplus >= 201103L + // -4085 == 0xf00b + // CHECK-CPP0X: store i16 -4085 + char16_t uc = u'\uF00B'; + + // CHECK-CPP0X: store i32 61451 + char32_t Uc = U'\uF00B'; +#endif + + // CHECK-C: store i32 1110027 + // CHECK-CPP0X: store i32 1110027 + wchar_t wd = L'\U0010F00B'; + +#if __cplusplus >= 201103L + // CHECK-CPP0X: store i32 1110027 + char32_t Ud = U'\U0010F00B'; +#endif + + // Should pick second character. + // CHECK-C: store i32 1110027 + // CHECK-CPP0X: store i32 1110027 + wchar_t we = L'\u1234\U0010F00B'; +} diff --git a/clang/test/CodeGen/cleanup-stack.c b/clang/test/CodeGen/cleanup-stack.c new file mode 100644 index 0000000..72a1a6c --- /dev/null +++ b/clang/test/CodeGen/cleanup-stack.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/complex-indirect.c b/clang/test/CodeGen/complex-indirect.c new file mode 100644 index 0000000..0daa970 --- /dev/null +++ b/clang/test/CodeGen/complex-indirect.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t -triple=x86_64-apple-darwin10 +// RUN: FileCheck < %t %s + +// Make sure this doesn't crash. We used to generate a byval here and wanted to +// verify a valid alignment, but we now realize we can use an i16 and let the +// backend guarantee the alignment. + +void a(int,int,int,int,int,int,__complex__ char); +void b(__complex__ char *y) { a(0,0,0,0,0,0,*y); } +// CHECK: define void @b +// CHECK: alloca { i8, i8 }*, align 8 +// CHECK: call void @a(i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i16 {{.*}}) diff --git a/clang/test/CodeGen/complex-init-list.c b/clang/test/CodeGen/complex-init-list.c new file mode 100644 index 0000000..99c1c62 --- /dev/null +++ b/clang/test/CodeGen/complex-init-list.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s + +// This file tests the clang extension which allows initializing the components +// of a complex number individually using an initialization list. (There is a +// extensive description and test in test/Sema/complex-init-list.c.) + +_Complex float x = { 1.0f, 1.0f/0.0f }; +// CHECK: @x = global { float, float } { float 1.000000e+00, float 0x7FF0000000000000 }, align 4 + +_Complex float f(float x, float y) { _Complex float z = { x, y }; return z; } +// CHECK: define <2 x float> @f +// CHECK: alloca { float, float } +// CHECK: alloca { float, float } + +_Complex float f2(float x, float y) { return (_Complex float){ x, y }; } +// CHECK: define <2 x float> @f2 +// CHECK: alloca { float, float } +// CHECK: alloca { float, float } diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c new file mode 100644 index 0000000..1212660 --- /dev/null +++ b/clang/test/CodeGen/complex.c @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -emit-llvm-only %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; +} + +__complex__ int ci1, ci2; +__complex__ short cs; +int i; +void test3int() { + ci1 = ci1 + ci2; + ci1 = ci1 - ci2; + ci1 = ci1 * ci2; + ci1 = +-~ci1; + + i = __real ci1; + + cs += i; + // FIXME: Currently unsupported! + //D += cf; + cs /= ci1; + ci1 = ci1 + i; + ci1 = i + ci1; +} + +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(); +} + +void t6() { + g1++; + g1--; + ++g1; + --g1; + ci1++; + ci1--; + ++ci1; + --ci1; +} + +// <rdar://problem/7958272> +double t7(double _Complex c) { + return __builtin_fabs(__real__(c)); +} + +void t8() { + __complex__ int *x = &(__complex__ int){1}; +} diff --git a/clang/test/CodeGen/compound-literal.c b/clang/test/CodeGen/compound-literal.c new file mode 100644 index 0000000..969c5af --- /dev/null +++ b/clang/test/CodeGen/compound-literal.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +int* a = &(int){1}; +struct s {int a, b, c;} * b = &(struct s) {1, 2, 3}; +_Complex double * x = &(_Complex double){1.0f}; +typedef int v4i32 __attribute((vector_size(16))); +v4i32 *y = &(v4i32){1,2,3,4}; + +void xxx() { +int* a = &(int){1}; +struct s {int a, b, c;} * b = &(struct s) {1, 2, 3}; +_Complex double * x = &(_Complex double){1.0f}; +} + +// CHECK: define void @f() +void f() { + typedef struct S { int x,y; } S; + // CHECK: [[S:%[a-zA-Z0-9.]+]] = alloca [[STRUCT:%[a-zA-Z0-9.]+]], + struct S s; + // CHECK-NEXT: [[COMPOUNDLIT:%[a-zA-Z0-9.]+]] = alloca [[STRUCT]] + // CHECK-NEXT: [[CX:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]]* [[COMPOUNDLIT]], i32 0, i32 0 + // CHECK-NEXT: [[SY:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]]* [[S]], i32 0, i32 1 + // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i32* [[SY]] + // CHECK-NEXT: store i32 [[TMP]], i32* [[CX]] + // CHECK-NEXT: [[CY:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]]* [[COMPOUNDLIT]], i32 0, i32 1 + // CHECK-NEXT: [[SX:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]]* [[S]], i32 0, i32 0 + // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i32* [[SX]] + // CHECK-NEXT: store i32 [[TMP]], i32* [[CY]] + // CHECK-NEXT: [[SI8:%[a-zA-Z0-9.]+]] = bitcast [[STRUCT]]* [[S]] to i8* + // CHECK-NEXT: [[COMPOUNDLITI8:%[a-zA-Z0-9.]+]] = bitcast [[STRUCT]]* [[COMPOUNDLIT]] to i8* + // CHECK-NEXT: call void @llvm.memcpy{{.*}}(i8* [[SI8]], i8* [[COMPOUNDLITI8]] + s = (S){s.y,s.x}; + // CHECK-NEXT: ret void +} diff --git a/clang/test/CodeGen/compound-type.c b/clang/test/CodeGen/compound-type.c new file mode 100644 index 0000000..63ba694 --- /dev/null +++ b/clang/test/CodeGen/compound-type.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 < %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/clang/test/CodeGen/compound.c b/clang/test/CodeGen/compound.c new file mode 100644 index 0000000..960b2e8 --- /dev/null +++ b/clang/test/CodeGen/compound.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 < %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/clang/test/CodeGen/conditional-gnu-ext.c b/clang/test/CodeGen/conditional-gnu-ext.c new file mode 100644 index 0000000..2e32d3a --- /dev/null +++ b/clang/test/CodeGen/conditional-gnu-ext.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -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; +} + +// rdar://8446940 +extern void abort(); +void test1 () { + char x[1]; + char *y = x ? : 0; + + if (x != y) + abort(); +} + +// rdar://8453812 +_Complex int getComplex(_Complex int val) { + static int count; + if (count++) + abort(); + return val; +} + +_Complex int complx() { + _Complex int cond; + _Complex int rhs; + + return getComplex(1+2i) ? : rhs; +} diff --git a/clang/test/CodeGen/conditional.c b/clang/test/CodeGen/conditional.c new file mode 100644 index 0000000..88538a2 --- /dev/null +++ b/clang/test/CodeGen/conditional.c @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +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); +} + +// PR5526 +struct test9 { int a; }; +void* test9spare(); +void test9(struct test9 *p) { + p ? p : test9spare(); +} + +// CHECK: @test10 +// CHECK: select i1 {{.*}}, i32 4, i32 5 +int test10(int c) { + return c ? 4 : 5; +} +enum { Gronk = 5 }; + +// rdar://9289603 +// CHECK: @test11 +// CHECK: select i1 {{.*}}, i32 4, i32 5 +int test11(int c) { + return c ? 4 : Gronk; +} + +// CHECK: @test12 +// CHECK: select i1 {{.*}}, double 4.0{{.*}}, double 2.0 +double test12(int c) { + return c ? 4.0 : 2.0; +} +// CHECK: @test13 +// CHECK: call {{.*}} @f2( +int f2(void); +void test13() { + f2() ? (void)0 : (void)0; +} diff --git a/clang/test/CodeGen/const-arithmetic.c b/clang/test/CodeGen/const-arithmetic.c new file mode 100644 index 0000000..a28f73f --- /dev/null +++ b/clang/test/CodeGen/const-arithmetic.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +// CHECK: @g1 = global [2 x i8*] [i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -2), i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -46)], align 16 +// CHECK: @g2 = global [2 x i8*] [i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -2), i8* getelementptr (i8* getelementptr inbounds ([0 x %struct.anon]* @g0, i32 0, i32 0, i32 0), i64 -46)], align 16 + +extern struct { unsigned char a, b; } g0[]; +void *g1[] = {g0 + -1, g0 + -23 }; +void *g2[] = {g0 - 1, g0 - 23 }; diff --git a/clang/test/CodeGen/const-init.c b/clang/test/CodeGen/const-init.c new file mode 100644 index 0000000..4f3f7ab --- /dev/null +++ b/clang/test/CodeGen/const-init.c @@ -0,0 +1,146 @@ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -ffreestanding -verify -emit-llvm -o - %s | FileCheck %s + +#include <stdint.h> + +// Brace-enclosed string array initializers +char a[] = { "asdf" }; +// CHECK: @a = global [5 x i8] c"asdf\00" + +char a2[2][5] = { "asdf" }; +// CHECK: @a2 = global [2 x [5 x i8]] {{\[}}[5 x i8] c"asdf\00", [5 x i8] zeroinitializer] + +// 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); + +// CHECK: @g1x = global { double, double } { double 1.000000e+00{{[0]*}}, double 0.000000e+00{{[0]*}} } +_Complex double g1x = 1.0f; +// CHECK: @g1y = global { double, double } { double 0.000000e+00{{[0]*}}, double 1.000000e+00{{[0]*}} } +_Complex double g1y = 1.0fi; +// CHECK: @g1 = global { i8, i8 } { i8 1, i8 10 } +_Complex char g1 = (char) 1 + (char) 10 * 1i; +// CHECK: @g2 = global { i32, i32 } { i32 1, i32 10 } +_Complex int g2 = 1 + 10i; +// CHECK: @g3 = global { float, float } { float 1.000000e+00{{[0]*}}, float 1.000000e+0{{[0]*}}1 } +_Complex float g3 = 1.0 + 10.0i; +// CHECK: @g4 = global { double, double } { double 1.000000e+00{{[0]*}}, double 1.000000e+0{{[0]*}}1 } +_Complex double g4 = 1.0 + 10.0i; +// CHECK: @g5 = global { i32, i32 } zeroinitializer +_Complex int g5 = (2 + 3i) == (5 + 7i); +// CHECK: @g6 = global { double, double } { double -1.100000e+0{{[0]*}}1, double 2.900000e+0{{[0]*}}1 } +_Complex double g6 = (2.0 + 3.0i) * (5.0 + 7.0i); +// CHECK: @g7 = global i32 1 +int g7 = (2 + 3i) * (5 + 7i) == (-11 + 29i); +// CHECK: @g8 = global i32 1 +int g8 = (2.0 + 3.0i) * (5.0 + 7.0i) == (-11.0 + 29.0i); +// CHECK: @g9 = global i32 0 +int g9 = (2 + 3i) * (5 + 7i) != (-11 + 29i); +// CHECK: @g10 = global i32 0 +int g10 = (2.0 + 3.0i) * (5.0 + 7.0i) != (-11.0 + 29.0i); + +// PR5108 +// CHECK: @gv1 = global %struct.anon <{ i32 0, i8 7 }>, align 1 +struct { + unsigned long a; + unsigned long b:3; +} __attribute__((__packed__)) gv1 = { .a = 0x0, .b = 7, }; + +// PR5118 +// CHECK: @gv2 = global %struct.anon.0 <{ i8 1, i8* null }>, align 1 +struct { + unsigned char a; + char *b; +} __attribute__((__packed__)) gv2 = { 1, (void*)0 }; + +// Global references +// CHECK: @g11.l0 = internal global i32 ptrtoint (i32 ()* @g11 to i32) +long g11() { + static long l0 = (long) g11; + return l0; +} + +// CHECK: @g12 = global i32 ptrtoint (i8* @g12_tmp to i32) +static char g12_tmp; +long g12 = (long) &g12_tmp; + +// CHECK: @g13 = global [1 x %struct.g13_s0] [%struct.g13_s0 { i32 ptrtoint (i8* @g12_tmp to i32) }] +struct g13_s0 { + long a; +}; +struct g13_s0 g13[] = { + { (long) &g12_tmp } +}; + +// CHECK: @g14 = global i8* inttoptr (i64 100 to i8*) +void *g14 = (void*) 100; + +// CHECK: @g15 = global i32 -1 +int g15 = (int) (char) ((void*) 0 + 255); + +// CHECK: @g16 = global i64 4294967295 +long long g16 = (long long) ((void*) 0xFFFFFFFF); + +// CHECK: @g17 = global i32* @g15 +int *g17 = (int *) ((long) &g15); + +// CHECK: @g18.p = internal global [1 x i32*] [i32* @g19] +void g18(void) { + extern int g19; + static int *p[] = { &g19 }; +} + +// CHECK: @g20.l0 = internal global %struct.g20_s1 { %struct.g20_s0* null, %struct.g20_s0** getelementptr inbounds (%struct.g20_s1* @g20.l0, i32 0, i32 0) } +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}; + +// PR5474 +struct g22 {int x;} __attribute((packed)); +struct g23 {char a; short b; char c; struct g22 d;}; +struct g23 g24 = {1,2,3,4}; + +// CHECK: @g25.g26 = internal global i8* getelementptr inbounds ([4 x i8]* @__func__.g25, i32 0, i32 0) +// CHECK: @__func__.g25 = private unnamed_addr constant [4 x i8] c"g25\00" +int g25() { + static const char *g26 = __func__; + return *g26; +} + +// CHECK: @g27.x = internal global i8* bitcast (i8** @g27.x to i8*), align 4 +void g27() { // PR8073 + static void *x = &x; +} + +void g28() { + typedef long long v1i64 __attribute((vector_size(8))); + typedef short v12i16 __attribute((vector_size(24))); + typedef long double v2f80 __attribute((vector_size(24))); + // CHECK: @g28.a = internal global <1 x i64> <i64 10> + // CHECK: @g28.b = internal global <12 x i16> <i16 0, i16 0, i16 0, i16 -32768, i16 16383, i16 0, i16 0, i16 0, i16 0, i16 -32768, i16 16384, i16 0> + // CHECK: @g28.c = internal global <2 x x86_fp80> <x86_fp80 0xK3FFF8000000000000000, x86_fp80 0xK40008000000000000000>, align 32 + static v1i64 a = (v1i64)10LL; + static v12i16 b = (v2f80){1,2}; + static v2f80 c = (v12i16){0,0,0,-32768,16383,0,0,0,0,-32768,16384,0}; +} diff --git a/clang/test/CodeGen/const-label-addr.c b/clang/test/CodeGen/const-label-addr.c new file mode 100644 index 0000000..9d99f88 --- /dev/null +++ b/clang/test/CodeGen/const-label-addr.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t +int a() { +A:;static void* a = &&A; +} diff --git a/clang/test/CodeGen/const-unordered-compare.c b/clang/test/CodeGen/const-unordered-compare.c new file mode 100644 index 0000000..ffd04db --- /dev/null +++ b/clang/test/CodeGen/const-unordered-compare.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// Checks folding of an unordered comparison +int nan_ne_check() { + // CHECK: ret i32 1 + return (__builtin_nanf("") != __builtin_nanf("")) ? 1 : 0; +} diff --git a/clang/test/CodeGen/constant-comparison.c b/clang/test/CodeGen/constant-comparison.c new file mode 100644 index 0000000..371cb17 --- /dev/null +++ b/clang/test/CodeGen/constant-comparison.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - 2>&1 | not grep warning +// RUN: %clang_cc1 -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/clang/test/CodeGen/constructor-attribute.c b/clang/test/CodeGen/constructor-attribute.c new file mode 100644 index 0000000..a1f0e60 --- /dev/null +++ b/clang/test/CodeGen/constructor-attribute.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -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 + +int printf(const char *, ...); + +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/clang/test/CodeGen/count-builtins.c b/clang/test/CodeGen/count-builtins.c new file mode 100644 index 0000000..e6133c5 --- /dev/null +++ b/clang/test/CodeGen/count-builtins.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +int leading, trailing, pop; + +void test_i16(short P) { + leading = __builtin_clzs(P); + trailing = __builtin_ctzs(P); + +// CHECK: @test_i16 +// CHECK: call i16 @llvm.ctlz.i16 +// CHECK: call i16 @llvm.cttz.i16 +} + +void test_i32(int P) { + leading = __builtin_clz(P); + trailing = __builtin_ctz(P); + pop = __builtin_popcount(P); + +// CHECK: @test_i32 +// CHECK: call i32 @llvm.ctlz.i32 +// CHECK: call i32 @llvm.cttz.i32 +// CHECK: call i32 @llvm.ctpop.i32 +} + +void test_i64(float P) { + leading = __builtin_clzll(P); + trailing = __builtin_ctzll(P); + pop = __builtin_popcountll(P); +// CHECK: @test_i64 +// CHECK: call i64 @llvm.ctlz.i64 +// CHECK: call i64 @llvm.cttz.i64 +// CHECK: call i64 @llvm.ctpop.i64 +} diff --git a/clang/test/CodeGen/cxx-condition.cpp b/clang/test/CodeGen/cxx-condition.cpp new file mode 100644 index 0000000..5aa0c5e --- /dev/null +++ b/clang/test/CodeGen/cxx-condition.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/cxx-default-arg.cpp b/clang/test/CodeGen/cxx-default-arg.cpp new file mode 100644 index 0000000..25b7c10 --- /dev/null +++ b/clang/test/CodeGen/cxx-default-arg.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/cxx-value-init.cpp b/clang/test/CodeGen/cxx-value-init.cpp new file mode 100644 index 0000000..6e4cc03 --- /dev/null +++ b/clang/test/CodeGen/cxx-value-init.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/darwin-string-literals.c b/clang/test/CodeGen/darwin-string-literals.c new file mode 100644 index 0000000..968386a --- /dev/null +++ b/clang/test/CodeGen/darwin-string-literals.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix LSB %s + +// CHECK-LSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00" +// CHECK-LSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00" +// CHECK-LSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2 +// CHECK-LSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2 + + +// RUN: %clang_cc1 -triple powerpc-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix MSB %s + +// CHECK-MSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00" +// CHECK-MSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00" +// CHECK-MSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2 +// CHECK-MSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2 + +const char *g0 = "string0"; +const void *g1 = __builtin___CFStringMakeConstantString("string1"); +const void *g2 = __builtin___CFStringMakeConstantString("hello \u2192 \u2603 \u2190 world"); +const void *g3 = __builtin___CFStringMakeConstantString("testâ„¢"); diff --git a/clang/test/CodeGen/darwin-thread-specifier.c b/clang/test/CodeGen/darwin-thread-specifier.c new file mode 100644 index 0000000..605d461 --- /dev/null +++ b/clang/test/CodeGen/darwin-thread-specifier.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s +// CHECK: @b = thread_local global i32 5, align 4 +__thread int b = 5; diff --git a/clang/test/CodeGen/debug-dead-local-var.c b/clang/test/CodeGen/debug-dead-local-var.c new file mode 100644 index 0000000..f9ca8f2 --- /dev/null +++ b/clang/test/CodeGen/debug-dead-local-var.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -mllvm -asm-verbose -S -O2 -g %s -o - | FileCheck %s +// Radar 8122864 + +// Code is not generated for function foo, but preserve type information of +// local variable xyz. +static void foo() { +// CHECK: DW_TAG_structure_type + struct X { int a; int b; } xyz; +} + +int bar() { + foo(); + return 1; +} diff --git a/clang/test/CodeGen/debug-info-args.c b/clang/test/CodeGen/debug-info-args.c new file mode 100644 index 0000000..1d4ea10 --- /dev/null +++ b/clang/test/CodeGen/debug-info-args.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -g %s | FileCheck %s + +int somefunc(char *x, int y, double z) { + + // CHECK: {{.*metadata !8, i32 0, i32 0}.*DW_TAG_subroutine_type}} + // CHECK: {{!8 = .*metadata ![^,]*, metadata ![^,]*, metadata ![^,]*, metadata ![^,]*}} + + return y; +} diff --git a/clang/test/CodeGen/debug-info-block.c b/clang/test/CodeGen/debug-info-block.c new file mode 100644 index 0000000..403e4aa --- /dev/null +++ b/clang/test/CodeGen/debug-info-block.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fblocks -g -emit-llvm -o - %s | FileCheck %s +// APPLE LOCAL file 5939894 */ +// Verify that the desired debugging type is generated for a structure +// member that is a pointer to a block. + +// CHECK: __block_literal_generic{{.*}}DW_TAG_structure_type +// CHECK: __block_descriptor{{.*}}DW_TAG_structure_type +struct inStruct { + void (^genericBlockPtr)(); +} is; + diff --git a/clang/test/CodeGen/debug-info-compilation-dir.c b/clang/test/CodeGen/debug-info-compilation-dir.c new file mode 100644 index 0000000..4b47299 --- /dev/null +++ b/clang/test/CodeGen/debug-info-compilation-dir.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fdebug-compilation-dir /nonsense -emit-llvm -g %s -o - | FileCheck -check-prefix=CHECK-NONSENSE %s +// CHECK-NONSENSE: nonsense + +// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck -check-prefix=CHECK-DIR %s +// CHECK-DIR: CodeGen + diff --git a/clang/test/CodeGen/debug-info-crash.c b/clang/test/CodeGen/debug-info-crash.c new file mode 100644 index 0000000..f04548b --- /dev/null +++ b/clang/test/CodeGen/debug-info-crash.c @@ -0,0 +1,31 @@ +// REQUIRES: x86-registered-target +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -g -S %s -o - + +// rdar://7590323 +typedef struct dispatch_queue_s *dispatch_queue_t; +__attribute__((visibility("default"))) +extern struct dispatch_queue_s _dispatch_main_q; +typedef struct dispatch_item_s *dispatch_item_t; +typedef void (^dispatch_legacy_block_t)(dispatch_item_t); +dispatch_item_t LEGACY_dispatch_call(dispatch_queue_t dq, + dispatch_legacy_block_t dispatch_block, + dispatch_legacy_block_t callback_block) { + dispatch_queue_t lq = _dispatch_queue_get_current() ?: (&_dispatch_main_q); + dispatch_async(dq, ^{ + if (callback_block) { + dispatch_async(lq, ^{ + } + ); + } + } + ); +} + +// radar://9008853 +typedef struct P { + int x; +} PS; +# 1 "" +void foo() { + PS p2; +} diff --git a/clang/test/CodeGen/debug-info-enum.c b/clang/test/CodeGen/debug-info-enum.c new file mode 100644 index 0000000..b4a1ce0 --- /dev/null +++ b/clang/test/CodeGen/debug-info-enum.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o %t +// RUN: grep DW_TAG_enumeration_type %t +// Radar 8195980 + +enum vtag { + VT_ONE +}; + +int foo(int i) { + return i == VT_ONE; +} diff --git a/clang/test/CodeGen/debug-info-iv.c b/clang/test/CodeGen/debug-info-iv.c new file mode 100644 index 0000000..6684fe3 --- /dev/null +++ b/clang/test/CodeGen/debug-info-iv.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -Os -S -g -o - %s | FileCheck %s +// REQUIRES: x86-registered-target + +int calculate(int); +static void test_indvars(int *Array1, int Array2[100][200]) { + unsigned i, j; + Array1[1] = Array2[3][6] = 12345; + + for (i = 0; i < 100; i+=2) + Array1[i] = i; /* Step by non unit amount */ + + for (i = 3; i < 103; i++) + Array1[i] = i+4; /* Step with an offset */ + + for (i = 13; i < 100; i++) + for (j = 0; j < 100; j+=3) /* 2d array access */ + Array2[i][j/3] = Array2[i][i]; +} + + +int main() { + int Array[100][200], i, j; + double sum = 0.0; + + for (i=0; i < 100; i+=2) + for (j=0; j < 200; j++) + Array[i][j] = 0; + test_indvars(Array[0], Array); + +//CHECK: .loc 2 31 8 + for (i=0; i < 100; i+=2) + for (j=0; j < 200; j++) + sum += Array[i][j]; + + return calculate(sum); +} diff --git a/clang/test/CodeGen/debug-info-line.c b/clang/test/CodeGen/debug-info-line.c new file mode 100644 index 0000000..9e6e971 --- /dev/null +++ b/clang/test/CodeGen/debug-info-line.c @@ -0,0 +1,23 @@ +// RUN: %clang -emit-llvm -S -g %s -o - | FileCheck %s + +// Radar 8396182 +// There is only one lexical block, but we need a DILexicalBlock and two +// DILexicalBlockFile to correctly represent file info. This means we have +// two lexical blocks shown as the latter is also tagged as a lexical block. + +int foo() { + int i = 1; +# 4 "m.c" +# 1 "m.h" 1 + int j = 2; +# 2 "m.h" +# 5 "m.c" 2 + return i + j; +} + +// CHECK: DW_TAG_lexical_block +// CHECK: DW_TAG_lexical_block +// CHECK: !"m.h" +// CHECK: DW_TAG_lexical_block +// CHECK: !"m.c" +// CHECK-NOT: DW_TAG_lexical_block diff --git a/clang/test/CodeGen/debug-info-line2.c b/clang/test/CodeGen/debug-info-line2.c new file mode 100644 index 0000000..b5eba8a --- /dev/null +++ b/clang/test/CodeGen/debug-info-line2.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-darwin-apple -g -emit-llvm -o - %s | FileCheck %s +// Radar 9199234 + +int bar(); +int foo(int i) { + int j = 0; + if (i) { + j = bar(); +//CHECK: store i32 +//CHECK-NOT: br label %{{%[a-zA-Z0-9\.]+}}, !dbg + } + else + { + j = bar() + 2; + } + return j; +} diff --git a/clang/test/CodeGen/debug-info-line3.c b/clang/test/CodeGen/debug-info-line3.c new file mode 100644 index 0000000..645ffb9 --- /dev/null +++ b/clang/test/CodeGen/debug-info-line3.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -g -S -emit-llvm %s -o - | FileCheck %s + +void func(char c, char* d) +{ + *d = c + 1; + return; + + + + + + +} + +// CHECK: ret void, !dbg !19 +// CHECK: !19 = metadata !{i32 6, diff --git a/clang/test/CodeGen/debug-info-member.c b/clang/test/CodeGen/debug-info-member.c new file mode 100644 index 0000000..43d26f8 --- /dev/null +++ b/clang/test/CodeGen/debug-info-member.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-llvm -g < %s | grep DW_TAG_member + +struct A { int x; } a; diff --git a/clang/test/CodeGen/debug-info-scope.c b/clang/test/CodeGen/debug-info-scope.c new file mode 100644 index 0000000..6051e6e --- /dev/null +++ b/clang/test/CodeGen/debug-info-scope.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -g -emit-llvm < %s | FileCheck %s +// Two variables with same name in separate scope. +// Radar 8330217. +int main() { + int j = 0; + int k = 0; +// CHECK: DW_TAG_auto_variable +// CHECK-NEXT: DW_TAG_lexical_block + for (int i = 0; i < 10; i++) + j++; + for (int i = 0; i < 10; i++) + k++; + return 0; +} diff --git a/clang/test/CodeGen/debug-info-static.c b/clang/test/CodeGen/debug-info-static.c new file mode 100644 index 0000000..e75d20f --- /dev/null +++ b/clang/test/CodeGen/debug-info-static.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -g -emit-llvm -o - %s | FileCheck %s + +// CHECK: xyzzy} ; [ DW_TAG_variable ] +void f(void) +{ + static int xyzzy; + xyzzy += 3; +} diff --git a/clang/test/CodeGen/debug-info-var-location.c b/clang/test/CodeGen/debug-info-var-location.c new file mode 100644 index 0000000..12edb08 --- /dev/null +++ b/clang/test/CodeGen/debug-info-var-location.c @@ -0,0 +1,21 @@ +// RUN: %clang -S -g -fverbose-asm %s -o - | FileCheck %s +// Radar 8461032 +// CHECK: DW_AT_location +// CHECK-NEXT: byte 145 + +// 145 is DW_OP_fbreg +struct s { + int a; + struct s *next; +}; + +int foo(struct s *s) { + switch (s->a) { + case 1: + case 2: { + struct s *sp = s->next; + } + break; + } + return 1; +} diff --git a/clang/test/CodeGen/debug-info.c b/clang/test/CodeGen/debug-info.c new file mode 100644 index 0000000..af2ce96 --- /dev/null +++ b/clang/test/CodeGen/debug-info.c @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -o %t -emit-llvm -g %s +// RUN: FileCheck --input-file=%t %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; + + +// Radar 7325611 +// CHECK: "barfoo" +typedef int barfoo; +barfoo foo() { +} + +// CHECK: __uint128_t +__uint128_t foo128 () +{ + __uint128_t int128 = 44; + return int128; +} + +// CHECK: uint64x2_t +typedef unsigned long long uint64_t; +typedef uint64_t uint64x2_t __attribute__((ext_vector_type(2))); +uint64x2_t extvectbar[4]; diff --git a/clang/test/CodeGen/debug-line-1.c b/clang/test/CodeGen/debug-line-1.c new file mode 100644 index 0000000..00d4f42 --- /dev/null +++ b/clang/test/CodeGen/debug-line-1.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -o - -emit-llvm -g %s | FileCheck %s +// REQUIRES: asserts +// PR9796 + +// Check to make sure that we emit the block for the break so that we can count the line. +// CHECK: sw.bb: ; preds = %entry +// CHECK: br label %sw.epilog, !dbg !21 + +extern int atoi(const char *); + +int f(char* arg) { + int x = atoi(arg); + + switch(x) { + case 1: + break; + } + + return 0; +} diff --git a/clang/test/CodeGen/decl-in-prototype.c b/clang/test/CodeGen/decl-in-prototype.c new file mode 100644 index 0000000..949793d --- /dev/null +++ b/clang/test/CodeGen/decl-in-prototype.c @@ -0,0 +1,21 @@ +// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s + +const int AA = 5; + +// CHECK: define i32 @f1 +int f1(enum {AA,BB} E) { + // CHECK: ret i32 1 + return BB; +} + +// CHECK: define i32 @f2 +int f2(enum {AA=7,BB} E) { + // CHECK: ret i32 7 + return AA; +} + +// Check nested function declarators work. +int f(void (*g)(), enum {AA,BB} h) { + // CHECK: ret i32 0 + return AA; +} diff --git a/clang/test/CodeGen/decl.c b/clang/test/CodeGen/decl.c new file mode 100644 index 0000000..2065e33 --- /dev/null +++ b/clang/test/CodeGen/decl.c @@ -0,0 +1,119 @@ +// RUN: %clang_cc1 -w -emit-llvm < %s | FileCheck %s + +// CHECK: @test1.x = internal constant [12 x i32] [i32 1 +// CHECK: @test2.x = private unnamed_addr constant [13 x i32] [i32 1, +// CHECK: @test5w = global { i32, [4 x i8] } { i32 2, [4 x i8] undef } +// CHECK: @test5y = global { double } { double 7.300000e+0{{[0]*}}1 } + +// CHECK: @test6.x = private unnamed_addr constant %struct.SelectDest { i8 1, i8 2, i32 3, i32 0 } + +// CHECK: @test7 = global [2 x %struct.test7s] [%struct.test7s { i32 1, i32 2 }, %struct.test7s { i32 4, i32 0 }] + +void test1() { + // This should codegen as a "@test1.x" global. + const int x[] = { 1, 2, 3, 4, 6, 8, 9, 10, 123, 231, 123,23 }; + foo(x); + +// CHECK: @test1() +// CHECK: {{call.*@foo.*@test1.x}} +} + + +// rdar://7346691 +void test2() { + // This should codegen as a "@test2.x" global + memcpy. + int x[] = { 1, 2, 3, 4, 6, 8, 9, 10, 123, 231, 123,23, 24 }; + foo(x); + + // CHECK: @test2() + // CHECK: %x = alloca [13 x i32] + // CHECK: call void @llvm.memcpy + // CHECK: call{{.*}}@foo{{.*}}i32* % +} + + +void test3() { + // This should codegen as a memset. + int x[100] = { 0 }; + foo(x); + + // CHECK: @test3() + // CHECK: %x = alloca [100 x i32] + // CHECK: call void @llvm.memset +} + +void test4(void) { + char a[10] = "asdf"; + char b[10] = { "asdf" }; + // CHECK: @test4() + // CHECK: %a = alloca [10 x i8] + // CHECK: %b = alloca [10 x i8] + // CHECK: call void @llvm.memcpy + // CHECK: call void @llvm.memcpy +} + + +union test5u { int i; double d; }; + +void test5() { + union test5u ola = (union test5u) 351; + union test5u olb = (union test5u) 1.0; +} + +union test5u test5w = (union test5u)2; +union test5u test5y = (union test5u)73.0; + + + +// PR6660 - sqlite miscompile +struct SelectDest { + unsigned char eDest; + unsigned char affinity; + int iParm; + int iMem; +}; + +void test6() { + struct SelectDest x = {1, 2, 3}; + test6f(&x); +} + +// rdar://7657600 +struct test7s { int a; int b; } test7[] = { + {1, 2}, + {4}, +}; + +// rdar://7872531 +#pragma pack(push, 2) +struct test8s { int f0; char f1; } test8g = {}; + + +// PR7519 + +struct S { + void (*x) (struct S *); +}; + +extern struct S *global_dc; +void cp_diagnostic_starter(struct S *); + +void init_error(void) { + global_dc->x = cp_diagnostic_starter; +} + + + +// rdar://8147692 - ABI crash in recursive struct-through-function-pointer. +typedef struct { + int x5a; +} x5; + +typedef struct x2 *x0; +typedef long (*x1)(x0 x0a, x5 x6); +struct x2 { + x1 x4; +}; +long x3(x0 x0a, x5 a) { + return x0a->x4(x0a, a); +} diff --git a/clang/test/CodeGen/designated-initializers.c b/clang/test/CodeGen/designated-initializers.c new file mode 100644 index 0000000..6561ce5 --- /dev/null +++ b/clang/test/CodeGen/designated-initializers.c @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s + +struct foo { + void *a; + int b; +}; + +// CHECK: @u = global %union.anon zeroinitializer +union { int i; float f; } u = { }; + +// CHECK: @u2 = global { i32, [4 x i8] } { i32 0, [4 x i8] undef } +union { int i; double f; } u2 = { }; + +// CHECK: @u3 = global %union.anon.1 zeroinitializer +union { double f; int i; } u3 = { }; + +// CHECK: @b = global [2 x i32] [i32 0, i32 22] +int b[2] = { + [1] = 22 +}; + +// PR6955 + +struct ds { + struct { + struct { + short a; + }; + short b; + struct { + short c; + }; + }; +}; + +// Traditional C anonymous member init +struct ds ds0 = { { { .a = 0 } } }; +// C1X lookup-based anonymous member init cases +struct ds ds1 = { { .a = 1 } }; +struct ds ds2 = { { .b = 1 } }; +struct ds ds3 = { .a = 0 }; +// CHECK: @ds4 = global %struct.ds { %struct.anon.3 { %struct.anon zeroinitializer, i16 0, %struct.anon.2 { i16 1 } } } +struct ds ds4 = { .c = 1 }; +struct ds ds5 = { { { .a = 0 } }, .b = 1 }; +struct ds ds6 = { { .a = 0, .b = 1 } }; +// CHECK: @ds7 = global %struct.ds { %struct.anon.3 { %struct.anon { i16 2 }, i16 3, %struct.anon.2 zeroinitializer } } +struct ds ds7 = { + { { + .a = 1 + } }, + .a = 2, + .b = 3 +}; + +void test1(int argc, char **argv) +{ + // CHECK: internal global %struct.foo { i8* null, i32 1024 } + static struct foo foo = { + .b = 1024, + }; + + // CHECK: bitcast %union.anon.4* %u2 + // CHECK: call void @llvm.memset + union { int i; float f; } u2 = { }; + + // CHECK-NOT: call void @llvm.memset + union { int i; float f; } u3; + + // CHECK: ret void +} + + +// PR7151 +struct S { + int nkeys; + int *keys; + union { + void *data; + }; +}; + +void test2() { + struct S *btkr; + + *btkr = (struct S) { + .keys = 0, + { .data = 0 }, + }; +} diff --git a/clang/test/CodeGen/dllimport-dllexport.c b/clang/test/CodeGen/dllimport-dllexport.c new file mode 100644 index 0000000..c187503 --- /dev/null +++ b/clang/test/CodeGen/dllimport-dllexport.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple i386-mingw32 -emit-llvm < %s | FileCheck %s + +void __attribute__((dllimport)) foo1(); +void __attribute__((dllexport)) foo1(){} +// CHECK: define dllexport void @foo1 +void __attribute__((dllexport)) foo2(); + +// PR6269 +__declspec(dllimport) void foo3(); +__declspec(dllexport) void foo3(){} +// CHECK: define dllexport void @foo3 +__declspec(dllexport) void foo4(); diff --git a/clang/test/CodeGen/dostmt.c b/clang/test/CodeGen/dostmt.c new file mode 100644 index 0000000..1a2e02a --- /dev/null +++ b/clang/test/CodeGen/dostmt.c @@ -0,0 +1,70 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/emit-all-decls.c b/clang/test/CodeGen/emit-all-decls.c new file mode 100644 index 0000000..deeb573 --- /dev/null +++ b/clang/test/CodeGen/emit-all-decls.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm -o %t %s +// RUN: not grep "@foo" %t +// RUN: %clang_cc1 -femit-all-decls -emit-llvm -o %t %s +// RUN: grep "@foo" %t + +static void foo() { + +} diff --git a/clang/test/CodeGen/empty-union-init.c b/clang/test/CodeGen/empty-union-init.c new file mode 100644 index 0000000..a58354b --- /dev/null +++ b/clang/test/CodeGen/empty-union-init.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm < %s -o - +// PR2419 + +struct Mem { + union { + } u; +}; + +struct Mem *columnMem(){ + static const struct Mem nullMem = { {} }; +} + + diff --git a/clang/test/CodeGen/enum.c b/clang/test/CodeGen/enum.c new file mode 100644 index 0000000..0e239f1 --- /dev/null +++ b/clang/test/CodeGen/enum.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -O3 -emit-llvm -o - | grep 'ret i32 6' +// RUN: %clang_cc1 -triple i386-unknown-unknown -x c++ %s -O3 -emit-llvm -o - | grep 'ret i32 7' + +// This test case illustrates a peculiarity of the promotion of +// enumeration types in C and C++. In particular, the enumeration type +// "z" below promotes to an unsigned int in C but int in C++. +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/clang/test/CodeGen/enum2.c b/clang/test/CodeGen/enum2.c new file mode 100644 index 0000000..3203627 --- /dev/null +++ b/clang/test/CodeGen/enum2.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -g -emit-llvm -o /dev/null +int v; +enum e { MAX }; + +void foo (void) +{ + v = MAX; +} diff --git a/clang/test/CodeGen/exact-div-expr.c b/clang/test/CodeGen/exact-div-expr.c new file mode 100644 index 0000000..a2c12a0 --- /dev/null +++ b/clang/test/CodeGen/exact-div-expr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -O1 | grep ashr +// RUN: %clang_cc1 -emit-llvm %s -o - -O1 | not grep sdiv + +long long test(int *A, int *B) { + return A-B; +} diff --git a/clang/test/CodeGen/exceptions.c b/clang/test/CodeGen/exceptions.c new file mode 100644 index 0000000..20eb706 --- /dev/null +++ b/clang/test/CodeGen/exceptions.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fexceptions -fblocks | FileCheck %s +// RUN: %clang_cc1 -triple armv7-apple-unknown -emit-llvm -o - %s -fexceptions -fsjlj-exceptions -fblocks | FileCheck %s -check-prefix=CHECK-ARM + +// rdar://problem/8621849 +void test1() { + extern void test1_helper(void (^)(int)); + + // CHECK: define void @test1() + // CHECK-ARM: define arm_aapcscc void @test1() + + __block int x = 10; + + // CHECK: invoke void @test1_helper( + // CHECK-ARM: invoke arm_aapcscc void @test1_helper( + test1_helper(^(int v) { x = v; }); + + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*) + // CHECK-NEXT: cleanup + // CHECK-ARM: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gcc_personality_sj0 to i8*) + // CHECK-ARM-NEXT: cleanup +} diff --git a/clang/test/CodeGen/exprs.c b/clang/test/CodeGen/exprs.c new file mode 100644 index 0000000..cc03be6 --- /dev/null +++ b/clang/test/CodeGen/exprs.c @@ -0,0 +1,176 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s + +// 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); return 0; } + +// 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]); +} + +void f10() { + __builtin_sin(0); +} + +// rdar://7530813 +// CHECK: define i32 @f11 +int f11(long X) { + int A[100]; + return A[X]; + +// CHECK: [[Xaddr:%[^ ]+]] = alloca i64, align 8 +// CHECK: load {{.*}}* [[Xaddr]] +// CHECK-NEXT: getelementptr inbounds [100 x i32]* %A, i32 0, +// CHECK-NEXT: load i32* +} + +int f12() { + // PR3150 + // CHECK: define i32 @f12 + // CHECK: ret i32 1 + return 1||1; +} + +// Make sure negate of fp uses -0.0 for proper -0 handling. +double f13(double X) { + // CHECK: define double @f13 + // CHECK: fsub double -0.0 + return -X; +} + +// Check operations on incomplete types. +void f14(struct s14 *a) { + (void) &*a; +} + +// CHECK: define void @f15 +void f15() { + extern void f15_start(void); + f15_start(); + // CHECK: call void @f15_start() + + extern void *f15_v(void); + extern const void *f15_cv(void); + extern volatile void *f15_vv(void); + *f15_v(); *f15_v(), *f15_v(); f15_v() ? *f15_v() : *f15_v(); + *f15_cv(); *f15_cv(), *f15_cv(); f15_cv() ? *f15_cv() : *f15_cv(); + *f15_vv(); *f15_vv(), *f15_vv(); f15_vv() ? *f15_vv() : *f15_vv(); + // CHECK-NOT: load + // CHECK: ret void +} + +// PR8967: this was crashing +// CHECK: define void @f16() +void f16() { + __extension__({ goto lbl; }); + lbl: + ; +} diff --git a/clang/test/CodeGen/ext-vector-member-alignment.c b/clang/test/CodeGen/ext-vector-member-alignment.c new file mode 100644 index 0000000..49e6997 --- /dev/null +++ b/clang/test/CodeGen/ext-vector-member-alignment.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +typedef float float4 __attribute__((ext_vector_type(4))); + +struct __attribute__((packed, aligned(4))) struct1 { + float4 position; +}; +int x = __alignof(struct struct1); + +float4 f(struct struct1* x) { return x->position; } + +void func(struct struct1* p, float *a, float *b, float c) { + p->position.x = c; + *a = p->position.y; + *b = p->position[0]; + p->position[2] = c; + // FIXME: We should be able to come up with a more aggressive alignment + // estimate. + // CHECK: @func + // CHECK: load <4 x float>* {{%.*}}, align 1 + // CHECK: store <4 x float> {{%.*}}, <4 x float>* {{%.*}}, align 1 + // CHECK: load <4 x float>* {{%.*}}, align 1 + // CHECK: load <4 x float>* {{%.*}}, align 1 + // CHECK: load <4 x float>* {{%.*}}, align 1 + // CHECK: store <4 x float> {{%.*}}, <4 x float>* {{%.*}}, align 1 + // CHECK: ret void +} diff --git a/clang/test/CodeGen/ext-vector.c b/clang/test/CodeGen/ext-vector.c new file mode 100644 index 0000000..a9fa151 --- /dev/null +++ b/clang/test/CodeGen/ext-vector.c @@ -0,0 +1,288 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +typedef __attribute__(( ext_vector_type(4) )) float float4; +typedef __attribute__(( ext_vector_type(2) )) float float2; +typedef __attribute__(( ext_vector_type(4) )) int int4; +typedef __attribute__(( ext_vector_type(4) )) unsigned int uint4; + +// CHECK: @foo = global <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00> +float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 }; + +// CHECK: @bar = constant <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 0x7FF0000000000000> +const float4 bar = (float4){ 1.0, 2.0, 3.0, __builtin_inff() }; + +// CHECK: @test1 +// CHECK: fadd <4 x float> +float4 test1(float4 V) { + return V.wzyx+V; +} + +float2 vec2, vec2_2; +float4 vec4, vec4_2; +float f; + +// CHECK: @test2 +// CHECK: shufflevector {{.*}} <i32 0, i32 1> +// CHECK: extractelement +// CHECK: shufflevector {{.*}} <i32 1, i32 1, i32 1, i32 1> +// CHECK: insertelement +// CHECK: shufflevector {{.*}} <i32 1, i32 0> +void test2() { + vec2 = vec4.xy; // shorten + f = vec2.x; // extract elt + vec4 = vec4.yyyy; // splat + + vec2.x = f; // insert one. + vec2.yx = vec2; // reverse +} + +// CHECK: @test3 +// CHECK: store <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00> +void test3(float4 *out) { + *out = ((float4) {1.0f, 2.0f, 3.0f, 4.0f }); +} + +// CHECK: @test4 +// CHECK: store <4 x float> +// CHECK: store <4 x float> +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}); +} + +// CHECK: @test5 +// CHECK: shufflevector {{.*}} <4 x i32> zeroinitializer +// CHECK: fmul <4 x float> +// CHECK: fmul <4 x float> +// CHECK: shufflevector {{.*}} <4 x i32> zeroinitializer +// CHECK: fmul <4 x float> +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; +} + +// CHECK: @test6 +void test6(float4 *ap, float4 *bp, float c) { + float4 a = *ap; + float4 b = *bp; + + // CHECK: fadd <4 x float> + // CHECK: fsub <4 x float> + // CHECK: fmul <4 x float> + // CHECK: fdiv <4 x float> + a = a + b; + a = a - b; + a = a * b; + a = a / b; + + // CHECK: fadd <4 x float> + // CHECK: fsub <4 x float> + // CHECK: fmul <4 x float> + // CHECK: fdiv <4 x float> + a = a + c; + a = a - c; + a = a * c; + a = a / c; + + // CHECK: fadd <4 x float> + // CHECK: fsub <4 x float> + // CHECK: fmul <4 x float> + // CHECK: fdiv <4 x float> + a += b; + a -= b; + a *= b; + a /= b; + + // CHECK: fadd <4 x float> + // CHECK: fsub <4 x float> + // CHECK: fmul <4 x float> + // CHECK: fdiv <4 x float> + 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 +} + +// CHECK: @test7 +void test7(int4 *ap, int4 *bp, int c) { + int4 a = *ap; + int4 b = *bp; + + // CHECK: add <4 x i32> + // CHECK: sub <4 x i32> + // CHECK: mul <4 x i32> + // CHECK: sdiv <4 x i32> + // CHECK: srem <4 x i32> + a = a + b; + a = a - b; + a = a * b; + a = a / b; + a = a % b; + + // CHECK: add <4 x i32> + // CHECK: sub <4 x i32> + // CHECK: mul <4 x i32> + // CHECK: sdiv <4 x i32> + // CHECK: srem <4 x i32> + a = a + c; + a = a - c; + a = a * c; + a = a / c; + a = a % c; + + // CHECK: add <4 x i32> + // CHECK: sub <4 x i32> + // CHECK: mul <4 x i32> + // CHECK: sdiv <4 x i32> + // CHECK: srem <4 x i32> + a += b; + a -= b; + a *= b; + a /= b; + a %= b; + + // CHECK: add <4 x i32> + // CHECK: sub <4 x i32> + // CHECK: mul <4 x i32> + // CHECK: sdiv <4 x i32> + // CHECK: srem <4 x i32> + a += c; + a -= c; + a *= c; + a /= c; + a %= c; + + + // Vector comparisons. + // CHECK: icmp slt + // CHECK: icmp sle + // CHECK: icmp sgt + // CHECK: icmp sge + // CHECK: icmp eq + // CHECK: icmp ne + int4 cmp; + cmp = a < b; + cmp = a <= b; + cmp = a > b; + cmp = a >= b; + cmp = a == b; + cmp = a != b; +} + +// CHECK: @test8 +void test8(float4 *ap, float4 *bp, int c) { + float4 a = *ap; + float4 b = *bp; + + // Vector comparisons. + // CHECK: fcmp olt + // CHECK: fcmp ole + // CHECK: fcmp ogt + // CHECK: fcmp oge + // CHECK: fcmp oeq + // CHECK: fcmp une + int4 cmp; + cmp = a < b; + cmp = a <= b; + cmp = a > b; + cmp = a >= b; + cmp = a == b; + cmp = a != b; +} + +// CHECK: @test9 +// CHECK: extractelement <4 x i32> +int test9(int4 V) { + return V.xy.x; +} + +// CHECK: @test10 +// CHECK: add <4 x i32> +// CHECK: extractelement <4 x i32> +int test10(int4 V) { + return (V+V).x; +} + +// CHECK: @test11 +// CHECK: extractelement <4 x i32> +int4 test11a(); +int test11() { + return test11a().x; +} + +// CHECK: @test12 +// CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0> +// CHECK: shufflevector {{.*}} <i32 0, i32 1, i32 2, i32 undef> +// CHECK: shufflevector {{.*}} <i32 4, i32 5, i32 6, i32 3> +int4 test12(int4 V) { + V.xyz = V.zyx; + return V; +} + +// CHECK: @test13 +// CHECK: shufflevector {{.*}} <i32 2, i32 1, i32 0, i32 3> +int4 test13(int4 *V) { + return V->zyxw; +} + +// CHECK: @test14 +void test14(uint4 *ap, uint4 *bp, unsigned c) { + uint4 a = *ap; + uint4 b = *bp; + int4 d; + + // CHECK: udiv <4 x i32> + // CHECK: urem <4 x i32> + a = a / b; + a = a % b; + + // CHECK: udiv <4 x i32> + // CHECK: urem <4 x i32> + a = a / c; + a = a % c; + + // CHECK: icmp ult + // CHECK: icmp ule + // CHECK: icmp ugt + // CHECK: icmp uge + // CHECK: icmp eq + // CHECK: icmp ne + d = a < b; + d = a <= b; + d = a > b; + d = a >= b; + d = a == b; + d = a != b; +} + +// CHECK: @test15 +int4 test15(uint4 V0) { + // CHECK: icmp eq <4 x i32> + int4 V = !V0; + V = V && V; + V = V || V; + return V; +} diff --git a/clang/test/CodeGen/extern-block-var.c b/clang/test/CodeGen/extern-block-var.c new file mode 100644 index 0000000..329f109 --- /dev/null +++ b/clang/test/CodeGen/extern-block-var.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -emit-llvm -o %t + +int f() { + extern int a; + return a; +} diff --git a/clang/test/CodeGen/extern-inline.c b/clang/test/CodeGen/extern-inline.c new file mode 100644 index 0000000..e3df996 --- /dev/null +++ b/clang/test/CodeGen/extern-inline.c @@ -0,0 +1,26 @@ +// RUN: %clang -S -emit-llvm -std=gnu89 -o - %s | FileCheck %s +// RUN: %clang -S -emit-llvm -fgnu89-inline -o - %s | FileCheck %s +// PR5253 + +// If an extern inline function is redefined, functions should call the +// redefinition. +extern inline int f(int a) {return a;} +int g(void) {return f(0);} +// CHECK: call i32 @f +int f(int b) {return 1+b;} +// CHECK: load i32* %{{.*}} +// CHECK: add nsw i32 1, %{{.*}} +int h(void) {return f(1);} +// CHECK: call i32 @f + +// It shouldn't matter if the function was redefined static. +extern inline int f2(int a, int b) {return a+b;} +int g2(void) {return f2(0,1);} +// CHECK: call i32 @f2 +static int f2(int a, int b) {return a*b;} +// CHECK: load i32* %{{.*}} +// CHECK: load i32* %{{.*}} +// CHECK: mul nsw i32 %{{.*}}, %{{.*}} +int h2(void) {return f2(1,2);} +// CHECK: call i32 @f2 + diff --git a/clang/test/CodeGen/extern-weak.c b/clang/test/CodeGen/extern-weak.c new file mode 100644 index 0000000..6a78a33 --- /dev/null +++ b/clang/test/CodeGen/extern-weak.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -O3 -emit-llvm -o - %s | grep extern_weak +// RUN: %clang_cc1 -O3 -emit-llvm -o - %s | llc + +#if !defined(__linux__) && !defined(__FreeBSD__) && \ + !defined(__OpenBSD__) && !defined(__CYGWIN__) && !defined(__DragonFly__) +void foo() __attribute__((weak_import)); +#else +void foo() __attribute__((weak)); +#endif + +void bar() { foo(); } + diff --git a/clang/test/CodeGen/flexible-array-init.c b/clang/test/CodeGen/flexible-array-init.c new file mode 100644 index 0000000..d3079dc --- /dev/null +++ b/clang/test/CodeGen/flexible-array-init.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +struct { int x; int y[]; } a = { 1, 7, 11 }; +// CHECK: @a = global { i32, [2 x i32] } { i32 1, [2 x i32] [i32 7, i32 11] } + +struct { int x; int y[]; } b = { 1, { 13, 15 } }; +// CHECK: @b = global { i32, [2 x i32] } { i32 1, [2 x i32] [i32 13, i32 15] } diff --git a/clang/test/CodeGen/fma4-builtins.c b/clang/test/CodeGen/fma4-builtins.c new file mode 100644 index 0000000..ddbaba7 --- /dev/null +++ b/clang/test/CodeGen/fma4-builtins.c @@ -0,0 +1,166 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +fma4 -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +__m128 test_mm_macc_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmadd.ps + return _mm_macc_ps(a, b, c); +} + +__m128d test_mm_macc_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmadd.pd + return _mm_macc_pd(a, b, c); +} + +__m128 test_mm_macc_ss(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmadd.ss + return _mm_macc_ss(a, b, c); +} + +__m128d test_mm_macc_sd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmadd.sd + return _mm_macc_sd(a, b, c); +} + +__m128 test_mm_msub_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmsub.ps + return _mm_msub_ps(a, b, c); +} + +__m128d test_mm_msub_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmsub.pd + return _mm_msub_pd(a, b, c); +} + +__m128 test_mm_msub_ss(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmsub.ss + return _mm_msub_ss(a, b, c); +} + +__m128d test_mm_msub_sd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmsub.sd + return _mm_msub_sd(a, b, c); +} + +__m128 test_mm_nmacc_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfnmadd.ps + return _mm_nmacc_ps(a, b, c); +} + +__m128d test_mm_nmacc_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfnmadd.pd + return _mm_nmacc_pd(a, b, c); +} + +__m128 test_mm_nmacc_ss(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfnmadd.ss + return _mm_nmacc_ss(a, b, c); +} + +__m128d test_mm_nmacc_sd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfnmadd.sd + return _mm_nmacc_sd(a, b, c); +} + +__m128 test_mm_nmsub_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfnmsub.ps + return _mm_nmsub_ps(a, b, c); +} + +__m128d test_mm_nmsub_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfnmsub.pd + return _mm_nmsub_pd(a, b, c); +} + +__m128 test_mm_nmsub_ss(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfnmsub.ss + return _mm_nmsub_ss(a, b, c); +} + +__m128d test_mm_nmsub_sd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfnmsub.sd + return _mm_nmsub_sd(a, b, c); +} + +__m128 test_mm_maddsub_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmaddsub.ps + return _mm_maddsub_ps(a, b, c); +} + +__m128d test_mm_maddsub_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmaddsub.pd + return _mm_maddsub_pd(a, b, c); +} + +__m128 test_mm_msubadd_ps(__m128 a, __m128 b, __m128 c) { + // CHECK: @llvm.x86.fma4.vfmsubadd.ps + return _mm_msubadd_ps(a, b, c); +} + +__m128d test_mm_msubadd_pd(__m128d a, __m128d b, __m128d c) { + // CHECK: @llvm.x86.fma4.vfmsubadd.pd + return _mm_msubadd_pd(a, b, c); +} + +__m256 test_mm256_macc_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfmadd.ps.256 + return _mm256_macc_ps(a, b, c); +} + +__m256d test_mm256_macc_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfmadd.pd.256 + return _mm256_macc_pd(a, b, c); +} + +__m256 test_mm256_msub_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfmsub.ps.256 + return _mm256_msub_ps(a, b, c); +} + +__m256d test_mm256_msub_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfmsub.pd.256 + return _mm256_msub_pd(a, b, c); +} + +__m256 test_mm256_nmacc_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfnmadd.ps.256 + return _mm256_nmacc_ps(a, b, c); +} + +__m256d test_mm256_nmacc_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfnmadd.pd.256 + return _mm256_nmacc_pd(a, b, c); +} + +__m256 test_mm256_nmsub_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfnmsub.ps.256 + return _mm256_nmsub_ps(a, b, c); +} + +__m256d test_mm256_nmsub_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfnmsub.pd.256 + return _mm256_nmsub_pd(a, b, c); +} + +__m256 test_mm256_maddsub_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfmaddsub.ps.256 + return _mm256_maddsub_ps(a, b, c); +} + +__m256d test_mm256_maddsub_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfmaddsub.pd.256 + return _mm256_maddsub_pd(a, b, c); +} + +__m256 test_mm256_msubadd_ps(__m256 a, __m256 b, __m256 c) { + // CHECK: @llvm.x86.fma4.vfmsubadd.ps.256 + return _mm256_msubadd_ps(a, b, c); +} + +__m256d test_mm256_msubadd_pd(__m256d a, __m256d b, __m256d c) { + // CHECK: @llvm.x86.fma4.vfmsubadd.pd.256 + return _mm256_msubadd_pd(a, b, c); +} diff --git a/clang/test/CodeGen/fold-const-declref.c b/clang/test/CodeGen/fold-const-declref.c new file mode 100644 index 0000000..5a7ba8e --- /dev/null +++ b/clang/test/CodeGen/fold-const-declref.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -verify -emit-llvm-only + +// PR7242: Check that this doesn't crash. +int main(void) +{ + int __negative = 1; + const int __max = __negative && 0 ; + __max / 0; +} diff --git a/clang/test/CodeGen/fp16-ops.c b/clang/test/CodeGen/fp16-ops.c new file mode 100644 index 0000000..cbbfb88 --- /dev/null +++ b/clang/test/CodeGen/fp16-ops.c @@ -0,0 +1,283 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s +typedef unsigned cond_t; + +volatile cond_t test; +volatile __fp16 h0 = 0.0, h1 = 1.0, h2; +volatile float f0, f1, f2; + +void foo(void) { + // CHECK: define void @foo() + + // Check unary ops + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK fptoi float + test = (h0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp une float + test = (!h1); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fsub float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = -h1; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = +h1; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd float + // CHECK: call i16 @llvm.convert.to.fp16 + h1++; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd float + // CHECK: call i16 @llvm.convert.to.fp16 + ++h1; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd float + // CHECK: call i16 @llvm.convert.to.fp16 + --h1; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd float + // CHECK: call i16 @llvm.convert.to.fp16 + h1--; + + // Check binary ops with various operands + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fmul float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = h0 * h2; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call i16 @llvm.convert.to.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fmul float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = h0 * (__fp16) -2.0; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fmul float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = h0 * f2; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fmul float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = f0 * h2; + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fdiv float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (h0 / h2); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fdiv float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (h0 / (__fp16) -2.0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fdiv float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (h0 / f2); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fdiv float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (f0 / h2); + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (h2 + h0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = ((__fp16)-2.0 + h0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (h2 + f0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (f2 + h0); + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fsub float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (h2 - h0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fsub float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = ((__fp16)-2.0 - h0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fsub float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (h2 - f0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fsub float + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (f2 - h0); + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp olt + test = (h2 < h0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp olt + test = (h2 < (__fp16)42.0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp olt + test = (h2 < f0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp olt + test = (f2 < h0); + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp ogt + test = (h0 > h2); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp ogt + test = ((__fp16)42.0 > h2); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp ogt + test = (h0 > f2); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp ogt + test = (f0 > h2); + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp ole + test = (h2 <= h0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp ole + test = (h2 <= (__fp16)42.0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp ole + test = (h2 <= f0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp ole + test = (f2 <= h0); + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp oge + test = (h0 >= h2); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp oge + test = (h0 >= (__fp16)-2.0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp oge + test = (h0 >= f2); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp oge + test = (f0 >= h2); + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp oeq + test = (h1 == h2); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp oeq + test = (h1 == (__fp16)1.0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp oeq + test = (h1 == f1); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp oeq + test = (f1 == h1); + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp une + test = (h1 != h2); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp une + test = (h1 != (__fp16)1.0); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp une + test = (h1 != f1); + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp une + test = (f1 != h1); + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fcmp une + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call i16 @llvm.convert.to.fp16 + h1 = (h1 ? h2 : h0); + // Check assignments (inc. compound) + h0 = h1; + // CHECK: call i16 @llvm.convert.to.fp16 + h0 = (__fp16)-2.0; + // CHECK: call i16 @llvm.convert.to.fp16 + h0 = f0; + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd float + // CHECK: call i16 @llvm.convert.to.fp16 + h0 += h1; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd + // CHECK: call i16 @llvm.convert.to.fp16 + h0 += (__fp16)1.0; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fadd + // CHECK: call i16 @llvm.convert.to.fp16 + h0 += f2; + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fsub + // CHECK: call i16 @llvm.convert.to.fp16 + h0 -= h1; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fsub + // CHECK: call i16 @llvm.convert.to.fp16 + h0 -= (__fp16)1.0; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fsub + // CHECK: call i16 @llvm.convert.to.fp16 + h0 -= f2; + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fmul + // CHECK: call i16 @llvm.convert.to.fp16 + h0 *= h1; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fmul + // CHECK: call i16 @llvm.convert.to.fp16 + h0 *= (__fp16)1.0; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fmul + // CHECK: call i16 @llvm.convert.to.fp16 + h0 *= f2; + + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fdiv + // CHECK: call i16 @llvm.convert.to.fp16 + h0 /= h1; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fdiv + // CHECK: call i16 @llvm.convert.to.fp16 + h0 /= (__fp16)1.0; + // CHECK: call float @llvm.convert.from.fp16 + // CHECK: fdiv + // CHECK: call i16 @llvm.convert.to.fp16 + h0 /= f2; +} diff --git a/clang/test/CodeGen/frame-pointer-elim.c b/clang/test/CodeGen/frame-pointer-elim.c new file mode 100644 index 0000000..b105a19 --- /dev/null +++ b/clang/test/CodeGen/frame-pointer-elim.c @@ -0,0 +1,40 @@ +// REQUIRES: x86-registered-target + +// RUN: %clang -target i386-apple-darwin -S -o - %s | \ +// RUN: FileCheck --check-prefix=DARWIN %s +// DARWIN: f0: +// DARWIN: pushl %ebp +// DARWIN: ret +// DARWIN: f1: +// DARWIN: pushl %ebp +// DARWIN: ret + +// RUN: %clang -target i386-pc-linux-gnu -S -o - %s | \ +// RUN: FileCheck --check-prefix=LINUX %s +// LINUX: f0: +// LINUX-NOT: pushl %ebp +// LINUX: ret +// LINUX: f1: +// LINUX: pushl %ebp +// LINUX: ret + +// RUN: %clang -target i386-darwin -S -o - -fomit-frame-pointer %s | \ +// RUN: FileCheck --check-prefix=OMIT_ALL %s +// OMIT_ALL: f0: +// OMIT_ALL-NOT: pushl %ebp +// OMIT_ALL: ret +// OMIT_ALL: f1: +// OMIT_ALL-NOT: pushl %ebp +// OMIT_ALL: ret + +// RUN: %clang -target i386-darwin -S -o - -momit-leaf-frame-pointer %s | \ +// RUN: FileCheck --check-prefix=OMIT_LEAF %s +// OMIT_LEAF: f0: +// OMIT_LEAF-NOT: pushl %ebp +// OMIT_LEAF: ret +// OMIT_LEAF: f1: +// OMIT_LEAF: pushl %ebp +// OMIT_LEAF: ret + +void f0() {} +void f1() { f0(); } diff --git a/clang/test/CodeGen/func-aligned.c b/clang/test/CodeGen/func-aligned.c new file mode 100644 index 0000000..f8a4a29 --- /dev/null +++ b/clang/test/CodeGen/func-aligned.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// rdar://7270273 +void foo() __attribute__((aligned (64))); +void foo() { +// CHECK: define void @foo() {{.*}} align 64 +} diff --git a/clang/test/CodeGen/func-decl-cleanup.c b/clang/test/CodeGen/func-decl-cleanup.c new file mode 100644 index 0000000..0af8b69 --- /dev/null +++ b/clang/test/CodeGen/func-decl-cleanup.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + + +// PR2360 +typedef void fn_t(); + +fn_t a,b; + +void b() +{ +} + diff --git a/clang/test/CodeGen/func-in-block.c b/clang/test/CodeGen/func-in-block.c new file mode 100644 index 0000000..1900135 --- /dev/null +++ b/clang/test/CodeGen/func-in-block.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -emit-llvm -o - %s | FileCheck %s +// rdar: // 7860965 + +extern void PRINTF(const char *); +extern void B(void (^)(void)); + +int main() +{ + PRINTF(__func__); + B( + ^{ + PRINTF(__func__); + } + ); + return 0; // not reached +} + +// CHECK: @__func__.__main_block_invoke_0 = private unnamed_addr constant [22 x i8] c"__main_block_invoke_0\00" +// CHECK: call void @PRINTF({{.*}}@__func__.__main_block_invoke_ diff --git a/clang/test/CodeGen/func-ptr-cast-decl.c b/clang/test/CodeGen/func-ptr-cast-decl.c new file mode 100644 index 0000000..e630796 --- /dev/null +++ b/clang/test/CodeGen/func-ptr-cast-decl.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm-only %s -verify +// PR5882 + +int q_sk_num(void *a); +typedef int (*fptr)(double); +void a() { ((fptr)q_sk_num)(0); } diff --git a/clang/test/CodeGen/func-return-member.c b/clang/test/CodeGen/func-return-member.c new file mode 100644 index 0000000..8c55a96 --- /dev/null +++ b/clang/test/CodeGen/func-return-member.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +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; + +// CHECK: define void @bar +void bar(void) { + X = foo().f.f.x; +} + +// CHECK: define void @bun +void bun(void) { + F = foo().f.f; +} + +// CHECK: define void @ban +void ban(void) { + C = foo().f.f.c; +} diff --git a/clang/test/CodeGen/funccall.c b/clang/test/CodeGen/funccall.c new file mode 100644 index 0000000..9735e34 --- /dev/null +++ b/clang/test/CodeGen/funccall.c @@ -0,0 +1,17 @@ + +static int q; + +void foo() { + int t = q; + q = t + 1; +} +int main() { + q = 0; + foo(); + q = q - 1; + + return q; +} + +// This is the source that corresponds to funccall.ll +// RUN: echo foo diff --git a/clang/test/CodeGen/function-attributes.c b/clang/test/CodeGen/function-attributes.c new file mode 100644 index 0000000..6cbf40b --- /dev/null +++ b/clang/test/CodeGen/function-attributes.c @@ -0,0 +1,113 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -Os -o - %s | FileCheck %s +// CHECK: define signext i8 @f0(i32 %x) nounwind +// CHECK: define zeroext i8 @f1(i32 %x) nounwind +// CHECK: define void @f2(i8 signext %x) nounwind +// CHECK: define void @f3(i8 zeroext %x) nounwind +// CHECK: define signext i16 @f4(i32 %x) nounwind +// CHECK: define zeroext i16 @f5(i32 %x) nounwind +// CHECK: define void @f6(i16 signext %x) nounwind +// CHECK: define void @f7(i16 zeroext %x) nounwind + +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) { } + +// CHECK: define void @f8() +// CHECK: nounwind +// CHECK: alwaysinline +// CHECK: { +void __attribute__((always_inline)) f8(void) { } + +// CHECK: call void @f9_t() +// CHECK: noreturn +// CHECK: { +void __attribute__((noreturn)) f9_t(void); +void f9(void) { f9_t(); } + +// FIXME: We should be setting nounwind on calls. +// CHECK: call i32 @f10_t() +// CHECK: readnone +// CHECK: { +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(); +} + +// CHECK: define void @f13() nounwind readnone +void f13(void) __attribute__((pure)) __attribute__((const)); +void f13(void){} + + +// Ensure that these get inlined: rdar://6853279 +// CHECK: define void @f14 +// CHECK-NOT: @ai_ +// CHECK: call void @f14_end +static __inline__ __attribute__((always_inline)) +int ai_1() { return 4; } + +static __inline__ __attribute__((always_inline)) +struct { + int a, b, c, d, e; +} ai_2() { while (1) {} } + +void f14(int a) { + extern void f14_end(void); + if (a) + ai_2(); + ai_1(); + f14_end(); +} + +// <rdar://problem/7102668> [irgen] clang isn't setting the optsize bit on functions +// CHECK: define void @f15 +// CHECK: optsize +// CHECK: { +void f15(void) { +} + +// PR5254 +// CHECK: define void @f16 +// CHECK: alignstack(16) +// CHECK: { +void __attribute__((force_align_arg_pointer)) f16(void) { +} + +// PR11038 +// CHECK: define void @f18() +// CHECK: returns_twice +// CHECK: { +// CHECK: call void @f17() +// CHECK: returns_twice +// CHECK: ret void +__attribute__ ((returns_twice)) void f17(void); +__attribute__ ((returns_twice)) void f18(void) { + f17(); +} + +// CHECK: define void @f19() +// CHECK: { +// CHECK: call i32 @setjmp(i32* null) +// CHECK: returns_twice +// CHECK: ret void +typedef int jmp_buf[((9 * 2) + 3 + 16)]; +int setjmp(jmp_buf); +void f19(void) { + setjmp(0); +} diff --git a/clang/test/CodeGen/functions.c b/clang/test/CodeGen/functions.c new file mode 100644 index 0000000..28e4bd0 --- /dev/null +++ b/clang/test/CodeGen/functions.c @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - -verify | FileCheck %s + +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;} + +void f0() {} +// CHECK: define void @f0() + +void f1(); +void f2(void) { +// CHECK: call void bitcast (void ()* @f1 to void (i32, i32, i32)*)(i32 1, i32 2, i32 3) + f1(1, 2, 3); +} +// CHECK: define void @f1() +void f1() {} + +// CHECK: define {{.*}} @f3{{\(\)|\(.*sret.*\)}} +struct foo { int X, Y, Z; } f3() { + while (1) {} +} + +// PR4423 - This shouldn't crash in codegen +void f4() {} +void f5() { f4(42); } //expected-warning {{too many arguments}} + +// Qualifiers on parameter types shouldn't make a difference. +static void f6(const float f, const float g) { +} +void f7(float f, float g) { + f6(f, g); +// CHECK: define void @f7(float{{.*}}, float{{.*}}) +// CHECK: call void @f6(float{{.*}}, float{{.*}}) +} + +// PR6911 - incomplete function types +struct Incomplete; +void f8_callback(struct Incomplete); +void f8_user(void (*callback)(struct Incomplete)); +void f8_test() { + f8_user(&f8_callback); +// CHECK: define void @f8_test() +// CHECK: call void @f8_user({{.*}}* bitcast (void ()* @f8_callback to {{.*}}*)) +// CHECK: declare void @f8_user({{.*}}*) +// CHECK: declare void @f8_callback() +} + +// PR10204: don't crash +static void test9_helper(void) {} +void test9() { + (void) test9_helper; +} diff --git a/clang/test/CodeGen/global-decls.c b/clang/test/CodeGen/global-decls.c new file mode 100644 index 0000000..89e899f --- /dev/null +++ b/clang/test/CodeGen/global-decls.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -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) { return 0; } + +// Force _ext references +void f0() { + int a = g0_ext; + int b = g1_ext(); +} + diff --git a/clang/test/CodeGen/global-init.c b/clang/test/CodeGen/global-init.c new file mode 100644 index 0000000..dab5a07 --- /dev/null +++ b/clang/test/CodeGen/global-init.c @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple i386-linux-gnu %s | FileCheck %s + +// This checks that the global won't be marked as common. +// (It shouldn't because it's being initialized). + +int a; +int a = 242; +// CHECK: @a = global i32 242 + +// This should get normal weak linkage. +int c __attribute__((weak))= 0; +// CHECK: @c = weak global i32 0 + + +// Since this is marked const, it should get weak_odr linkage, since all +// definitions have to be the same. +// CHECK: @d = weak_odr constant i32 0 +const int d __attribute__((weak))= 0; + +// PR6168 "too many undefs" +struct ManyFields { + int a; + int b; + int c; + char d; + int e; + int f; +}; + +// CHECK: global %struct.ManyFields { i32 1, i32 2, i32 0, i8 0, i32 0, i32 0 } +struct ManyFields FewInits = {1, 2}; + + +// PR6766 +// CHECK: @l = global %struct.K { [6 x i32] [i32 102, i32 111, i32 111, i32 0, i32 0, i32 0], i32 1 } +typedef __WCHAR_TYPE__ wchar_t; +struct K { + wchar_t L[6]; + int M; +} l = { { L"foo" }, 1 }; + + +// CHECK: @yuv_types = global [4 x [6 x i8]] {{\[}}[6 x i8] c"4:0:0\00", [6 x i8] c"4:2:0\00", [6 x i8] c"4:2:2\00", [6 x i8] c"4:4:4\00"] +char yuv_types[4][6]= {"4:0:0","4:2:0","4:2:2","4:4:4"}; + + +// NOTE: tentative definitions are processed at the end of the translation unit. + +// This shouldn't be emitted as common because it has an explicit section. +// rdar://7119244 +// CHECK: @b = global i32 0, section "foo" +int b __attribute__((section("foo"))); diff --git a/clang/test/CodeGen/global-with-initialiser.c b/clang/test/CodeGen/global-with-initialiser.c new file mode 100644 index 0000000..27d209e --- /dev/null +++ b/clang/test/CodeGen/global-with-initialiser.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/globalinit.c b/clang/test/CodeGen/globalinit.c new file mode 100644 index 0000000..e07a419 --- /dev/null +++ b/clang/test/CodeGen/globalinit.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/hidden-visibility.c b/clang/test/CodeGen/hidden-visibility.c new file mode 100644 index 0000000..65e6616 --- /dev/null +++ b/clang/test/CodeGen/hidden-visibility.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: hidden global +int X __attribute__ ((__visibility__ ("hidden"))) = 123; diff --git a/clang/test/CodeGen/imaginary.c b/clang/test/CodeGen/imaginary.c new file mode 100644 index 0000000..2649ceb --- /dev/null +++ b/clang/test/CodeGen/imaginary.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -verify -emit-llvm-only %s + +// Just verify that we don't crash until we support _Imaginary. +double _Imaginary foo; // expected-error {{imaginary types are not supported}} diff --git a/clang/test/CodeGen/implicit-arg.c b/clang/test/CodeGen/implicit-arg.c new file mode 100644 index 0000000..52ab58e --- /dev/null +++ b/clang/test/CodeGen/implicit-arg.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -emit-llvm -O0 -o - +// RUN: %clang_cc1 %s -emit-llvm -O1 -o - +// rdar://6518089 + +static int bar(); +void foo() { + int a = bar(); +} +int bar(unsigned a) { +} diff --git a/clang/test/CodeGen/incomplete-function-type.c b/clang/test/CodeGen/incomplete-function-type.c new file mode 100644 index 0000000..0ba6633 --- /dev/null +++ b/clang/test/CodeGen/incomplete-function-type.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// CHECK: ModuleID +// CHECK-NOT: opaque +// CHECK: define void @f0 + +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; }; + +void f0() {} diff --git a/clang/test/CodeGen/indirect-goto.c b/clang/test/CodeGen/indirect-goto.c new file mode 100644 index 0000000..7a3d717 --- /dev/null +++ b/clang/test/CodeGen/indirect-goto.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm -o - %s | grep "ret i32 2520" + +static int foo(unsigned i) { + 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; +} + +static int foo2(unsigned i) { + static 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 main() { + return foo(3)+foo2(4); +} diff --git a/clang/test/CodeGen/init-with-member-expr.c b/clang/test/CodeGen/init-with-member-expr.c new file mode 100644 index 0000000..fdc8c14 --- /dev/null +++ b/clang/test/CodeGen/init-with-member-expr.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 < %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/clang/test/CodeGen/init.c b/clang/test/CodeGen/init.c new file mode 100644 index 0000000..426233d --- /dev/null +++ b/clang/test/CodeGen/init.c @@ -0,0 +1,132 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +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 +// CHECK: @g3 = constant i32 10 +// CHECK: @f4.g4 = internal constant i32 12 +const int g3 = 10; +int f4() { + static const int g4 = 12; + return g4; +} + +// PR6537 +typedef union vec3 { + struct { double x, y, z; }; + double component[3]; +} vec3; +vec3 f5(vec3 value) { + return (vec3) {{ + .x = value.x + }}; +} + +// rdar://problem/8154689 +void f6() { + int x; + long ids[] = { (long) &x }; +} + + + + +// CHECK: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" } +// PR8217 +struct a7 { + int b; + char v[]; +}; + +struct a7 test7 = { .b = 0, .v = "bar" }; + + +// PR279 comment #3 +char test8(int X) { + char str[100000] = "abc"; // tail should be memset. + return str[X]; +// CHECK: @test8( +// CHECK: call void @llvm.memset +// CHECK: store i8 97 +// CHECK: store i8 98 +// CHECK: store i8 99 +} + +void bar(void*); + +// PR279 +int test9(int X) { + int Arr[100] = { X }; // Should use memset + bar(Arr); +// CHECK: @test9 +// CHECK: call void @llvm.memset +// CHECK-NOT: store i32 0 +// CHECK: call void @bar +} + +struct a { + int a, b, c, d, e, f, g, h, i, j, k, *p; +}; + +struct b { + struct a a,b,c,d,e,f,g; +}; + +int test10(int X) { + struct b S = { .a.a = X, .d.e = X, .f.e = 0, .f.f = 0, .f.p = 0 }; + bar(&S); + + // CHECK: @test10 + // CHECK: call void @llvm.memset + // CHECK-NOT: store i32 0 + // CHECK: call void @bar +} + + +// PR9257 +struct test11S { + int A[10]; +}; +void test11(struct test11S *P) { + *P = (struct test11S) { .A = { [0 ... 3] = 4 } }; + // CHECK: @test11 + // CHECK: store i32 4 + // CHECK: store i32 4 + // CHECK: store i32 4 + // CHECK: store i32 4 + // CHECK: ret void +} + + +// Verify that we can convert a recursive struct with a memory that returns +// an instance of the struct we're converting. +struct test12 { + struct test12 (*p)(void); +} test12g; + + +void test13(int x) { + struct X { int a; int b : 10; int c; }; + struct X y = {.c = x}; + // CHECK: @test13 + // CHECK: and i32 {{.*}}, -1024 +} diff --git a/clang/test/CodeGen/inline-asm-mrv.c b/clang/test/CodeGen/inline-asm-mrv.c new file mode 100644 index 0000000..929dd90 --- /dev/null +++ b/clang/test/CodeGen/inline-asm-mrv.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -O | not grep alloca +// PR2094 + +int sad16_sse2(void *v, unsigned char *blk2, unsigned char *blk1, + int stride, int h) { + int ret; + asm volatile( "%0 %1 %2 %3" + : "+r" (h), "+r" (blk1), "+r" (blk2) + : "r" ((long)stride)); + asm volatile("set %0 %1" : "=r"(ret) : "r"(blk1)); + return ret; +} diff --git a/clang/test/CodeGen/inline.c b/clang/test/CodeGen/inline.c new file mode 100644 index 0000000..2a01f25 --- /dev/null +++ b/clang/test/CodeGen/inline.c @@ -0,0 +1,129 @@ +// RUN: echo "GNU89 tests:" +// RUN: %clang %s -O1 -emit-llvm -S -o %t -std=gnu89 +// 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: grep "define i32 @test6" %t +// RUN: grep "define void @test7" %t +// RUN: grep "define i.. @strlcpy" %t +// RUN: not grep test9 %t +// RUN: grep "define void @testA" %t +// RUN: grep "define void @testB" %t +// RUN: grep "define void @testC" %t + +// RUN: echo "C99 tests:" +// RUN: %clang %s -O1 -emit-llvm -S -o %t -std=gnu99 +// 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 void @test3" %t +// RUN: grep "define available_externally i32 @test4" %t +// RUN: grep "define available_externally i32 @test5" %t +// RUN: grep "define i32 @test6" %t +// RUN: grep "define void @test7" %t +// RUN: grep "define available_externally i.. @strlcpy" %t +// RUN: grep "define void @test9" %t +// RUN: grep "define void @testA" %t +// RUN: grep "define void @testB" %t +// RUN: grep "define void @testC" %t + +// RUN: echo "C++ tests:" +// RUN: %clang -x c++ %s -O1 -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 __attribute__((gnu_inline)) test3() {} + +extern int test4(void); +extern __inline __attribute__ ((__gnu_inline__)) int test4(void) +{ + return 0; +} + +void test_test4() { test4(); } + +extern __inline int test5(void) __attribute__ ((__gnu_inline__)); +extern __inline int __attribute__ ((__gnu_inline__)) test5(void) +{ + return 0; +} + +void test_test5() { test5(); } + +// PR10233 + +__inline int test6() { return 0; } +extern int test6(); + + +// No PR#, but this once crashed clang in C99 mode due to buggy extern inline +// redeclaration detection. +void test7() { } +void test7(); + +// PR11062; the fact that the function is named strlcpy matters here. +inline __typeof(sizeof(int)) strlcpy(char *dest, const char *src, __typeof(sizeof(int)) size) { return 3; } +void test8() { strlcpy(0,0,0); } + +// PR10657; the test crashed in C99 mode +extern inline void test9() { } +void test9(); + +inline void testA() {} +void testA(); + +void testB(); +inline void testB() {} +extern void testB(); + +extern inline void testC() {} +inline void testC(); diff --git a/clang/test/CodeGen/inline2.c b/clang/test/CodeGen/inline2.c new file mode 100644 index 0000000..fca4fff --- /dev/null +++ b/clang/test/CodeGen/inline2.c @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -O1 -std=gnu89 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix GNU89 %s +// RUN: %clang_cc1 -O1 -std=c99 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix C99 %s + +// CHECK-GNU89: define i32 @f0() +// CHECK-C99: define i32 @f0() +int f0(void); +int f0(void) { return 0; } + +// CHECK-GNU89: define i32 @f1() +// CHECK-C99: define i32 @f1() +inline int f1(void); +int f1(void) { return 0; } + +// CHECK-GNU89: define i32 @f2() +// CHECK-C99: define i32 @f2() +int f2(void); +inline int f2(void) { return 0; } + +// CHECK-GNU89: define i32 @f3() +// CHECK-C99: define i32 @f3() +extern inline int f3(void); +int f3(void) { return 0; } + +// CHECK-GNU89: define i32 @f5() +// CHECK-C99: define i32 @f5() +extern inline int f5(void); +inline int f5(void) { return 0; } + +// CHECK-GNU89: define i32 @f6() +// CHECK-C99: define i32 @f6() +inline int f6(void); +extern inline int f6(void) { return 0; } + +// CHECK-GNU89: define i32 @f7() +// CHECK-C99: define i32 @f7() +extern inline int f7(void); +extern int f7(void) { return 0; } + +// CHECK-GNU89: define i32 @fA() +inline int fA(void) { return 0; } + +// CHECK-GNU89: define available_externally i32 @f4() +// CHECK-C99: define i32 @f4() +int f4(void); +extern inline int f4(void) { return 0; } + +// CHECK-GNU89: define available_externally i32 @f8() +// CHECK-C99: define i32 @f8() +extern int f8(void); +extern inline int f8(void) { return 0; } + +// CHECK-GNU89: define available_externally i32 @f9() +// CHECK-C99: define i32 @f9() +extern inline int f9(void); +extern inline int f9(void) { return 0; } + +// CHECK-C99: define available_externally i32 @fA() + +int test_all() { + return f0() + f1() + f2() + f3() + f4() + f5() + f6() + f7() + f8() + f9() + + fA(); +} diff --git a/clang/test/CodeGen/instrument-functions.c b/clang/test/CodeGen/instrument-functions.c new file mode 100644 index 0000000..d80385e --- /dev/null +++ b/clang/test/CodeGen/instrument-functions.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions | FileCheck %s + +// CHECK: @test1 +int test1(int x) { +// CHECK: __cyg_profile_func_enter +// CHECK: __cyg_profile_func_exit +// CHECK: ret + return x; +} + +// CHECK: @test2 +int test2(int) __attribute__((no_instrument_function)); +int test2(int x) { +// CHECK-NOT: __cyg_profile_func_enter +// CHECK-NOT: __cyg_profile_func_exit +// CHECK: ret + return x; +} diff --git a/clang/test/CodeGen/int-to-pointer.c b/clang/test/CodeGen/int-to-pointer.c new file mode 100644 index 0000000..242a8a6 --- /dev/null +++ b/clang/test/CodeGen/int-to-pointer.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t + +void *test(int i) +{ + return (void *)i; +} diff --git a/clang/test/CodeGen/integer-overflow.c b/clang/test/CodeGen/integer-overflow.c new file mode 100644 index 0000000..1d46065 --- /dev/null +++ b/clang/test/CodeGen/integer-overflow.c @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang_cc1 %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV +// RUN: %clang_cc1 %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV +// RUN: %clang_cc1 %s -emit-llvm -o - -ftrapv -ftrapv-handler foo | FileCheck %s --check-prefix=TRAPV_HANDLER + + +// Tests for signed integer overflow stuff. +// rdar://7432000 rdar://7221421 +void test1() { + // DEFAULT: define void @test1 + // WRAPV: define void @test1 + // TRAPV: define void @test1 + extern volatile int f11G, a, b; + + // DEFAULT: add nsw i32 + // WRAPV: add i32 + // TRAPV: llvm.sadd.with.overflow.i32 + // TRAPV_HANDLER: foo( + f11G = a + b; + + // DEFAULT: sub nsw i32 + // WRAPV: sub i32 + // TRAPV: llvm.ssub.with.overflow.i32 + // TRAPV_HANDLER: foo( + f11G = a - b; + + // DEFAULT: mul nsw i32 + // WRAPV: mul i32 + // TRAPV: llvm.smul.with.overflow.i32 + // TRAPV_HANDLER: foo( + f11G = a * b; + + // DEFAULT: sub nsw i32 0, + // WRAPV: sub i32 0, + // TRAPV: llvm.ssub.with.overflow.i32(i32 0 + // TRAPV_HANDLER: foo( + f11G = -a; + + // PR7426 - Overflow checking for increments. + + // DEFAULT: add nsw i32 {{.*}}, 1 + // WRAPV: add i32 {{.*}}, 1 + // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 1) + // TRAPV_HANDLER: foo( + ++a; + + // DEFAULT: add nsw i32 {{.*}}, -1 + // WRAPV: add i32 {{.*}}, -1 + // TRAPV: llvm.sadd.with.overflow.i32({{.*}}, i32 -1) + // TRAPV_HANDLER: foo( + --a; + + // -fwrapv should turn off inbounds for GEP's, PR9256 + extern int* P; + ++P; + // DEFAULT: getelementptr inbounds i32* + // WRAPV: getelementptr i32* + // TRAPV: getelementptr inbounds i32* + + // PR9350: char increment never overflows. + extern volatile signed char PR9350; + // DEFAULT: add i8 {{.*}}, 1 + // WRAPV: add i8 {{.*}}, 1 + // TRAPV: add i8 {{.*}}, 1 + ++PR9350; +} diff --git a/clang/test/CodeGen/kr-func-promote.c b/clang/test/CodeGen/kr-func-promote.c new file mode 100644 index 0000000..fcdbac3 --- /dev/null +++ b/clang/test/CodeGen/kr-func-promote.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | grep "i32 @a(i32)" + +int a(); +int a(x) short x; {return x;} + diff --git a/clang/test/CodeGen/kr-style-block.c b/clang/test/CodeGen/kr-style-block.c new file mode 100644 index 0000000..09efb37 --- /dev/null +++ b/clang/test/CodeGen/kr-style-block.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t -fblocks + +void foo (void(^)()); + +int main() +{ +foo( + ^() { } +); +} diff --git a/clang/test/CodeGen/libcalls-d.c b/clang/test/CodeGen/libcalls-d.c new file mode 100644 index 0000000..b375f2b --- /dev/null +++ b/clang/test/CodeGen/libcalls-d.c @@ -0,0 +1,16 @@ +// llvm-gcc -O1+ should run simplify libcalls, O0 shouldn't +// and -fno-builtins shouldn't. +// -fno-math-errno should emit an llvm intrinsic, -fmath-errno should not. +// RUN: %clang_cc1 %s -emit-llvm -fno-math-errno -O0 -o - | grep {call.*exp2\\.f64} +// RUN: %clang_cc1 %s -emit-llvm -fmath-errno -O0 -o - | grep {call.*exp2} +// RUN: %clang_cc1 %s -emit-llvm -O1 -o - | grep {call.*ldexp} +// RUN: %clang_cc1 %s -emit-llvm -O3 -fno-builtin -o - | grep {call.*exp2} + +// clang doesn't support this yet. +// XFAIL: * + +double exp2(double); + +double t4(unsigned char x) { + return exp2(x); +} diff --git a/clang/test/CodeGen/libcalls-fno-builtin.c b/clang/test/CodeGen/libcalls-fno-builtin.c new file mode 100644 index 0000000..ce10759 --- /dev/null +++ b/clang/test/CodeGen/libcalls-fno-builtin.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -S -O3 -fno-builtin -o - %s | FileCheck %s +// rdar://10551066 + +double ceil(double x); +double copysign(double,double); +double cos(double x); +double fabs(double x); +double floor(double x); + +double t1(double x) { return ceil(x); } +// CHECK: t1 +// CHECK: ceil + +double t2(double x, double y) { return copysign(x,y); } +// CHECK: t2 +// CHECK: copysign + +double t3(double x) { return cos(x); } +// CHECK: t3 +// CHECK: cos + +double t4(double x) { return fabs(x); } +// CHECK: t4 +// CHECK: fabs + +double t5(double x) { return floor(x); } +// CHECK: t5 +// CHECK: floor diff --git a/clang/test/CodeGen/libcalls-ld.c b/clang/test/CodeGen/libcalls-ld.c new file mode 100644 index 0000000..2758761 --- /dev/null +++ b/clang/test/CodeGen/libcalls-ld.c @@ -0,0 +1,19 @@ +// llvm-gcc -O1+ should run simplify libcalls, O0 shouldn't +// and -fno-builtins shouldn't. +// -fno-math-errno should emit an llvm intrinsic, -fmath-errno should not. +// RUN: %clang_cc1 %s -emit-llvm -fno-math-errno -O0 -o - | grep {call.*exp2\\..*f} +// RUN: %clang_cc1 %s -emit-llvm -fmath-errno -O0 -o - | grep {call.*exp2l} +// RUN: %clang_cc1 %s -emit-llvm -O1 -o - | grep {call.*ldexp} +// RUN: %clang_cc1 %s -emit-llvm -O3 -fno-builtin -o - | grep {call.*exp2l} + +// clang doesn't support this yet. +// XFAIL: * + +// If this fails for you because your target doesn't support long double, +// please xfail the test. + +long double exp2l(long double); + +long double t4(unsigned char x) { + return exp2l(x); +} diff --git a/clang/test/CodeGen/libcalls.c b/clang/test/CodeGen/libcalls.c new file mode 100644 index 0000000..458c591 --- /dev/null +++ b/clang/test/CodeGen/libcalls.c @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -fmath-errno -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix YES %s +// RUN: %clang_cc1 -emit-llvm -o - %s -triple i386-unknown-unknown | FileCheck -check-prefix NO %s + +// CHECK-YES: define void @test_sqrt +// CHECK-NO: define void @test_sqrt +void test_sqrt(float a0, double a1, long double a2) { + // Following llvm-gcc's lead, we never emit these as intrinsics; + // no-math-errno isn't good enough. We could probably use intrinsics + // with appropriate guards if it proves worthwhile. + + // CHECK-YES: call float @sqrtf + // CHECK-NO: call float @sqrtf + float l0 = sqrtf(a0); + + // CHECK-YES: call double @sqrt + // CHECK-NO: call double @sqrt + double l1 = sqrt(a1); + + // CHECK-YES: call x86_fp80 @sqrtl + // CHECK-NO: call x86_fp80 @sqrtl + long double l2 = sqrtl(a2); +} + +// CHECK-YES: declare float @sqrtf(float) +// CHECK-YES: declare double @sqrt(double) +// CHECK-YES: declare x86_fp80 @sqrtl(x86_fp80) +// CHECK-NO: declare float @sqrtf(float) nounwind readnone +// CHECK-NO: declare double @sqrt(double) nounwind readnone +// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) nounwind readnone + +// CHECK-YES: define void @test_pow +// CHECK-NO: define void @test_pow +void test_pow(float a0, double a1, long double a2) { + // CHECK-YES: call float @powf + // CHECK-NO: call float @llvm.pow.f32 + float l0 = powf(a0, a0); + + // CHECK-YES: call double @pow + // CHECK-NO: call double @llvm.pow.f64 + double l1 = pow(a1, a1); + + // CHECK-YES: call x86_fp80 @powl + // CHECK-NO: call x86_fp80 @llvm.pow.f80 + long double l2 = powl(a2, a2); +} + +// CHECK-YES: declare float @powf(float, float) +// CHECK-YES: declare double @pow(double, double) +// CHECK-YES: declare x86_fp80 @powl(x86_fp80, x86_fp80) +// CHECK-NO: declare float @llvm.pow.f32(float, float) nounwind readonly +// CHECK-NO: declare double @llvm.pow.f64(double, double) nounwind readonly +// CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) nounwind readonly + +// CHECK-YES: define void @test_fma +// CHECK-NO: define void @test_fma +void test_fma(float a0, double a1, long double a2) { + // CHECK-YES: call float @llvm.fma.f32 + // CHECK-NO: call float @llvm.fma.f32 + float l0 = fmaf(a0, a0, a0); + + // CHECK-YES: call double @llvm.fma.f64 + // CHECK-NO: call double @llvm.fma.f64 + double l1 = fma(a1, a1, a1); + + // CHECK-YES: call x86_fp80 @llvm.fma.f80 + // CHECK-NO: call x86_fp80 @llvm.fma.f80 + long double l2 = fmal(a2, a2, a2); +} + +// CHECK-YES: declare float @llvm.fma.f32(float, float, float) nounwind readnone +// CHECK-YES: declare double @llvm.fma.f64(double, double, double) nounwind readnone +// CHECK-YES: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone +// CHECK-NO: declare float @llvm.fma.f32(float, float, float) nounwind readnone +// CHECK-NO: declare double @llvm.fma.f64(double, double, double) nounwind readnone +// CHECK-NO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone diff --git a/clang/test/CodeGen/lifetime.c b/clang/test/CodeGen/lifetime.c new file mode 100644 index 0000000..2203840 --- /dev/null +++ b/clang/test/CodeGen/lifetime.c @@ -0,0 +1,23 @@ +// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefix=O0 +// RUN: %clang -S -emit-llvm -o - -O1 %s | FileCheck %s -check-prefix=O1 +// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefix=O2 +// RUN: %clang -S -emit-llvm -o - -O3 %s | FileCheck %s -check-prefix=O3 + +extern void use(char *a); + +__attribute__((always_inline)) void helper_no_markers() { + char a; + use(&a); +} + +void lifetime_test() { +// O0: lifetime_test +// O1: lifetime_test +// O2: lifetime_test +// O3: lifetime_test +// O0-NOT: @llvm.lifetime.start +// O1: @llvm.lifetime.start +// O2: @llvm.lifetime.start +// O3: @llvm.lifetime.start + helper_no_markers(); +} diff --git a/clang/test/CodeGen/lineno-dbginfo.c b/clang/test/CodeGen/lineno-dbginfo.c new file mode 100644 index 0000000..72fa337 --- /dev/null +++ b/clang/test/CodeGen/lineno-dbginfo.c @@ -0,0 +1,5 @@ +// RUN: echo "#include <stddef.h>" > %t.h +// RUN: %clang -S -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/clang/test/CodeGen/link-bitcode-file.c b/clang/test/CodeGen/link-bitcode-file.c new file mode 100644 index 0000000..7740406 --- /dev/null +++ b/clang/test/CodeGen/link-bitcode-file.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -DBITCODE -emit-llvm-bc -o %t.bc %s +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -mlink-bitcode-file %t.bc -O3 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NO-BC %s +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -DBITCODE -mlink-bitcode-file %t.bc -O3 -emit-llvm -o - %s 2>&1 | FileCheck -check-prefix=CHECK-BC %s + +int f(void); + +#ifdef BITCODE + +// CHECK-BC: 'f': symbol multiply defined +int f(void) { + return 42; +} + +#else + +// CHECK-NO-BC: define i32 @g +// CHECK-NO-BC: ret i32 42 +int g(void) { + return f(); +} + +// CHECK-NO-BC: define i32 @f + +#endif diff --git a/clang/test/CodeGen/linkage-redecl.c b/clang/test/CodeGen/linkage-redecl.c new file mode 100644 index 0000000..09b51f0 --- /dev/null +++ b/clang/test/CodeGen/linkage-redecl.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/long-double-x86.c b/clang/test/CodeGen/long-double-x86.c new file mode 100644 index 0000000..f040207 --- /dev/null +++ b/clang/test/CodeGen/long-double-x86.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/lzcnt-builtins.c b/clang/test/CodeGen/lzcnt-builtins.c new file mode 100644 index 0000000..a43c4ee --- /dev/null +++ b/clang/test/CodeGen/lzcnt-builtins.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +lzcnt -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +unsigned short test__lzcnt16(unsigned short __X) +{ + // CHECK: @llvm.ctlz.i16 + return __lzcnt16(__X); +} + +unsigned int test_lzcnt32(unsigned int __X) +{ + // CHECK: @llvm.ctlz.i32 + return __lzcnt32(__X); +} + +unsigned long long test__lzcnt64(unsigned long long __X) +{ + // CHECK: @llvm.ctlz.i64 + return __lzcnt64(__X); +} diff --git a/clang/test/CodeGen/mandel.c b/clang/test/CodeGen/mandel.c new file mode 100644 index 0000000..8ecf8f2 --- /dev/null +++ b/clang/test/CodeGen/mandel.c @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -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 + +int putchar(char c); + +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/clang/test/CodeGen/mangle.c b/clang/test/CodeGen/mangle.c new file mode 100644 index 0000000..46ef512 --- /dev/null +++ b/clang/test/CodeGen/mangle.c @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// CHECK: @foo + +// Make sure we mangle overloadable, even in C system headers. +# 1 "somesystemheader.h" 1 3 4 +// CHECK: @_Z2f0i +void __attribute__((__overloadable__)) f0(int a) {} +// CHECK: @_Z2f0l +void __attribute__((__overloadable__)) f0(long b) {} + +// CHECK: @bar + +// These should get merged. +void foo() __asm__("bar"); +void foo2() __asm__("bar"); + +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; + +// PR4412 +int func(void); +extern int func (void) __asm__ ("FUNC"); + +// CHECK: @FUNC +int func(void) { + return 42; +} + +// CHECK: @_Z4foo9Dv4_f +typedef __attribute__(( vector_size(16) )) float float4; +void __attribute__((__overloadable__)) foo9(float4 f) {} + +// Intrinsic calls. +extern int llvm_cas(volatile int*, int, int) + __asm__("llvm.atomic.cmp.swap.i32.p0i32"); + +int foo10(volatile int* add, int from, int to) { + // CHECK: call i32 @llvm.atomic.cmp.swap.i32.p0i32 + return llvm_cas(add, from, to); +} diff --git a/clang/test/CodeGen/may-alias.c b/clang/test/CodeGen/may-alias.c new file mode 100644 index 0000000..b73ee15 --- /dev/null +++ b/clang/test/CodeGen/may-alias.c @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-optzns -o %t %s +// RUN: FileCheck < %t %s + +// Types with the may_alias attribute should be considered equivalent +// to char for aliasing. + +typedef int __attribute__((may_alias)) aliasing_int; + +void test0(aliasing_int *ai, int *i) +{ +// CHECK: store i32 0, i32* %{{.*}}, !tbaa !1 + *ai = 0; +// CHECK: store i32 1, i32* %{{.*}}, !tbaa !3 + *i = 1; +} + +// PR9307 +struct Test1 { int x; }; +struct Test1MA { int x; } __attribute__((may_alias)); +void test1(struct Test1MA *p1, struct Test1 *p2) { + // CHECK: store i32 2, i32* {{%.*}}, !tbaa !1 + p1->x = 2; + // CHECK: store i32 3, i32* {{%.*}}, !tbaa !3 + p2->x = 3; +} + +// CHECK: !0 = metadata !{metadata !"any pointer", metadata !1} +// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2} +// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"} +// CHECK: !3 = metadata !{metadata !"int", metadata !1} diff --git a/clang/test/CodeGen/mcount.c b/clang/test/CodeGen/mcount.c new file mode 100644 index 0000000..1cf3d6a --- /dev/null +++ b/clang/test/CodeGen/mcount.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -pg -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s +void foo(void) { +// CHECK: call void @mcount() +} diff --git a/clang/test/CodeGen/merge-attrs.c b/clang/test/CodeGen/merge-attrs.c new file mode 100644 index 0000000..474b172 --- /dev/null +++ b/clang/test/CodeGen/merge-attrs.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/merge-statics.c b/clang/test/CodeGen/merge-statics.c new file mode 100644 index 0000000..6716935 --- /dev/null +++ b/clang/test/CodeGen/merge-statics.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 < %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/clang/test/CodeGen/microsoft-call-conv.c b/clang/test/CodeGen/microsoft-call-conv.c new file mode 100644 index 0000000..390c3be --- /dev/null +++ b/clang/test/CodeGen/microsoft-call-conv.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s + +void __fastcall f1(void); +void __stdcall f2(void); +void __thiscall f3(void); +void __fastcall f4(void) { +// CHECK: define x86_fastcallcc void @f4() + f1(); +// CHECK: call x86_fastcallcc void @f1() +} +void __stdcall f5(void) { +// CHECK: define x86_stdcallcc void @f5() + f2(); +// CHECK: call x86_stdcallcc void @f2() +} +void __thiscall f6(void) { +// CHECK: define x86_thiscallcc void @f6() + f3(); +// CHECK: call x86_thiscallcc void @f3() +} + +// PR5280 +void (__fastcall *pf1)(void) = f1; +void (__stdcall *pf2)(void) = f2; +void (__thiscall *pf3)(void) = f3; +void (__fastcall *pf4)(void) = f4; +void (__stdcall *pf5)(void) = f5; +void (__thiscall *pf6)(void) = f6; + +int main(void) { + f4(); f5(); f6(); + // CHECK: call x86_fastcallcc void @f4() + // CHECK: call x86_stdcallcc void @f5() + // CHECK: call x86_thiscallcc void @f6() + pf1(); pf2(); pf3(); pf4(); pf5(); pf6(); + // CHECK: call x86_fastcallcc void %{{.*}}() + // CHECK: call x86_stdcallcc void %{{.*}}() + // CHECK: call x86_thiscallcc void %{{.*}}() + // CHECK: call x86_fastcallcc void %{{.*}}() + // CHECK: call x86_stdcallcc void %{{.*}}() + // CHECK: call x86_thiscallcc void %{{.*}}() + return 0; +} + +// PR7117 +void __stdcall f7(foo) int foo; {} +void f8(void) { + f7(0); + // CHECK: call x86_stdcallcc void @f7(i32 0) +} diff --git a/clang/test/CodeGen/mips-clobber-reg.c b/clang/test/CodeGen/mips-clobber-reg.c new file mode 100644 index 0000000..2a06e53 --- /dev/null +++ b/clang/test/CodeGen/mips-clobber-reg.c @@ -0,0 +1,80 @@ +// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -S -o - -emit-llvm %s + +/* + This checks that the frontend will accept both + enumerated and symbolic Mips GPR register names. + + Any bad names will make the frontend choke. + */ + +main() +{ + + __asm__ __volatile__ (".set noat \n\t addi $7,$at,77":::"at"); + __asm__ __volatile__ ("addi $7,$v0,77":::"v0"); + __asm__ __volatile__ ("addi $7,$v1,77":::"v1"); + __asm__ __volatile__ ("addi $7,$a0,77":::"a0"); + __asm__ __volatile__ ("addi $7,$a1,77":::"a1"); + __asm__ __volatile__ ("addi $7,$a2,77":::"a2"); + __asm__ __volatile__ ("addi $7,$a3,77":::"a3"); + __asm__ __volatile__ ("addi $7,$t0,77":::"t0"); + __asm__ __volatile__ ("addi $7,$t1,77":::"t1"); + __asm__ __volatile__ ("addi $7,$t2,77":::"t2"); + __asm__ __volatile__ ("addi $7,$t3,77":::"t3"); + __asm__ __volatile__ ("addi $7,$t4,77":::"t4"); + __asm__ __volatile__ ("addi $7,$t5,77":::"t5"); + __asm__ __volatile__ ("addi $7,$t6,77":::"t6"); + __asm__ __volatile__ ("addi $7,$t7,77":::"t7"); + __asm__ __volatile__ ("addi $7,$s0,77":::"s0"); + __asm__ __volatile__ ("addi $7,$s1,77":::"s1"); + __asm__ __volatile__ ("addi $7,$s2,77":::"s2"); + __asm__ __volatile__ ("addi $7,$s3,77":::"s3"); + __asm__ __volatile__ ("addi $7,$s4,77":::"s4"); + __asm__ __volatile__ ("addi $7,$s5,77":::"s5"); + __asm__ __volatile__ ("addi $7,$s6,77":::"s6"); + __asm__ __volatile__ ("addi $7,$s7,77":::"s7"); + __asm__ __volatile__ ("addi $7,$t8,77":::"t8"); + __asm__ __volatile__ ("addi $7,$t9,77":::"t9"); + __asm__ __volatile__ ("addi $7,$k0,77":::"k0"); + __asm__ __volatile__ ("addi $7,$k1,77":::"k1"); + __asm__ __volatile__ ("addi $7,$gp,77":::"gp"); + __asm__ __volatile__ ("addi $7,$sp,77":::"sp"); + __asm__ __volatile__ ("addi $7,$fp,77":::"fp"); + __asm__ __volatile__ ("addi $7,$sp,77":::"$sp"); + __asm__ __volatile__ ("addi $7,$fp,77":::"$fp"); + __asm__ __volatile__ ("addi $7,$ra,77":::"ra"); + + __asm__ __volatile__ ("addi $7,$0,77":::"$0"); + __asm__ __volatile__ (".set noat \n\t addi $7,$1,77":::"$1"); + __asm__ __volatile__ ("addi $7,$2,77":::"$2"); + __asm__ __volatile__ ("addi $7,$3,77":::"$3"); + __asm__ __volatile__ ("addi $7,$4,77":::"$4"); + __asm__ __volatile__ ("addi $7,$5,77":::"$5"); + __asm__ __volatile__ ("addi $7,$6,77":::"$6"); + __asm__ __volatile__ ("addi $7,$7,77":::"$7"); + __asm__ __volatile__ ("addi $7,$8,77":::"$8"); + __asm__ __volatile__ ("addi $7,$9,77":::"$9"); + __asm__ __volatile__ ("addi $7,$10,77":::"$10"); + __asm__ __volatile__ ("addi $7,$11,77":::"$10"); + __asm__ __volatile__ ("addi $7,$12,77":::"$12"); + __asm__ __volatile__ ("addi $7,$13,77":::"$13"); + __asm__ __volatile__ ("addi $7,$14,77":::"$14"); + __asm__ __volatile__ ("addi $7,$15,77":::"$15"); + __asm__ __volatile__ ("addi $7,$16,77":::"$16"); + __asm__ __volatile__ ("addi $7,$17,77":::"$17"); + __asm__ __volatile__ ("addi $7,$18,77":::"$18"); + __asm__ __volatile__ ("addi $7,$19,77":::"$19"); + __asm__ __volatile__ ("addi $7,$20,77":::"$20"); + __asm__ __volatile__ ("addi $7,$21,77":::"$21"); + __asm__ __volatile__ ("addi $7,$22,77":::"$22"); + __asm__ __volatile__ ("addi $7,$23,77":::"$23"); + __asm__ __volatile__ ("addi $7,$24,77":::"$24"); + __asm__ __volatile__ ("addi $7,$25,77":::"$25"); + __asm__ __volatile__ ("addi $7,$26,77":::"$26"); + __asm__ __volatile__ ("addi $7,$27,77":::"$27"); + __asm__ __volatile__ ("addi $7,$28,77":::"$28"); + __asm__ __volatile__ ("addi $7,$29,77":::"$29"); + __asm__ __volatile__ ("addi $7,$30,77":::"$30"); + __asm__ __volatile__ ("addi $7,$31,77":::"$31"); + +} diff --git a/clang/test/CodeGen/mips-constraint-regs.c b/clang/test/CodeGen/mips-constraint-regs.c new file mode 100644 index 0000000..075be05 --- /dev/null +++ b/clang/test/CodeGen/mips-constraint-regs.c @@ -0,0 +1,44 @@ +// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -S -o - -emit-llvm %s + +// This checks that the frontend will accept inline asm constraints +// c', 'l' and 'x'. Semantic checking will happen in the +// llvm backend. Any bad constraint letters will cause the frontend to +// error out. + +int main() +{ + // 'c': 16 bit address register for Mips16, GPR for all others + // I am using 'c' to constrain both the target and one of the source + // registers. We are looking for syntactical correctness. + int __s, __v = 17; + int __t; + __asm__ __volatile__( + "addi %0,%1,%2 \n\t\t" + : "=c" (__t) + : "c" (__s), "I" (__v)); + + // 'l': lo register + // We are making it clear that destination register is lo with the + // use of the 'l' constraint ("=l"). + int i_temp = 44; + int i_result; + __asm__ __volatile__( + "mtlo %1 \n\t\t" + : "=l" (i_result) + : "r" (i_temp) + : "lo"); + + // 'x': Combined lo/hi registers + // We are specifying that destination registers are the hi/lo pair with the + // use of the 'x' constraint ("=x"). + int i_hi = 3; + int i_lo = 2; + long long ll_result = 0; + __asm__ __volatile__( + "mthi %1 \n\t\t" + "mtlo %2 \n\t\t" + : "=x" (ll_result) + : "r" (i_hi), "r" (i_lo) + : ); + return 0; +} diff --git a/clang/test/CodeGen/mips64-class-return.cpp b/clang/test/CodeGen/mips64-class-return.cpp new file mode 100644 index 0000000..dc9ec0f --- /dev/null +++ b/clang/test/CodeGen/mips64-class-return.cpp @@ -0,0 +1,46 @@ +// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s + +class B0 { + double d; +}; + +class D0 : public B0 { + float f; +}; + +class B1 { +}; + +class D1 : public B1 { + double d; + float f; +}; + +class D2 : public B0 { + double d2; +}; + +extern D0 gd0; +extern D1 gd1; +extern D2 gd2; + +// CHECK: define { i64, i64 } @_Z4foo1v() +D0 foo1(void) { + return gd0; +} + +// CHECK: define { double, float } @_Z4foo2v() +D1 foo2(void) { + return gd1; +} + +// CHECK: define void @_Z4foo32D2(i64 %a0.coerce0, double %a0.coerce1) +void foo3(D2 a0) { + gd2 = a0; +} + +// CHECK: define void @_Z4foo42D0(%class.D0* nocapture byval %a0) +void foo4(D0 a0) { + gd0 = a0; +} + diff --git a/clang/test/CodeGen/mips64-f128-literal.c b/clang/test/CodeGen/mips64-f128-literal.c new file mode 100644 index 0000000..2f01520 --- /dev/null +++ b/clang/test/CodeGen/mips64-f128-literal.c @@ -0,0 +1,9 @@ +// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s + +typedef long double LD; + +// CHECK: ret fp128 + +LD foo0() { + return 2.625L; +} diff --git a/clang/test/CodeGen/mips64-nontrivial-return.cpp b/clang/test/CodeGen/mips64-nontrivial-return.cpp new file mode 100644 index 0000000..8aff9ab --- /dev/null +++ b/clang/test/CodeGen/mips64-nontrivial-return.cpp @@ -0,0 +1,17 @@ +// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s + +class B { +public: + virtual ~B() {} +}; + +class D : public B { +}; + +extern D gd0; + +// CHECK: _Z4foo1v(%class.D* noalias nocapture sret + +D foo1(void) { + return gd0; +} diff --git a/clang/test/CodeGen/mips64-padding-arg.c b/clang/test/CodeGen/mips64-padding-arg.c new file mode 100644 index 0000000..b4dcfba --- /dev/null +++ b/clang/test/CodeGen/mips64-padding-arg.c @@ -0,0 +1,43 @@ +// RUN: %clang -target mips64el-unknown-linux -ccc-clang-archs mips64el -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s + +typedef struct { + double d; + long double ld; +} S0; + +// Insert padding to ensure arguments of type S0 are aligned to 16-byte boundaries. + +// CHECK: define void @foo1(i32 %a0, i64, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 %b, i64, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3) +// CHECK: tail call void @foo2(i32 1, i32 2, i32 %a0, i64 undef, double %a1.coerce0, i64 %a1.coerce1, i64 %a1.coerce2, i64 %a1.coerce3, double %a2.coerce0, i64 %a2.coerce1, i64 %a2.coerce2, i64 %a2.coerce3, i32 3, i64 undef, double %a3.coerce0, i64 %a3.coerce1, i64 %a3.coerce2, i64 %a3.coerce3) +// CHECK: declare void @foo2(i32, i32, i32, i64, double, i64, i64, i64, double, i64, i64, i64, i32, i64, double, i64, i64, i64) + +extern void foo2(int, int, int, S0, S0, int, S0); + +void foo1(int a0, S0 a1, S0 a2, int b, S0 a3) { + foo2(1, 2, a0, a1, a2, 3, a3); +} + +// Insert padding before long double argument. +// +// CHECK: define void @foo3(i32 %a0, i64, fp128 %a1) +// CHECK: tail call void @foo4(i32 1, i32 2, i32 %a0, i64 undef, fp128 %a1) +// CHECK: declare void @foo4(i32, i32, i32, i64, fp128) + +extern void foo4(int, int, int, long double); + +void foo3(int a0, long double a1) { + foo4(1, 2, a0, a1); +} + +// Insert padding after hidden argument. +// +// CHECK: define void @foo5(%struct.S0* noalias sret %agg.result, i64, fp128 %a0) +// CHECK: call void @foo6(%struct.S0* sret %agg.result, i32 1, i32 2, i64 undef, fp128 %a0) +// CHECK: declare void @foo6(%struct.S0* sret, i32, i32, i64, fp128) + +extern S0 foo6(int, int, long double); + +S0 foo5(long double a0) { + return foo6(1, 2, a0); +} + diff --git a/clang/test/CodeGen/misaligned-param.c b/clang/test/CodeGen/misaligned-param.c new file mode 100644 index 0000000..53f1f29 --- /dev/null +++ b/clang/test/CodeGen/misaligned-param.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -triple i386-apple-darwin -emit-llvm -o - | FileCheck %s +// Misaligned parameter must be memcpy'd to correctly aligned temporary. + +struct s { int x; long double y; }; +long double foo(struct s x, int i, struct s y) { +// CHECK: foo +// CHECK: %x = alloca %struct.s, align 16 +// CHECK: %y = alloca %struct.s, align 16 +// CHECK: memcpy +// CHECK: memcpy +// CHECK: bar + return bar(&x, &y); +} diff --git a/clang/test/CodeGen/mms-bitfields.c b/clang/test/CodeGen/mms-bitfields.c new file mode 100644 index 0000000..1617e8a --- /dev/null +++ b/clang/test/CodeGen/mms-bitfields.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -mms-bitfields -emit-llvm %s -o - | FileCheck %s + +struct s1 { + int f32; + long long f64; +} s1; + +// CHECK: %struct.s1 = type { i32, [4 x i8], i64 } + +struct s2 { + int f32; + long long f64[4]; +} s2; + +// CHECK: %struct.s2 = type { i32, [4 x i8], [4 x i64] } + +struct s3 { + int f32; + struct s1 s; +} s3; + +// CHECK: %struct.s3 = type { i32, [4 x i8], %struct.s1 } diff --git a/clang/test/CodeGen/mmx-builtins.c b/clang/test/CodeGen/mmx-builtins.c new file mode 100644 index 0000000..b142684 --- /dev/null +++ b/clang/test/CodeGen/mmx-builtins.c @@ -0,0 +1,453 @@ +// REQUIRES: x86-64-registered-target +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +ssse3 -S -o - | FileCheck %s + +// FIXME: Disable inclusion of mm_malloc.h, our current implementation is broken +// on win32 since we don't generally know how to find errno.h. +#define __MM_MALLOC_H + +#include <tmmintrin.h> + +__m64 test1(__m64 a, __m64 b) { + // CHECK: phaddw + return _mm_hadd_pi16(a, b); +} + +__m64 test2(__m64 a, __m64 b) { + // CHECK: phaddd + return _mm_hadd_pi32(a, b); +} + +__m64 test3(__m64 a, __m64 b) { + // CHECK: phaddsw + return _mm_hadds_pi16(a, b); +} + +__m64 test4(__m64 a, __m64 b) { + // CHECK: phsubw + return _mm_hsub_pi16(a, b); +} + +__m64 test5(__m64 a, __m64 b) { + // CHECK: phsubd + return _mm_hsub_pi32(a, b); +} + +__m64 test6(__m64 a, __m64 b) { + // CHECK: phsubsw + return _mm_hsubs_pi16(a, b); +} + +__m64 test7(__m64 a, __m64 b) { + // CHECK: pmaddubsw + return _mm_maddubs_pi16(a, b); +} + +__m64 test8(__m64 a, __m64 b) { + // CHECK: pmulhrsw + return _mm_mulhrs_pi16(a, b); +} + +__m64 test9(__m64 a, __m64 b) { + // CHECK: pshufb + return _mm_shuffle_pi8(a, b); +} + +__m64 test10(__m64 a, __m64 b) { + // CHECK: psignb + return _mm_sign_pi8(a, b); +} + +__m64 test11(__m64 a, __m64 b) { + // CHECK: psignw + return _mm_sign_pi16(a, b); +} + +__m64 test12(__m64 a, __m64 b) { + // CHECK: psignd + return _mm_sign_pi32(a, b); +} + +__m64 test13(__m64 a) { + // CHECK: pabsb + return _mm_abs_pi8(a); +} + +__m64 test14(__m64 a) { + // CHECK: pabsw + return _mm_abs_pi16(a); +} + +__m64 test15(__m64 a) { + // CHECK: pabsd + return _mm_abs_pi32(a); +} + +__m64 test16(__m64 a, __m64 b) { + // CHECK: palignr + return _mm_alignr_pi8(a, b, 2); +} + +__m64 test17(__m128d a) { + // CHECK: cvtpd2pi + return _mm_cvtpd_pi32(a); +} + +__m64 test18(__m128d a) { + // CHECK: cvttpd2pi + return _mm_cvttpd_pi32(a); +} + +__m128d test19(__m64 a) { + // CHECK: cvtpi2pd + return _mm_cvtpi32_pd(a); +} + +__m64 test20(__m64 a, __m64 b) { + // CHECK: pmuludq + return _mm_mul_su32(a, b); +} + +__m64 test21(__m64 a) { + // CHECK: pshufw + return _mm_shuffle_pi16(a, 3); +} + +__m64 test22(__m64 a, __m64 b) { + // CHECK: pmulhuw + return _mm_mulhi_pu16(a, b); +} + +void test23(__m64 d, __m64 n, char *p) { + // CHECK: maskmovq + _mm_maskmove_si64(d, n, p); +} + +int test24(__m64 a) { + // CHECK: pmovmskb + return _mm_movemask_pi8(a); +} + +void test25(__m64 *p, __m64 a) { + // CHECK: movntq + _mm_stream_pi(p, a); +} + +__m64 test26(__m64 a, __m64 b) { + // CHECK: pavgb + return _mm_avg_pu8(a, b); +} + +__m64 test27(__m64 a, __m64 b) { + // CHECK: pavgw + return _mm_avg_pu16(a, b); +} + +__m64 test28(__m64 a, __m64 b) { + // CHECK: pmaxub + return _mm_max_pu8(a, b); +} + +__m64 test29(__m64 a, __m64 b) { + // CHECK: pmaxsw + return _mm_max_pi16(a, b); +} + +__m64 test30(__m64 a, __m64 b) { + // CHECK: pminub + return _mm_min_pu8(a, b); +} + +__m64 test31(__m64 a, __m64 b) { + // CHECK: pminsw + return _mm_min_pi16(a, b); +} + +__m64 test32(__m64 a, __m64 b) { + // CHECK: psadbw + return _mm_sad_pu8(a, b); +} + +__m64 test33(__m64 a, __m64 b) { + // CHECK: paddb + return _mm_add_pi8(a, b); +} + +__m64 test34(__m64 a, __m64 b) { + // CHECK: paddw + return _mm_add_pi16(a, b); +} + +__m64 test35(__m64 a, __m64 b) { + // CHECK: paddd + return _mm_add_pi32(a, b); +} + +__m64 test36(__m64 a, __m64 b) { + // CHECK: paddq + return __builtin_ia32_paddq(a, b); +} + +__m64 test37(__m64 a, __m64 b) { + // CHECK: paddsb + return _mm_adds_pi8(a, b); +} + +__m64 test38(__m64 a, __m64 b) { + // CHECK: paddsw + return _mm_adds_pi16(a, b); +} + +__m64 test39(__m64 a, __m64 b) { + // CHECK: paddusb + return _mm_adds_pu8(a, b); +} + +__m64 test40(__m64 a, __m64 b) { + // CHECK: paddusw + return _mm_adds_pu16(a, b); +} + +__m64 test41(__m64 a, __m64 b) { + // CHECK: psubb + return _mm_sub_pi8(a, b); +} + +__m64 test42(__m64 a, __m64 b) { + // CHECK: psubw + return _mm_sub_pi16(a, b); +} + +__m64 test43(__m64 a, __m64 b) { + // CHECK: psubd + return _mm_sub_pi32(a, b); +} + +__m64 test44(__m64 a, __m64 b) { + // CHECK: psubq + return __builtin_ia32_psubq(a, b); +} + +__m64 test45(__m64 a, __m64 b) { + // CHECK: psubsb + return _mm_subs_pi8(a, b); +} + +__m64 test46(__m64 a, __m64 b) { + // CHECK: psubsw + return _mm_subs_pi16(a, b); +} + +__m64 test47(__m64 a, __m64 b) { + // CHECK: psubusb + return _mm_subs_pu8(a, b); +} + +__m64 test48(__m64 a, __m64 b) { + // CHECK: psubusw + return _mm_subs_pu16(a, b); +} + +__m64 test49(__m64 a, __m64 b) { + // CHECK: pmaddwd + return _mm_madd_pi16(a, b); +} + +__m64 test50(__m64 a, __m64 b) { + // CHECK: pmulhw + return _mm_mulhi_pi16(a, b); +} + +__m64 test51(__m64 a, __m64 b) { + // CHECK: pmullw + return _mm_mullo_pi16(a, b); +} + +__m64 test52(__m64 a, __m64 b) { + // CHECK: pmullw + return _mm_mullo_pi16(a, b); +} + +__m64 test53(__m64 a, __m64 b) { + // CHECK: pand + return _mm_and_si64(a, b); +} + +__m64 test54(__m64 a, __m64 b) { + // CHECK: pandn + return _mm_andnot_si64(a, b); +} + +__m64 test55(__m64 a, __m64 b) { + // CHECK: por + return _mm_or_si64(a, b); +} + +__m64 test56(__m64 a, __m64 b) { + // CHECK: pxor + return _mm_xor_si64(a, b); +} + +__m64 test57(__m64 a, __m64 b) { + // CHECK: pavgb + return _mm_avg_pu8(a, b); +} + +__m64 test58(__m64 a, __m64 b) { + // CHECK: pavgw + return _mm_avg_pu16(a, b); +} + +__m64 test59(__m64 a, __m64 b) { + // CHECK: psllw + return _mm_sll_pi16(a, b); +} + +__m64 test60(__m64 a, __m64 b) { + // CHECK: pslld + return _mm_sll_pi32(a, b); +} + +__m64 test61(__m64 a, __m64 b) { + // CHECK: psllq + return _mm_sll_si64(a, b); +} + +__m64 test62(__m64 a, __m64 b) { + // CHECK: psrlw + return _mm_srl_pi16(a, b); +} + +__m64 test63(__m64 a, __m64 b) { + // CHECK: psrld + return _mm_srl_pi32(a, b); +} + +__m64 test64(__m64 a, __m64 b) { + // CHECK: psrlq + return _mm_srl_si64(a, b); +} + +__m64 test65(__m64 a, __m64 b) { + // CHECK: psraw + return _mm_sra_pi16(a, b); +} + +__m64 test66(__m64 a, __m64 b) { + // CHECK: psrad + return _mm_sra_pi32(a, b); +} + +__m64 test67(__m64 a) { + // CHECK: psllw + return _mm_slli_pi16(a, 3); +} + +__m64 test68(__m64 a) { + // CHECK: pslld + return _mm_slli_pi32(a, 3); +} + +__m64 test69(__m64 a) { + // CHECK: psllq + return _mm_slli_si64(a, 3); +} + +__m64 test70(__m64 a) { + // CHECK: psrlw + return _mm_srli_pi16(a, 3); +} + +__m64 test71(__m64 a) { + // CHECK: psrld + return _mm_srli_pi32(a, 3); +} + +__m64 test72(__m64 a) { + // CHECK: psrlq + return _mm_srli_si64(a, 3); +} + +__m64 test73(__m64 a) { + // CHECK: psraw + return _mm_srai_pi16(a, 3); +} + +__m64 test74(__m64 a) { + // CHECK: psrad + return _mm_srai_pi32(a, 3); +} + +__m64 test75(__m64 a, __m64 b) { + // CHECK: packsswb + return _mm_packs_pi16(a, b); +} + +__m64 test76(__m64 a, __m64 b) { + // CHECK: packssdw + return _mm_packs_pi32(a, b); +} + +__m64 test77(__m64 a, __m64 b) { + // CHECK: packuswb + return _mm_packs_pu16(a, b); +} + +__m64 test78(__m64 a, __m64 b) { + // CHECK: punpckhbw + return _mm_unpackhi_pi8(a, b); +} + +__m64 test79(__m64 a, __m64 b) { + // CHECK: punpckhwd + return _mm_unpackhi_pi16(a, b); +} + +__m64 test80(__m64 a, __m64 b) { + // CHECK: punpckhdq + return _mm_unpackhi_pi32(a, b); +} + +__m64 test81(__m64 a, __m64 b) { + // CHECK: punpcklbw + return _mm_unpacklo_pi8(a, b); +} + +__m64 test82(__m64 a, __m64 b) { + // CHECK: punpcklwd + return _mm_unpacklo_pi16(a, b); +} + +__m64 test83(__m64 a, __m64 b) { + // CHECK: punpckldq + return _mm_unpacklo_pi32(a, b); +} + +__m64 test84(__m64 a, __m64 b) { + // CHECK: pcmpeqb + return _mm_cmpeq_pi8(a, b); +} + +__m64 test85(__m64 a, __m64 b) { + // CHECK: pcmpeqw + return _mm_cmpeq_pi16(a, b); +} + +__m64 test86(__m64 a, __m64 b) { + // CHECK: pcmpeqd + return _mm_cmpeq_pi32(a, b); +} + +__m64 test87(__m64 a, __m64 b) { + // CHECK: pcmpgtb + return _mm_cmpgt_pi8(a, b); +} + +__m64 test88(__m64 a, __m64 b) { + // CHECK: pcmpgtw + return _mm_cmpgt_pi16(a, b); +} + +__m64 test89(__m64 a, __m64 b) { + // CHECK: pcmpgtd + return _mm_cmpgt_pi32(a, b); +} diff --git a/clang/test/CodeGen/mmx-inline-asm.c b/clang/test/CodeGen/mmx-inline-asm.c new file mode 100644 index 0000000..635e2a6 --- /dev/null +++ b/clang/test/CodeGen/mmx-inline-asm.c @@ -0,0 +1,22 @@ +// RUN: %clang -mmmx -target i386-unknown-unknown -emit-llvm -S %s -o - | FileCheck %s +// <rdar://problem/9091220> +#include <mmintrin.h> + +// CHECK: { x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx } + +void foo(long long fill) { + __m64 vfill = _mm_cvtsi64_m64(fill); + __m64 v1, v2, v3, v4, v5, v6, v7; + + __asm__ __volatile__ ( + "\tmovq %7, %0\n" + "\tmovq %7, %1\n" + "\tmovq %7, %2\n" + "\tmovq %7, %3\n" + "\tmovq %7, %4\n" + "\tmovq %7, %5\n" + "\tmovq %7, %6" + : "=&y" (v1), "=&y" (v2), "=&y" (v3), + "=&y" (v4), "=&y" (v5), "=&y" (v6), "=y" (v7) + : "y" (vfill)); +} diff --git a/clang/test/CodeGen/mmx-shift-with-immediate.c b/clang/test/CodeGen/mmx-shift-with-immediate.c new file mode 100644 index 0000000..ecd1881 --- /dev/null +++ b/clang/test/CodeGen/mmx-shift-with-immediate.c @@ -0,0 +1,23 @@ +// RUN: %clang -mmmx -target i386-unknown-unknown -emit-llvm -S %s -o - | FileCheck %s +#include <mmintrin.h> + +void shift(__m64 a, __m64 b, int c) { + // CHECK: x86_mmx @llvm.x86.mmx.pslli.w(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_slli_pi16(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.pslli.d(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_slli_pi32(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.pslli.q(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_slli_si64(a, c); + + // CHECK: x86_mmx @llvm.x86.mmx.psrli.w(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srli_pi16(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.psrli.d(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srli_pi32(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.psrli.q(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srli_si64(a, c); + + // CHECK: x86_mmx @llvm.x86.mmx.psrai.w(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srai_pi16(a, c); + // CHECK: x86_mmx @llvm.x86.mmx.psrai.d(x86_mmx %{{.*}}, i32 {{.*}}) + _mm_srai_pi32(a, c); +} diff --git a/clang/test/CodeGen/mrtd.c b/clang/test/CodeGen/mrtd.c new file mode 100644 index 0000000..d7729a5 --- /dev/null +++ b/clang/test/CodeGen/mrtd.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -mrtd -triple i386-unknown-freebsd9.0 -emit-llvm -o - %s | FileCheck %s + +void baz(int arg); + +// CHECK: define x86_stdcallcc void @foo(i32 %arg) nounwind +void foo(int arg) { +// CHECK: call x86_stdcallcc i32 bitcast (i32 (...)* @bar to i32 (i32)*)( + bar(arg); +// CHECK: call x86_stdcallcc void @baz(i32 + baz(arg); +} + +// CHECK: declare x86_stdcallcc i32 @bar(...) + +// CHECK: declare x86_stdcallcc void @baz(i32) diff --git a/clang/test/CodeGen/ms-anonymous-struct.c b/clang/test/CodeGen/ms-anonymous-struct.c new file mode 100644 index 0000000..b41caab --- /dev/null +++ b/clang/test/CodeGen/ms-anonymous-struct.c @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -fms-extensions -emit-llvm -o - %s | FileCheck %s + +// CHECK: %struct.test = type { i32, %struct.nested2, i32 } +// CHECK: %struct.nested2 = type { i32, %struct.nested1, i32 } +// CHECK: %struct.nested1 = type { i32, i32 } +typedef struct nested1 { + int a1; + int b1; +} NESTED1; + +struct nested2 { + int a; + NESTED1; + int b; +}; + +struct test { + int x; + struct nested2; + int y; +}; + + +void foo() +{ + // CHECK: %var = alloca %struct.test, align 4 + struct test var; + + // CHECK: getelementptr inbounds %struct.test* %var, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.a; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 2 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.b; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.a1; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}var, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.b1; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.x; + + // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 2 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var.y; +} + +void foo2(struct test* var) +{ + // CHECK: alloca %struct.test*, align + // CHECK-NEXT: store %struct.test* %var, %struct.test** %{{.*}}, align + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->a; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 2 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->b; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->a1; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 1 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->b1; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 0 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->x; + + // CHECK-NEXT: load %struct.test** %{{.*}}, align + // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 2 + // CHECK-NEXT: load i32* %{{.*}}, align 4 + var->y; +} diff --git a/clang/test/CodeGen/ms-declspecs.c b/clang/test/CodeGen/ms-declspecs.c new file mode 100644 index 0000000..d3235ae --- /dev/null +++ b/clang/test/CodeGen/ms-declspecs.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s + +// CHECK: define void @t3() nounwind noinline naked { +__declspec(naked) void t3() {} + +// CHECK: define void @t22() nounwind +void __declspec(nothrow) t22(); +void t22() {} + +// CHECK: define void @t2() nounwind noinline { +__declspec(noinline) void t2() {} + +// CHECK: call void @f20_t() +// CHECK: noreturn +__declspec(noreturn) void f20_t(void); +void f20(void) { f20_t(); } diff --git a/clang/test/CodeGen/ms_struct-bitfield-1.c b/clang/test/CodeGen/ms_struct-bitfield-1.c new file mode 100644 index 0000000..25c0ba2 --- /dev/null +++ b/clang/test/CodeGen/ms_struct-bitfield-1.c @@ -0,0 +1,91 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-darwin9 %s +// rdar://8823265 + +#define ATTR __attribute__((__ms_struct__)) + +struct { + unsigned int bf_1 : 12; + unsigned int : 0; + unsigned int bf_2 : 12; +} ATTR t1; +static int a1[(sizeof(t1) == 8) -1]; + +struct +{ + char foo : 4; + short : 0; + char bar; +} ATTR t2; +static int a2[(sizeof(t2) == 4) -1]; + +#pragma ms_struct on +struct +{ + char foo : 4; + short : 0; + char bar; +} t3; +#pragma ms_struct off +static int a3[(sizeof(t3) == 4) -1]; + +struct +{ + char foo : 6; + long : 0; +} ATTR t4; +static int a4[(sizeof(t4) == 8) -1]; + +struct +{ + char foo : 4; + short : 0; + char bar : 8; +} ATTR t5; +static int a5[(sizeof(t5) == 4) -1]; + +struct +{ + char foo : 4; + short : 0; + long : 0; + char bar; +} ATTR t6; +static int a6[(sizeof(t6) == 4) -1]; + +struct +{ + char foo : 4; + long : 0; + short : 0; + char bar; +} ATTR t7; +static int a7[(sizeof(t7) == 16) -1]; + +struct +{ + char foo : 4; + short : 0; + long : 0; + char bar:7; +} ATTR t8; +static int a8[(sizeof(t8) == 4) -1]; + +struct +{ + char foo : 4; + long : 0; + short : 0; + char bar: 8; +} ATTR t9; +static int a9[(sizeof(t9) == 16) -1]; + +struct +{ + char foo : 4; + char : 0; + short : 0; + int : 0; + long :0; + char bar; +} ATTR t10; +static int a10[(sizeof(t10) == 2) -1]; diff --git a/clang/test/CodeGen/ms_struct-bitfield-2.c b/clang/test/CodeGen/ms_struct-bitfield-2.c new file mode 100644 index 0000000..36e0172 --- /dev/null +++ b/clang/test/CodeGen/ms_struct-bitfield-2.c @@ -0,0 +1,135 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-darwin9 %s +// rdar://8823265 + +#define ATTR __attribute__((__ms_struct__)) + +#define size_struct_0 1 +#define size_struct_1 4 +#define size_struct_2 24 +#define size_struct_3 8 +#define size_struct_4 32 +#define size_struct_5 12 +#define size_struct_6 40 +#define size_struct_7 8 +#define size_struct_8 20 +#define size_struct_9 32 + +struct _struct_0 +{ + char member_0; +} ATTR; +typedef struct _struct_0 struct_0; + +struct _struct_1 +{ + char member_0; + short member_1:13; +} ATTR; +typedef struct _struct_1 struct_1; + +struct _struct_2 +{ + double member_0; + unsigned char member_1:8; + int member_2:32; + unsigned char member_3:5; + short member_4:14; + short member_5:13; + unsigned char:0; +} ATTR; +typedef struct _struct_2 struct_2; + +struct _struct_3 +{ + unsigned int member_0:26; + unsigned char member_1:2; + +} ATTR; +typedef struct _struct_3 struct_3; + +struct _struct_4 +{ + unsigned char member_0:7; + double member_1; + double member_2; + short member_3:5; + char member_4:2; + +} ATTR; +typedef struct _struct_4 struct_4; + +struct _struct_5 +{ + unsigned short member_0:12; + int member_1:1; + unsigned short member_2:6; + +} ATTR; +typedef struct _struct_5 struct_5; + +struct _struct_6 +{ + unsigned char member_0:7; + unsigned int member_1:25; + char member_2:1; + double member_3; + short member_4:9; + double member_5; + +} ATTR; +typedef struct _struct_6 struct_6; + +struct _struct_7 +{ + double member_0; + +} ATTR; +typedef struct _struct_7 struct_7; + +struct _struct_8 +{ + unsigned char member_0:7; + int member_1:11; + int member_2:5; + int:0; + char member_4:8; + unsigned short member_5:4; + unsigned char member_6:3; + int member_7:23; + +} ATTR; +typedef struct _struct_8 struct_8; + +struct _struct_9 +{ + double member_0; + unsigned int member_1:6; + int member_2:17; + double member_3; + unsigned int member_4:22; + +} ATTR; +typedef struct _struct_9 struct_9; + +struct_0 test_struct_0 = { 123 }; +struct_1 test_struct_1 = { 82, 1081 }; +struct_2 test_struct_2 = { 20.0, 31, 407760, 1, 14916, 6712 }; +struct_3 test_struct_3 = { 64616999, 1 }; +struct_4 test_struct_4 = { 61, 20.0, 20.0, 12, 0 }; +struct_5 test_struct_5 = { 909, 1, 57 }; +struct_6 test_struct_6 = { 12, 21355796, 0, 20.0, 467, 20.0 }; +struct_7 test_struct_7 = { 20.0 }; +struct_8 test_struct_8 = { 126, 1821, 22, 125, 6, 0, 2432638 }; +struct_9 test_struct_9 = { 20.0, 3, 23957, 20.0, 1001631 }; + + +static int a0[(sizeof (struct_0) == size_struct_0) -1]; +static int a1[(sizeof (struct_1) == size_struct_1) -1]; +static int a2[(sizeof (struct_2) == size_struct_2) -1]; +static int a3[(sizeof (struct_3) == size_struct_3) -1]; +static int a4[(sizeof (struct_4) == size_struct_4) -1]; +static int a5[(sizeof (struct_5) == size_struct_5) -1]; +static int a6[(sizeof (struct_6) == size_struct_6) -1]; +static int a7[(sizeof (struct_7) == size_struct_7) -1]; +static int a8[(sizeof (struct_8) == size_struct_8) -1]; +static int a9[(sizeof (struct_9) == size_struct_9) -1]; diff --git a/clang/test/CodeGen/ms_struct-bitfield-3.c b/clang/test/CodeGen/ms_struct-bitfield-3.c new file mode 100644 index 0000000..0eba435 --- /dev/null +++ b/clang/test/CodeGen/ms_struct-bitfield-3.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple i386-apple-darwin9 %s +// rdar://8823265 + +#define ATTR __attribute__((__ms_struct__)) + +struct _struct_0 +{ + int member_0 : 25 ; + short member_1 : 6 ; + char member_2 : 2 ; + unsigned short member_3 : 1 ; + unsigned char member_4 : 7 ; + short member_5 : 16 ; + int : 0 ; + char member_7 ; + +} ATTR; + +typedef struct _struct_0 struct_0; + +#define size_struct_0 20 + +struct_0 test_struct_0 = { 18557917, 17, 3, 0, 80, 6487, 93 }; +static int a[(size_struct_0 == sizeof (struct_0)) -1]; + +struct _struct_1 { + int d; + unsigned char a; + unsigned short b:7; + char c; +} ATTR; + +typedef struct _struct_1 struct_1; + +#define size_struct_1 12 + +struct_1 test_struct_1 = { 18557917, 'a', 3, 'b' }; + +static int a1[(size_struct_1 == sizeof (struct_1)) -1]; + +struct ten { + long long a:3; + long long b:3; + char c; +} __attribute__ ((ms_struct)); + +#define size_struct_2 16 + +static int a2[(size_struct_2 == sizeof (struct ten)) -1]; diff --git a/clang/test/CodeGen/ms_struct-bitfield-init.c b/clang/test/CodeGen/ms_struct-bitfield-init.c new file mode 100644 index 0000000..7a483fb --- /dev/null +++ b/clang/test/CodeGen/ms_struct-bitfield-init.c @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-darwin9 %s +// rdar://8823265 + +extern void abort(void); +#define ATTR __attribute__((__ms_struct__)) + +struct +{ + char foo; + long : 0; + char : 0; + int : 0; + char bar; +} ATTR t1 = {'a', 'b'}; + +struct +{ + char bar0; + long : 0; + int : 0; + char bar1; + char bar2; + long : 0; + char bar3; + char bar4; + char : 0; + char bar5; + char bar6; + char : 0; + char bar7; + char bar8; +} ATTR t2 = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}; + +struct { + int : 0; + int i1; + int : 0; + int i2; + int : 0; + int i3; + int : 0; + int i4; +} t3 = {1,2,3,4}; + +int main() { + if (sizeof(t1) != 2) + abort(); + if (t1.foo != 'a') + abort(); + if (t1.bar != 'b') + abort(); + t1.foo = 'c'; + t1.bar = 'd'; + if (t1.foo != 'c') + abort(); + if (t1.bar != 'd') + abort(); + if (sizeof(t2) != 9) + abort(); + if (t2.bar0 != 'a' || t2.bar8 != 'i') + abort(); + if (sizeof(t3) != 16) + abort(); + if (t3.i1 != 1 || t3.i4 != 4) + abort(); + return 0; +} + diff --git a/clang/test/CodeGen/ms_struct-bitfield.c b/clang/test/CodeGen/ms_struct-bitfield.c new file mode 100644 index 0000000..a8f4c91 --- /dev/null +++ b/clang/test/CodeGen/ms_struct-bitfield.c @@ -0,0 +1,131 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-darwin9 %s +// rdar://8823265 + +#define ATTR __attribute__((__ms_struct__)) + +struct +{ + char foo; + long : 0; + char bar; +} ATTR t1; + +struct +{ + char foo; + long : 0; + char : 0; + int : 0; + char bar; +} ATTR t2; + +struct +{ + char foo; + long : 0; + char : 0; + int : 0; + char bar; + long : 0; + char : 0; +} ATTR t3; + +struct +{ + long : 0; + char bar; +} ATTR t4; + +struct +{ + long : 0; + long : 0; + char : 0; + char bar; +} ATTR t5; + +struct +{ + long : 0; + long : 0; + char : 0; + char bar; +} ATTR t6; + +struct +{ + char foo; + long : 0; + int : 0; + char bar; + char bar1; + long : 0; + char bar2; + char bar3; + char : 0; + char bar4; + char bar5; + char : 0; + char bar6; + char bar7; +} ATTR t7; + +struct +{ + long : 0; + long : 0; + char : 0; +} ATTR t8; + +struct +{ + char foo; + long : 0; + int : 0; + char bar; + char bar1; + long : 0; + char bar2; + char bar3; + char : 0; + char bar4; + char bar5; + char : 0; + char bar6; + char bar7; + int i1; + char : 0; + long : 0; + char :4; + char bar8; + char : 0; + char bar9; + char bar10; + int i2; + char : 0; + long : 0; + char :4; +} ATTR t9; + +struct +{ + char foo: 8; + long : 0; + char bar; +} ATTR t10; + +static int arr1[(sizeof(t1) == 2) -1]; +static int arr2[(sizeof(t2) == 2) -1]; +static int arr3[(sizeof(t3) == 2) -1]; +static int arr4[(sizeof(t4) == 1) -1]; +static int arr5[(sizeof(t5) == 1) -1]; +static int arr6[(sizeof(t6) == 1) -1]; +static int arr7[(sizeof(t7) == 9) -1]; +static int arr8[(sizeof(t8) == 0) -1]; +static int arr9[(sizeof(t9) == 28) -1]; +static int arr10[(sizeof(t10) == 16) -1]; + +int main() { + return 0; +} + diff --git a/clang/test/CodeGen/ms_struct-pack.c b/clang/test/CodeGen/ms_struct-pack.c new file mode 100644 index 0000000..da94f54 --- /dev/null +++ b/clang/test/CodeGen/ms_struct-pack.c @@ -0,0 +1,125 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple i386-apple-darwin9 %s +// rdar://8823265 + +#pragma pack(1) +struct _one_ms { + short m:9; // size is 2 + int q:27; // size is 6 + short w:13; // size is 8 + short e:3; // size is 8 + char r:4; // size is 9 + char t:7; // size is 10 + short y:16; // size is 12 + short u:1; // size is 14 + char i:2; // size is 15 + int a; // size is 19 + char o:6; // size is 20 + char s:2; // size is 20 + short d:10; // size is 22 + short f:4; // size is 22 + char b; // size is 23 + char g:1; // size is 24 + short h:13; // size is 26 + char j:8; // size is 27 + char k:5; // size is 28 + char c; // size is 29 + int l:28; // size is 33 + char z:7; // size is 34 + int x:20; // size is 38 +} __attribute__((__ms_struct__)); +typedef struct _one_ms one_ms; + +static int a1[(sizeof(one_ms) == 38) - 1]; + +#pragma pack(2) +struct _two_ms { + short m:9; + int q:27; + short w:13; + short e:3; + char r:4; + char t:7; + short y:16; + short u:1; + char i:2; + int a; + char o:6; + char s:2; + short d:10; + short f:4; + char b; + char g:1; + short h:13; + char j:8; + char k:5; + char c; + int l:28; + char z:7; + int x:20; +} __attribute__((__ms_struct__)); + +typedef struct _two_ms two_ms; + +static int a2[(sizeof(two_ms) == 42) - 1]; + +#pragma pack(4) +struct _four_ms { + short m:9; + int q:27; + short w:13; + short e:3; + char r:4; + char t:7; + short y:16; + short u:1; + char i:2; + int a; + char o:6; + char s:2; + short d:10; + short f:4; + char b; + char g:1; + short h:13; + char j:8; + char k:5; + char c; + int l:28; + char z:7; + int x:20; +} __attribute__((__ms_struct__)); +typedef struct _four_ms four_ms; + +static int a4[(sizeof(four_ms) == 48) - 1]; + +#pragma pack(8) +struct _eight_ms { + short m:9; + int q:27; + short w:13; + short e:3; + char r:4; + char t:7; + short y:16; + short u:1; + char i:2; + int a; + char o:6; + char s:2; + short d:10; + short f:4; + char b; + char g:1; + short h:13; + char j:8; + char k:5; + char c; + int l:28; + char z:7; + int x:20; +} __attribute__((__ms_struct__)); + +typedef struct _eight_ms eight_ms; + +static int a8[(sizeof(eight_ms) == 48) - 1]; + diff --git a/clang/test/CodeGen/ms_struct.c b/clang/test/CodeGen/ms_struct.c new file mode 100644 index 0000000..a5f9606 --- /dev/null +++ b/clang/test/CodeGen/ms_struct.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm %s -o - | FileCheck %s + +#define ATTR __attribute__((__ms_struct__)) +struct s1 { + int f32; + long long f64; +} ATTR s1; + +// CHECK: %struct.s1 = type { i32, [4 x i8], i64 } + +struct s2 { + int f32; + long long f64[4]; +} ATTR s2; + +// CHECK: %struct.s2 = type { i32, [4 x i8], [4 x i64] } + +struct s3 { + int f32; + struct s1 s; +} ATTR s3; + +// CHECK: %struct.s3 = type { i32, [4 x i8], %struct.s1 } diff --git a/clang/test/CodeGen/mult-alt-generic.c b/clang/test/CodeGen/mult-alt-generic.c new file mode 100644 index 0000000..1665f9c --- /dev/null +++ b/clang/test/CodeGen/mult-alt-generic.c @@ -0,0 +1,281 @@ +// RUN: %clang_cc1 -triple i686 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple arm %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple cellspu %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple mblaze %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple mips %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple mipsel %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple powerpc %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple powerpc64 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple sparc %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple thumb %s -emit-llvm -o - | FileCheck %s + +int mout0; +int min1; +int marray[2]; + +// CHECK: @single_m +void single_m() +{ + // CHECK: call void asm "foo $1,$0", "=*m,*m[[CLOBBERS:[a-zA-Z0-9@%{},~_ ]*\"]](i32* {{[a-zA-Z0-9@%]+}}, i32* {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=m" (mout0) : "m" (min1)); +} + +// CHECK: @single_o +void single_o() +{ + register int out0 = 0; + register int index = 1; + // Doesn't really do an offset... + //asm("foo %1, %2,%0" : "=r" (out0) : "o" (min1)); +} + +// CHECK: @single_V +void single_V() +{ +// asm("foo %1,%0" : "=m" (mout0) : "V" (min1)); +} + +// CHECK: @single_lt +void single_lt() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,<r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "<r" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r,r<[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "r<" (in1)); +} + +// CHECK: @single_gt +void single_gt() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,>r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : ">r" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r,r>[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "r>" (in1)); +} + +// CHECK: @single_r +void single_r() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "r" (in1)); +} + +// CHECK: @single_i +void single_i() +{ + register int out0 = 0; + // CHECK: call i32 asm "foo $1,$0", "=r,i[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r" (out0) : "i" (1)); +} + +// CHECK: @single_n +void single_n() +{ + register int out0 = 0; + // CHECK: call i32 asm "foo $1,$0", "=r,n[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r" (out0) : "n" (1)); +} + +// CHECK: @single_E +void single_E() +{ + register double out0 = 0.0; + // CHECK: call double asm "foo $1,$0", "=r,E[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r" (out0) : "E" (1.0e+01)); +} + +// CHECK: @single_F +void single_F() +{ + register double out0 = 0.0; + // CHECK: call double asm "foo $1,$0", "=r,F[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r" (out0) : "F" (1.0)); +} + +// CHECK: @single_s +void single_s() +{ + register int out0 = 0; + //asm("foo %1,%0" : "=r" (out0) : "s" (single_s)); +} + +// CHECK: @single_g +void single_g() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,imr[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "g" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r,imr[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "g" (min1)); + // CHECK: call i32 asm "foo $1,$0", "=r,imr[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r" (out0) : "g" (1)); +} + +// CHECK: @single_X +void single_X() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "X" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r" (out0) : "X" (min1)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r" (out0) : "X" (1)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0)) + asm("foo %1,%0" : "=r" (out0) : "X" (marray)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r" (out0) : "X" (1.0e+01)); + // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r" (out0) : "X" (1.0)); +} + +// CHECK: @single_p +void single_p() +{ + register int out0 = 0; + // Constraint converted differently on different platforms moved to platform-specific. + // : call i32 asm "foo $1,$0", "=r,im[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0)) + asm("foo %1,%0" : "=r" (out0) : "p" (marray)); +} + +// CHECK: @multi_m +void multi_m() +{ + // CHECK: call void asm "foo $1,$0", "=*m|r,m|r[[CLOBBERS]](i32* {{[a-zA-Z0-9@%]+}}, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=m,r" (mout0) : "m,r" (min1)); +} + +// CHECK: @multi_o +void multi_o() +{ + register int out0 = 0; + register int index = 1; + // Doesn't really do an offset... + //asm("foo %1, %2,%0" : "=r,r" (out0) : "r,o" (min1)); +} + +// CHECK: @multi_V +void multi_V() +{ +// asm("foo %1,%0" : "=m,r" (mout0) : "r,V" (min1)); +} + +// CHECK: @multi_lt +void multi_lt() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|<r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,<r" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|r<[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,r<" (in1)); +} + +// CHECK: @multi_gt +void multi_gt() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|>r[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,>r" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|r>[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,r>" (in1)); +} + +// CHECK: @multi_r +void multi_r() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|m[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,m" (in1)); +} + +// CHECK: @multi_i +void multi_i() +{ + register int out0 = 0; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|i[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r,r" (out0) : "r,i" (1)); +} + +// CHECK: @multi_n +void multi_n() +{ + register int out0 = 0; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|n[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r,r" (out0) : "r,n" (1)); +} + +// CHECK: @multi_E +void multi_E() +{ + register double out0 = 0.0; + // CHECK: call double asm "foo $1,$0", "=r|r,r|E[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,E" (1.0e+01)); +} + +// CHECK: @multi_F +void multi_F() +{ + register double out0 = 0.0; + // CHECK: call double asm "foo $1,$0", "=r|r,r|F[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,F" (1.0)); +} + +// CHECK: @multi_s +void multi_s() +{ + register int out0 = 0; + //asm("foo %1,%0" : "=r,r" (out0) : "r,s" (multi_s)); +} + +// CHECK: @multi_g +void multi_g() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|imr[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,g" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|imr[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,g" (min1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|imr[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r,r" (out0) : "r,g" (1)); +} + +// CHECK: @multi_X +void multi_X() +{ + register int out0 = 0; + register int in1 = 1; + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (in1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (min1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32 1) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0)) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (marray)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1.0e+01)); + // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](double {{[0-9.eE+-]+}}) + asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1.0)); +} + +// CHECK: @multi_p +void multi_p() +{ + register int out0 = 0; + // Constraint converted differently on different platforms moved to platform-specific. + // : call i32 asm "foo $1,$0", "=r|r,r|im[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0)) + asm("foo %1,%0" : "=r,r" (out0) : "r,p" (marray)); +} diff --git a/clang/test/CodeGen/mult-alt-x86.c b/clang/test/CodeGen/mult-alt-x86.c new file mode 100644 index 0000000..4e2a69d --- /dev/null +++ b/clang/test/CodeGen/mult-alt-x86.c @@ -0,0 +1,374 @@ +// RUN: %clang_cc1 -triple i686 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64 -emit-llvm %s -o - | FileCheck %s + +int mout0; +int min1; +int marray[2]; +double dout0; +double din1; + +// CHECK: @single_R +void single_R() +{ + // CHECK: asm "foo $1,$0", "=R,R[[CLOBBERS:[a-zA-Z0-9@%{},~_ ]*\"]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=R" (mout0) : "R" (min1)); +} + +// CHECK: @single_q +void single_q() +{ + // CHECK: asm "foo $1,$0", "=q,q[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=q" (mout0) : "q" (min1)); +} + +// CHECK: @single_Q +void single_Q() +{ + // CHECK: asm "foo $1,$0", "=Q,Q[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=Q" (mout0) : "Q" (min1)); +} + +// CHECK: @single_a +void single_a() +{ + // CHECK: asm "foo $1,$0", "={ax},{ax}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=a" (mout0) : "a" (min1)); +} + +// CHECK: @single_b +void single_b() +{ + // CHECK: asm "foo $1,$0", "={bx},{bx}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=b" (mout0) : "b" (min1)); +} + +// CHECK: @single_c +void single_c() +{ + // CHECK: asm "foo $1,$0", "={cx},{cx}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=c" (mout0) : "c" (min1)); +} + +// CHECK: @single_d +void single_d() +{ + // CHECK: asm "foo $1,$0", "={dx},{dx}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=d" (mout0) : "d" (min1)); +} + +// CHECK: @single_S +void single_S() +{ + // CHECK: asm "foo $1,$0", "={si},{si}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=S" (mout0) : "S" (min1)); +} + +// CHECK: @single_D +void single_D() +{ + // CHECK: asm "foo $1,$0", "={di},{di}[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=D" (mout0) : "D" (min1)); +} + +// CHECK: @single_A +void single_A() +{ + // CHECK: asm "foo $1,$0", "=A,A[[CLOBBERS]](i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=A" (mout0) : "A" (min1)); +} + +// CHECK: @single_f +void single_f() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @single_t +void single_t() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @single_u +void single_u() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @single_y +void single_y() +{ + // CHECK: call double asm "foo $1,$0", "=y,y[[CLOBBERS]](double {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=y" (dout0) : "y" (din1)); +} + +// CHECK: @single_x +void single_x() +{ + // CHECK: asm "foo $1,$0", "=x,x[[CLOBBERS]](double {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=x" (dout0) : "x" (din1)); +} + +// CHECK: @single_Y +void single_Y0() +{ + // Y constraint currently broken. + //asm("foo %1,%0" : "=Y0" (mout0) : "Y0" (min1)); + //asm("foo %1,%0" : "=Yz" (mout0) : "Yz" (min1)); + //asm("foo %1,%0" : "=Yt" (mout0) : "Yt" (min1)); + //asm("foo %1,%0" : "=Yi" (mout0) : "Yi" (min1)); + //asm("foo %1,%0" : "=Ym" (mout0) : "Ym" (min1)); +} + +// CHECK: @single_I +void single_I() +{ + // CHECK: asm "foo $1,$0", "=*m,I[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "I" (1)); +} + +// CHECK: @single_J +void single_J() +{ + // CHECK: asm "foo $1,$0", "=*m,J[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "J" (1)); +} + +// CHECK: @single_K +void single_K() +{ + // CHECK: asm "foo $1,$0", "=*m,K[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "K" (1)); +} + +// CHECK: @single_L +void single_L() +{ + // CHECK: asm "foo $1,$0", "=*m,L[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "L" (1)); +} + +// CHECK: @single_M +void single_M() +{ + // CHECK: asm "foo $1,$0", "=*m,M[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "M" (1)); +} + +// CHECK: @single_N +void single_N() +{ + // CHECK: asm "foo $1,$0", "=*m,N[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "N" (1)); +} + +// CHECK: @single_G +void single_G() +{ + // CHECK: asm "foo $1,$0", "=*m,G[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + asm("foo %1,%0" : "=m" (mout0) : "G" (1.0)); +} + +// CHECK: @single_C +void single_C() +{ + // CHECK: asm "foo $1,$0", "=*m,C[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + asm("foo %1,%0" : "=m" (mout0) : "C" (1.0)); +} + +// CHECK: @single_e +void single_e() +{ + // CHECK: asm "foo $1,$0", "=*m,e[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "e" (1)); +} + +// CHECK: @single_Z +void single_Z() +{ + // CHECK: asm "foo $1,$0", "=*m,Z[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=m" (mout0) : "Z" (1)); +} + +// CHECK: @multi_R +void multi_R() +{ + // CHECK: asm "foo $1,$0", "=*r|R|m,r|R|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,R,m" (mout0) : "r,R,m" (min1)); +} + +// CHECK: @multi_q +void multi_q() +{ + // CHECK: asm "foo $1,$0", "=*r|q|m,r|q|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,q,m" (mout0) : "r,q,m" (min1)); +} + +// CHECK: @multi_Q +void multi_Q() +{ + // CHECK: asm "foo $1,$0", "=*r|Q|m,r|Q|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,Q,m" (mout0) : "r,Q,m" (min1)); +} + +// CHECK: @multi_a +void multi_a() +{ + // CHECK: asm "foo $1,$0", "=*r|{ax}|m,r|{ax}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,a,m" (mout0) : "r,a,m" (min1)); +} + +// CHECK: @multi_b +void multi_b() +{ + // CHECK: asm "foo $1,$0", "=*r|{bx}|m,r|{bx}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,b,m" (mout0) : "r,b,m" (min1)); +} + +// CHECK: @multi_c +void multi_c() +{ + // CHECK: asm "foo $1,$0", "=*r|{cx}|m,r|{cx}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,c,m" (mout0) : "r,c,m" (min1)); +} + +// CHECK: @multi_d +void multi_d() +{ + // CHECK: asm "foo $1,$0", "=*r|{dx}|m,r|{dx}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,d,m" (mout0) : "r,d,m" (min1)); +} + +// CHECK: @multi_S +void multi_S() +{ + // CHECK: asm "foo $1,$0", "=*r|{si}|m,r|{si}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,S,m" (mout0) : "r,S,m" (min1)); +} + +// CHECK: @multi_D +void multi_D() +{ + // CHECK: asm "foo $1,$0", "=*r|{di}|m,r|{di}|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,D,m" (mout0) : "r,D,m" (min1)); +} + +// CHECK: @multi_A +void multi_A() +{ + // CHECK: asm "foo $1,$0", "=*r|A|m,r|A|m[[CLOBBERS]](i32* @mout0, i32 {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,A,m" (mout0) : "r,A,m" (min1)); +} + +// CHECK: @multi_f +void multi_f() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @multi_t +void multi_t() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @multi_u +void multi_u() +{ +//FIXME: I don't know how to do an 80387 floating point stack register operation, which I think is fp80. +} + +// CHECK: @multi_y +void multi_y() +{ + // CHECK: asm "foo $1,$0", "=*r|y|m,r|y|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,y,m" (dout0) : "r,y,m" (din1)); +} + +// CHECK: @multi_x +void multi_x() +{ + // CHECK: asm "foo $1,$0", "=*r|x|m,r|x|m[[CLOBBERS]](double* @dout0, double {{[a-zA-Z0-9@%]+}}) + asm("foo %1,%0" : "=r,x,m" (dout0) : "r,x,m" (din1)); +} + +// CHECK: @multi_Y +void multi_Y0() +{ + // Y constraint currently broken. + //asm("foo %1,%0" : "=r,Y0,m" (mout0) : "r,Y0,m" (min1)); + //asm("foo %1,%0" : "=r,Yz,m" (mout0) : "r,Yz,m" (min1)); + //asm("foo %1,%0" : "=r,Yt,m" (mout0) : "r,Yt,m" (min1)); + //asm("foo %1,%0" : "=r,Yi,m" (mout0) : "r,Yi,m" (min1)); + //asm("foo %1,%0" : "=r,Ym,m" (mout0) : "r,Ym,m" (min1)); +} + +// CHECK: @multi_I +void multi_I() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|I|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,I,m" (1)); +} + +// CHECK: @multi_J +void multi_J() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|J|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,J,m" (1)); +} + +// CHECK: @multi_K +void multi_K() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|K|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,K,m" (1)); +} + +// CHECK: @multi_L +void multi_L() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|L|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,L,m" (1)); +} + +// CHECK: @multi_M +void multi_M() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|M|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,M,m" (1)); +} + +// CHECK: @multi_N +void multi_N() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|N|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,N,m" (1)); +} + +// CHECK: @multi_G +void multi_G() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|G|m[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,G,m" (1.0)); +} + +// CHECK: @multi_C +void multi_C() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|C|m[[CLOBBERS]](i32* @mout0, double {{1.[0]+e[+]*[0]+}}) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,C,m" (1.0)); +} + +// CHECK: @multi_e +void multi_e() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|e|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,e,m" (1)); +} + +// CHECK: @multi_Z +void multi_Z() +{ + // CHECK: asm "foo $1,$0", "=*r|m|m,r|Z|m[[CLOBBERS]](i32* @mout0, i32 1) + asm("foo %1,%0" : "=r,m,m" (mout0) : "r,Z,m" (1)); +} diff --git a/clang/test/CodeGen/no-common.c b/clang/test/CodeGen/no-common.c new file mode 100644 index 0000000..7beefc7 --- /dev/null +++ b/clang/test/CodeGen/no-common.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT +// RUN: %clang_cc1 %s -fno-common -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-NOCOMMON + +// CHECK-DEFAULT: @x = common global +// CHECK-NOCOMMON: @x = global +int x; + +// CHECK-DEFAULT: @ABC = global +// CHECK-NOCOMMON: @ABC = global +typedef void* (*fn_t)(long a, long b, char *f, int c); +fn_t ABC __attribute__ ((nocommon)); + +// CHECK-DEFAULT: @y = common global +// CHECK-NOCOMMON: @y = common global +int y __attribute__((common));
\ No newline at end of file diff --git a/clang/test/CodeGen/noinline.c b/clang/test/CodeGen/noinline.c new file mode 100644 index 0000000..e64a1a5 --- /dev/null +++ b/clang/test/CodeGen/noinline.c @@ -0,0 +1,14 @@ +// Make sure -fno-inline-functions is behaving correctly. +// rdar://10972766 + +// RUN: %clang_cc1 -O3 -fno-inline -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s + +inline int dont_inline_me(int a, int b) { return(a+b); } + +volatile int *pa = (int*) 0x1000; +void foo() { +// NOINLINE: @foo +// NOINLINE: dont_inline_me +// NOINLINE-NOT: inlinehint + pa[0] = dont_inline_me(pa[1],pa[2]); +} diff --git a/clang/test/CodeGen/object-size.c b/clang/test/CodeGen/object-size.c new file mode 100644 index 0000000..1f16d02 --- /dev/null +++ b/clang/test/CodeGen/object-size.c @@ -0,0 +1,136 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s + +#define strcpy(dest, src) \ + ((__builtin_object_size(dest, 0) != -1ULL) \ + ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \ + : __inline_strcpy_chk(dest, src)) + +static char *__inline_strcpy_chk (char *dest, const char *src) { + return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1)); +} + +char gbuf[63]; +char *gp; +int gi, gj; + +// CHECK: define void @test1 +void test1() { + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 4), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 59) + strcpy(&gbuf[4], "Hi there"); +} + +// CHECK: define void @test2 +void test2() { + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 63) + strcpy(gbuf, "Hi there"); +} + +// CHECK: define void @test3 +void test3() { + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) + strcpy(&gbuf[100], "Hi there"); +} + +// CHECK: define void @test4 +void test4() { + // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i64 -1), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 0) + strcpy((char*)(void*)&gbuf[-1], "Hi there"); +} + +// CHECK: define void @test5 +void test5() { + // CHECK: = load i8** @gp + // CHECK-NEXT:= call i64 @llvm.objectsize.i64(i8* %{{.*}}, i1 false) + strcpy(gp, "Hi there"); +} + +// CHECK: define void @test6 +void test6() { + char buf[57]; + + // CHECK: = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i64 53) + strcpy(&buf[4], "Hi there"); +} + +// CHECK: define void @test7 +void test7() { + int i; + // CHECK: = call i64 @llvm.objectsize.i64(i8* {{.*}}@gbuf{{.*}}, i1 false) + strcpy((++i, gbuf), "Hi there"); +} + +// CHECK: define void @test8 +void test8() { + char *buf[50]; + // CHECK-NOT: __strcpy_chk + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + strcpy(buf[++gi], "Hi there"); +} + +// CHECK: define void @test9 +void test9() { + // CHECK-NOT: __strcpy_chk + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + strcpy((char *)((++gi) + gj), "Hi there"); +} + +// CHECK: define void @test10 +char **p; +void test10() { + // CHECK-NOT: __strcpy_chk + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + strcpy(*(++p), "Hi there"); +} + +// CHECK: define void @test11 +void test11() { + // CHECK-NOT: __strcpy_chk + // CHECK: = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + strcpy(gp = gbuf, "Hi there"); +} + +// CHECK: define void @test12 +void test12() { + // CHECK-NOT: __strcpy_chk + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + strcpy(++gp, "Hi there"); +} + +// CHECK: define void @test13 +void test13() { + // CHECK-NOT: __strcpy_chk + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + strcpy(gp++, "Hi there"); +} + +// CHECK: define void @test14 +void test14() { + // CHECK-NOT: __strcpy_chk + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + strcpy(--gp, "Hi there"); +} + +// CHECK: define void @test15 +void test15() { + // CHECK-NOT: __strcpy_chk + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + strcpy(gp--, "Hi there"); +} + +// CHECK: define void @test16 +void test16() { + // CHECK-NOT: __strcpy_chk + // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0)) + strcpy(gp += 1, "Hi there"); +} + +void test17() { + // CHECK: store i32 -1 + gi = __builtin_object_size(gp++, 0); + // CHECK: store i32 -1 + gi = __builtin_object_size(gp++, 1); + // CHECK: store i32 0 + gi = __builtin_object_size(gp++, 2); + // CHECK: store i32 0 + gi = __builtin_object_size(gp++, 3); +} diff --git a/clang/test/CodeGen/offsetof.c b/clang/test/CodeGen/offsetof.c new file mode 100644 index 0000000..c279e22 --- /dev/null +++ b/clang/test/CodeGen/offsetof.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/opaque-pointer.c b/clang/test/CodeGen/opaque-pointer.c new file mode 100644 index 0000000..d658db1 --- /dev/null +++ b/clang/test/CodeGen/opaque-pointer.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/overloadable.c b/clang/test/CodeGen/overloadable.c new file mode 100644 index 0000000..1ed72b1 --- /dev/null +++ b/clang/test/CodeGen/overloadable.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/override-layout.c b/clang/test/CodeGen/override-layout.c new file mode 100644 index 0000000..99c2cd6 --- /dev/null +++ b/clang/test/CodeGen/override-layout.c @@ -0,0 +1,174 @@ +// RUN: %clang_cc1 -w -fdump-record-layouts %s 2> %t.layouts +// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.before 2>&1 +// RUN: %clang_cc1 -w -DPACKED= -DALIGNED16= -fdump-record-layouts-simple -foverride-record-layout=%t.layouts %s > %t.after 2>&1 +// RUN: diff %t.before %t.after +// RUN: FileCheck %s < %t.after + +// If not explicitly disabled, set PACKED to the packed attribute. +#ifndef PACKED +# define PACKED __attribute__((packed)) +#endif + +// If not explicitly disabled, set ALIGNED16 to 16-byte alignment. +#ifndef ALIGNED16 +# define ALIGNED16 __attribute__((aligned(16))) +#endif + +// CHECK: Type: struct X0 +struct X0 { + int x[6] PACKED; +}; + +// CHECK: Type: struct X1 +struct X1 { + char x[13]; + struct X0 y; +} PACKED; + +// CHECK: Type: struct X2 +struct PACKED X2 { + short x; + int y; +}; + +// CHECK: Type: struct X3 +struct X3 { + short x PACKED; + int y; +}; + +#pragma pack(push,2) +// CHECK: Type: struct X4 +struct X4 { + int x; + int y; +}; +#pragma pack(pop) + +// CHECK: Type: struct X5 +struct PACKED X5 { double a[19]; signed char b; }; + +// CHECK: Type: struct X6 +struct PACKED X6 { long double a; char b; }; + +// CHECK: Type: struct X7 +struct X7 { + unsigned x; + unsigned char y; +} PACKED; + +// CHECK: Type: union X8 +union X8 { + struct X7 x; + unsigned y; +} PACKED; + +// CHECK: Type: struct X9 +struct X9 { + unsigned int x[2] PACKED; + unsigned int y; + unsigned int z PACKED; +}; + +// CHECK: Type: struct X10 +struct X10 { + unsigned int x[2] PACKED; + unsigned int y PACKED; + unsigned int z PACKED; +}; + +// CHECK: Type: struct X11 +struct PACKED X11 { + unsigned int x[2]; + unsigned int y; + unsigned int z; +}; + +// CHECK: Type: struct X12 +struct PACKED X12 { + int x : 24; +}; + +// CHECK: Type: struct X13 +struct PACKED X13 { + signed x : 10; + signed y : 10; +}; + +// CHECK: Type: union X14 +union PACKED X14 { + unsigned long long x : 3; +}; + +// CHECK: Type: struct X15 +struct X15 { + unsigned x : 16; + unsigned y : 28 PACKED; +}; + +// CHECK: Type: struct X16 +struct ALIGNED16 X16 { + int a, b, c; + int x : 5; + int y : 29; +}; + +void use_structs() { + struct X0 x0; + x0.x[5] = sizeof(struct X0); + + struct X1 x1; + x1.x[5] = sizeof(struct X1); + + struct X2 x2; + x2.y = sizeof(struct X2); + + struct X3 x3; + x3.y = sizeof(struct X3); + + struct X4 x4; + x4.y = sizeof(struct X4); + + struct X5 x5; + x5.b = sizeof(struct X5); + + struct X6 x6; + x6.b = sizeof(struct X6); + + struct X7 x7; + typedef int X7array[sizeof(struct X7)]; + x7.x = sizeof(struct X7); + x7.y = x7.x; + + union X8 x8; + typedef int X8array[sizeof(union X8)]; + x8.y = sizeof(union X8); + x8.x.x = x8.y; + + struct X9 x9; + typedef int X9array[sizeof(struct X9)]; + x9.y = sizeof(struct X9); + + struct X10 x10; + typedef int X10array[sizeof(struct X10)]; + x10.y = sizeof(struct X10); + + struct X11 x11; + typedef int X11array[sizeof(struct X11)]; + x11.y = sizeof(struct X11); + + struct X12 x12; + x12.x = sizeof(struct X12); + + struct X13 x13; + x13.x = sizeof(struct X13); + + union X14 x14; + x14.x = sizeof(union X14); + + struct X15 x15; + x15.x = sizeof(struct X15); + + struct X16 x16; + x16.x = sizeof(struct X16); +} diff --git a/clang/test/CodeGen/packed-arrays.c b/clang/test/CodeGen/packed-arrays.c new file mode 100644 index 0000000..0c8bb6c --- /dev/null +++ b/clang/test/CodeGen/packed-arrays.c @@ -0,0 +1,155 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -emit-llvm -Os -o %t %s +// RUN: FileCheck < %t %s + +struct s0 { + unsigned int x[2] __attribute__((packed)); +}; + +struct s1 { + unsigned int x[2] __attribute__((packed)); + unsigned int y; + unsigned int z __attribute__((packed)); +}; + +struct s2 { + unsigned int x[2] __attribute__((packed)); + unsigned int y __attribute__((packed)); + unsigned int z __attribute__((packed)); +}; + +struct __attribute__((packed)) s3 { + unsigned int x[2]; + unsigned int y; + unsigned int z; +}; + +// CHECK: @align0 = global i32 1 +int align0 = __alignof(struct s0); +// CHECK: @align1 = global i32 4 +int align1 = __alignof(struct s1); +// CHECK: @align2 = global i32 1 +int align2 = __alignof(struct s2); +// CHECK: @align3 = global i32 1 +int align3 = __alignof(struct s3); + +// CHECK: @align0_x = global i32 1 +int align0_x = __alignof(((struct s0*) 0)->x); +// +// CHECK: @align1_x = global i32 1 +int align1_x = __alignof(((struct s1*) 0)->x); +// CHECK: @align2_x = global i32 1 +int align2_x = __alignof(((struct s2*) 0)->x); +// CHECK: @align3_x = global i32 1 +int align3_x = __alignof(((struct s3*) 0)->x); + +// CHECK: @align0_x0 = global i32 4 +int align0_x0 = __alignof(((struct s0*) 0)->x[0]); +// CHECK: @align1_x0 = global i32 4 +int align1_x0 = __alignof(((struct s1*) 0)->x[0]); +// CHECK: @align2_x0 = global i32 4 +int align2_x0 = __alignof(((struct s2*) 0)->x[0]); +// CHECK: @align3_x0 = global i32 4 +int align3_x0 = __alignof(((struct s3*) 0)->x[0]); + +// CHECK: define i32 @f0_a +// CHECK: load i32* %{{.*}}, align 1 +// CHECK: } +// CHECK: define i32 @f0_b +// CHECK: load i32* %{{.*}}, align 4 +// CHECK: } +int f0_a(struct s0 *a) { + return a->x[1]; +} +int f0_b(struct s0 *a) { + return *(a->x + 1); +} + +// Note that we are incompatible with GCC on this example. +// +// CHECK: define i32 @f1_a +// CHECK: load i32* %{{.*}}, align 1 +// CHECK: } +// CHECK: define i32 @f1_b +// CHECK: load i32* %{{.*}}, align 4 +// CHECK: } + +// Note that we are incompatible with GCC on this example. +// +// CHECK: define i32 @f1_c +// CHECK: load i32* %{{.*}}, align 4 +// CHECK: } +// CHECK: define i32 @f1_d +// CHECK: load i32* %{{.*}}, align 1 +// CHECK: } +int f1_a(struct s1 *a) { + return a->x[1]; +} +int f1_b(struct s1 *a) { + return *(a->x + 1); +} +int f1_c(struct s1 *a) { + return a->y; +} +int f1_d(struct s1 *a) { + return a->z; +} + +// CHECK: define i32 @f2_a +// CHECK: load i32* %{{.*}}, align 1 +// CHECK: } +// CHECK: define i32 @f2_b +// CHECK: load i32* %{{.*}}, align 4 +// CHECK: } +// CHECK: define i32 @f2_c +// CHECK: load i32* %{{.*}}, align 1 +// CHECK: } +// CHECK: define i32 @f2_d +// CHECK: load i32* %{{.*}}, align 1 +// CHECK: } +int f2_a(struct s2 *a) { + return a->x[1]; +} +int f2_b(struct s2 *a) { + return *(a->x + 1); +} +int f2_c(struct s2 *a) { + return a->y; +} +int f2_d(struct s2 *a) { + return a->z; +} + +// CHECK: define i32 @f3_a +// CHECK: load i32* %{{.*}}, align 1 +// CHECK: } +// CHECK: define i32 @f3_b +// CHECK: load i32* %{{.*}}, align 4 +// CHECK: } +// CHECK: define i32 @f3_c +// CHECK: load i32* %{{.*}}, align 1 +// CHECK: } +// CHECK: define i32 @f3_d +// CHECK: load i32* %{{.*}}, align 1 +// CHECK: } +int f3_a(struct s3 *a) { + return a->x[1]; +} +int f3_b(struct s3 *a) { + return *(a->x + 1); +} +int f3_c(struct s3 *a) { + return a->y; +} +int f3_d(struct s3 *a) { + return a->z; +} + +// Verify we don't claim things are overaligned. +// +// CHECK: define double @f4 +// CHECK: load double* {{.*}}, align 8 +// CHECK: } +extern double g4[5] __attribute__((aligned(16))); +double f4() { + return g4[1]; +} diff --git a/clang/test/CodeGen/packed-nest-unpacked.c b/clang/test/CodeGen/packed-nest-unpacked.c new file mode 100644 index 0000000..0ccc0c4 --- /dev/null +++ b/clang/test/CodeGen/packed-nest-unpacked.c @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 %s -triple x86_64-apple-macosx10.7.2 -emit-llvm -o - | FileCheck %s + +struct X { int x[6]; }; +struct Y { char x[13]; struct X y; } __attribute((packed)); +struct Y g; +void f(struct X); +struct X foo(void); + +// <rdar://problem/10463337> +struct X test1() { + // CHECK: @test1 + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false) + return g.y; +} +struct X test2() { + // CHECK: @test2 + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false) + struct X a = g.y; + return a; +} + +void test3(struct X a) { + // CHECK: @test3 + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i8* {{.*}}, i64 24, i32 1, i1 false) + g.y = a; +} + +// <rdar://problem/10530444> +void test4() { + // CHECK: @test4 + // FIXME: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i64 24, i32 1, i1 false) + f(g.y); +} + +// PR12395 +int test5() { + // CHECK: @test5 + // CHECK: load i32* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1, i32 0, i64 0), align 1 + return g.y.x[0]; +} + +// <rdar://problem/11220251> +void test6() { + // CHECK: @test6 + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%struct.X* getelementptr inbounds (%struct.Y* @g, i32 0, i32 1) to i8*), i8* %{{.*}}, i64 24, i32 1, i1 false) + g.y = foo(); +} diff --git a/clang/test/CodeGen/packed-structure.c b/clang/test/CodeGen/packed-structure.c new file mode 100644 index 0000000..3aeaa23 --- /dev/null +++ b/clang/test/CodeGen/packed-structure.c @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -triple x86_64 -emit-llvm -o - %s | opt -S -strip -o %t +// RUX: llvm-gcc -flto -S -O3 -o %t %s +// RUN: FileCheck --check-prefix=CHECK-GLOBAL < %t %s +// RUN: FileCheck --check-prefix=CHECK-FUNCTIONS < %t %s + +struct s0 { + int x; + int y __attribute__((packed)); +}; + +// CHECK-GLOBAL: @s0_align_x = global i32 4 + +// CHECK-GLOBAL: @s0_align_y = global i32 1 + +// CHECK-GLOBAL: @s0_align = global i32 4 +int s0_align_x = __alignof(((struct s0*)0)->x); +int s0_align_y = __alignof(((struct s0*)0)->y); +int s0_align = __alignof(struct s0); + +// CHECK-FUNCTIONS: define i32 @s0_load_x +// CHECK-FUNCTIONS: [[s0_load_x:%.*]] = load i32* {{.*}}, align 4 +// CHECK-FUNCTIONS: ret i32 [[s0_load_x]] +int s0_load_x(struct s0 *a) { return a->x; } +// FIXME: This seems like it should be align 1. This is actually something which +// has changed in llvm-gcc recently, previously both x and y would be loaded +// with align 1 (in 2363.1 at least). +// +// CHECK-FUNCTIONS: define i32 @s0_load_y +// CHECK-FUNCTIONS: [[s0_load_y:%.*]] = load i32* {{.*}}, align 1 +// CHECK-FUNCTIONS: ret i32 [[s0_load_y]] +int s0_load_y(struct s0 *a) { return a->y; } +// CHECK-FUNCTIONS: define void @s0_copy +// CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 4, i1 false) +void s0_copy(struct s0 *a, struct s0 *b) { *b = *a; } + +// + +struct s1 { + int x; + int y; +} __attribute__((packed)); + +// CHECK-GLOBAL: @s1_align_x = global i32 1 +// CHECK-GLOBAL: @s1_align_y = global i32 1 +// CHECK-GLOBAL: @s1_align = global i32 1 +int s1_align_x = __alignof(((struct s1*)0)->x); +int s1_align_y = __alignof(((struct s1*)0)->y); +int s1_align = __alignof(struct s1); + +// CHECK-FUNCTIONS: define i32 @s1_load_x +// CHECK-FUNCTIONS: [[s1_load_x:%.*]] = load i32* {{.*}}, align 1 +// CHECK-FUNCTIONS: ret i32 [[s1_load_x]] +int s1_load_x(struct s1 *a) { return a->x; } +// CHECK-FUNCTIONS: define i32 @s1_load_y +// CHECK-FUNCTIONS: [[s1_load_y:%.*]] = load i32* {{.*}}, align 1 +// CHECK-FUNCTIONS: ret i32 [[s1_load_y]] +int s1_load_y(struct s1 *a) { return a->y; } +// CHECK-FUNCTIONS: define void @s1_copy +// CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 1, i1 false) +void s1_copy(struct s1 *a, struct s1 *b) { *b = *a; } + +// + +#pragma pack(push,2) +struct s2 { + int x; + int y; +}; +#pragma pack(pop) + +// CHECK-GLOBAL: @s2_align_x = global i32 2 +// CHECK-GLOBAL: @s2_align_y = global i32 2 +// CHECK-GLOBAL: @s2_align = global i32 2 +int s2_align_x = __alignof(((struct s2*)0)->x); +int s2_align_y = __alignof(((struct s2*)0)->y); +int s2_align = __alignof(struct s2); + +// CHECK-FUNCTIONS: define i32 @s2_load_x +// CHECK-FUNCTIONS: [[s2_load_y:%.*]] = load i32* {{.*}}, align 2 +// CHECK-FUNCTIONS: ret i32 [[s2_load_y]] +int s2_load_x(struct s2 *a) { return a->x; } +// CHECK-FUNCTIONS: define i32 @s2_load_y +// CHECK-FUNCTIONS: [[s2_load_y:%.*]] = load i32* {{.*}}, align 2 +// CHECK-FUNCTIONS: ret i32 [[s2_load_y]] +int s2_load_y(struct s2 *a) { return a->y; } +// CHECK-FUNCTIONS: define void @s2_copy +// CHECK-FUNCTIONS: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 8, i32 2, i1 false) +void s2_copy(struct s2 *a, struct s2 *b) { *b = *a; } + +struct __attribute__((packed, aligned)) s3 { + short aShort; + int anInt; +}; +// CHECK-GLOBAL: @s3_1 = global i32 1 +int s3_1 = __alignof(((struct s3*) 0)->anInt); +// CHECK-FUNCTIONS: define i32 @test3( +int test3(struct s3 *ptr) { + // CHECK-FUNCTIONS: [[PTR:%.*]] = getelementptr inbounds {{%.*}}* {{%.*}}, i32 0, i32 1 + // CHECK-FUNCTIONS-NEXT: load i32* [[PTR]], align 1 + return ptr->anInt; +} diff --git a/clang/test/CodeGen/packed-union.c b/clang/test/CodeGen/packed-union.c new file mode 100644 index 0000000..31ce614 --- /dev/null +++ b/clang/test/CodeGen/packed-union.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o %t + +typedef struct _attrs { + unsigned file_attributes; + unsigned char filename_length; +} __attribute__((__packed__)) attrs; + +// RUN: grep "union._attr_union = type <{ i32, i8 }>" %t +typedef union _attr_union { + attrs file_attrs; + unsigned owner_id; +} __attribute__((__packed__)) attr_union; + +attr_union u; + diff --git a/clang/test/CodeGen/palignr.c b/clang/test/CodeGen/palignr.c new file mode 100644 index 0000000..1712df5 --- /dev/null +++ b/clang/test/CodeGen/palignr.c @@ -0,0 +1,31 @@ +// REQUIRES: x86-registered-target +// RUN: %clang_cc1 %s -triple=i686-apple-darwin -target-feature +ssse3 -O1 -S -o - | FileCheck %s + +#define _mm_alignr_epi8(a, b, n) (__builtin_ia32_palignr128((a), (b), (n))) +typedef __attribute__((vector_size(16))) int int4; + +// CHECK: palignr +int4 align1(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 15); } +// CHECK: ret +// CHECK: ret +// CHECK-NOT: palignr +int4 align2(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 16); } +// CHECK: psrldq +int4 align3(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 17); } +// CHECK: xor +int4 align4(int4 a, int4 b) { return _mm_alignr_epi8(a, b, 32); } + +#define _mm_alignr_pi8(a, b, n) (__builtin_ia32_palignr((a), (b), (n))) +typedef __attribute__((vector_size(8))) int int2; + +// CHECK: palignr +int2 align5(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 8); } + +// CHECK: palignr +int2 align6(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 9); } + +// CHECK: palignr +int2 align7(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 16); } + +// CHECK: palignr +int2 align8(int2 a, int2 b) { return _mm_alignr_pi8(a, b, 7); } diff --git a/clang/test/CodeGen/parameter-passing.c b/clang/test/CodeGen/parameter-passing.c new file mode 100644 index 0000000..e48815b --- /dev/null +++ b/clang/test/CodeGen/parameter-passing.c @@ -0,0 +1,56 @@ +// 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_cc1 %s -triple i386-unknown-unknown -O3 -emit-llvm -o %t +// RUN: not grep '@g0' %t + +// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -O3 -emit-llvm -o %t +// RUN: not grep '@g0' %t + +// RUN: %clang_cc1 %s -triple powerpc-unknown-unknown -O3 -emit-llvm -o %t +// RUN: not grep '@g0' %t + +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/clang/test/CodeGen/pascal-string.c b/clang/test/CodeGen/pascal-string.c new file mode 100644 index 0000000..0a9ee67 --- /dev/null +++ b/clang/test/CodeGen/pascal-string.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s -fpascal-strings | grep "05Hello" + +unsigned char * Foo( void ) +{ + static unsigned char s[256] = "\pHello"; + return s; +} + diff --git a/clang/test/CodeGen/pascal-wchar-string.c b/clang/test/CodeGen/pascal-wchar-string.c new file mode 100644 index 0000000..626fc99 --- /dev/null +++ b/clang/test/CodeGen/pascal-wchar-string.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s -fpascal-strings -fshort-wchar | FileCheck %s +// rdar://8020384 + +#include <stddef.h> + +extern void abort (void); + +typedef unsigned short UInt16; + +typedef UInt16 UniChar; + +int main(int argc, char* argv[]) +{ + + char st[] = "\pfoo"; // pascal string + UniChar wt[] = L"\pbar"; // pascal Unicode string + UniChar wt1[] = L"\p"; + UniChar wt2[] = L"\pgorf"; + + if (st[0] != 3) + abort (); + if (wt[0] != 3) + abort (); + if (wt1[0] != 0) + abort (); + if (wt2[0] != 4) + abort (); + + return 0; +} + +// CHECK: [i16 3, i16 98, i16 97, i16 114, i16 0] +// CHECK: [i16 4, i16 103, i16 111, i16 114, i16 102, i16 0] + + +// PR8856 - -fshort-wchar makes wchar_t be unsigned. +// CHECK: @test2 +// CHECK: store volatile i32 1, i32* %isUnsigned +void test2() { + volatile int isUnsigned = (wchar_t)-1 > (wchar_t)0; +} diff --git a/clang/test/CodeGen/pointer-arithmetic.c b/clang/test/CodeGen/pointer-arithmetic.c new file mode 100644 index 0000000..f67a36d --- /dev/null +++ b/clang/test/CodeGen/pointer-arithmetic.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -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_0(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); } +void f8(void *a, int b) { return *(a + b); } +void f8_1(void *a, int b) { return a[b]; } diff --git a/clang/test/CodeGen/pointer-cmp-type.c b/clang/test/CodeGen/pointer-cmp-type.c new file mode 100644 index 0000000..59b2712 --- /dev/null +++ b/clang/test/CodeGen/pointer-cmp-type.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | grep "icmp ult" + +int a(char* a, char* b) {return a<b;} diff --git a/clang/test/CodeGen/pointer-signext.c b/clang/test/CodeGen/pointer-signext.c new file mode 100644 index 0000000..e809eff --- /dev/null +++ b/clang/test/CodeGen/pointer-signext.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm -O2 -o - %s | FileCheck %s + +// Under Windows 64, int and long are 32-bits. Make sure pointer math doesn't +// cause any sign extensions. + +// CHECK: [[P:%.*]] = add i64 %param, -8 +// CHECK-NEXT: [[Q:%.*]] = inttoptr i64 [[P]] to [[R:%.*\*]] +// CHECK-NEXT: {{%.*}} = getelementptr inbounds [[R]] [[Q]], i64 0, i32 0 + +#define CR(Record, TYPE, Field) \ + ((TYPE *) ((unsigned char *) (Record) - (unsigned char *) &(((TYPE *) 0)->Field))) + +typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *ForwardLink; + struct _LIST_ENTRY *BackLink; +} LIST_ENTRY; + +typedef struct { + unsigned long long Signature; + LIST_ENTRY Link; +} MEMORY_MAP; + +int test(unsigned long long param) +{ + LIST_ENTRY *Link; + MEMORY_MAP *Entry; + + Link = (LIST_ENTRY *) param; + + Entry = CR (Link, MEMORY_MAP, Link); + return (int) Entry->Signature; +} diff --git a/clang/test/CodeGen/pointer-to-int.c b/clang/test/CodeGen/pointer-to-int.c new file mode 100644 index 0000000..30a6db2 --- /dev/null +++ b/clang/test/CodeGen/pointer-to-int.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +int test(void* i) +{ + return (int)i; +} + +// rdar://6093986 +int test2(void) { + float x[2]; + return x; +} + diff --git a/clang/test/CodeGen/popcnt-builtins.c b/clang/test/CodeGen/popcnt-builtins.c new file mode 100644 index 0000000..f072b29 --- /dev/null +++ b/clang/test/CodeGen/popcnt-builtins.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <x86intrin.h> + +unsigned int test_mm_popcnt_u32(unsigned int __X) { + // CHECK: @llvm.ctpop.i32 + return _mm_popcnt_u32(__X); +} + +unsigned long long test_mm_popcnt_u64(unsigned long long __X) { + // CHECK: @llvm.ctpop.i64 + return _mm_popcnt_u64(__X); +} diff --git a/clang/test/CodeGen/powerpc_types.c b/clang/test/CodeGen/powerpc_types.c new file mode 100644 index 0000000..b7d0f5d --- /dev/null +++ b/clang/test/CodeGen/powerpc_types.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple powerpc-unknown-freebsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s + +#include <stdarg.h> + +int va_list_size = sizeof(va_list); +// SVR4-CHECK: va_list_size = global i32 12, align 4 +int long_double_size = sizeof(long double); +// SVR4-CHECK: long_double_size = global i32 8, align 4 +int double_size = sizeof(double); +// SVR4-CHECK: double_size = global i32 8, align 4 diff --git a/clang/test/CodeGen/pr12251.c b/clang/test/CodeGen/pr12251.c new file mode 100644 index 0000000..a644bb7 --- /dev/null +++ b/clang/test/CodeGen/pr12251.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -O1 -relaxed-aliasing -o - | FileCheck %s + +enum e1 {e1_a = -1 }; +enum e1 g1(enum e1 *x) { + return *x; +} + +// CHECK: define i32 @g1 +// CHECK: load i32* %x, align 4 +// CHECK-NOT: range +// CHECK: ret diff --git a/clang/test/CodeGen/pr2394.c b/clang/test/CodeGen/pr2394.c new file mode 100644 index 0000000..e43281a --- /dev/null +++ b/clang/test/CodeGen/pr2394.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +struct __attribute((packed)) x {int a : 24;}; +int a(struct x* g) { + // CHECK: load i16 + // CHECK: load i8 + return g->a; +} diff --git a/clang/test/CodeGen/pr3518.c b/clang/test/CodeGen/pr3518.c new file mode 100644 index 0000000..f96a5aa --- /dev/null +++ b/clang/test/CodeGen/pr3518.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | FileCheck %s +// PR 3518 +// Some of the objects were coming out as unintialized (external) before 3518 +// was fixed. Internal names are different between llvm-gcc and clang so they +// are not tested. + +extern void abort (void); + +// CHECK: @.compoundliteral = internal global %struct.A { i32 1, i32 2 } +// CHECK: @.compoundliteral1 = internal global %struct.A { i32 3, i32 4 } +// CHECK: @.compoundliteral2 = internal global %struct.B { %struct.A* @.compoundliteral, %struct.A* @.compoundliteral1 } +// CHECK: @.compoundliteral3 = internal global %struct.A { i32 5, i32 6 } + +struct A { int i; int j; }; +struct B { struct A *a; struct A *b; }; +struct C { struct B *c; struct A *d; }; +struct C e = { &(struct B) { &(struct A) { 1, 2 }, &(struct A) { 3, 4 } }, &(struct A) { 5, 6 } }; + +int +main (void) +{ + if (e.c->a->i != 1 || e.c->a->j != 2) + abort (); + if (e.c->b->i != 3 || e.c->b->j != 4) + abort (); + if (e.d->i != 5 || e.d->j != 6) + abort (); + return 0; +} diff --git a/clang/test/CodeGen/pr4349.c b/clang/test/CodeGen/pr4349.c new file mode 100644 index 0000000..94b4fbd --- /dev/null +++ b/clang/test/CodeGen/pr4349.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | FileCheck %s +// PR 4349 + +union reg +{ + unsigned char b[2][2]; + unsigned short w[2]; + unsigned int d; +}; +struct cpu +{ + union reg pc; +}; +extern struct cpu cpu; +struct svar +{ + void *ptr; +}; +// CHECK: @svars1 = global [1 x %struct.svar] [%struct.svar { i8* bitcast (%struct.cpu* @cpu to i8*) }] +struct svar svars1[] = +{ + { &((cpu.pc).w[0]) } +}; +// CHECK: @svars2 = global [1 x %struct.svar] [%struct.svar { i8* getelementptr (i8* bitcast (%struct.cpu* @cpu to i8*), i64 1) }] +struct svar svars2[] = +{ + { &((cpu.pc).b[0][1]) } +}; +// CHECK: @svars3 = global [1 x %struct.svar] [%struct.svar { i8* getelementptr (i8* bitcast (%struct.cpu* @cpu to i8*), i64 2) }] +struct svar svars3[] = +{ + { &((cpu.pc).w[1]) } +}; +// CHECK: @svars4 = global [1 x %struct.svar] [%struct.svar { i8* getelementptr (i8* bitcast (%struct.cpu* @cpu to i8*), i64 3) }] +struct svar svars4[] = +{ + { &((cpu.pc).b[1][1]) } +}; diff --git a/clang/test/CodeGen/pr5406.c b/clang/test/CodeGen/pr5406.c new file mode 100644 index 0000000..da74d6b --- /dev/null +++ b/clang/test/CodeGen/pr5406.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple arm-apple-darwin -o - | FileCheck %s +// PR 5406 + +typedef struct { char x[3]; } A0; +void foo (int i, ...); + + +// CHECK: call arm_aapcscc void (i32, ...)* @foo(i32 1, [1 x i32] {{.*}}) +int main (void) +{ + A0 a3; + a3.x[0] = 0; + a3.x[0] = 0; + a3.x[2] = 26; + foo (1, a3 ); + return 0; +} diff --git a/clang/test/CodeGen/pr9614.c b/clang/test/CodeGen/pr9614.c new file mode 100644 index 0000000..8fdb2f2 --- /dev/null +++ b/clang/test/CodeGen/pr9614.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck %s + +extern void foo_alias (void) __asm ("foo"); +inline void foo (void) { + return foo_alias (); +} +extern void bar_alias (void) __asm ("bar"); +inline __attribute__ ((__always_inline__)) void bar (void) { + return bar_alias (); +} +extern char *strrchr_foo (const char *__s, int __c) __asm ("strrchr"); +extern inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * strrchr_foo (const char *__s, int __c) { + return __builtin_strrchr (__s, __c); +} +void f(void) { + foo(); + bar(); + strrchr_foo("", '.'); +} + +// CHECK: define void @f() +// CHECK: call void @foo() +// CHECK-NEXT: call void @bar() +// CHECK-NEXT: call i8* @strrchr( +// CHECK-NEXT: ret void + +// CHECK: declare void @foo() +// CHECK: declare void @bar() +// CHECK: declare i8* @strrchr(i8*, i32) diff --git a/clang/test/CodeGen/pragma-pack-1.c b/clang/test/CodeGen/pragma-pack-1.c new file mode 100644 index 0000000..c30a62a --- /dev/null +++ b/clang/test/CodeGen/pragma-pack-1.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s + +// PR4610 +#pragma pack(4) +struct ref { + struct ref *next; +} refs; diff --git a/clang/test/CodeGen/pragma-pack-2.c b/clang/test/CodeGen/pragma-pack-2.c new file mode 100644 index 0000000..bfb34d7 --- /dev/null +++ b/clang/test/CodeGen/pragma-pack-2.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X32 %s +// CHECK-X32: %struct.s0 = type { i64, i64, i32, [12 x i32] } +// CHECK-X32: %struct.s1 = type { [15 x i32], %struct.s0 } + +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X64 %s +// CHECK-X64: %struct.s0 = type <{ i64, i64, i32, [12 x i32] }> +// CHECK-X64: %struct.s1 = type <{ [15 x i32], %struct.s0 }> + +// rdar://problem/7095436 +#pragma pack(4) + +struct s0 { + long long a __attribute__((aligned(8))); + long long b __attribute__((aligned(8))); + unsigned int c __attribute__((aligned(8))); + int d[12]; +} a; + +struct s1 { + int a[15]; + struct s0 b; +} b; + diff --git a/clang/test/CodeGen/pragma-pack-3.c b/clang/test/CodeGen/pragma-pack-3.c new file mode 100644 index 0000000..04b636e --- /dev/null +++ b/clang/test/CodeGen/pragma-pack-3.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X32 %s +// CHECK-X32: %union.command = type <{ i8*, [2 x i8] }> + +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X64 %s +// CHECK-X64: %union.command = type <{ i8*, [2 x i8] }> + +// <rdar://problem/7184250> +#pragma pack(push, 2) +typedef union command { + void *windowRef; + struct menu { + void *menuRef; + unsigned char menuItemIndex; + } menu; +} command; + +command c; diff --git a/clang/test/CodeGen/pragma-visibility.c b/clang/test/CodeGen/pragma-visibility.c new file mode 100644 index 0000000..16460a2 --- /dev/null +++ b/clang/test/CodeGen/pragma-visibility.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +#pragma GCC visibility push(hidden) +int x = 2; +// CHECK: @x = hidden global + +extern int y; +#pragma GCC visibility pop +int y = 4; +// CHECK: @y = hidden global + +#pragma GCC visibility push(hidden) +extern __attribute((visibility("default"))) int z; +int z = 0; +// CHECK: @z = global +#pragma GCC visibility pop + +#pragma GCC visibility push(hidden) +void f() {} +// CHECK: define hidden void @f + +__attribute((visibility("default"))) void g(); +void g() {} +// CHECK: define void @g diff --git a/clang/test/CodeGen/pragma-weak.c b/clang/test/CodeGen/pragma-weak.c new file mode 100644 index 0000000..7ad2b77 --- /dev/null +++ b/clang/test/CodeGen/pragma-weak.c @@ -0,0 +1,172 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm %s -o - -verify | FileCheck %s + +// CHECK: @weakvar = weak global +// CHECK: @__weakvar_alias = common global +// CHECK: @correct_linkage = weak global + + +// CHECK: @both = alias void ()* @__both +// CHECK: @both2 = alias void ()* @__both2 +// CHECK: @both3 = alias weak void ()* @__both3 +// CHECK: @a3 = alias weak void ()* @__a3 +// CHECK: @weakvar_alias = alias weak i32* @__weakvar_alias +// CHECK: @foo = alias weak void ()* @__foo +// CHECK: @foo2 = alias weak void ()* @__foo2 +// CHECK: @stutter = alias weak void ()* @__stutter +// CHECK: @stutter2 = alias weak void ()* @__stutter2 +// CHECK: @declfirst = alias weak void ()* @__declfirst +// CHECK: @declfirstattr = alias weak void ()* @__declfirstattr +// CHECK: @mix2 = alias weak void ()* @__mix2 +// CHECK: @a1 = alias weak void ()* @__a1 +// CHECK: @xxx = alias weak void ()* @__xxx + + + +// CHECK: define weak void @weakdef() + + +#pragma weak weakvar +int weakvar; + +#pragma weak weakdef +void weakdef(void) {} + +#pragma weak param // expected-warning {{weak identifier 'param' never declared}} +#pragma weak correct_linkage +void f(int param) { + int correct_linkage; +} + +#pragma weak weakvar_alias = __weakvar_alias +int __weakvar_alias; + +#pragma weak foo = __foo +void __foo(void) {} +// CHECK: define void @__foo() + + +void __foo2(void) {} +#pragma weak foo2 = __foo2 +// CHECK: define void @__foo2() + + +///// test errors + +#pragma weak unused // expected-warning {{weak identifier 'unused' never declared}} +#pragma weak unused_alias = __unused_alias // expected-warning {{weak identifier '__unused_alias' never declared}} + +#pragma weak td // expected-warning {{weak identifier 'td' never declared}} +typedef int td; + +#pragma weak td2 = __td2 // expected-warning {{weak identifier '__td2' never declared}} +typedef int __td2; + + +///// test weird cases + +// test repeats + +#pragma weak stutter = __stutter +#pragma weak stutter = __stutter +void __stutter(void) {} +// CHECK: define void @__stutter() + +void __stutter2(void) {} +#pragma weak stutter2 = __stutter2 +#pragma weak stutter2 = __stutter2 +// CHECK: define void @__stutter2() + + +// test decl/pragma weak order + +void __declfirst(void); +#pragma weak declfirst = __declfirst +void __declfirst(void) {} +// CHECK: define void @__declfirst() + +void __declfirstattr(void) __attribute((noinline)); +#pragma weak declfirstattr = __declfirstattr +void __declfirstattr(void) {} +// CHECK: define void @__declfirstattr() + +//// test that other attributes are preserved + +//// ensure that pragma weak/__attribute((weak)) play nice + +void mix(void); +#pragma weak mix +__attribute((weak)) void mix(void) { } +// CHECK: define weak void @mix() + +// ensure following __attributes are preserved and that only a single +// alias is generated +#pragma weak mix2 = __mix2 +void __mix2(void) __attribute((noinline)); +void __mix2(void) __attribute((noinline)); +void __mix2(void) {} +// CHECK: define void @__mix2() + +////////////// test #pragma weak/__attribute combinations + +// if the SAME ALIAS is already declared then it overrides #pragma weak +// resulting in a non-weak alias in this case +void both(void) __attribute((alias("__both"))); +#pragma weak both = __both +void __both(void) {} +// CHECK: define void @__both() + +// if the TARGET is previously declared then whichever aliasing method +// comes first applies and subsequent aliases are discarded. +// TODO: warn about this + +void __both2(void); +void both2(void) __attribute((alias("__both2"))); // first, wins +#pragma weak both2 = __both2 +void __both2(void) {} +// CHECK: define void @__both2() + +void __both3(void); +#pragma weak both3 = __both3 // first, wins +void both3(void) __attribute((alias("__both3"))); +void __both3(void) {} +// CHECK: define void @__both3() + +///////////// ensure that #pragma weak does not alter existing __attributes() + +void __a1(void) __attribute((noinline)); +#pragma weak a1 = __a1 +void __a1(void) {} +// CHECK: define void @__a1() {{.*}} noinline + +// attributes introduced BEFORE a combination of #pragma weak and alias() +// hold... +void __a3(void) __attribute((noinline)); +#pragma weak a3 = __a3 +void a3(void) __attribute((alias("__a3"))); +void __a3(void) {} +// CHECK: define void @__a3() {{.*}} noinline + +#pragma weak xxx = __xxx +__attribute((pure,noinline,const,fastcall)) void __xxx(void) { } +// CHECK: void @__xxx() {{.*}} noinline + +///////////// PR10878: Make sure we can call a weak alias +void SHA512Pad(void *context) {} +#pragma weak SHA384Pad = SHA512Pad +void PR10878() { SHA384Pad(0); } +// CHECK: call void @SHA384Pad(i8* null) + + +///////////// TODO: stuff that still doesn't work + +// due to the fact that disparate TopLevelDecls cannot affect each other +// (due to clang's Parser and ASTConsumer behavior, and quite reasonable) +// #pragma weak must appear before or within the same TopLevelDecl as it +// references. +void yyy(void){} +void zzz(void){} +#pragma weak yyy +// NOTE: weak doesn't apply, not before or in same TopLevelDec(!) +// CHECK: define void @yyy() + +int correct_linkage; diff --git a/clang/test/CodeGen/predefined-expr.c b/clang/test/CodeGen/predefined-expr.c new file mode 100644 index 0000000..e2826b6 --- /dev/null +++ b/clang/test/CodeGen/predefined-expr.c @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +// CHECK: @__func__.plainFunction = private unnamed_addr constant [14 x i8] c"plainFunction\00" +// CHECK: @__PRETTY_FUNCTION__.plainFunction = private unnamed_addr constant [21 x i8] c"void plainFunction()\00" +// CHECK: @__func__.externFunction = private unnamed_addr constant [15 x i8] c"externFunction\00" +// CHECK: @__PRETTY_FUNCTION__.externFunction = private unnamed_addr constant [22 x i8] c"void externFunction()\00" +// CHECK: @__func__.privateExternFunction = private unnamed_addr constant [22 x i8] c"privateExternFunction\00" +// CHECK: @__PRETTY_FUNCTION__.privateExternFunction = private unnamed_addr constant [29 x i8] c"void privateExternFunction()\00" +// CHECK: @__func__.staticFunction = private unnamed_addr constant [15 x i8] c"staticFunction\00" +// CHECK: @__PRETTY_FUNCTION__.staticFunction = private unnamed_addr constant [22 x i8] c"void staticFunction()\00" + +int printf(const char *, ...); + +void plainFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); +} + +extern void externFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); +} + +__private_extern__ void privateExternFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); +} + +static void staticFunction() { + printf("__func__ %s\n", __func__); + printf("__FUNCTION__ %s\n", __FUNCTION__); + printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__); +} + +int main() { + plainFunction(); + externFunction(); + privateExternFunction(); + staticFunction(); + + return 0; +} diff --git a/clang/test/CodeGen/private-extern-redef.c b/clang/test/CodeGen/private-extern-redef.c new file mode 100644 index 0000000..580ce9b --- /dev/null +++ b/clang/test/CodeGen/private-extern-redef.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple x86_64-darwin-apple -emit-llvm -o - %s | FileCheck %s +// rdar://9609649 + +__private_extern__ const int I; +__private_extern__ const int J = 927; + +__private_extern__ const int K; +const int K = 37; + +const int L = 10; +__private_extern__ const int L; + +__private_extern__ int M; +int M = 20; + +__private_extern__ int N; +int N; + +__private_extern__ int O; +int O=1; + +__private_extern__ int P; +extern int P; + +void bar(int); + +void foo() { + bar(I); +} + +// CHECK: @J = hidden constant +// CHECK: @K = hidden constant +// CHECK: @L = constant +// CHECK: @M = hidden global +// CHECK: @O = hidden global +// CHECK: @I = external hidden +// CHECK: @N = common hidden global +// CHECK-NOT: @P + diff --git a/clang/test/CodeGen/private-extern.c b/clang/test/CodeGen/private-extern.c new file mode 100644 index 0000000..2d34d54 --- /dev/null +++ b/clang/test/CodeGen/private-extern.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/ptx-cc.c b/clang/test/CodeGen/ptx-cc.c new file mode 100644 index 0000000..2212d42 --- /dev/null +++ b/clang/test/CodeGen/ptx-cc.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple ptx32-unknown-unknown -O3 -S -o %t %s -emit-llvm +// RUN: %clang_cc1 -triple ptx64-unknown-unknown -O3 -S -o %t %s -emit-llvm + +// Just make sure Clang uses the proper calling convention for the PTX back-end. +// If something is wrong, the back-end will fail. +void foo(float* a, + float* b) { + a[0] = b[0]; +} diff --git a/clang/test/CodeGen/redef-ext-inline.c b/clang/test/CodeGen/redef-ext-inline.c new file mode 100644 index 0000000..b8e2f36 --- /dev/null +++ b/clang/test/CodeGen/redef-ext-inline.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -std=gnu89 +// rdar://7208839 + +extern inline int f1 (void) {return 1;} +int f3 (void) {return f1();} +int f1 (void) {return 0;} diff --git a/clang/test/CodeGen/redefine_extname.c b/clang/test/CodeGen/redefine_extname.c new file mode 100644 index 0000000..e73a3ad --- /dev/null +++ b/clang/test/CodeGen/redefine_extname.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple=i386-pc-solaris2.11 -w -emit-llvm %s -o - | FileCheck %s + +#pragma redefine_extname fake real +#pragma redefine_extname name alias + +extern int fake(void); + +int name; + +// __PRAGMA_REDEFINE_EXTNAME should be defined. This will fail if it isn't... +int fish() { return fake() + __PRAGMA_REDEFINE_EXTNAME + name; } +// Check that the call to fake() is emitted as a call to real() +// CHECK: call i32 @real() +// Check that this also works with variables names +// CHECK: load i32* @alias diff --git a/clang/test/CodeGen/regparm-flag.c b/clang/test/CodeGen/regparm-flag.c new file mode 100644 index 0000000..8ecf539 --- /dev/null +++ b/clang/test/CodeGen/regparm-flag.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -mregparm 4 %s -emit-llvm -o %t +// RUN: FileCheck < %t %s + +void f1(int a, int b, int c, int d, + int e, int f, int g, int h); + +void f2(int a, int b) __attribute((regparm(0))); + +void f0() { +// CHECK: call void @f1(i32 inreg 1, i32 inreg 2, i32 inreg 3, i32 inreg 4, +// CHECK: i32 5, i32 6, i32 7, i32 8) + f1(1, 2, 3, 4, 5, 6, 7, 8); +// CHECK: call void @f2(i32 1, i32 2) + f2(1, 2); +} + +// CHECK: declare void @f1(i32 inreg, i32 inreg, i32 inreg, i32 inreg, +// CHECK: i32, i32, i32, i32) +// CHECK: declare void @f2(i32, i32) + diff --git a/clang/test/CodeGen/regparm.c b/clang/test/CodeGen/regparm.c new file mode 100644 index 0000000..d628b68 --- /dev/null +++ b/clang/test/CodeGen/regparm.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s + +#define FASTCALL __attribute__((regparm(2))) + +typedef struct { + int aaa; + double bbbb; + int ccc[200]; +} foo; + +typedef void (*FType)(int, int) __attribute ((regparm (3), stdcall)); +FType bar; + +extern void FASTCALL reduced(char b, double c, foo* d, double e, int f); + +// PR7025 +void FASTCALL f1(int i, int j, int k); +// CHECK: define void @f1(i32 inreg %i, i32 inreg %j, i32 %k) +void f1(int i, int j, int k) { } + +int +main(void) { + // CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.foo* inreg null + reduced(0, 0.0, 0, 0.0, 0); + // CHECK: call x86_stdcallcc void {{.*}}(i32 inreg 1, i32 inreg 2) + bar(1,2); +} diff --git a/clang/test/CodeGen/restrict.c b/clang/test/CodeGen/restrict.c new file mode 100644 index 0000000..8bbff24 --- /dev/null +++ b/clang/test/CodeGen/restrict.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-darwin-apple -emit-llvm %s -o - | FileCheck %s + +// PR6695 + +// CHECK: define void @test0(i32* %{{.*}}, i32 %{{.*}}) +void test0(int *x, int y) { +} + +// CHECK: define void @test1(i32* noalias %{{.*}}, i32 %{{.*}}) +void test1(int * restrict x, int y) { +} + +// CHECK: define void @test2(i32* %{{.*}}, i32* noalias %{{.*}}) +void test2(int *x, int * restrict y) { +} + +typedef int * restrict rp; + +// CHECK: define void @test3(i32* noalias %{{.*}}, i32 %{{.*}}) +void test3(rp x, int y) { +} + +// CHECK: define void @test4(i32* %{{.*}}, i32* noalias %{{.*}}) +void test4(int *x, rp y) { +} + diff --git a/clang/test/CodeGen/shared-string-literals.c b/clang/test/CodeGen/shared-string-literals.c new file mode 100644 index 0000000..00636b0 --- /dev/null +++ b/clang/test/CodeGen/shared-string-literals.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o %t + +char *globalString = "abc"; +char *globalStringArray[5] = { "123", "abc" }; +char *anotherGlobalString = "123"; + +int main() { + printf("123"); +} diff --git a/clang/test/CodeGen/sizeof-vla.c b/clang/test/CodeGen/sizeof-vla.c new file mode 100644 index 0000000..c5fc912 --- /dev/null +++ b/clang/test/CodeGen/sizeof-vla.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s + +// PR3442 + +void *g(unsigned long len); + +void +f(int n) +{ + unsigned begin_set[n]; + + g(sizeof(begin_set)); +} diff --git a/clang/test/CodeGen/sret.c b/clang/test/CodeGen/sret.c new file mode 100644 index 0000000..ed1f9a4 --- /dev/null +++ b/clang/test/CodeGen/sret.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | grep sret | count 5 + +struct abc { + long a; + long b; + long c; +}; + +struct abc foo1(void); +struct abc foo2(); + +void bar() { + struct abc dummy1 = foo1(); + struct abc dummy2 = foo2(); +} diff --git a/clang/test/CodeGen/sret2.c b/clang/test/CodeGen/sret2.c new file mode 100644 index 0000000..c96ce4d --- /dev/null +++ b/clang/test/CodeGen/sret2.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | grep sret | count 2 + +struct abc { + long a; + long b; + long c; +}; + +struct abc foo2(){} diff --git a/clang/test/CodeGen/sse-builtins.c b/clang/test/CodeGen/sse-builtins.c new file mode 100644 index 0000000..2d57425 --- /dev/null +++ b/clang/test/CodeGen/sse-builtins.c @@ -0,0 +1,153 @@ +// RUN: %clang_cc1 -ffreestanding -triple i386-apple-darwin9 -target-cpu pentium4 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s + +#include <emmintrin.h> +#include <smmintrin.h> + +__m128 test_loadl_pi(__m128 x, void* y) { + // CHECK: define {{.*}} @test_loadl_pi + // CHECK: load <2 x float>* {{.*}}, align 1{{$}} + // CHECK: shufflevector {{.*}} <4 x i32> <i32 0, i32 1 + // CHECK: shufflevector {{.*}} <4 x i32> <i32 4, i32 5, i32 2, i32 3> + return _mm_loadl_pi(x,y); +} + +__m128 test_loadh_pi(__m128 x, void* y) { + // CHECK: define {{.*}} @test_loadh_pi + // CHECK: load <2 x float>* {{.*}}, align 1{{$}} + // CHECK: shufflevector {{.*}} <4 x i32> <i32 0, i32 1 + // CHECK: shufflevector {{.*}} <4 x i32> <i32 0, i32 1, i32 4, i32 5> + return _mm_loadh_pi(x,y); +} + +__m128 test_load_ss(void* y) { + // CHECK: define {{.*}} @test_load_ss + // CHECK: load float* {{.*}}, align 1{{$}} + return _mm_load_ss(y); +} + +__m128 test_load1_ps(void* y) { + // CHECK: define {{.*}} @test_load1_ps + // CHECK: load float* {{.*}}, align 1{{$}} + return _mm_load1_ps(y); +} + +void test_store_ss(__m128 x, void* y) { + // CHECK: define void @test_store_ss + // CHECK: store {{.*}} float* {{.*}}, align 1, + _mm_store_ss(y, x); +} + +__m128d test_load1_pd(__m128 x, void* y) { + // CHECK: define {{.*}} @test_load1_pd + // CHECK: load double* {{.*}}, align 1{{$}} + return _mm_load1_pd(y); +} + +__m128d test_loadr_pd(__m128 x, void* y) { + // CHECK: define {{.*}} @test_loadr_pd + // CHECK: load <2 x double>* {{.*}}, align 16{{$}} + return _mm_loadr_pd(y); +} + +__m128d test_load_sd(void* y) { + // CHECK: define {{.*}} @test_load_sd + // CHECK: load double* {{.*}}, align 1{{$}} + return _mm_load_sd(y); +} + +__m128d test_loadh_pd(__m128d x, void* y) { + // CHECK: define {{.*}} @test_loadh_pd + // CHECK: load double* {{.*}}, align 1{{$}} + return _mm_loadh_pd(x, y); +} + +__m128d test_loadl_pd(__m128d x, void* y) { + // CHECK: define {{.*}} @test_loadl_pd + // CHECK: load double* {{.*}}, align 1{{$}} + return _mm_loadl_pd(x, y); +} + +void test_store_sd(__m128d x, void* y) { + // CHECK: define void @test_store_sd + // CHECK: store {{.*}} double* {{.*}}, align 1{{$}} + _mm_store_sd(y, x); +} + +void test_store1_pd(__m128d x, void* y) { + // CHECK: define void @test_store1_pd + // CHECK: store {{.*}} double* {{.*}}, align 1{{$}} + // CHECK: store {{.*}} double* {{.*}}, align 1{{$}} + _mm_store1_pd(y, x); +} + +void test_storer_pd(__m128d x, void* y) { + // CHECK: define void @test_storer_pd + // CHECK: store {{.*}} <2 x double>* {{.*}}, align 16{{$}} + _mm_storer_pd(y, x); +} + +void test_storeh_pd(__m128d x, void* y) { + // CHECK: define void @test_storeh_pd + // CHECK: store {{.*}} double* {{.*}}, align 1{{$}} + _mm_storeh_pd(y, x); +} + +void test_storel_pd(__m128d x, void* y) { + // CHECK: define void @test_storel_pd + // CHECK: store {{.*}} double* {{.*}}, align 1{{$}} + _mm_storel_pd(y, x); +} + +__m128i test_loadl_epi64(void* y) { + // CHECK: define {{.*}} @test_loadl_epi64 + // CHECK: load i64* {{.*}}, align 1{{$}} + return _mm_loadl_epi64(y); +} + +__m128i test_mm_minpos_epu16(__m128i x) { + // CHECK: define {{.*}} @test_mm_minpos_epu16 + // CHECK: @llvm.x86.sse41.phminposuw + return _mm_minpos_epu16(x); +} + +__m128i test_mm_mpsadbw_epu8(__m128i x, __m128i y) { + // CHECK: define {{.*}} @test_mm_mpsadbw_epu8 + // CHECK: @llvm.x86.sse41.mpsadbw + return _mm_mpsadbw_epu8(x, y, 1); +} + +__m128 test_mm_dp_ps(__m128 x, __m128 y) { + // CHECK: define {{.*}} @test_mm_dp_ps + // CHECK: @llvm.x86.sse41.dpps + return _mm_dp_ps(x, y, 2); +} + +__m128d test_mm_dp_pd(__m128d x, __m128d y) { + // CHECK: define {{.*}} @test_mm_dp_pd + // CHECK: @llvm.x86.sse41.dppd + return _mm_dp_pd(x, y, 2); +} + +__m128 test_mm_round_ps(__m128 x) { + // CHECK: define {{.*}} @test_mm_round_ps + // CHECK: @llvm.x86.sse41.round.ps + return _mm_round_ps(x, 2); +} + +__m128 test_mm_round_ss(__m128 x, __m128 y) { + // CHECK: define {{.*}} @test_mm_round_ss + // CHECK: @llvm.x86.sse41.round.ss + return _mm_round_ss(x, y, 2); +} + +__m128d test_mm_round_pd(__m128d x) { + // CHECK: define {{.*}} @test_mm_round_pd + // CHECK: @llvm.x86.sse41.round.pd + return _mm_round_pd(x, 2); +} + +__m128d test_mm_round_sd(__m128d x, __m128d y) { + // CHECK: define {{.*}} @test_mm_round_sd + // CHECK: @llvm.x86.sse41.round.sd + return _mm_round_sd(x, y, 2); +} diff --git a/clang/test/CodeGen/stack-protector.c b/clang/test/CodeGen/stack-protector.c new file mode 100644 index 0000000..eb4cea2 --- /dev/null +++ b/clang/test/CodeGen/stack-protector.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 0 | FileCheck -check-prefix=NOSSP %s +// NOSSP: define void @test1(i8* %msg) nounwind { +// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 1 | FileCheck -check-prefix=WITHSSP %s +// WITHSSP: define void @test1(i8* %msg) nounwind ssp { +// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 2 | FileCheck -check-prefix=SSPREQ %s +// SSPREQ: define void @test1(i8* %msg) nounwind sspreq { + +int printf(const char * _Format, ...); + +void test1(const char *msg) { + char a[strlen(msg) + 1]; + strcpy(a, msg); + printf("%s\n", a); +} diff --git a/clang/test/CodeGen/statements.c b/clang/test/CodeGen/statements.c new file mode 100644 index 0000000..e2bbb5a --- /dev/null +++ b/clang/test/CodeGen/statements.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -Wno-error=return-type %s -emit-llvm-only + +void test1(int x) { +switch (x) { +case 111111111111111111111111111111111111111: +bar(); +} +} + +// Mismatched type between return and function result. +int test2() { return; } +void test3() { return 4; } + + +void test4() { +bar: +baz: +blong: +bing: + ; + +// PR5131 +static long x = &&bar - &&baz; +static long y = &&baz; + &&bing; + &&blong; + if (y) + goto *y; + + goto *x; +} + +// PR3869 +int test5(long long b) { + static void *lbls[] = { &&lbl }; + goto *b; + lbl: + return 0; +} + diff --git a/clang/test/CodeGen/static-forward-decl-fun.c b/clang/test/CodeGen/static-forward-decl-fun.c new file mode 100644 index 0000000..e33ee62 --- /dev/null +++ b/clang/test/CodeGen/static-forward-decl-fun.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/static-forward-decl.c b/clang/test/CodeGen/static-forward-decl.c new file mode 100644 index 0000000..0d35061 --- /dev/null +++ b/clang/test/CodeGen/static-forward-decl.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/static-local-union.c b/clang/test/CodeGen/static-local-union.c new file mode 100644 index 0000000..bd32519 --- /dev/null +++ b/clang/test/CodeGen/static-local-union.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm < %s + +int a() {static union{int a;} r[2] = {1,2};return r[1].a;} + diff --git a/clang/test/CodeGen/static-order.c b/clang/test/CodeGen/static-order.c new file mode 100644 index 0000000..e7f9814 --- /dev/null +++ b/clang/test/CodeGen/static-order.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// CHECK: ModuleID +// CHECK-NOT: zeroinitializer +// CHECK: define i8* @f + +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/clang/test/CodeGen/staticinit.c b/clang/test/CodeGen/staticinit.c new file mode 100644 index 0000000..8c5cdd0 --- /dev/null +++ b/clang/test/CodeGen/staticinit.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -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; } + +// PR7044 +char *f2(char key) { + switch (key) { + static char _msg[40]; + case '\014': + return _msg; + } + + return 0; +} diff --git a/clang/test/CodeGen/stdcall-fastcall.c b/clang/test/CodeGen/stdcall-fastcall.c new file mode 100644 index 0000000..3de7b67 --- /dev/null +++ b/clang/test/CodeGen/stdcall-fastcall.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s + +void __attribute__((fastcall)) f1(void); +void __attribute__((stdcall)) f2(void); +void __attribute__((thiscall)) f3(void); +void __attribute__((fastcall)) f4(void) { +// CHECK: define x86_fastcallcc void @f4() + f1(); +// CHECK: call x86_fastcallcc void @f1() +} +void __attribute__((stdcall)) f5(void) { +// CHECK: define x86_stdcallcc void @f5() + f2(); +// CHECK: call x86_stdcallcc void @f2() +} +void __attribute__((thiscall)) f6(void) { +// CHECK: define x86_thiscallcc void @f6() + f3(); +// CHECK: call x86_thiscallcc void @f3() +} + +// PR5280 +void (__attribute__((fastcall)) *pf1)(void) = f1; +void (__attribute__((stdcall)) *pf2)(void) = f2; +void (__attribute__((thiscall)) *pf3)(void) = f3; +void (__attribute__((fastcall)) *pf4)(void) = f4; +void (__attribute__((stdcall)) *pf5)(void) = f5; +void (__attribute__((thiscall)) *pf6)(void) = f6; + +int main(void) { + f4(); f5(); f6(); + // CHECK: call x86_fastcallcc void @f4() + // CHECK: call x86_stdcallcc void @f5() + // CHECK: call x86_thiscallcc void @f6() + pf1(); pf2(); pf3(); pf4(); pf5(); pf6(); + // CHECK: call x86_fastcallcc void %{{.*}}() + // CHECK: call x86_stdcallcc void %{{.*}}() + // CHECK: call x86_thiscallcc void %{{.*}}() + // CHECK: call x86_fastcallcc void %{{.*}}() + // CHECK: call x86_stdcallcc void %{{.*}}() + // CHECK: call x86_thiscallcc void %{{.*}}() + return 0; +} + +// PR7117 +void __attribute((stdcall)) f7(foo) int foo; {} +void f8(void) { + f7(0); + // CHECK: call x86_stdcallcc void @f7(i32 0) +} diff --git a/clang/test/CodeGen/string-literal-short-wstring.c b/clang/test/CodeGen/string-literal-short-wstring.c new file mode 100644 index 0000000..88e4a1e --- /dev/null +++ b/clang/test/CodeGen/string-literal-short-wstring.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -x c++ -emit-llvm -fshort-wchar %s -o - | FileCheck %s +// Runs in c++ mode so that wchar_t is available. + +int main() { + // This should convert to utf8. + // CHECK: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1 + char b[10] = "\u1120\u0220\U00102030"; + + // CHECK: private unnamed_addr constant [3 x i16] [i16 65, i16 66, i16 0] + const wchar_t *foo = L"AB"; + + // This should convert to utf16. + // CHECK: private unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0] + const wchar_t *bar = L"\u1120\u0220\U00102030"; + + + + // Should pick second character. + // CHECK: store i8 98 + char c = 'ab'; + + // CHECK: store i16 97 + wchar_t wa = L'a'; + + // Should pick second character. + // CHECK: store i16 98 + wchar_t wb = L'ab'; + + // -4085 == 0xf00b + // CHECK: store i16 -4085 + wchar_t wc = L'\uF00B'; +} diff --git a/clang/test/CodeGen/string-literal-unicode-conversion.c b/clang/test/CodeGen/string-literal-unicode-conversion.c new file mode 100644 index 0000000..3e5b7fb --- /dev/null +++ b/clang/test/CodeGen/string-literal-unicode-conversion.c @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=C %s +// RUN: %clang_cc1 -x c++ -std=c++0x -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CPP0X %s +// RUN: %clang_cc1 -x c++ -std=c++0x -fshort-wchar -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=SHORTWCHAR %s + +// This file contains a mix of ISO-8859-1 and UTF-8 encoded data. +// the literal assigned to 'aa' should be the ISO-8859-1 encoding for the code +// points U+00C0 U+00E9 U+00EE U+00F5 U+00FC + +// The rest of the literals should contain the UTF-8 encoding for U+041A U+043E +// U+0448 U+043A U+0430 + +#ifndef __cplusplus +#include <stddef.h> +#endif + +#ifdef __cplusplus +extern "C" +#endif +void f() { + // CHECK-C: private unnamed_addr constant [6 x i8] c"\C0\E9\EE\F5\FC\00", align 1 + // CHECK-CPP0X: private unnamed_addr constant [6 x i8] c"\C0\E9\EE\F5\FC\00", align 1 + char const *aa = "Àéîõü"; + + // CHECK-C: private unnamed_addr constant [11 x i8] c"\D0\9A\D0\BE\D1\88\D0\BA\D0\B0\00", align 1 + // CHECK-CPP0X: private unnamed_addr constant [11 x i8] c"\D0\9A\D0\BE\D1\88\D0\BA\D0\B0\00", align 1 + char const *a = "Кошка"; + + // CHECK-C: private unnamed_addr constant [6 x i32] [i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + // CHECK-SHORTWCHAR: private unnamed_addr constant [6 x i16] [i16 1050, i16 1086, i16 1096, i16 1082, i16 1072, i16 0], align 2 + // CHECK-CPP0X: private unnamed_addr constant [6 x i32] [i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + wchar_t const *b = L"Кошка"; + + // CHECK-C: private unnamed_addr constant [4 x i32] [i32 20320, i32 22909, i32 66304, i32 0], align 4 + // CHECK-SHORTWCHAR: private unnamed_addr constant [4 x i16] [i16 20320, i16 22909, i16 768, i16 0], align 2 + // CHECK-CPP0X: private unnamed_addr constant [4 x i32] [i32 20320, i32 22909, i32 66304, i32 0], align 4 + wchar_t const *b2 = L"\x4f60\x597d\x10300"; + +#if __cplusplus >= 201103L + + // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"1\D0\9A\D0\BE\D1\88\D0\BA\D0\B0\00", align 1 + char const *c = u8"1Кошка"; + + // CHECK-CPP0X: private unnamed_addr constant [7 x i16] [i16 50, i16 1050, i16 1086, i16 1096, i16 1082, i16 1072, i16 0], align 2 + char16_t const *e = u"2Кошка"; + + // CHECK-CPP0X: private unnamed_addr constant [7 x i32] [i32 51, i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + char32_t const *f = U"3Кошка"; + + // CHECK-CPP0X: private unnamed_addr constant [12 x i8] c"4\D0\9A\D0\BE\D1\88\D0\BA\D0\B0\00", align 1 + char const *d = u8R"(4Кошка)"; + + // CHECK-CPP0X: private unnamed_addr constant [7 x i16] [i16 53, i16 1050, i16 1086, i16 1096, i16 1082, i16 1072, i16 0], align 2 + char16_t const *g = uR"(5Кошка)"; + + // CHECK-CPP0X: private unnamed_addr constant [7 x i32] [i32 54, i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + char32_t const *h = UR"(6Кошка)"; + + // CHECK-SHORTWCHAR: private unnamed_addr constant [7 x i16] [i16 55, i16 1050, i16 1086, i16 1096, i16 1082, i16 1072, i16 0], align 2 + // CHECK-CPP0X: private unnamed_addr constant [7 x i32] [i32 55, i32 1050, i32 1086, i32 1096, i32 1082, i32 1072, i32 0], align 4 + wchar_t const *i = LR"(7Кошка)"; + +#endif +} diff --git a/clang/test/CodeGen/string-literal.c b/clang/test/CodeGen/string-literal.c new file mode 100644 index 0000000..12d431a --- /dev/null +++ b/clang/test/CodeGen/string-literal.c @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=C %s +// RUN: %clang_cc1 -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=C %s +// RUN: %clang_cc1 -x c++ -std=c++11 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix=CPP0X %s + +#include <stddef.h> + +int main() { + // CHECK-C: private unnamed_addr constant [10 x i8] c"abc\00\00\00\00\00\00\00", align 1 + // CHECK-CPP0X: private unnamed_addr constant [10 x i8] c"abc\00\00\00\00\00\00\00", align 1 + char a[10] = "abc"; + + // This should convert to utf8. + // CHECK-C: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1 + // CHECK-CPP0X: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1 + char b[10] = "\u1120\u0220\U00102030"; + + // CHECK-C: private unnamed_addr constant [3 x i32] [i32 65, i32 66, i32 0], align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 65, i32 66, i32 0], align 4 + const wchar_t *foo = L"AB"; + + // CHECK-C: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110027, i32 0], align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110027, i32 0], align 4 + const wchar_t *bar = L"\u1234\U0010F00B"; + + // CHECK-C: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110028, i32 0], align 4 + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4660, i32 1110028, i32 0], align 4 + const wchar_t *baz = L"\u1234" "\U0010F00C"; + +#if __cplusplus >= 201103L + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 67, i32 68, i32 0], align 4 + const char32_t *c = U"CD"; + + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110028, i32 0], align 4 + const char32_t *d = U"\u1235\U0010F00C"; + + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 4661, i32 1110027, i32 0], align 4 + const char32_t *o = "\u1235" U"\U0010F00B"; + + // CHECK-CPP0X: private unnamed_addr constant [3 x i16] [i16 69, i16 70, i16 0], align 2 + const char16_t *e = u"EF"; + + // This should convert to utf16. + // CHECK-CPP0X: private unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0], align 2 + const char16_t *f = u"\u1120\u0220\U00102030"; + + // This should convert to utf16. + // CHECK-CPP0X: private unnamed_addr constant [5 x i16] [i16 4384, i16 800, i16 -9272, i16 -9168, i16 0], align 2 + const char16_t *p = u"\u1120\u0320" "\U00102030"; + + // CHECK-CPP0X: private unnamed_addr constant [4 x i8] c"def\00", align 1 + const char *g = u8"def"; + + // CHECK-CPP0X: private unnamed_addr constant [4 x i8] c"ghi\00", align 1 + const char *h = R"foo(ghi)foo"; + + // CHECK-CPP0X: private unnamed_addr constant [4 x i8] c"jkl\00", align 1 + const char *i = u8R"bar(jkl)bar"; + + // CHECK-CPP0X: private unnamed_addr constant [3 x i16] [i16 71, i16 72, i16 0], align 2 + const char16_t *j = uR"foo(GH)foo"; + + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 73, i32 74, i32 0], align 4 + const char32_t *k = UR"bar(IJ)bar"; + + // CHECK-CPP0X: private unnamed_addr constant [3 x i32] [i32 75, i32 76, i32 0], align 4 + const wchar_t *l = LR"bar(KL)bar"; + + // CHECK-CPP0X: private unnamed_addr constant [9 x i8] c"abc\5Cndef\00", align 1 + const char *m = R"(abc\ndef)"; + + // CHECK-CPP0X: private unnamed_addr constant [8 x i8] c"abc\0Adef\00", align 1 + const char *n = R"(abc +def)"; + + // CHECK-CPP0X: private unnamed_addr constant [11 x i8] c"abc\0Adefghi\00", align 1 + const char *q = R"(abc +def)" "ghi"; + +#endif +} diff --git a/clang/test/CodeGen/struct-comma.c b/clang/test/CodeGen/struct-comma.c new file mode 100644 index 0000000..e5b5151 --- /dev/null +++ b/clang/test/CodeGen/struct-comma.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +struct S {int a, b;} x; +void a(struct S* b) {*b = (r(), x);} diff --git a/clang/test/CodeGen/struct-copy.c b/clang/test/CodeGen/struct-copy.c new file mode 100644 index 0000000..6f3b664 --- /dev/null +++ b/clang/test/CodeGen/struct-copy.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/struct-init.c b/clang/test/CodeGen/struct-init.c new file mode 100644 index 0000000..6247729 --- /dev/null +++ b/clang/test/CodeGen/struct-init.c @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -S -triple armv7-apple-darwin %s -emit-llvm -o - | FileCheck %s + +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)}, +}; + +// PR7564 +struct GLGENH { + int : 27; + int EMHJAA : 1; +}; + +struct GLGENH ABHFBF = {1}; + +typedef __attribute__(( ext_vector_type(2) )) unsigned int uint2; +typedef __attribute__(( __vector_size__(8) )) unsigned int __neon_uint32x2_t; + +// rdar://8183908 +typedef unsigned int uint32_t; +typedef __attribute__((neon_vector_type(2))) uint32_t uint32x2_t; +void foo() { + const uint32x2_t signBit = { (uint2) 0x80000000 }; +} + +// CHECK: %struct.fp_struct_foo = type { void ([1 x i32])* } +struct fp_struct_bar { int a; }; + +struct fp_struct_foo { + void (*FP)(struct fp_struct_bar); +} G; diff --git a/clang/test/CodeGen/struct-matching-constraint.c b/clang/test/CodeGen/struct-matching-constraint.c new file mode 100644 index 0000000..40c444f --- /dev/null +++ b/clang/test/CodeGen/struct-matching-constraint.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -S -emit-llvm -triple armv7a-apple-darwin %s -o /dev/null +typedef unsigned short uint16_t; +typedef __attribute__((neon_vector_type(8))) uint16_t uint16x8_t; + +void b(uint16x8_t sat, uint16x8_t luma) +{ + __asm__("vmov.16 %1, %0 \n\t" + "vtrn.16 %0, %1 \n\t" + :"=w"(luma), "=w"(sat) + :"0"(luma) + ); + +} diff --git a/clang/test/CodeGen/struct-passing.c b/clang/test/CodeGen/struct-passing.c new file mode 100644 index 0000000..efb00ef --- /dev/null +++ b/clang/test/CodeGen/struct-passing.c @@ -0,0 +1,24 @@ +// This verifies that structs returned from functions by value are passed +// correctly according to their attributes and the ABI. +// SEE: PR3835 + +// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +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 }; + +// CHECK: declare i32 @f0() nounwind readnone +// CHECK: declare i32 @f1() nounwind readonly +// CHECK: declare void @f2({{.*}} sret) +// CHECK: declare void @f3({{.*}} sret) +// CHECK: declare void @f4({{.*}} byval align 4) +// CHECK: declare void @f5({{.*}} byval align 4) diff --git a/clang/test/CodeGen/struct-x86-darwin.c b/clang/test/CodeGen/struct-x86-darwin.c new file mode 100644 index 0000000..afdcb8a --- /dev/null +++ b/clang/test/CodeGen/struct-x86-darwin.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 < %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, 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, \[2 x i8\], i8, i8 }" %t1 +// RUN: grep "STestB6 = type { i8, i8, \[2 x 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/clang/test/CodeGen/struct.c b/clang/test/CodeGen/struct.c new file mode 100644 index 0000000..e173931 --- /dev/null +++ b/clang/test/CodeGen/struct.c @@ -0,0 +1,196 @@ +// RUN: %clang_cc1 -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; +} + + + +// Complex forward reference of struct. +struct f19S; +extern struct f19T { + struct f19S (*p)(void); +} t; +struct f19S { int i; }; +void f19(void) { + t.p(); +} + diff --git a/clang/test/CodeGen/switch-dce.c b/clang/test/CodeGen/switch-dce.c new file mode 100644 index 0000000..a18d3bc --- /dev/null +++ b/clang/test/CodeGen/switch-dce.c @@ -0,0 +1,234 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -O0 %s -emit-llvm -o - | FileCheck %s + +// PR9322 and rdar://6970405 + +// CHECK: @test1 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: add nsw i32 {{.*}}, 1 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: ret void +int i; +void dead(); + +void test1() { + switch (1) + case 1: + ++i; + + switch (0) + case 1: + dead(); +} + + +// CHECK: @test2 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: add nsw i32 {{.*}}, 2 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: ret void +void test2() { + switch (4) { + case 1: + dead(); + break; + case 4: + i += 2; + // Fall off the end of the switch. + } +} + + +// CHECK: @test3 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: add nsw i32 {{.*}}, 2 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: ret void +void test3() { + switch (4) { + case 1: + dead(); + break; + case 4: { + i += 2; + break; + } + } +} + +// CHECK: @test4 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: add nsw i32 {{.*}}, 2 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: ret void +void test4() { + switch (4) { + case 1: + dead(); + break; + default: { + i += 2; + break; + } + } +} + +// This shouldn't crash codegen, but we don't have to optimize out the switch +// in this case. +void test5() { + switch (1) { + int x; // eliding var decl? + case 1: + x = 4; + i = x; + break; + } +} + +// CHECK: @test6 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: ret void +void test6() { + // Neither case is reachable. + switch (40) { + case 1: + dead(); + break; + case 4: { + dead(); + break; + } + } +} + +// CHECK: @test7 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: add nsw i32 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: ret void +void test7() { + switch (4) { + case 1: + dead(); + break; + { + case 4: // crazy brace scenario + ++i; + } + break; + } +} + +// CHECK: @test8 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: add nsw i32 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: ret void +void test8() { + switch (4) { + case 1: + dead(); + break; + case 4: + ++i; + // Fall off the end of the switch. + } +} + +// CHECK: @test9 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: add nsw i32 +// CHECK: add nsw i32 +// CHECK-NOT: switch +// CHECK-NOT: @dead +// CHECK: ret void +void test9(int i) { + switch (1) { + case 5: + dead(); + case 1: + ++i; + // Fall through is fine. + case 4: + ++i; + break; + } +} + +// CHECK: @test10 +// CHECK-NOT: switch +// CHECK: ret i32 +int test10(void) { + switch(8) { + case 8: + break; + case 4: + break; + default: + dead(); + } + + return 0; +} + +// CHECK: @test11 +// CHECK-NOT: switch +// CHECK: ret void +void test11() { + switch (1) { + case 1: + break; + case 42: ; + int x; // eliding var decl? + x = 4; + break; + } +} + +// CHECK: @test12 +// CHECK-NOT: switch +// CHECK: ret void +void test12() { + switch (1) { + case 2: { + int a; // Ok to skip this vardecl. + a = 42; + } + case 1: + break; + case 42: ; + int x; // eliding var decl? + x = 4; + break; + } +} + +// Verify that case 42 only calls test14 once. +// CHECK: @test13 +// CHECK: call void @test13(i32 97) +// CHECK-NEXT: br label %[[EPILOG2:[0-9.a-z]+]] +// CHECK: [[EPILOG2]] +// CHECK-NEXT: br label [[EPILOG:%[0-9.a-z]+]] +// CHECK: call void @test13(i32 42) +// CHECK-NEXT: br label [[EPILOG]] +void test13(int x) { + switch (x) { + case 42: test13(97); // fallthrough + case 11: break; + default: test13(42); break; + } +} + diff --git a/clang/test/CodeGen/switch.c b/clang/test/CodeGen/switch.c new file mode 100644 index 0000000..8b94a09 --- /dev/null +++ b/clang/test/CodeGen/switch.c @@ -0,0 +1,213 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 %s -emit-llvm -o - | FileCheck %s + +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; +} + + +static 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; +} + +// CHECK: define i32 @foo4t() +// CHECK: ret i32 376 +// CHECK: } +int foo4t() { + // 111 + 1 + 222 + 42 = 376 + return foo4(111) + foo4(99) + foo4(222) + foo4(601); +} + +// CHECK: define void @foo5() +// CHECK-NOT: switch +// CHECK: } +void foo5(){ + switch(0){ + default: + if (0) { + + } + } +} + +// CHECK: define void @foo6() +// CHECK-NOT: switch +// CHECK: } +void foo6(){ + switch(0){ + } +} + +// CHECK: define void @foo7() +// CHECK-NOT: switch +// CHECK: } +void foo7(){ + switch(0){ + foo7(); + } +} + + +// CHECK: define i32 @f8( +// CHECK: ret i32 3 +// CHECK: } +int f8(unsigned x) { + switch(x) { + default: + return 3; + case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned. + return 0; + } +} + +// Ensure that default after a case range is not ignored. +// +// CHECK: define i32 @f9() +// CHECK: ret i32 10 +// CHECK: } +static int f9_0(unsigned x) { + switch(x) { + case 10 ... 0xFFFFFFFF: + return 0; + default: + return 10; + } +} +int f9() { + return f9_0(2); +} + +// Ensure that this doesn't compile to infinite loop in g() due to +// miscompilation of fallthrough from default to a (tested) case +// range. +// +// CHECK: define i32 @f10() +// CHECK: ret i32 10 +// CHECK: } +static int f10_0(unsigned x) { + switch(x) { + default: + x += 1; + case 10 ... 0xFFFFFFFF: + return 0; + } +} + +int f10() { + f10_0(1); + return 10; +} + +// This generated incorrect code because of poor switch chaining. +// +// CHECK: define i32 @f11( +// CHECK: ret i32 3 +// CHECK: } +int f11(int x) { + switch(x) { + default: + return 3; + case 10 ... 0xFFFFFFFF: + return 0; + } +} + +// This just asserted because of the way case ranges were calculated. +// +// CHECK: define i32 @f12( +// CHECK: ret i32 3 +// CHECK: } +int f12(int x) { + switch (x) { + default: + return 3; + case 10 ... -1: + return 0; + } +} + +// Make sure return is not constant (if empty range is skipped or miscompiled) +// +// CHECK: define i32 @f13( +// CHECK: ret i32 % +// CHECK: } +int f13(unsigned x) { + switch(x) { + case 2: + // fallthrough empty range + case 10 ... 9: + return 10; + default: + return 0; + } +} + +// Don't delete a basic block that we want to introduce later references to. +// This isn't really specific to switches, but it's easy to show with them. +// rdar://problem/8837067 +int f14(int x) { + switch (x) { + + // case range so that the case block has no predecessors + case 0 ... 15: + // any expression which doesn't introduce a new block + (void) 0; + // kaboom + + default: + return x; + } +} diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c new file mode 100644 index 0000000..fc8f758 --- /dev/null +++ b/clang/test/CodeGen/target-data.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple i686-unknown-unknown -emit-llvm -o %t %s +// RUN: grep 'target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"' %t +// RUN: %clang_cc1 -triple i686-apple-darwin9 -emit-llvm -o %t %s +// RUN: grep 'target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128"' %t +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s +// RUN: grep 'target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"' %t diff --git a/clang/test/CodeGen/tbaa-for-vptr.cpp b/clang/test/CodeGen/tbaa-for-vptr.cpp new file mode 100644 index 0000000..5ce6bf3 --- /dev/null +++ b/clang/test/CodeGen/tbaa-for-vptr.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -emit-llvm -o - -O1 %s | FileCheck %s +// Check that we generate TBAA for vtable pointer loads and stores. +struct A { + virtual int foo() const ; + virtual ~A(); +}; + +void CreateA() { + new A; +} + +void CallFoo(A *a) { + a->foo(); +} + +// CHECK: %{{.*}} = load {{.*}} !tbaa !0 +// CHECK: store {{.*}} !tbaa !0 +// CHECK: !0 = metadata !{metadata !"vtable pointer", metadata !1} +// CHECK: !1 = metadata !{metadata !"Simple C/C++ TBAA"} diff --git a/clang/test/CodeGen/tentative-decls.c b/clang/test/CodeGen/tentative-decls.c new file mode 100644 index 0000000..d88c346 --- /dev/null +++ b/clang/test/CodeGen/tentative-decls.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -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(); } + diff --git a/clang/test/CodeGen/thread-specifier.c b/clang/test/CodeGen/thread-specifier.c new file mode 100644 index 0000000..a1f3e16 --- /dev/null +++ b/clang/test/CodeGen/thread-specifier.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple i686-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// CHECK: @b = external thread_local global +// CHECK: @d.e = internal thread_local global +// CHECK: @d.f = internal thread_local global +// CHECK: @a = thread_local global +__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}; + return 0; +} + diff --git a/clang/test/CodeGen/transparent-union.c b/clang/test/CodeGen/transparent-union.c new file mode 100644 index 0000000..afdb3d6 --- /dev/null +++ b/clang/test/CodeGen/transparent-union.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -o %t %s +// RUN: FileCheck < %t %s +// +// FIXME: Note that we don't currently get the ABI right here. f0() should be +// f0(i8*). + +typedef union { + void *f0; +} transp_t0 __attribute__((transparent_union)); + +void f0(transp_t0 obj); + +// CHECK: define void @f1_0(i32* %a0) +// CHECK: call void @f0(%union.transp_t0* byval align 4 %{{.*}}) +// CHECK: call void %{{.*}}(i8* %{{[a-z0-9]*}}) +// CHECK: } +void f1_0(int *a0) { + void (*f0p)(void *) = f0; + f0(a0); + f0p(a0); +} + +void f1_1(int *a0) { + f0((transp_t0) { a0 }); +} diff --git a/clang/test/CodeGen/trapv.c b/clang/test/CodeGen/trapv.c new file mode 100644 index 0000000..f52dad5 --- /dev/null +++ b/clang/test/CodeGen/trapv.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -ftrapv %s -emit-llvm -o - | FileCheck %s + +unsigned int ui, uj, uk; +int i, j, k; + +// CHECK: define void @test0() +void test0() { + // -ftrapv doesn't affect unsigned arithmetic. + // CHECK: [[T1:%.*]] = load i32* @uj + // CHECK-NEXT: [[T2:%.*]] = load i32* @uk + // CHECK-NEXT: [[T3:%.*]] = add i32 [[T1]], [[T2]] + // CHECK-NEXT: store i32 [[T3]], i32* @ui + ui = uj + uk; + + // CHECK: [[T1:%.*]] = load i32* @j + // CHECK-NEXT: [[T2:%.*]] = load i32* @k + // CHECK-NEXT: [[T3:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 [[T2]]) + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T3]], 0 + // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T3]], 1 + // CHECK-NEXT: br i1 [[T5]] + // CHECK: call void @llvm.trap() + i = j + k; +} + +// CHECK: define void @test1() +void test1() { + extern void opaque(int); + opaque(i++); + + // CHECK: [[T1:%.*]] = load i32* @i + // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 + // CHECK-NEXT: br i1 [[T4]] + // CHECK: call void @llvm.trap() +} + +// CHECK: define void @test2() +void test2() { + extern void opaque(int); + opaque(++i); + + // CHECK: [[T1:%.*]] = load i32* @i + // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T1]], i32 1) + // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 0 + // CHECK-NEXT: [[T4:%.*]] = extractvalue { i32, i1 } [[T2]], 1 + // CHECK-NEXT: br i1 [[T4]] + // CHECK: call void @llvm.trap() +} diff --git a/clang/test/CodeGen/typedef-func.c b/clang/test/CodeGen/typedef-func.c new file mode 100644 index 0000000..1467e8b --- /dev/null +++ b/clang/test/CodeGen/typedef-func.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm < %s + +// PR2414 +struct mad_frame{}; +enum mad_flow {ont}; + +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/clang/test/CodeGen/typedef.c b/clang/test/CodeGen/typedef.c new file mode 100644 index 0000000..4af9d81 --- /dev/null +++ b/clang/test/CodeGen/typedef.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +typedef struct { int i; } Value; +typedef Value *PValue; + +int get_value(PValue v) { + return v->i; +} diff --git a/clang/test/CodeGen/types.c b/clang/test/CodeGen/types.c new file mode 100644 index 0000000..55b806c --- /dev/null +++ b/clang/test/CodeGen/types.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/uint128_t.c b/clang/test/CodeGen/uint128_t.c new file mode 100644 index 0000000..92cb5fa --- /dev/null +++ b/clang/test/CodeGen/uint128_t.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/unaligned-memcpy.c b/clang/test/CodeGen/unaligned-memcpy.c new file mode 100644 index 0000000..0373b56 --- /dev/null +++ b/clang/test/CodeGen/unaligned-memcpy.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +void bork() { + char Qux[33] = {0}; +} diff --git a/clang/test/CodeGen/union-align.c b/clang/test/CodeGen/union-align.c new file mode 100644 index 0000000..89a9456 --- /dev/null +++ b/clang/test/CodeGen/union-align.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | grep load | grep "4 x float" | not grep "align 4" +// RUN: %clang_cc1 -emit-llvm %s -o - | grep load | grep "4 x float" | grep "align 16" +// PR3432 +// rdar://6536377 + +typedef float __m128 __attribute__ ((__vector_size__ (16))); + +typedef union +{ + int i[4]; + float f[4]; + __m128 v; +} u_t; + +__m128 t(u_t *a) { + return a->v; +} diff --git a/clang/test/CodeGen/union-init.c b/clang/test/CodeGen/union-init.c new file mode 100644 index 0000000..60906b5 --- /dev/null +++ b/clang/test/CodeGen/union-init.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/union-init2.c b/clang/test/CodeGen/union-init2.c new file mode 100644 index 0000000..bf20696 --- /dev/null +++ b/clang/test/CodeGen/union-init2.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s + +// Make sure we generate something sane instead of a ptrtoint +// CHECK: bitcast ({ %union.x*, [4 x i8] }* @r to %union.x*), [4 x i8] undef +union x {long long b;union x* a;} r = {.a = &r}; + + +// CHECK: global { [3 x i8], [5 x i8] } { [3 x i8] zeroinitializer, [5 x i8] undef } +union z { + char a[3]; + long long b; +}; +union z y = {}; diff --git a/clang/test/CodeGen/union.c b/clang/test/CodeGen/union.c new file mode 100644 index 0000000..5c89e2d --- /dev/null +++ b/clang/test/CodeGen/union.c @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 %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;} + +// PR6164 +typedef union T0 { unsigned int : 0; } T0; +T0 t0; + +union { int large_bitfield: 31; char c } u2; diff --git a/clang/test/CodeGen/unreachable.c b/clang/test/CodeGen/unreachable.c new file mode 100644 index 0000000..5e9fa6a --- /dev/null +++ b/clang/test/CodeGen/unreachable.c @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -emit-llvm -o %t %s +// RUN: grep '@unreachable' %t | count 0 + +extern void abort() __attribute__((noreturn)); +extern int unreachable(); + +int f0() { + return 0; + unreachable(); +} + +int f1(int i) { + goto L0; + int a = unreachable(); + L0: + return 0; +} + +int f2(int i) { + goto L0; + unreachable(); + int a; + unreachable(); + L0: + a = i + 1; + return a; +} + +int f3(int i) { + if (i) { + return 0; + } else { + abort(); + } + unreachable(); + return 3; +} diff --git a/clang/test/CodeGen/unwind-attr.c b/clang/test/CodeGen/unwind-attr.c new file mode 100644 index 0000000..c588ca8 --- /dev/null +++ b/clang/test/CodeGen/unwind-attr.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fexceptions -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix NOEXC %s + +int opaque(); + +// CHECK: define [[INT:i.*]] @test0() { +// CHECK-NOEXC: define [[INT:i.*]] @test0() nounwind { +int test0(void) { + return opaque(); +} + +// <rdar://problem/8087431>: locally infer nounwind at -O0 +// CHECK: define [[INT:i.*]] @test1() nounwind { +// CHECK-NOEXC: define [[INT:i.*]] @test1() nounwind { +int test1(void) { + return 0; +} + +// <rdar://problem/8283071>: not for weak functions +// CHECK: define weak [[INT:i.*]] @test2() { +// CHECK-NOEXC: define weak [[INT:i.*]] @test2() nounwind { +__attribute__((weak)) int test2(void) { + return 0; +} diff --git a/clang/test/CodeGen/utf16-cfstrings.c b/clang/test/CodeGen/utf16-cfstrings.c new file mode 100644 index 0000000..d4f214b --- /dev/null +++ b/clang/test/CodeGen/utf16-cfstrings.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s +// <rdar://problem/10655949> + +// CHECK: @.str = internal unnamed_addr constant [9 x i16] [i16 252, i16 98, i16 101, i16 114, i16 104, i16 117, i16 110, i16 100, i16 0], align 2 + +#define CFSTR __builtin___CFStringMakeConstantString + +void foo() { + CFSTR("überhund"); +} diff --git a/clang/test/CodeGen/varargs.c b/clang/test/CodeGen/varargs.c new file mode 100644 index 0000000..b3dba24 --- /dev/null +++ b/clang/test/CodeGen/varargs.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s + + +// PR6433 - Don't crash on va_arg(typedef). +typedef double gdouble; +void focus_changed_cb () { + __builtin_va_list pa; + double mfloat; + mfloat = __builtin_va_arg((pa), gdouble); +} + diff --git a/clang/test/CodeGen/variable-array.c b/clang/test/CodeGen/variable-array.c new file mode 100644 index 0000000..80ca78d --- /dev/null +++ b/clang/test/CodeGen/variable-array.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -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/clang/test/CodeGen/vector.c b/clang/test/CodeGen/vector.c new file mode 100644 index 0000000..3fa5f14 --- /dev/null +++ b/clang/test/CodeGen/vector.c @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin9 -O1 -target-cpu pentium4 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s +typedef short __v4hi __attribute__ ((__vector_size__ (8))); + +void test1() { + __v4hi A = (__v4hi)0LL; +} + +__v4hi x = {1,2,3}; +__v4hi y = {1,2,3,4}; + +typedef int vty __attribute((vector_size(16))); +int test2() { vty b; return b[2LL]; } + +// PR4339 +typedef float vec4 __attribute__((vector_size(16))); + +void test3 ( vec4* a, char b, float c ) { + (*a)[b] = c; +} + + + +// Don't include mm_malloc.h, it's system specific. +#define __MM_MALLOC_H + +#include <mmintrin.h> + +int test4(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(); + + return result; +} + +#include <smmintrin.h> + +unsigned long test_epi8(__m128i x) { return _mm_extract_epi8(x, 4); } +// CHECK: @test_epi8 +// CHECK: extractelement <16 x i8> {{.*}}, i32 4 +// CHECK: zext i8 {{.*}} to i32 + +unsigned long test_epi16(__m128i x) { return _mm_extract_epi16(x, 3); } + +// CHECK: @test_epi16 +// CHECK: extractelement <8 x i16> {{.*}}, i32 3 +// CHECK: zext i16 {{.*}} to i32 diff --git a/clang/test/CodeGen/vfprintf.c b/clang/test/CodeGen/vfprintf.c new file mode 100644 index 0000000..7c583b5 --- /dev/null +++ b/clang/test/CodeGen/vfprintf.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm-only %s + +typedef struct _IO_FILE FILE; +int vfprintf(FILE*restrict,const char*restrict, __builtin_va_list); +void foo(__builtin_va_list ap) { + vfprintf(0, " ", ap); +} + diff --git a/clang/test/CodeGen/visibility.c b/clang/test/CodeGen/visibility.c new file mode 100644 index 0000000..fa4b599 --- /dev/null +++ b/clang/test/CodeGen/visibility.c @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility default -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility protected -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-PROTECTED +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN + +// CHECK-DEFAULT: @g_def = global i32 0 +// CHECK-DEFAULT: @g_com = common global i32 0 +// CHECK-DEFAULT: @g_ext = external global i32 +// CHECK-DEFAULT: @g_deferred = internal global +// CHECK-PROTECTED: @g_def = protected global i32 0 +// CHECK-PROTECTED: @g_com = common protected global i32 0 +// CHECK-PROTECTED: @g_ext = external global i32 +// CHECK-PROTECTED: @g_deferred = internal global +// CHECK-HIDDEN: @g_def = hidden global i32 0 +// CHECK-HIDDEN: @g_com = common hidden global i32 0 +// CHECK-HIDDEN: @g_ext = external global i32 +// CHECK-HIDDEN: @g_deferred = internal global +int g_com; +int g_def = 0; +extern int g_ext; +static char g_deferred[] = "hello"; + +// CHECK-DEFAULT: @test4 = hidden global i32 10 +// CHECK-PROTECTED: @test4 = hidden global i32 10 +// CHECK-HIDDEN: @test4 = hidden global i32 10 + +// CHECK-DEFAULT: define i32 @f_def() +// CHECK-DEFAULT: declare void @f_ext() +// CHECK-DEFAULT: define internal void @f_deferred() +// CHECK-PROTECTED: define protected i32 @f_def() +// CHECK-PROTECTED: declare void @f_ext() +// CHECK-PROTECTED: define internal void @f_deferred() +// CHECK-HIDDEN: define hidden i32 @f_def() +// CHECK-HIDDEN: declare void @f_ext() +// CHECK-HIDDEN: define internal void @f_deferred() + +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]; +} + +// PR8457 +// CHECK-DEFAULT: define void @test1( +// CHECK-PROTECTED: define void @test1( +// CHECK-HIDDEN: define void @test1( +struct Test1 { int field; }; +void __attribute__((visibility("default"))) test1(struct Test1 *v) { } + +// rdar://problem/8595231 +// CHECK-DEFAULT: define void @test2() +// CHECK-PROTECTED: define void @test2() +// CHECK-HIDDEN: define void @test2() +void test2(void); +void __attribute__((visibility("default"))) test2(void) {} + +// CHECK-DEFAULT: define hidden void @test3() +// CHECK-PROTECTED: define hidden void @test3() +// CHECK-HIDDEN: define hidden void @test3() +extern void test3(void); +__private_extern__ void test3(void) {} + +// Top of file. +extern int test4; +__private_extern__ int test4 = 10; diff --git a/clang/test/CodeGen/vla-2.c b/clang/test/CodeGen/vla-2.c new file mode 100644 index 0000000..0a74907 --- /dev/null +++ b/clang/test/CodeGen/vla-2.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=gnu99 %s -emit-llvm -o - | grep ".*alloca.*align 16" + +extern void bar(int[]); + +void foo(int a) +{ + int var[a] __attribute__((__aligned__(16))); + bar(var); + return; +} diff --git a/clang/test/CodeGen/vla-3.c b/clang/test/CodeGen/vla-3.c new file mode 100644 index 0000000..4927b46 --- /dev/null +++ b/clang/test/CodeGen/vla-3.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=gnu99 %s -emit-llvm -o - | grep ".*alloca.*align 16" + +void adr(char *); + +void vlaalign(int size) +{ + char __attribute__((aligned(16))) tmp[size+32]; + char tmp2[size+16]; + + adr(tmp); +} diff --git a/clang/test/CodeGen/vla-4.c b/clang/test/CodeGen/vla-4.c new file mode 100644 index 0000000..6e4ca98 --- /dev/null +++ b/clang/test/CodeGen/vla-4.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s + +int f(); +int h(); + +void t1() { + _Atomic(typeof((int (*)[f()]) h())) v; + // CHECK: [[N:%.*]] = alloca i32*, align 4 + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @h to i32 ()*)() +} + +void t2() { + typeof(typeof((int (*)[f()]) h())) v; + // CHECK: [[N:%.*]] = alloca i32*, align 4 + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @h to i32 ()*)() +} + +void t3(typeof((int (*)[f()]) h()) v) { + // CHECK: store i32* %v, i32** %{{[.0-9A-Za-z]+}}, align 4 + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() + // CHECK-NEXT: [[P:%.*]] = call i32 bitcast (i32 (...)* @h to i32 ()*)() +} diff --git a/clang/test/CodeGen/vla.c b/clang/test/CodeGen/vla.c new file mode 100644 index 0000000..9e62da5 --- /dev/null +++ b/clang/test/CodeGen/vla.c @@ -0,0 +1,144 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s + +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]; +} + +// rdar://8403108 +// CHECK: define void @f_8403108 +void f_8403108(unsigned x) { + // CHECK: call i8* @llvm.stacksave() + char s1[x]; + while (1) { + // CHECK: call i8* @llvm.stacksave() + char s2[x]; + if (1) + break; + // CHECK: call void @llvm.stackrestore(i8* + } + // CHECK: call void @llvm.stackrestore(i8* +} + +// pr7827 +void function(short width, int data[][width]) {} // expected-note {{passing argument to parameter 'data' here}} + +void test() { + int bork[4][13]; + // CHECK: call void @function(i16 signext 1, i32* null) + function(1, 0); + // CHECK: call void @function(i16 signext 1, i32* inttoptr + function(1, 0xbadbeef); // expected-warning {{incompatible integer to pointer conversion passing}} + // CHECK: call void @function(i16 signext 1, i32* {{.*}}) + function(1, bork); +} + +void function1(short width, int data[][width][width]) {} +void test1() { + int bork[4][13][15]; + // CHECK: call void @function1(i16 signext 1, i32* {{.*}}) + function1(1, bork); + // CHECK: call void @function(i16 signext 1, i32* {{.*}}) + function(1, bork[2]); +} + +// rdar://8476159 +static int GLOB; +int test2(int n) +{ + GLOB = 0; + char b[1][n+3]; /* Variable length array. */ + // CHECK: [[tmp_1:%.*]] = load i32* @GLOB, align 4 + // CHECK-NEXT: add nsw i32 [[tmp_1]], 1 + __typeof__(b[GLOB++]) c; + return GLOB; +} + +// http://llvm.org/PR8567 +// CHECK: define double @test_PR8567 +double test_PR8567(int n, double (*p)[n][5]) { + // CHECK: [[NV:%.*]] = alloca i32, align 4 + // CHECK-NEXT: [[PV:%.*]] = alloca [5 x double]*, align 4 + // CHECK-NEXT: store + // CHECK-NEXT: store + // CHECK-NEXT: [[N:%.*]] = load i32* [[NV]], align 4 + // CHECK-NEXT: [[P:%.*]] = load [5 x double]** [[PV]], align 4 + // CHECK-NEXT: [[T0:%.*]] = mul nsw i32 1, [[N]] + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [5 x double]* [[P]], i32 [[T0]] + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [5 x double]* [[T1]], i32 2 + // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [5 x double]* [[T2]], i32 0, i32 3 + // CHECK-NEXT: [[T4:%.*]] = load double* [[T3]] + // CHECK-NEXT: ret double [[T4]] + return p[1][2][3]; +} + +int test4(unsigned n, char (*p)[n][n+1][6]) { + // CHECK: define i32 @test4( + // CHECK: [[N:%.*]] = alloca i32, align 4 + // CHECK-NEXT: [[P:%.*]] = alloca [6 x i8]*, align 4 + // CHECK-NEXT: [[P2:%.*]] = alloca [6 x i8]*, align 4 + // CHECK-NEXT: store i32 + // CHECK-NEXT: store [6 x i8]* + + // VLA captures. + // CHECK-NEXT: [[DIM0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1 + + // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]** [[P]], align 4 + // CHECK-NEXT: [[T1:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2 + // CHECK-NEXT: [[T3:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] + // CHECK-NEXT: [[T4:%.*]] = mul nsw i32 [[T2]], [[T3]] + // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [6 x i8]* [[T0]], i32 [[T4]] + // CHECK-NEXT: [[T6:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[T7:%.*]] = udiv i32 [[T6]], 4 + // CHECK-NEXT: [[T8:%.*]] = sub i32 0, [[T7]] + // CHECK-NEXT: [[T9:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] + // CHECK-NEXT: [[T10:%.*]] = mul nsw i32 [[T8]], [[T9]] + // CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds [6 x i8]* [[T5]], i32 [[T10]] + // CHECK-NEXT: store [6 x i8]* [[T11]], [6 x i8]** [[P2]], align 4 + __typeof(p) p2 = (p + n/2) - n/4; + + // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]** [[P2]], align 4 + // CHECK-NEXT: [[T1:%.*]] = load [6 x i8]** [[P]], align 4 + // CHECK-NEXT: [[T2:%.*]] = ptrtoint [6 x i8]* [[T0]] to i32 + // CHECK-NEXT: [[T3:%.*]] = ptrtoint [6 x i8]* [[T1]] to i32 + // CHECK-NEXT: [[T4:%.*]] = sub i32 [[T2]], [[T3]] + // CHECK-NEXT: [[T5:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] + // CHECK-NEXT: [[T6:%.*]] = mul nuw i32 6, [[T5]] + // CHECK-NEXT: [[T7:%.*]] = sdiv exact i32 [[T4]], [[T6]] + // CHECK-NEXT: ret i32 [[T7]] + return p2 - p; +} diff --git a/clang/test/CodeGen/vld_dup.c b/clang/test/CodeGen/vld_dup.c new file mode 100644 index 0000000..e1d63cc --- /dev/null +++ b/clang/test/CodeGen/vld_dup.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple armv7a-linux-gnueabi \ +// RUN: -target-cpu cortex-a8 \ +// RUN: -emit-llvm -O0 -o - %s | FileCheck %s +#include <arm_neon.h> +int main(){ + int32_t v0[3]; + int32x2x3_t v1; + int32_t v2[4]; + int32x2x4_t v3; + int64x1x3_t v4; + int64x1x4_t v5; + int64_t v6[3]; + int64_t v7[4]; + + v1 = vld3_dup_s32(v0); +// CHECK: [[T168:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32> } @llvm.arm.neon.vld3lane.v2i32(i8* {{.*}}, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 {{[0-9]+}}, i32 {{[0-9]+}}) +// CHECK-NEXT: [[T169:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T168]], 0 +// CHECK-NEXT: [[T170:%.*]] = shufflevector <2 x i32> [[T169]], <2 x i32> [[T169]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T171:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T168]], <2 x i32> [[T170]], 0 +// CHECK-NEXT: [[T172:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T171]], 1 +// CHECK-NEXT: [[T173:%.*]] = shufflevector <2 x i32> [[T172]], <2 x i32> [[T172]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T174:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T171]], <2 x i32> [[T173]], 1 +// CHECK-NEXT: [[T175:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T174]], 2 +// CHECK-NEXT: [[T176:%.*]] = shufflevector <2 x i32> [[T175]], <2 x i32> [[T175]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T177:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T174]], <2 x i32> [[T176]], 2 + + v3 = vld4_dup_s32(v2); +// CHECK: [[T178:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } @llvm.arm.neon.vld4lane.v2i32(i8* {{.*}}, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 {{[0-9]+}}, i32 {{[0-9]+}}) +// CHECK-NEXT: [[T179:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T178]], 0 +// CHECK-NEXT: [[T180:%.*]] = shufflevector <2 x i32> [[T179]], <2 x i32> [[T179]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T181:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T178]], <2 x i32> [[T180]], 0 +// CHECK-NEXT: [[T182:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T181]], 1 +// CHECK-NEXT: [[T183:%.*]] = shufflevector <2 x i32> [[T182]], <2 x i32> [[T182]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T184:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T181]], <2 x i32> [[T183]], 1 +// CHECK-NEXT: [[T185:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T184]], 2 +// CHECK-NEXT: [[T186:%.*]] = shufflevector <2 x i32> [[T185]], <2 x i32> [[T185]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T187:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T184]], <2 x i32> [[T186]], 2 +// CHECK-NEXT: [[T188:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T187]], 3 +// CHECK-NEXT: [[T189:%.*]] = shufflevector <2 x i32> [[T188]], <2 x i32> [[T188]], <2 x i32> zeroinitializer +// CHECK-NEXT: [[T190:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T187]], <2 x i32> [[T189]], 3 + + v4 = vld3_dup_s64(v6); +// CHECK: {{%.*}} = call { <1 x i64>, <1 x i64>, <1 x i64> } @llvm.arm.neon.vld3.v1i64(i8* {{.*}}, i32 {{[0-9]+}}) + + v5 = vld4_dup_s64(v7); +// CHECK: {{%.*}} = call { <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64> } @llvm.arm.neon.vld4.v1i64(i8* {{.*}}, i32 {{[0-9]+}}) + + return 0; +} diff --git a/clang/test/CodeGen/volatile-1.c b/clang/test/CodeGen/volatile-1.c new file mode 100644 index 0000000..6551159 --- /dev/null +++ b/clang/test/CodeGen/volatile-1.c @@ -0,0 +1,315 @@ +// RUN: %clang_cc1 -Wno-return-type -Wno-unused-value -emit-llvm %s -o - | FileCheck %s + +// CHECK: @i = common global [[INT:i[0-9]+]] 0 +volatile int i, j, k; +volatile int ar[5]; +volatile char c; +// CHECK: @ci = common global [[CINT:.*]] zeroinitializer +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; +int printf(const char *, ...); + + +// Note that these test results are very much specific to C! +// Assignments in C++ yield l-values, not r-values, and the situations +// that do implicit lvalue-to-rvalue conversion are substantially +// reduced. + +// CHECK: define void @test() +void test() { + // CHECK: load volatile [[INT]]* @i + i; + // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: sitofp [[INT]] + (float)(ci); + // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + (void)ci; + // CHECK-NEXT: bitcast + // CHECK-NEXT: memcpy + (void)a; + // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + (void)(ci=ci); + // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* @j + // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* @i + (void)(i=j); + // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // Not sure why they're ordered this way. + // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] + // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] + // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + ci+=ci; + + // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] + // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] + // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // These additions can be elided + // CHECK-NEXT: add [[INT]] [[R]], [[R2]] + // CHECK-NEXT: add [[INT]] [[I]], [[I2]] + (ci += ci) + ci; + // CHECK-NEXT: call void asm + asm("nop"); + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: add nsw [[INT]] + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: add nsw [[INT]] + (i += j) + k; + // CHECK-NEXT: call void asm + asm("nop"); + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: add nsw [[INT]] + // CHECK-NEXT: store volatile + // CHECK-NEXT: add nsw [[INT]] + (i += j) + 1; + // CHECK-NEXT: call void asm + asm("nop"); + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: add [[INT]] + // CHECK-NEXT: add [[INT]] + ci+ci; + + // CHECK-NEXT: load volatile + __real i; + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + +ci; + // CHECK-NEXT: call void asm + asm("nop"); + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + (void)(i=i); + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: sitofp + (float)(i=i); + // CHECK-NEXT: load volatile + (void)i; + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + i=i; + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + i=i=i; +#ifndef __cplusplus + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + (void)__builtin_choose_expr(0, i=i, j=j); +#endif + // CHECK-NEXT: load volatile + // CHECK-NEXT: icmp + // CHECK-NEXT: br i1 + // CHECK: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: br label + // CHECK: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: br label + k ? (i=i) : (j=j); + // CHECK: phi + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + (void)(i,(i=i)); + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + i=i,i; + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + (i=j,k=j); + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + (i=j,k); + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + (i,j); + // CHECK-NEXT: load volatile + // CHECK-NEXT: trunc + // CHECK-NEXT: store volatile + // CHECK-NEXT: sext + // CHECK-NEXT: store volatile + i=c=k; + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: add nsw [[INT]] + // CHECK-NEXT: store volatile + i+=k; + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + ci; +#ifndef __cplusplus + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + (int)ci; + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: icmp ne + // CHECK-NEXT: icmp ne + // CHECK-NEXT: or i1 + (_Bool)ci; +#endif + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + ci=ci; + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + ci=ci=ci; + // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + __imag ci = __imag ci = __imag ci; + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + __real (i = j); + // CHECK-NEXT: load volatile + __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. + // CHECK-NEXT: call void @llvm.memcpy{{.*}}, i1 true + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @llvm.memcpy{{.*}}, i1 true + ((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. + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + __imag (i = j); + +#ifndef __cplusplus + // A use of the real part + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: sitofp + (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. + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + (int)(ci=ci); +#endif + + // A use. + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: sitofp + (float)(i=i); + // A use. gcc treats this as not a use, that's probably a bug due to tree + // folding ignoring volatile. + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + (int)(i=i); + + // A use. + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: sub + -(i=j); + // A use. gcc treats this a not a use, that's probably a bug due to tree + // folding ignoring volatile. + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + +(i=k); + + // A use. gcc treats this a not a use, that's probably a bug due to tree + // folding ignoring volatile. + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + __real (ci=ci); + + // A use. + // CHECK-NEXT: load volatile + // CHECK-NEXT: add + i + 0; + // A use. + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: add + (i=j) + i; + // A use. gcc treats this as not a use, that's probably a bug due to tree + // folding ignoring volatile. + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: add + (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 +} + +extern volatile enum X x; +// CHECK: define void @test1() +void test1() { + extern void test1_helper(void); + test1_helper(); + // CHECK: call void @test1_helper() + // CHECK-NEXT: ret void + x; + (void) x; + return x; +} diff --git a/clang/test/CodeGen/volatile-2.c b/clang/test/CodeGen/volatile-2.c new file mode 100644 index 0000000..3d342de --- /dev/null +++ b/clang/test/CodeGen/volatile-2.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +void test0() { + // CHECK: define void @test0() + // CHECK: [[F:%.*]] = alloca float + // CHECK-NEXT: [[REAL:%.*]] = load volatile float* getelementptr inbounds ({ float, float }* @test0_v, i32 0, i32 0) + // CHECK-NEXT: load volatile float* getelementptr inbounds ({{.*}} @test0_v, i32 0, i32 1) + // CHECK-NEXT: store float [[REAL]], float* [[F]], align 4 + // CHECK-NEXT: ret void + extern volatile _Complex float test0_v; + float f = (float) test0_v; +} + +void test1() { + // CHECK: define void @test1() + // CHECK: [[REAL:%.*]] = load volatile float* getelementptr inbounds ({{.*}} @test1_v, i32 0, i32 0) + // CHECK-NEXT: [[IMAG:%.*]] = load volatile float* getelementptr inbounds ({{.*}} @test1_v, i32 0, i32 1) + // CHECK-NEXT: store volatile float [[REAL]], float* getelementptr inbounds ({{.*}} @test1_v, i32 0, i32 0) + // CHECK-NEXT: store volatile float [[IMAG]], float* getelementptr inbounds ({{.*}} @test1_v, i32 0, i32 1) + // CHECK-NEXT: ret void + extern volatile _Complex float test1_v; + test1_v = test1_v; +} diff --git a/clang/test/CodeGen/volatile.c b/clang/test/CodeGen/volatile.c new file mode 100644 index 0000000..1a996de --- /dev/null +++ b/clang/test/CodeGen/volatile.c @@ -0,0 +1,100 @@ +// RUN: %clang_cc1 -emit-llvm < %s -o %t +// RUN: grep volatile %t | count 28 +// RUN: grep memcpy %t | count 7 + +// The number 28 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); + +typedef volatile int volatile_int; +volatile_int vtS; + +int 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; // Note: not volatile + i=vtS; + + + // 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; + vtS=i; + + // other ops: + ++S; + ++vS; + i+=S; + i+=vS; + ++vtS; + (void)vF2; + vF2 = vF2; + vF2 = vF2 = vF2; + vF2 = (vF2, vF2); +} diff --git a/clang/test/CodeGen/wchar-const.c b/clang/test/CodeGen/wchar-const.c new file mode 100644 index 0000000..a9e7e52 --- /dev/null +++ b/clang/test/CodeGen/wchar-const.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple i386-pc-win32 | FileCheck %s --check-prefix=WIN +// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-apple-darwin | FileCheck %s --check-prefix=DAR +// This should pass for any endianness combination of host and target. + +// This bit is taken from Sema/wchar.c so we can avoid the wchar.h include. +typedef __WCHAR_TYPE__ wchar_t; +#if defined(_WIN32) || defined(_M_IX86) || defined(__CYGWIN__) \ + || defined(_M_X64) || defined(SHORT_WCHAR) + #define WCHAR_T_TYPE unsigned short +#elif defined(__sun) || defined(__AuroraUX__) + #define WCHAR_T_TYPE long +#else /* Solaris or AuroraUX. */ + #define WCHAR_T_TYPE int +#endif + + +// CHECK-DAR: private unnamed_addr constant [18 x i32] [i32 84, +// CHECK-WIN: private unnamed_addr constant [18 x i16] [i16 84, +extern void foo(const wchar_t* p); +int main (int argc, const char * argv[]) +{ + foo(L"This is some text"); + return 0; +} diff --git a/clang/test/CodeGen/weak-global.c b/clang/test/CodeGen/weak-global.c new file mode 100644 index 0000000..f972cea --- /dev/null +++ b/clang/test/CodeGen/weak-global.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-llvm < %s | grep common + +int i; diff --git a/clang/test/CodeGen/weak-incomplete.c b/clang/test/CodeGen/weak-incomplete.c new file mode 100644 index 0000000..af91ae7 --- /dev/null +++ b/clang/test/CodeGen/weak-incomplete.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm < %s | grep 'extern_weak' | count 1 + +struct S; +void __attribute__((weak)) foo1(struct S); +void (*foo2)(struct S) = foo1; diff --git a/clang/test/CodeGen/weak_constant.c b/clang/test/CodeGen/weak_constant.c new file mode 100644 index 0000000..726d2ef --- /dev/null +++ b/clang/test/CodeGen/weak_constant.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -w -emit-llvm %s -O1 -o - | FileCheck %s +// Check for bug compatibility with gcc. + +const int x __attribute((weak)) = 123; + +int* f(void) { + return &x; +} + +int g(void) { + // CHECK: ret i32 123 + return *f(); +} diff --git a/clang/test/CodeGen/whilestmt.c b/clang/test/CodeGen/whilestmt.c new file mode 100644 index 0000000..3973b28 --- /dev/null +++ b/clang/test/CodeGen/whilestmt.c @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 %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/clang/test/CodeGen/writable-strings.c b/clang/test/CodeGen/writable-strings.c new file mode 100644 index 0000000..693fa5e --- /dev/null +++ b/clang/test/CodeGen/writable-strings.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm -o - -fwritable-strings %s + +int main() { + char *str = "abc"; + str[0] = '1'; + printf("%s", str); +} + diff --git a/clang/test/CodeGen/x86.c b/clang/test/CodeGen/x86.c new file mode 100644 index 0000000..e97d537 --- /dev/null +++ b/clang/test/CodeGen/x86.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %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)); +} diff --git a/clang/test/CodeGen/x86_32-arguments-darwin.c b/clang/test/CodeGen/x86_32-arguments-darwin.c new file mode 100644 index 0000000..0ac18b7 --- /dev/null +++ b/clang/test/CodeGen/x86_32-arguments-darwin.c @@ -0,0 +1,326 @@ +// RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -target-cpu yonah -emit-llvm -o - %s | FileCheck %s + +// CHECK: define signext i8 @f0() +char f0(void) { + return 0; +} + +// CHECK: define signext i16 @f1() +short f1(void) { + return 0; +} + +// CHECK: define i32 @f2() +int f2(void) { + return 0; +} + +// CHECK: define float @f3() +float f3(void) { + return 0; +} + +// CHECK: define double @f4() +double f4(void) { + return 0; +} + +// CHECK: define x86_fp80 @f5() +long double f5(void) { + return 0; +} + +// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4) +void f6(char a0, short a1, int a2, long long a3, void *a4) {} + +// CHECK: define void @f7(i32 %a0) +typedef enum { A, B, C } e7; +void f7(e7 a0) {} + +// CHECK: define i64 @f8_1() +// CHECK: define void @f8_2(i32 %a0.0, i32 %a0.1) +struct s8 { + int a; + int b; +}; +struct s8 f8_1(void) { while (1) {} } +void f8_2(struct s8 a0) {} + +// This should be passed just as s8. + +// CHECK: define i64 @f9_1() + +// FIXME: llvm-gcc expands this, this may have some value for the +// backend in terms of optimization but doesn't change the ABI. +// CHECK: define void @f9_2(%struct.s9* byval align 4 %a0) +struct s9 { + int a : 17; + int b; +}; +struct s9 f9_1(void) { while (1) {} } +void f9_2(struct s9 a0) {} + +// Return of small structures and unions + +// CHECK: float @f10() +struct s10 { + union { }; + float f; +} f10(void) { while (1) {} } + +// Small vectors and 1 x {i64,double} are returned in registers + +// CHECK: i32 @f11() +// CHECK: void @f12(<2 x i32>* noalias sret %agg.result) +// CHECK: i64 @f13() +// CHECK: i64 @f14() +// CHECK: <2 x i64> @f15() +// CHECK: <2 x i64> @f16() +typedef short T11 __attribute__ ((vector_size (4))); +T11 f11(void) { while (1) {} } +typedef int T12 __attribute__ ((vector_size (8))); +T12 f12(void) { while (1) {} } +typedef long long T13 __attribute__ ((vector_size (8))); +T13 f13(void) { while (1) {} } +typedef double T14 __attribute__ ((vector_size (8))); +T14 f14(void) { while (1) {} } +typedef long long T15 __attribute__ ((vector_size (16))); +T15 f15(void) { while (1) {} } +typedef double T16 __attribute__ ((vector_size (16))); +T16 f16(void) { while (1) {} } + +// And when the single element in a struct (but not for 64 and +// 128-bits). + +// CHECK: i32 @f17() +// CHECK: void @f18(%{{.*}}* noalias sret %agg.result) +// CHECK: void @f19(%{{.*}}* noalias sret %agg.result) +// CHECK: void @f20(%{{.*}}* noalias sret %agg.result) +// CHECK: void @f21(%{{.*}}* noalias sret %agg.result) +// CHECK: void @f22(%{{.*}}* noalias sret %agg.result) +struct { T11 a; } f17(void) { while (1) {} } +struct { T12 a; } f18(void) { while (1) {} } +struct { T13 a; } f19(void) { while (1) {} } +struct { T14 a; } f20(void) { while (1) {} } +struct { T15 a; } f21(void) { while (1) {} } +struct { T16 a; } f22(void) { while (1) {} } + +// Single element structures are handled specially + +// CHECK: float @f23() +// CHECK: float @f24() +// CHECK: float @f25() +struct { float a; } f23(void) { while (1) {} } +struct { float a[1]; } f24(void) { while (1) {} } +struct { struct {} a; struct { float a[1]; } b; } f25(void) { while (1) {} } + +// Small structures are handled recursively +// CHECK: i32 @f26() +// CHECK: void @f27(%struct.s27* noalias sret %agg.result) +struct s26 { struct { char a, b; } a; struct { char a, b; } b; } f26(void) { while (1) {} } +struct s27 { struct { char a, b, c; } a; struct { char a; } b; } f27(void) { while (1) {} } + +// CHECK: void @f28(%struct.s28* noalias sret %agg.result) +struct s28 { int a; int b[]; } f28(void) { while (1) {} } + +// CHECK: define i16 @f29() +struct s29 { struct { } a[1]; char b; char c; } f29(void) { while (1) {} } + +// CHECK: define i16 @f30() +struct s30 { char a; char b : 4; } f30(void) { while (1) {} } + +// CHECK: define float @f31() +struct s31 { char : 0; float b; char : 0; } f31(void) { while (1) {} } + +// CHECK: define i32 @f32() +struct s32 { char a; unsigned : 0; } f32(void) { while (1) {} } + +// CHECK: define float @f33() +struct s33 { float a; long long : 0; } f33(void) { while (1) {} } + +// CHECK: define float @f34() +struct s34 { struct { int : 0; } a; float b; } f34(void) { while (1) {} } + +// CHECK: define i16 @f35() +struct s35 { struct { int : 0; } a; char b; char c; } f35(void) { while (1) {} } + +// CHECK: define i16 @f36() +struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) { while (1) {} } + +// CHECK: define float @f37() +struct s37 { float c[1][1]; } f37(void) { while (1) {} } + +// CHECK: define void @f38(%struct.s38* noalias sret %agg.result) +struct s38 { char a[3]; short b; } f38(void) { while (1) {} } + +// CHECK: define void @f39(%struct.s39* byval align 16 %x) +typedef int v39 __attribute((vector_size(16))); +struct s39 { v39 x; }; +void f39(struct s39 x) {} + +// <rdar://problem/7247671> +// CHECK: define i32 @f40() +enum e40 { ec0 = 0 }; +enum e40 f40(void) { } + +// CHECK: define void ()* @f41() +typedef void (^vvbp)(void); +vvbp f41(void) { } + +// CHECK: define i32 @f42() +struct s42 { enum e40 f0; } f42(void) { } + +// CHECK: define i64 @f43() +struct s43 { enum e40 f0; int f1; } f43(void) { } + +// CHECK: define void ()* @f44() +struct s44 { vvbp f0; } f44(void) { } + +// CHECK: define i64 @f45() +struct s45 { vvbp f0; int f1; } f45(void) { } + +// CHECK: define void @f46(i32 %a0) +void f46(enum e40 a0) { } + +// CHECK: define void @f47(void ()* %a1) +void f47(vvbp a1) { } + +// CHECK: define void @f48(i32 %a0.0) +struct s48 { enum e40 f0; }; +void f48(struct s48 a0) { } + +// CHECK: define void @f49(i32 %a0.0, i32 %a0.1) +struct s49 { enum e40 f0; int f1; }; +void f49(struct s49 a0) { } + +// CHECK: define void @f50(void ()* %a0.0) +struct s50 { vvbp f0; }; +void f50(struct s50 a0) { } + +// CHECK: define void @f51(void ()* %a0.0, i32 %a0.1) +struct s51 { vvbp f0; int f1; }; +void f51(struct s51 a0) { } + +// CHECK: define void @f52(%struct.s52* byval align 4) +struct s52 { + long double a; +}; +void f52(struct s52 x) {} + +// CHECK: define void @f53(%struct.s53* byval align 4) +struct __attribute__((aligned(32))) s53 { + int x; + int y; +}; +void f53(struct s53 x) {} + +typedef unsigned short v2i16 __attribute__((__vector_size__(4))); + +// CHECK: define i32 @f54(i32 %arg.coerce) +// rdar://8359483 +v2i16 f54(v2i16 arg) { return arg+arg; } + + +typedef int v4i32 __attribute__((__vector_size__(16))); + +// CHECK: define <2 x i64> @f55(<4 x i32> %arg) +// PR8029 +v4i32 f55(v4i32 arg) { return arg+arg; } + +// CHECK: define void @f56( +// CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1, +// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4, +// CHECK: i64 %a4.coerce, %struct.s56_2* byval align 4, +// CHECK: <4 x i32> %a6, %struct.s56_3* byval align 16 %a7, +// CHECK: <2 x double> %a8, %struct.s56_4* byval align 16 %a9, +// CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4, +// CHECK: <4 x double> %a12, %struct.s56_6* byval align 4) + +// CHECK: call void (i32, ...)* @f56_0(i32 1, +// CHECK: i32 %{{[^ ]*}}, %struct.s56_0* byval align 4 %{{[^ ]*}}, +// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, +// CHECK: i64 %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}}, +// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 16 %{{[^ ]*}}, +// CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 16 %{{[^ ]*}}, +// CHECK: <8 x i32> {{[^ ]*}}, %struct.s56_5* byval align 4 %{{[^ ]*}}, +// CHECK: <4 x double> {{[^ ]*}}, %struct.s56_6* byval align 4 %{{[^ ]*}}) +// CHECK: } +// +// <rdar://problem/7964854> [i386] clang misaligns long double in structures +// when passed byval +// <rdar://problem/8431367> clang misaligns parameters on stack +typedef int __attribute__((vector_size (8))) t56_v2i; +typedef double __attribute__((vector_size (8))) t56_v1d; +typedef int __attribute__((vector_size (16))) t56_v4i; +typedef double __attribute__((vector_size (16))) t56_v2d; +typedef int __attribute__((vector_size (32))) t56_v8i; +typedef double __attribute__((vector_size (32))) t56_v4d; + +struct s56_0 { char a; }; +struct s56_1 { t56_v2i a; }; +struct s56_2 { t56_v1d a; }; +struct s56_3 { t56_v4i a; }; +struct s56_4 { t56_v2d a; }; +struct s56_5 { t56_v8i a; }; +struct s56_6 { t56_v4d a; }; + +void f56(char a0, struct s56_0 a1, + t56_v2i a2, struct s56_1 a3, + t56_v1d a4, struct s56_2 a5, + t56_v4i a6, struct s56_3 a7, + t56_v2d a8, struct s56_4 a9, + t56_v8i a10, struct s56_5 a11, + t56_v4d a12, struct s56_6 a13) { + extern void f56_0(int x, ...); + f56_0(1, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13); +} + +// CHECK: define void @f57(i32 %x.0, i32 %x.1) +// CHECK: call void @f57( +struct s57 { _Complex int x; }; +void f57(struct s57 x) {} void f57a(void) { f57((struct s57){1}); } + +// CHECK: define void @f58() +union u58 {}; +void f58(union u58 x) {} + +// CHECK: define i64 @f59() +struct s59 { float x __attribute((aligned(8))); }; +struct s59 f59() { while (1) {} } + +// CHECK: define void @f60(%struct.s60* byval align 4, i32 %y) +struct s60 { int x __attribute((aligned(8))); }; +void f60(struct s60 x, int y) {} + +// CHECK: define void @f61(i32 %x, %struct.s61* byval align 16 %y) +typedef int T61 __attribute((vector_size(16))); +struct s61 { T61 x; int y; }; +void f61(int x, struct s61 y) {} + +// CHECK: define void @f62(i32 %x, %struct.s62* byval align 4) +typedef int T62 __attribute((vector_size(16))); +struct s62 { T62 x; int y; } __attribute((packed, aligned(8))); +void f62(int x, struct s62 y) {} + +// CHECK: define i32 @f63 +// CHECK: ptrtoint +// CHECK: and {{.*}}, -16 +// CHECK: inttoptr +typedef int T63 __attribute((vector_size(16))); +struct s63 { T63 x; int y; }; +int f63(int i, ...) { + __builtin_va_list ap; + __builtin_va_start(ap, i); + struct s63 s = __builtin_va_arg(ap, struct s63); + __builtin_va_end(ap); + return s.y; +} + +// CHECK: define void @f64(%struct.s64* byval align 4 %x) +struct s64 { signed char a[0]; signed char b[]; }; +void f64(struct s64 x) {} + +// CHECK: define float @f65() +struct s65 { signed char a[0]; float b; }; +struct s65 f65() { return (struct s65){{},2}; } diff --git a/clang/test/CodeGen/x86_32-arguments-linux.c b/clang/test/CodeGen/x86_32-arguments-linux.c new file mode 100644 index 0000000..81dcaf6 --- /dev/null +++ b/clang/test/CodeGen/x86_32-arguments-linux.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -w -fblocks -triple i386-pc-linux-gnu -target-cpu pentium4 -emit-llvm -o %t %s +// RUN: FileCheck < %t %s + +// CHECK: define void @f56( +// CHECK: i8 signext %a0, %struct.s56_0* byval align 4 %a1, +// CHECK: x86_mmx %a2.coerce, %struct.s56_1* byval align 4, +// CHECK: <1 x double> %a4, %struct.s56_2* byval align 4, +// CHECK: <4 x i32> %a6, %struct.s56_3* byval align 4, +// CHECK: <2 x double> %a8, %struct.s56_4* byval align 4, +// CHECK: <8 x i32> %a10, %struct.s56_5* byval align 4, +// CHECK: <4 x double> %a12, %struct.s56_6* byval align 4) + +// CHECK: call void (i32, ...)* @f56_0(i32 1, +// CHECK: i32 %{{.*}}, %struct.s56_0* byval align 4 %{{[^ ]*}}, +// CHECK: x86_mmx %{{[^ ]*}}, %struct.s56_1* byval align 4 %{{[^ ]*}}, +// CHECK: <1 x double> %{{[^ ]*}}, %struct.s56_2* byval align 4 %{{[^ ]*}}, +// CHECK: <4 x i32> %{{[^ ]*}}, %struct.s56_3* byval align 4 %{{[^ ]*}}, +// CHECK: <2 x double> %{{[^ ]*}}, %struct.s56_4* byval align 4 %{{[^ ]*}}, +// CHECK: <8 x i32> %{{[^ ]*}}, %struct.s56_5* byval align 4 %{{[^ ]*}}, +// CHECK: <4 x double> %{{[^ ]*}}, %struct.s56_6* byval align 4 %{{[^ ]*}}) +// CHECK: } +// +// <rdar://problem/7964854> [i386] clang misaligns long double in structures +// when passed byval +// <rdar://problem/8431367> clang misaligns parameters on stack +typedef int __attribute__((vector_size (8))) t56_v2i; +typedef double __attribute__((vector_size (8))) t56_v1d; +typedef int __attribute__((vector_size (16))) t56_v4i; +typedef double __attribute__((vector_size (16))) t56_v2d; +typedef int __attribute__((vector_size (32))) t56_v8i; +typedef double __attribute__((vector_size (32))) t56_v4d; + +struct s56_0 { char a; }; +struct s56_1 { t56_v2i a; }; +struct s56_2 { t56_v1d a; }; +struct s56_3 { t56_v4i a; }; +struct s56_4 { t56_v2d a; }; +struct s56_5 { t56_v8i a; }; +struct s56_6 { t56_v4d a; }; + +void f56(char a0, struct s56_0 a1, + t56_v2i a2, struct s56_1 a3, + t56_v1d a4, struct s56_2 a5, + t56_v4i a6, struct s56_3 a7, + t56_v2d a8, struct s56_4 a9, + t56_v8i a10, struct s56_5 a11, + t56_v4d a12, struct s56_6 a13) { + extern void f56_0(int x, ...); + f56_0(1, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10, a11, a12, a13); +} diff --git a/clang/test/CodeGen/x86_32-arguments-nommx.c b/clang/test/CodeGen/x86_32-arguments-nommx.c new file mode 100644 index 0000000..40362f7 --- /dev/null +++ b/clang/test/CodeGen/x86_32-arguments-nommx.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -target-feature -mmx -target-feature +sse2 -triple i686-pc-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// no-mmx should put mmx into memory +typedef int __attribute__((vector_size (8))) i32v2; +int a(i32v2 x) { return x[0]; } +// CHECK: define i32 @a(i64 %x.coerce) + +// but SSE2 vectors should still go into an SSE2 register +typedef int __attribute__((vector_size (16))) i32v4; +int b(i32v4 x) { return x[0]; } +// CHECK: define i32 @b(<4 x i32> %x) diff --git a/clang/test/CodeGen/x86_32-arguments-realign.c b/clang/test/CodeGen/x86_32-arguments-realign.c new file mode 100644 index 0000000..b08862e --- /dev/null +++ b/clang/test/CodeGen/x86_32-arguments-realign.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s +// RUN: FileCheck < %t %s + +// CHECK: define void @f0(%struct.s0* byval align 4) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 16, i32 4, i1 false) +// CHECK: } +struct s0 { long double a; }; +void f0(struct s0 a0) { + extern long double f0_g0; + f0_g0 = a0.a; +} diff --git a/clang/test/CodeGen/x86_32-arguments-win32.c b/clang/test/CodeGen/x86_32-arguments-win32.c new file mode 100644 index 0000000..f18bb30 --- /dev/null +++ b/clang/test/CodeGen/x86_32-arguments-win32.c @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -w -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s + +// CHECK: define i64 @f1_1() +// CHECK: define void @f1_2(i32 %a0.0, i32 %a0.1) +struct s1 { + int a; + int b; +}; +struct s1 f1_1(void) { while (1) {} } +void f1_2(struct s1 a0) {} + +// CHECK: define i32 @f2_1() +struct s2 { + short a; + short b; +}; +struct s2 f2_1(void) { while (1) {} } + +// CHECK: define i16 @f3_1() +struct s3 { + char a; + char b; +}; +struct s3 f3_1(void) { while (1) {} } + +// CHECK: define i8 @f4_1() +struct s4 { + char a:4; + char b:4; +}; +struct s4 f4_1(void) { while (1) {} } + +// CHECK: define i64 @f5_1() +// CHECK: define void @f5_2(double %a0.0) +struct s5 { + double a; +}; +struct s5 f5_1(void) { while (1) {} } +void f5_2(struct s5 a0) {} + +// CHECK: define i32 @f6_1() +// CHECK: define void @f6_2(float %a0.0) +struct s6 { + float a; +}; +struct s6 f6_1(void) { while (1) {} } +void f6_2(struct s6 a0) {} + diff --git a/clang/test/CodeGen/x86_64-arguments-darwin.c b/clang/test/CodeGen/x86_64-arguments-darwin.c new file mode 100644 index 0000000..2f804e6 --- /dev/null +++ b/clang/test/CodeGen/x86_64-arguments-darwin.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s| FileCheck %s + +// rdar://9122143 +// CHECK: declare void @func(i64, double) +typedef struct _str { + union { + long double a; + long c; + }; +} str; + +void func(str s); +str ss; +void f9122143() +{ + func(ss); +} diff --git a/clang/test/CodeGen/x86_64-arguments.c b/clang/test/CodeGen/x86_64-arguments.c new file mode 100644 index 0000000..f73e1f0 --- /dev/null +++ b/clang/test/CodeGen/x86_64-arguments.c @@ -0,0 +1,356 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s| FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s -check-prefix=AVX +#include <stdarg.h> + +// CHECK: define signext i8 @f0() +char f0(void) { + return 0; +} + +// CHECK: define signext i16 @f1() +short f1(void) { + return 0; +} + +// CHECK: define i32 @f2() +int f2(void) { + return 0; +} + +// CHECK: define float @f3() +float f3(void) { + return 0; +} + +// CHECK: define double @f4() +double f4(void) { + return 0; +} + +// CHECK: define x86_fp80 @f5() +long double f5(void) { + return 0; +} + +// CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4) +void f6(char a0, short a1, int a2, long long a3, void *a4) { +} + +// CHECK: define void @f7(i32 %a0) +typedef enum { A, B, C } e7; +void f7(e7 a0) { +} + +// Test merging/passing of upper eightbyte with X87 class. +// +// CHECK: define void @f8_1(%union.u8* noalias sret %agg.result) +// CHECK: define void @f8_2(%union.u8* byval align 16 %a0) +union u8 { + long double a; + int b; +}; +union u8 f8_1() { while (1) {} } +void f8_2(union u8 a0) {} + +// CHECK: define i64 @f9() +struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} } + +// CHECK: define void @f10(i64 %a0.coerce) +struct s10 { int a; int b; int : 0; }; +void f10(struct s10 a0) {} + +// CHECK: define void @f11(%union.anon* noalias sret %agg.result) +union { long double a; float b; } f11() { while (1) {} } + +// CHECK: define i32 @f12_0() +// CHECK: define void @f12_1(i32 %a0.coerce) +struct s12 { int a __attribute__((aligned(16))); }; +struct s12 f12_0(void) { while (1) {} } +void f12_1(struct s12 a0) {} + +// Check that sret parameter is accounted for when checking available integer +// registers. +// CHECK: define void @f13(%struct.s13_0* noalias sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval align 8 %e, i32 %f) + +struct s13_0 { long long f0[3]; }; +struct s13_1 { long long f0[2]; }; +struct s13_0 f13(int a, int b, int c, int d, + struct s13_1 e, int f) { while (1) {} } + +// CHECK: define void @f14({{.*}}, i8 signext %X) +void f14(int a, int b, int c, int d, int e, int f, char X) {} + +// CHECK: define void @f15({{.*}}, i8* %X) +void f15(int a, int b, int c, int d, int e, int f, void *X) {} + +// CHECK: define void @f16({{.*}}, float %X) +void f16(float a, float b, float c, float d, float e, float f, float g, float h, + float X) {} + +// CHECK: define void @f17({{.*}}, x86_fp80 %X) +void f17(float a, float b, float c, float d, float e, float f, float g, float h, + long double X) {} + +// Check for valid coercion. The struct should be passed/returned as i32, not +// as i64 for better code quality. +// rdar://8135035 +// CHECK: define void @f18(i32 %a, i32 %f18_arg1.coerce) +struct f18_s0 { int f0; }; +void f18(int a, struct f18_s0 f18_arg1) { while (1) {} } + +// Check byval alignment. + +// CHECK: define void @f19(%struct.s19* byval align 16 %x) +struct s19 { + long double a; +}; +void f19(struct s19 x) {} + +// CHECK: define void @f20(%struct.s20* byval align 32 %x) +struct __attribute__((aligned(32))) s20 { + int x; + int y; +}; +void f20(struct s20 x) {} + +struct StringRef { + long x; + const char *Ptr; +}; + +// rdar://7375902 +// CHECK: define i8* @f21(i64 %S.coerce0, i8* %S.coerce1) +const char *f21(struct StringRef S) { return S.x+S.Ptr; } + +// PR7567 +typedef __attribute__ ((aligned(16))) struct f22s { unsigned long long x[2]; } L; +void f22(L x, L y) { } +// CHECK: @f22 +// CHECK: %x = alloca{{.*}}, align 16 +// CHECK: %y = alloca{{.*}}, align 16 + + + +// PR7714 +struct f23S { + short f0; + unsigned f1; + int f2; +}; + + +void f23(int A, struct f23S B) { + // CHECK: define void @f23(i32 %A, i64 %B.coerce0, i32 %B.coerce1) +} + +struct f24s { long a; int b; }; + +struct f23S f24(struct f23S *X, struct f24s *P2) { + return *X; + + // CHECK: define { i64, i32 } @f24(%struct.f23S* %X, %struct.f24s* %P2) +} + +// rdar://8248065 +typedef float v4f32 __attribute__((__vector_size__(16))); +v4f32 f25(v4f32 X) { + // CHECK: define <4 x float> @f25(<4 x float> %X) + // CHECK-NOT: alloca + // CHECK: alloca <4 x float> + // CHECK-NOT: alloca + // CHECK: store <4 x float> %X, <4 x float>* + // CHECK-NOT: store + // CHECK: ret <4 x float> + return X+X; +} + +struct foo26 { + int *X; + float *Y; +}; + +struct foo26 f26(struct foo26 *P) { + // CHECK: define { i32*, float* } @f26(%struct.foo26* %P) + return *P; +} + + +struct v4f32wrapper { + v4f32 v; +}; + +struct v4f32wrapper f27(struct v4f32wrapper X) { + // CHECK: define <4 x float> @f27(<4 x float> %X.coerce) + return X; +} + +// rdar://5711709 +struct f28c { + double x; + int y; +}; +void f28(struct f28c C) { + // CHECK: define void @f28(double %C.coerce0, i32 %C.coerce1) +} + +struct f29a { + struct c { + double x; + int y; + } x[1]; +}; + +void f29a(struct f29a A) { + // CHECK: define void @f29a(double %A.coerce0, i32 %A.coerce1) +} + +// rdar://8249586 +struct S0 { char f0[8]; char f2; char f3; char f4; }; +void f30(struct S0 p_4) { + // CHECK: define void @f30(i64 %p_4.coerce0, i24 %p_4.coerce1) +} + +// Pass the third element as a float when followed by tail padding. +// rdar://8251384 +struct f31foo { float a, b, c; }; +float f31(struct f31foo X) { + // CHECK: define float @f31(<2 x float> %X.coerce0, float %X.coerce1) + return X.c; +} + +_Complex float f32(_Complex float A, _Complex float B) { + // rdar://6379669 + // CHECK: define <2 x float> @f32(<2 x float> %A.coerce, <2 x float> %B.coerce) + return A+B; +} + + +// rdar://8357396 +struct f33s { long x; float c,d; }; + +void f33(va_list X) { + va_arg(X, struct f33s); +} + +typedef unsigned long long v1i64 __attribute__((__vector_size__(8))); + +// rdar://8359248 +// CHECK: define i64 @f34(i64 %arg.coerce) +v1i64 f34(v1i64 arg) { return arg; } + + +// rdar://8358475 +// CHECK: define i64 @f35(i64 %arg.coerce) +typedef unsigned long v1i64_2 __attribute__((__vector_size__(8))); +v1i64_2 f35(v1i64_2 arg) { return arg+arg; } + +// rdar://9122143 +// CHECK: declare void @func(%struct._str* byval align 16) +typedef struct _str { + union { + long double a; + long c; + }; +} str; + +void func(str s); +str ss; +void f9122143() +{ + func(ss); +} + +// CHECK: define double @f36(double %arg.coerce) +typedef unsigned v2i32 __attribute((__vector_size__(8))); +v2i32 f36(v2i32 arg) { return arg; } + +// AVX: declare void @f38(<8 x float>) +// AVX: declare void @f37(<8 x float>) +// CHECK: declare void @f38(%struct.s256* byval align 32) +// CHECK: declare void @f37(<8 x float>* byval align 32) +typedef float __m256 __attribute__ ((__vector_size__ (32))); +typedef struct { + __m256 m; +} s256; + +s256 x38; +__m256 x37; + +void f38(s256 x); +void f37(__m256 x); +void f39() { f38(x38); f37(x37); } + +// The two next tests make sure that the struct below is passed +// in the same way regardless of avx being used + +// CHECK: declare void @func40(%struct.t128* byval align 16) +typedef float __m128 __attribute__ ((__vector_size__ (16))); +typedef struct t128 { + __m128 m; + __m128 n; +} two128; + +extern void func40(two128 s); +void func41(two128 s) { + func40(s); +} + +// CHECK: declare void @func42(%struct.t128_2* byval align 16) +typedef struct xxx { + __m128 array[2]; +} Atwo128; +typedef struct t128_2 { + Atwo128 x; +} SA; + +extern void func42(SA s); +void func43(SA s) { + func42(s); +} + +// CHECK: define i32 @f44 +// CHECK: ptrtoint +// CHECK-NEXT: and {{.*}}, -32 +// CHECK-NEXT: inttoptr +typedef int T44 __attribute((vector_size(32))); +struct s44 { T44 x; int y; }; +int f44(int i, ...) { + __builtin_va_list ap; + __builtin_va_start(ap, i); + struct s44 s = __builtin_va_arg(ap, struct s44); + __builtin_va_end(ap); + return s.y; +} + +// Text that vec3 returns the correct LLVM IR type. +// AVX: define i32 @foo(<3 x i64> %X) +typedef long long3 __attribute((ext_vector_type(3))); +int foo(long3 X) +{ + return 0; +} + +// Make sure we don't use a varargs convention for a function without a +// prototype where AVX types are involved. +// AVX: @test45 +// AVX: call i32 bitcast (i32 (...)* @f45 to i32 (<8 x float>)*) +int f45(); +__m256 x45; +void test45() { f45(x45); } + +// Make sure we use byval to pass 64-bit vectors in memory; the LLVM call +// lowering can't handle this case correctly because it runs after legalization. +// CHECK: @test46 +// CHECK: call void @f46({{.*}}<2 x float>* byval align 8 {{.*}}, <2 x float>* byval align 8 {{.*}}) +typedef float v46 __attribute((vector_size(8))); +void f46(v46,v46,v46,v46,v46,v46,v46,v46,v46,v46); +void test46() { v46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); } + +// Check that we pass the struct below without using byval, which helps out +// codegen. +// +// CHECK: @test47 +// CHECK: call void @f47(i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}) +struct s47 { unsigned a; }; +void f47(int,int,int,int,int,int,struct s47); +void test47(int a, struct s47 b) { f47(a, a, a, a, a, a, b); } |