summaryrefslogtreecommitdiffstats
path: root/test/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen')
-rw-r--r--test/CodeGen/2010-02-10-PointerName.c4
-rw-r--r--test/CodeGen/arm-asm-diag.c23
-rw-r--r--test/CodeGen/builtins-aarch64.c6
-rw-r--r--test/CodeGen/c-strings.c13
-rw-r--r--test/CodeGen/le32-regparm.c41
-rw-r--r--test/CodeGen/linetable-endscope.c17
-rw-r--r--test/CodeGen/linux-arm-atomic.c11
-rw-r--r--test/CodeGen/may-alias.c15
-rw-r--r--test/CodeGen/mips-inline-asm-modifiers.c35
-rw-r--r--test/CodeGen/ms-inline-asm-64.c34
-rw-r--r--test/CodeGen/ms-inline-asm.c116
-rw-r--r--test/CodeGen/ms-inline-asm.cpp99
-rw-r--r--test/CodeGen/mult-alt-generic.c2
-rw-r--r--test/CodeGen/pragma-pack-1.c63
-rw-r--r--test/CodeGen/sparc-target-data.c5
-rw-r--r--test/CodeGen/systemz-inline-asm.c131
-rw-r--r--test/CodeGen/tbaa-class.cpp226
-rw-r--r--test/CodeGen/tbaa-struct.cpp30
-rw-r--r--test/CodeGen/tbaa.cpp134
-rw-r--r--test/CodeGen/thread-specifier.c3
-rw-r--r--test/CodeGen/x86_32-arguments-win32.c6
21 files changed, 869 insertions, 145 deletions
diff --git a/test/CodeGen/2010-02-10-PointerName.c b/test/CodeGen/2010-02-10-PointerName.c
index 2837de4..2321c01 100644
--- a/test/CodeGen/2010-02-10-PointerName.c
+++ b/test/CodeGen/2010-02-10-PointerName.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 %s -emit-llvm -g -o - | grep DW_TAG_pointer_type | grep -v {"char"}
+// RUN: %clang_cc1 %s -emit-llvm -g -o - | FileCheck %s
+// CHECK: DW_TAG_pointer_type
+// CHECK-NOT: {"char"}
char i = 1;
void foo() {
diff --git a/test/CodeGen/arm-asm-diag.c b/test/CodeGen/arm-asm-diag.c
new file mode 100644
index 0000000..eea7920
--- /dev/null
+++ b/test/CodeGen/arm-asm-diag.c
@@ -0,0 +1,23 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple armv7 %s -S -o /dev/null 2>&1 | FileCheck %s
+
+// rdar://13446483
+typedef __attribute__((neon_vector_type(2))) long long int64x2_t;
+typedef struct int64x2x4_t {
+ int64x2_t val[4];
+} int64x2x4_t;
+int64x2x4_t t1(const long long a[]) {
+ int64x2x4_t r;
+ __asm__("vldm %[a], { %q[r0], %q[r1], %q[r2], %q[r3] }"
+ : [r0] "=r"(r.val[0]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ [r1] "=r"(r.val[1]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ [r2] "=r"(r.val[2]), // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ [r3] "=r"(r.val[3]) // expected-warning {{the value is truncated when put into register, use a modifier to specify the size}}
+ : [a] "r"(a));
+ return r;
+}
+// We should see all four errors, rather than report a fatal error after the first.
+// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
+// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
+// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
+// CHECK: error: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
diff --git a/test/CodeGen/builtins-aarch64.c b/test/CodeGen/builtins-aarch64.c
new file mode 100644
index 0000000..8a93cb4
--- /dev/null
+++ b/test/CodeGen/builtins-aarch64.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -O3 -emit-llvm -o - %s | FileCheck %s
+
+void f0(char *a, char *b) {
+ __clear_cache(a,b);
+// CHECK: call {{.*}} @__clear_cache
+}
diff --git a/test/CodeGen/c-strings.c b/test/CodeGen/c-strings.c
index 1021010..60a6b01 100644
--- a/test/CodeGen/c-strings.c
+++ b/test/CodeGen/c-strings.c
@@ -3,12 +3,19 @@
// Should be 3 hello strings, two global (of different sizes), the rest are
// shared.
+// CHECK: @align = global i8 [[ALIGN:[0-9]+]]
// CHECK: @.str = private unnamed_addr constant [6 x i8] c"hello\00"
// CHECK: @f1.x = internal global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)
-// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align 1
-// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align 1
+// CHECK: @f2.x = internal global [6 x i8] c"hello\00", align [[ALIGN]]
+// CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align [[ALIGN]]
// CHECK: @f4.x = internal global %struct.s { i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0) }
-// CHECK: @x = global [3 x i8] c"ola", align 1
+// CHECK: @x = global [3 x i8] c"ola", align [[ALIGN]]
+
+#if defined(__s390x__)
+unsigned char align = 2;
+#else
+unsigned char align = 1;
+#endif
void bar(const char *);
diff --git a/test/CodeGen/le32-regparm.c b/test/CodeGen/le32-regparm.c
index 8c1ae5e..c8f7069 100644
--- a/test/CodeGen/le32-regparm.c
+++ b/test/CodeGen/le32-regparm.c
@@ -1,41 +1,4 @@
-// RUN: %clang_cc1 -triple le32-unknown-nacl %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple le32-unknown-nacl %s -fsyntax-only -verify
-#define FASTCALL __attribute__((regparm(2)))
+void __attribute__((regparm(2))) fc_f1(int i, int j, int k) {} // expected-error{{'regparm' is not valid on this platform}}
-typedef struct {
- int aaa;
- double bbbb;
- int ccc[200];
-} foo;
-
-// 2 inreg arguments are supported.
-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) { }
-
-// inreg structs are not supported.
-// CHECK: define void @f2(%struct.foo* inreg %a)
-void __attribute__((regparm(1))) f2(foo* a) {}
-
-// Only the first 2 arguments can be passed inreg, and the first
-// non-integral type consumes remaining available registers.
-// CHECK: define void @f3(%struct.foo* byval %a, i32 %b)
-void __attribute__((regparm(2))) f3(foo a, int b) {}
-
-// Only 64 total bits are supported
-// CHECK: define void @f4(i64 inreg %g, i32 %h)
-void __attribute__((regparm(2))) f4(long long g, int h) {}
-
-typedef void (*FType)(int, int) __attribute ((regparm (2)));
-FType bar;
-extern void FASTCALL reduced(char b, double c, foo* d, double e, int f);
-
-int
-main(void) {
- // The presence of double c means that foo* d is not passed inreg. This
- // behavior is different from current x86-32 behavior
- // CHECK: call void @reduced(i8 inreg signext 0, {{.*}} %struct.foo* null
- reduced(0, 0.0, 0, 0.0, 0);
- // CHECK: call void {{.*}}(i32 inreg 1, i32 inreg 2)
- bar(1,2);
-}
diff --git a/test/CodeGen/linetable-endscope.c b/test/CodeGen/linetable-endscope.c
new file mode 100644
index 0000000..236f605
--- /dev/null
+++ b/test/CodeGen/linetable-endscope.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+
+// Check the line numbers for the ret instruction. We expect it to be
+// at the closing of the lexical scope in this case. See the comments in
+// CodeGenFunction::FinishFunction() for more details.
+
+// CHECK: define {{.*}}foo
+// CHECK: store {{.*}}, !dbg ![[CONV:[0-9]+]]
+// CHECK: ret {{.*}}, !dbg ![[RET:[0-9]+]]
+
+void foo(char c)
+{
+ int i;
+ // CHECK: ![[CONV]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+ i = c;
+ // CHECK: ![[RET]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+}
diff --git a/test/CodeGen/linux-arm-atomic.c b/test/CodeGen/linux-arm-atomic.c
new file mode 100644
index 0000000..c7ce1d2
--- /dev/null
+++ b/test/CodeGen/linux-arm-atomic.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-linux | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv6-unknown-linux | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-unknown-linux | FileCheck %s
+
+typedef int _Atomic_word;
+_Atomic_word exchange_and_add(volatile _Atomic_word *__mem, int __val) {
+ return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL);
+}
+
+// CHECK: define {{.*}} @exchange_and_add
+// CHECK: atomicrmw {{.*}} add
diff --git a/test/CodeGen/may-alias.c b/test/CodeGen/may-alias.c
index b73ee15..c767244 100644
--- a/test/CodeGen/may-alias.c
+++ b/test/CodeGen/may-alias.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-optzns -o %t %s
-// RUN: FileCheck < %t %s
+// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -O1 -struct-path-tbaa -disable-llvm-optzns -o - %s | FileCheck %s -check-prefix=PATH
// Types with the may_alias attribute should be considered equivalent
// to char for aliasing.
@@ -9,8 +9,10 @@ typedef int __attribute__((may_alias)) aliasing_int;
void test0(aliasing_int *ai, int *i)
{
// CHECK: store i32 0, i32* %{{.*}}, !tbaa !1
+// PATH: store i32 0, i32* %{{.*}}, !tbaa [[TAG_CHAR:!.*]]
*ai = 0;
// CHECK: store i32 1, i32* %{{.*}}, !tbaa !3
+// PATH: store i32 1, i32* %{{.*}}, !tbaa [[TAG_INT:!.*]]
*i = 1;
}
@@ -19,8 +21,10 @@ 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
+ // PATH: store i32 2, i32* {{%.*}}, !tbaa [[TAG_CHAR]]
p1->x = 2;
// CHECK: store i32 3, i32* {{%.*}}, !tbaa !3
+ // PATH: store i32 3, i32* {{%.*}}, !tbaa [[TAG_test1_x:!.*]]
p2->x = 3;
}
@@ -28,3 +32,10 @@ void test1(struct Test1MA *p1, struct Test1 *p2) {
// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
// CHECK: !3 = metadata !{metadata !"int", metadata !1}
+
+// PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !{{.*}}
+// PATH: [[TAG_CHAR]] = metadata !{metadata [[TYPE_CHAR]], metadata [[TYPE_CHAR]], i64 0}
+// PATH: [[TAG_INT]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0}
+// PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_test1_x]] = metadata !{metadata [[TYPE_test1:!.*]], metadata [[TYPE_INT]], i64 0}
+// PATH: [[TYPE_test1]] = metadata !{metadata !"_ZTS5Test1", metadata [[TYPE_INT]], i64 0}
diff --git a/test/CodeGen/mips-inline-asm-modifiers.c b/test/CodeGen/mips-inline-asm-modifiers.c
new file mode 100644
index 0000000..7c4ca2c
--- /dev/null
+++ b/test/CodeGen/mips-inline-asm-modifiers.c
@@ -0,0 +1,35 @@
+// RUN: %clang -target mipsel-unknown-linux -S -o - -emit-llvm %s \
+// RUN: | FileCheck %s
+
+// This checks that the frontend will accept inline asm operand modifiers
+
+int printf(const char*, ...);
+
+ // CHECK: %{{[0-9]+}} = call i32 asm ".set noreorder;\0Alw $0,$1;\0A.set reorder;\0A", "=r,*m"(i32* getelementptr inbounds ([8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, !srcloc !0
+ // CHECK: %{{[0-9]+}} = call i32 asm "lw $0,${1:D};\0A", "=r,*m"(i32* getelementptr inbounds ([8 x i32]* @b, i32 {{[0-9]+}}, i32 {{[0-9]+}})) #2, !srcloc !1
+int b[8] = {0,1,2,3,4,5,6,7};
+int main()
+{
+ int i;
+
+ // The first word. Notice, no 'D'
+ {asm (
+ ".set noreorder;\n"
+ "lw %0,%1;\n"
+ ".set reorder;\n"
+ : "=r" (i)
+ : "m" (*(b+4)));}
+
+ printf("%d\n",i);
+
+ // The second word
+ {asm (
+ "lw %0,%D1;\n"
+ : "=r" (i)
+ : "m" (*(b+4))
+ );}
+
+ printf("%d\n",i);
+
+ return 1;
+}
diff --git a/test/CodeGen/ms-inline-asm-64.c b/test/CodeGen/ms-inline-asm-64.c
index 8d2940d..dd7b9b3 100644
--- a/test/CodeGen/ms-inline-asm-64.c
+++ b/test/CodeGen/ms-inline-asm-64.c
@@ -5,14 +5,42 @@ void t1() {
int var = 10;
__asm mov rax, offset var ; rax = address of myvar
// CHECK: t1
-// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW:#[0-9]+]]
+// CHECK: call void asm sideeffect inteldialect "mov rax, $0", "r,~{rax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
void t2() {
int var = 10;
__asm mov [eax], offset var
// CHECK: t2
-// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) [[NUW]]
+// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}})
}
-// CHECK: attributes [[NUW]] = { nounwind }
+struct t3_type { int a, b; };
+
+int t3() {
+ struct t3_type foo;
+ foo.a = 1;
+ foo.b = 2;
+ __asm {
+ lea ebx, foo
+ mov eax, [ebx].0
+ mov [ebx].4, ecx
+ }
+ return foo.b;
+// CHECK: t3
+// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr $0\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
+}
+
+int t4() {
+ struct t3_type foo;
+ foo.a = 1;
+ foo.b = 2;
+ __asm {
+ lea ebx, foo
+ mov eax, [ebx].foo.a
+ mov [ebx].foo.b, ecx
+ }
+ return foo.b;
+// CHECK: t4
+// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr $0\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}})
+}
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index d50ecfe..c71a8df 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -169,36 +169,6 @@ void t17() {
// CHECK: call void asm sideeffect inteldialect ".byte 0x4B", "~{dirflag},~{fpsr},~{flags}"()
}
-struct t18_type { int a, b; };
-
-int t18() {
- struct t18_type foo;
- foo.a = 1;
- foo.b = 2;
- __asm {
- lea ebx, foo
- mov eax, [ebx].0
- mov [ebx].4, ecx
- }
- return foo.b;
-// CHECK: t18
-// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-}
-
-int t19() {
- struct t18_type foo;
- foo.a = 1;
- foo.b = 2;
- __asm {
- lea ebx, foo
- mov eax, [ebx].foo.a
- mov [ebx].foo.b, ecx
- }
- return foo.b;
-// CHECK: t19
-// CHECK: call void asm sideeffect inteldialect "lea ebx, qword ptr foo\0A\09mov eax, [ebx].0\0A\09mov [ebx].4, ecx", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-}
-
void t20() {
char bar;
int foo;
@@ -284,9 +254,9 @@ void t25() {
__asm mov eax, 0xa2h
__asm mov eax, 0xa2
// CHECK: t25
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0ffffffffh", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0fh", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, $$0a2h", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967295", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$15", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$162", "~{eax},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2h", "~{eax},~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect "mov eax, $$0xa2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
@@ -310,7 +280,7 @@ void t26() {
void t27() {
__asm mov eax, fs:[0h]
// CHECK: t27
-// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0h]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
void t28() {
@@ -390,3 +360,81 @@ void t34() {
// CHECK: call void asm sideeffect inteldialect "prefetchnta $$64[eax]", "~{dirflag},~{fpsr},~{flags}"()
// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4[eax]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
}
+
+void t35() {
+ __asm prefetchnta [eax + (200*64)]
+ __asm mov eax, dword ptr [eax + (200*64)]
+// CHECK: t35
+// CHECK: call void asm sideeffect inteldialect "prefetchnta [eax + ($$200*$$64)]", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [eax + ($$200*$$64)]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t36() {
+ int arr[4];
+ __asm mov eax, 4[arr]
+ __asm mov eax, 4[arr + 4]
+ __asm mov eax, 8[arr + 4 + 32*2 - 4]
+ __asm mov eax, 12[4 + arr]
+ __asm mov eax, 4[4 + arr + 4]
+ __asm mov eax, 4[64 + arr + (2*32)]
+ __asm mov eax, 4[64 + arr - 2*32]
+ __asm mov eax, [arr + 4]
+ __asm mov eax, [arr + 4 + 32*2 - 4]
+ __asm mov eax, [4 + arr]
+ __asm mov eax, [4 + arr + 4]
+ __asm mov eax, [64 + arr + (2*32)]
+ __asm mov eax, [64 + arr - 2*32]
+// CHECK: t36
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$72$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$16$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$132$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$64$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$4$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$128$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+}
+
+void t37() {
+ __asm mov eax, 4 + 8
+ __asm mov eax, 4 + 8 * 16
+ __asm mov eax, -4 + 8 * 16
+ __asm mov eax, (4 + 4) * 16
+ __asm mov eax, 4 + 8 * -16
+ __asm mov eax, 4 + 16 / -8
+ __asm mov eax, (16 + 16) / -8
+// CHECK: t37
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$12", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$132", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$124", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$128", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967172", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967292", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t38() {
+ int arr[4];
+ __asm mov eax, 4+4[arr]
+ __asm mov eax, (4+4)[arr + 4]
+ __asm mov eax, 8*2[arr + 4 + 32*2 - 4]
+ __asm mov eax, 12+20[4 + arr]
+ __asm mov eax, 4*16+4[4 + arr + 4]
+ __asm mov eax, 4*4[64 + arr + (2*32)]
+ __asm mov eax, 4*(4-2)[64 + arr - 2*32]
+ __asm mov eax, 32*(4-2)[arr - 2*32]
+// CHECK: t38
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$12$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$80$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$36$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$76$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$144$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
+}
diff --git a/test/CodeGen/ms-inline-asm.cpp b/test/CodeGen/ms-inline-asm.cpp
index 9c160be..8f824f9 100644
--- a/test/CodeGen/ms-inline-asm.cpp
+++ b/test/CodeGen/ms-inline-asm.cpp
@@ -1,26 +1,105 @@
// REQUIRES: x86-64-registered-target
// RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -O0 -fasm-blocks -emit-llvm -o - | FileCheck %s
+// rdar://13645930
+
struct Foo {
static int *ptr;
static int a, b;
+ int arr[4];
struct Bar {
static int *ptr;
+ char arr[2];
};
};
void t1() {
Foo::ptr = (int *)0xDEADBEEF;
Foo::Bar::ptr = (int *)0xDEADBEEF;
- __asm mov eax, Foo::ptr
- __asm mov eax, Foo::Bar::ptr
- __asm mov eax, [Foo::ptr]
- __asm mov eax, dword ptr [Foo::ptr]
- __asm mov eax, dword ptr [Foo::ptr]
+ __asm mov eax, Foo ::ptr
+ __asm mov eax, Foo :: Bar :: ptr
+ __asm mov eax, [Foo:: ptr]
+ __asm mov eax, dword ptr [Foo :: ptr]
+ __asm mov eax, dword ptr [Foo :: ptr]
// CHECK: @_Z2t1v
-// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, Foo::Bar::ptr", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, [Foo::ptr]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [Foo::ptr]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr [Foo::ptr]", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+}
+
+int gvar = 10;
+void t2() {
+ int lvar = 10;
+ __asm mov eax, offset Foo::ptr
+ __asm mov eax, offset Foo::Bar::ptr
+// CHECK: t2
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE)
+// CHECK: call void asm sideeffect inteldialect "mov eax, $0", "r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3Bar3ptrE)
+}
+
+// CHECK: define void @_Z2t3v()
+void t3() {
+ __asm mov eax, LENGTH Foo::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, LENGTH Foo::Bar::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, LENGTH Foo::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, LENGTH Foo::Bar::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+
+ __asm mov eax, TYPE Foo::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, TYPE Foo::Bar::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, TYPE Foo::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, TYPE Foo::Bar::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+
+ __asm mov eax, SIZE Foo::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, SIZE Foo::Bar::ptr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, SIZE Foo::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$16", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ __asm mov eax, SIZE Foo::Bar::arr
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+
+}
+
+struct T4 {
+ int x;
+ static int y;
+ void test();
+};
+
+// CHECK: define void @_ZN2T44testEv(
+void T4::test() {
+// CHECK: [[T0:%.*]] = alloca [[T4:%.*]]*,
+// CHECK: [[THIS:%.*]] = load [[T4]]** [[T0]]
+// CHECK: [[X:%.*]] = getelementptr inbounds [[T4]]* [[THIS]], i32 0, i32 0
+ __asm mov eax, x;
+// CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* [[X]])
+ __asm mov y, eax;
+// CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* @_ZN2T41yE)
+}
+
+template <class T> struct T5 {
+ template <class U> static T create(U);
+ void run();
+};
+// CHECK: define void @_Z5test5v()
+void test5() {
+ // CHECK: [[X:%.*]] = alloca i32
+ // CHECK: [[Y:%.*]] = alloca i32
+ int x, y;
+ __asm push y
+ // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[Y]])
+ __asm call T5<int>::create<float>
+ // CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(i32 (float)* @_ZN2T5IiE6createIfEEiT_)
+ __asm mov x, eax
+ // CHECK: call void asm sideeffect inteldialect "mov dword ptr $0, eax", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[X]])
}
diff --git a/test/CodeGen/mult-alt-generic.c b/test/CodeGen/mult-alt-generic.c
index 6cf6f0a..111679e 100644
--- a/test/CodeGen/mult-alt-generic.c
+++ b/test/CodeGen/mult-alt-generic.c
@@ -6,7 +6,9 @@
// 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 s390x %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -triple sparc %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple sparcv9 %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -triple thumb %s -emit-llvm -o - | FileCheck %s
int mout0;
diff --git a/test/CodeGen/pragma-pack-1.c b/test/CodeGen/pragma-pack-1.c
index c30a62a..2a71c8f 100644
--- a/test/CodeGen/pragma-pack-1.c
+++ b/test/CodeGen/pragma-pack-1.c
@@ -1,7 +1,68 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s
// PR4610
#pragma pack(4)
struct ref {
struct ref *next;
} refs;
+
+// PR13580
+struct S
+{
+ char a[3];
+#pragma pack(1)
+ struct T
+ {
+ char b;
+ int c;
+ } d;
+#pragma pack()
+ struct T2
+ {
+ char b;
+ int c;
+ } d2;
+} ss;
+
+struct S3
+{
+ char a[3];
+#pragma pack(push, 2)
+ struct T3
+ {
+ char b;
+ int c;
+ } d;
+#pragma pack(pop)
+ struct T32
+ {
+ char b;
+ int c;
+ } e;
+} s3;
+
+struct S4
+{
+ char a[3];
+#pragma align=packed
+ struct T4
+ {
+ char b;
+ int c;
+ } d;
+ int e;
+} s4;
+
+// CHECK: [[struct_ref:%[a-zA-Z0-9_.]+]] = type <{ [[struct_ref]]* }>
+// CHECK: [[struct_S:%[a-zA-Z0-9_.]+]] = type { [3 x i8], [[struct_T:%[a-zA-Z0-9_.]+]], [[struct_T2:%[a-zA-Z0-9_.]+]] }
+// CHECK: [[struct_T]] = type <{ i8, i32 }>
+// CHECK: [[struct_T2]] = type { i8, i32 }
+
+// CHECK: %struct.S3 = type <{ [3 x i8], i8, %struct.T3, [2 x i8], %struct.T32 }>
+// CHECK: %struct.T3 = type <{ i8, i8, i32 }>
+// CHECK: %struct.T32 = type { i8, i32 }
+// CHECK: %struct.S4 = type { [3 x i8], %struct.T4, i32 }
+// CHECK: %struct.T4 = type <{ i8, i32 }>
+
+// CHECK: @refs = common global [[struct_ref]]
+// CHECK: @ss = common global [[struct_S]]
diff --git a/test/CodeGen/sparc-target-data.c b/test/CodeGen/sparc-target-data.c
new file mode 100644
index 0000000..bb32a21
--- /dev/null
+++ b/test/CodeGen/sparc-target-data.c
@@ -0,0 +1,5 @@
+// RUN: %clang -target sparc-sun-solaris -o - -emit-llvm -S %s | FileCheck %s -check-prefix=V8
+// RUN: %clang -target sparcv9-sun-solaris -o - -emit-llvm -S %s | FileCheck %s -check-prefix=V9
+
+// V8: E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64
+// V9: 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-n32:64-S128
diff --git a/test/CodeGen/systemz-inline-asm.c b/test/CodeGen/systemz-inline-asm.c
new file mode 100644
index 0000000..8e5854f
--- /dev/null
+++ b/test/CodeGen/systemz-inline-asm.c
@@ -0,0 +1,131 @@
+// RUN: %clang_cc1 -triple s390x-linux-gnu -O2 -emit-llvm -o - %s | FileCheck %s
+
+unsigned int gi;
+unsigned long gl;
+
+void test_store_m(unsigned int i) {
+ asm("st %1, %0" : "=m" (gi) : "r" (i));
+// CHECK: define void @test_store_m(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*m,r"(i32* @gi, i32 %i)
+}
+
+void test_store_Q(unsigned int i) {
+ asm("st %1, %0" : "=Q" (gi) : "r" (i));
+// CHECK: define void @test_store_Q(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*Q,r"(i32* @gi, i32 %i)
+}
+
+void test_store_R(unsigned int i) {
+ asm("st %1, %0" : "=R" (gi) : "r" (i));
+// CHECK: define void @test_store_R(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*R,r"(i32* @gi, i32 %i)
+}
+
+void test_store_S(unsigned int i) {
+ asm("st %1, %0" : "=S" (gi) : "r" (i));
+// CHECK: define void @test_store_S(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*S,r"(i32* @gi, i32 %i)
+}
+
+void test_store_T(unsigned int i) {
+ asm("st %1, %0" : "=T" (gi) : "r" (i));
+// CHECK: define void @test_store_T(i32 zeroext %i)
+// CHECK: call void asm "st $1, $0", "=*T,r"(i32* @gi, i32 %i)
+}
+
+int test_load_m() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "m" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_m()
+// CHECK: call i32 asm "l $0, $1", "=r,*m"(i32* @gi)
+}
+
+int test_load_Q() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "Q" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_Q()
+// CHECK: call i32 asm "l $0, $1", "=r,*Q"(i32* @gi)
+}
+
+int test_load_R() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "R" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_R()
+// CHECK: call i32 asm "l $0, $1", "=r,*R"(i32* @gi)
+}
+
+int test_load_S() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "S" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_S()
+// CHECK: call i32 asm "l $0, $1", "=r,*S"(i32* @gi)
+}
+
+int test_load_T() {
+ unsigned int i;
+ asm("l %0, %1" : "=r" (i) : "T" (gi));
+ return i;
+// CHECK: define signext i32 @test_load_T()
+// CHECK: call i32 asm "l $0, $1", "=r,*T"(i32* @gi)
+}
+
+void test_mI(unsigned char *c) {
+ asm volatile("cli %0, %1" :: "Q" (*c), "I" (100));
+// CHECK: define void @test_mI(i8* %c)
+// CHECK: call void asm sideeffect "cli $0, $1", "*Q,I"(i8* %c, i32 100)
+}
+
+unsigned int test_dJa(unsigned int i, unsigned int j) {
+ asm("sll %0, %2(%3)" : "=d" (i) : "0" (i), "J" (1000), "a" (j));
+ return i;
+// CHECK: define zeroext i32 @test_dJa(i32 zeroext %i, i32 zeroext %j)
+// CHECK: call i32 asm "sll $0, $2($3)", "=d,0,J,a"(i32 %i, i32 1000, i32 %j)
+}
+
+unsigned long test_rK(unsigned long i) {
+ asm("aghi %0, %2" : "=r" (i) : "0" (i), "K" (-30000));
+ return i;
+// CHECK: define i64 @test_rK(i64 %i)
+// CHECK: call i64 asm "aghi $0, $2", "=r,0,K"(i64 %i, i32 -30000)
+}
+
+unsigned long test_rL(unsigned long i) {
+ asm("sllg %0, %1, %2" : "=r" (i) : "r" (i), "L" (500000));
+ return i;
+// CHECK: define i64 @test_rL(i64 %i)
+// CHECK: call i64 asm "sllg $0, $1, $2", "=r,r,L"(i64 %i, i32 500000)
+}
+
+void test_M() {
+ asm volatile("#FOO %0" :: "M"(0x7fffffff));
+// CHECK: define void @test_M()
+// CHECK: call void asm sideeffect "#FOO $0", "M"(i32 2147483647)
+}
+
+float test_f32(float f, float g) {
+ asm("aebr %0, %2" : "=f" (f) : "0" (f), "f" (g));
+ return f;
+// CHECK: define float @test_f32(float %f, float %g)
+// CHECK: call float asm "aebr $0, $2", "=f,0,f"(float %f, float %g)
+}
+
+double test_f64(double f, double g) {
+ asm("adbr %0, %2" : "=f" (f) : "0" (f), "f" (g));
+ return f;
+// CHECK: define double @test_f64(double %f, double %g)
+// CHECK: call double asm "adbr $0, $2", "=f,0,f"(double %f, double %g)
+}
+
+long double test_f128(long double f, long double g) {
+ asm("axbr %0, %2" : "=f" (f) : "0" (f), "f" (g));
+ return f;
+// CHECK: define void @test_f128(fp128* noalias nocapture sret [[DEST:%.*]], fp128* byval nocapture, fp128* byval nocapture)
+// CHECK: %f = load fp128* %0
+// CHECK: %g = load fp128* %1
+// CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
+// CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
+}
diff --git a/test/CodeGen/tbaa-class.cpp b/test/CodeGen/tbaa-class.cpp
new file mode 100644
index 0000000..967ba19
--- /dev/null
+++ b/test/CodeGen/tbaa-class.cpp
@@ -0,0 +1,226 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
+// Test TBAA metadata generated by front-end.
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+class StructA
+{
+public:
+ uint16_t f16;
+ uint32_t f32;
+ uint16_t f16_2;
+ uint32_t f32_2;
+};
+class StructB
+{
+public:
+ uint16_t f16;
+ StructA a;
+ uint32_t f32;
+};
+class StructC
+{
+public:
+ uint16_t f16;
+ StructB b;
+ uint32_t f32;
+};
+class StructD
+{
+public:
+ uint16_t f16;
+ StructB b;
+ uint32_t f32;
+ uint8_t f8;
+};
+
+class StructS
+{
+public:
+ uint16_t f16;
+ uint32_t f32;
+};
+class StructS2 : public StructS
+{
+public:
+ uint16_t f16_2;
+ uint32_t f32_2;
+};
+
+uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]]
+ *s = 1;
+ A->f32 = 4;
+ return *s;
+}
+
+uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_A_f16:!.*]]
+ *s = 1;
+ A->f16 = 4;
+ return *s;
+}
+
+uint32_t g3(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]]
+ A->f32 = 1;
+ B->a.f32 = 4;
+ return A->f32;
+}
+
+uint32_t g4(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_B_a_f16:!.*]]
+ A->f32 = 1;
+ B->a.f16 = 4;
+ return A->f32;
+}
+
+uint32_t g5(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]]
+ A->f32 = 1;
+ B->f32 = 4;
+ return A->f32;
+}
+
+uint32_t g6(StructA *A, StructB *B, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]]
+ A->f32 = 1;
+ B->a.f32_2 = 4;
+ return A->f32;
+}
+
+uint32_t g7(StructA *A, StructS *S, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
+ A->f32 = 1;
+ S->f32 = 4;
+ return A->f32;
+}
+
+uint32_t g8(StructA *A, StructS *S, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S_f16:!.*]]
+ A->f32 = 1;
+ S->f16 = 4;
+ return A->f32;
+}
+
+uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
+ S->f32 = 1;
+ S2->f32 = 4;
+ return S->f32;
+}
+
+uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32_2:!.*]]
+ S->f32 = 1;
+ S2->f32_2 = 4;
+ return S->f32;
+}
+
+uint32_t g11(StructC *C, StructD *D, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]]
+ C->b.a.f32 = 1;
+ D->b.a.f32 = 4;
+ return C->b.a.f32;
+}
+
+uint32_t g12(StructC *C, StructD *D, uint64_t count) {
+// CHECK: define i32 @{{.*}}(
+// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
+// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
+// TODO: differentiate the two accesses.
+// PATH: define i32 @{{.*}}(
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
+ StructB *b1 = &(C->b);
+ StructB *b2 = &(D->b);
+ // b1, b2 have different context.
+ b1->a.f32 = 1;
+ b2->a.f32 = 4;
+ return b1->a.f32;
+}
+
+// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
+// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
+// CHECK: !4 = metadata !{metadata !"int", metadata !1}
+// CHECK: !5 = metadata !{metadata !"short", metadata !1}
+
+// PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !3
+// PATH: [[TAG_i32]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0}
+// PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_A_f32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_A]] = metadata !{metadata !"_ZTS7StructA", metadata [[TYPE_SHORT:!.*]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_SHORT:!.*]] = metadata !{metadata !"short", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_A_f16]] = metadata !{metadata [[TYPE_A]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_B_a_f32]] = metadata !{metadata [[TYPE_B:!.*]], metadata [[TYPE_INT]], i64 8}
+// PATH: [[TYPE_B]] = metadata !{metadata !"_ZTS7StructB", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_A]], i64 4, metadata [[TYPE_INT]], i64 20}
+// PATH: [[TAG_B_a_f16]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_SHORT]], i64 4}
+// PATH: [[TAG_B_f32]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 20}
+// PATH: [[TAG_B_a_f32_2]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 16}
+// PATH: [[TAG_S_f32]] = metadata !{metadata [[TYPE_S:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_S]] = metadata !{metadata !"_ZTS7StructS", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4}
+// PATH: [[TAG_S_f16]] = metadata !{metadata [[TYPE_S]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_S2_f32_2]] = metadata !{metadata [[TYPE_S2:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_S2]] = metadata !{metadata !"_ZTS8StructS2", metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12}
+// PATH: [[TAG_C_b_a_f32]] = metadata !{metadata [[TYPE_C:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_C]] = metadata !{metadata !"_ZTS7StructC", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28}
+// PATH: [[TAG_D_b_a_f32]] = metadata !{metadata [[TYPE_D:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_D]] = metadata !{metadata !"_ZTS7StructD", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28, metadata [[TYPE_CHAR]], i64 32}
diff --git a/test/CodeGen/tbaa-struct.cpp b/test/CodeGen/tbaa-struct.cpp
index 12a6f4d..6d593a3 100644
--- a/test/CodeGen/tbaa-struct.cpp
+++ b/test/CodeGen/tbaa-struct.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - -O1 %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - -O1 %s | FileCheck %s
//
// Check that we generate !tbaa.struct metadata for struct copies.
struct A {
@@ -39,8 +39,36 @@ void copy3 (T1 *a, T1 *b) {
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 12, i32 4, i1 false), !tbaa.struct [[TS3:!.*]]
+// Make sure that zero-length bitfield works.
+#define ATTR __attribute__ ((ms_struct))
+struct five {
+ char a;
+ int :0; /* ignored; prior field is not a bitfield. */
+ char b;
+ char c;
+} ATTR;
+void copy4(struct five *a, struct five *b) {
+ *a = *b;
+}
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 3, i32 1, i1 false), !tbaa.struct [[TS4:!.*]]
+
+struct six {
+ char a;
+ int :0;
+ char b;
+ char c;
+};
+void copy5(struct six *a, struct six *b) {
+ *a = *b;
+}
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 6, i32 1, i1 false), !tbaa.struct [[TS5:!.*]]
+
// CHECK: [[TS]] = metadata !{i64 0, i64 2, metadata !{{.*}}, i64 4, i64 4, metadata !{{.*}}, i64 8, i64 1, metadata !{{.*}}, i64 12, i64 4, metadata !{{.*}}}
+// CHECK: [[CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !{{.*}}}
+// CHECK: [[INT:!.*]] = metadata !{metadata !"int", metadata [[CHAR]]}
// (offset, size) = (0,1) char; (4,2) short; (8,4) int; (12,1) char; (16,4) int; (20,4) int
// CHECK: [[TS2]] = metadata !{i64 0, i64 1, metadata !{{.*}}, i64 4, i64 2, metadata !{{.*}}, i64 8, i64 4, metadata !{{.*}}, i64 12, i64 1, metadata !{{.*}}, i64 16, i64 4, metadata {{.*}}, i64 20, i64 4, metadata {{.*}}}
// (offset, size) = (0,8) char; (0,2) char; (4,8) char
// CHECK: [[TS3]] = metadata !{i64 0, i64 8, metadata !{{.*}}, i64 0, i64 2, metadata !{{.*}}, i64 4, i64 8, metadata !{{.*}}}
+// CHECK: [[TS4]] = metadata !{i64 0, i64 1, metadata [[CHAR]], i64 1, i64 1, metadata [[CHAR]], i64 2, i64 1, metadata [[CHAR]]}
+// CHECK: [[TS5]] = metadata !{i64 0, i64 1, metadata [[CHAR]], i64 4, i64 4, metadata [[INT]], i64 4, i64 1, metadata [[CHAR]], i64 5, i64 1, metadata [[CHAR]]}
diff --git a/test/CodeGen/tbaa.cpp b/test/CodeGen/tbaa.cpp
index c30e4a3..afb8893 100644
--- a/test/CodeGen/tbaa.cpp
+++ b/test/CodeGen/tbaa.cpp
@@ -1,8 +1,11 @@
-// RUN: %clang_cc1 -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
// Test TBAA metadata generated by front-end.
-#include <stdint.h>
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
typedef struct
{
uint16_t f16;
@@ -46,8 +49,8 @@ uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
-// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !5
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]]
*s = 1;
A->f32 = 4;
return *s;
@@ -58,8 +61,8 @@ uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
-// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !8
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_A_f16:!.*]]
*s = 1;
A->f16 = 4;
return *s;
@@ -70,8 +73,8 @@ uint32_t g3(StructA *A, StructB *B, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
-// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]]
A->f32 = 1;
B->a.f32 = 4;
return A->f32;
@@ -82,8 +85,8 @@ uint32_t g4(StructA *A, StructB *B, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
-// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !11
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_B_a_f16:!.*]]
A->f32 = 1;
B->a.f16 = 4;
return A->f32;
@@ -94,8 +97,8 @@ uint32_t g5(StructA *A, StructB *B, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
-// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !12
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]]
A->f32 = 1;
B->f32 = 4;
return A->f32;
@@ -106,8 +109,8 @@ uint32_t g6(StructA *A, StructB *B, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
-// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !13
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]]
A->f32 = 1;
B->a.f32_2 = 4;
return A->f32;
@@ -118,8 +121,8 @@ uint32_t g7(StructA *A, StructS *S, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
-// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !14
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
A->f32 = 1;
S->f32 = 4;
return A->f32;
@@ -130,8 +133,8 @@ uint32_t g8(StructA *A, StructS *S, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !5
-// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !16
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S_f16:!.*]]
A->f32 = 1;
S->f16 = 4;
return A->f32;
@@ -142,8 +145,8 @@ uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14
-// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !17
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32:!.*]]
S->f32 = 1;
S2->f32 = 4;
return S->f32;
@@ -154,8 +157,8 @@ uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa !5
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !14
-// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa !19
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
+// PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S2_f16:!.*]]
S->f32 = 1;
S2->f16 = 4;
return S->f32;
@@ -166,8 +169,8 @@ uint32_t g11(StructC *C, StructD *D, uint64_t count) {
// CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa !4
// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !20
-// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !22
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]]
C->b.a.f32 = 1;
D->b.a.f32 = 4;
return C->b.a.f32;
@@ -179,8 +182,8 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) {
// CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa !4
// TODO: differentiate the two accesses.
// PATH: define i32 @{{.*}}(
-// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa !9
-// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa !9
+// PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
+// PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
StructB *b1 = &(C->b);
StructB *b2 = &(D->b);
// b1, b2 have different context.
@@ -189,29 +192,64 @@ uint32_t g12(StructC *C, StructD *D, uint64_t count) {
return b1->a.f32;
}
+// Make sure that zero-length bitfield works.
+#define ATTR __attribute__ ((ms_struct))
+struct five {
+ char a;
+ int :0; /* ignored; prior field is not a bitfield. */
+ char b;
+ char c;
+} ATTR;
+char g13(struct five *a, struct five *b) {
+ return a->b;
+// CHECK: define signext i8 @{{.*}}(
+// CHECK: load i8* %{{.*}}, align 1, !tbaa !1
+// PATH: define signext i8 @{{.*}}(
+// PATH: load i8* %{{.*}}, align 1, !tbaa [[TAG_five_b:!.*]]
+}
+
+struct six {
+ char a;
+ int :0;
+ char b;
+ char c;
+};
+char g14(struct six *a, struct six *b) {
+// CHECK: define signext i8 @{{.*}}(
+// CHECK: load i8* %{{.*}}, align 1, !tbaa !1
+// PATH: define signext i8 @{{.*}}(
+// PATH: load i8* %{{.*}}, align 1, !tbaa [[TAG_six_b:!.*]]
+ return a->b;
+}
+
// CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}
// CHECK: !2 = metadata !{metadata !"Simple C/C++ TBAA"}
// CHECK: !4 = metadata !{metadata !"int", metadata !1}
// CHECK: !5 = metadata !{metadata !"short", metadata !1}
-// PATH: !1 = metadata !{metadata !"omnipotent char", metadata !2}
-// PATH: !4 = metadata !{metadata !"int", metadata !1}
-// PATH: !5 = metadata !{metadata !6, metadata !4, i64 4}
-// PATH: !6 = metadata !{metadata !"_ZTS7StructA", i64 0, metadata !7, i64 4, metadata !4}
-// PATH: !7 = metadata !{metadata !"short", metadata !1}
-// PATH: !8 = metadata !{metadata !6, metadata !7, i64 0}
-// PATH: !9 = metadata !{metadata !10, metadata !4, i64 8}
-// PATH: !10 = metadata !{metadata !"_ZTS7StructB", i64 0, metadata !7, i64 4, metadata !6, i64 20, metadata !4}
-// PATH: !11 = metadata !{metadata !10, metadata !7, i64 4}
-// PATH: !12 = metadata !{metadata !10, metadata !4, i64 20}
-// PATH: !13 = metadata !{metadata !10, metadata !4, i64 16}
-// PATH: !14 = metadata !{metadata !15, metadata !4, i64 4}
-// PATH: !15 = metadata !{metadata !"_ZTS7StructS", i64 0, metadata !7, i64 4, metadata !4}
-// PATH: !16 = metadata !{metadata !15, metadata !7, i64 0}
-// PATH: !17 = metadata !{metadata !18, metadata !4, i64 4}
-// PATH: !18 = metadata !{metadata !"_ZTS8StructS2", i64 0, metadata !7, i64 4, metadata !4}
-// PATH: !19 = metadata !{metadata !18, metadata !7, i64 0}
-// PATH: !20 = metadata !{metadata !21, metadata !4, i64 12}
-// PATH: !21 = metadata !{metadata !"_ZTS7StructC", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4}
-// PATH: !22 = metadata !{metadata !23, metadata !4, i64 12}
-// PATH: !23 = metadata !{metadata !"_ZTS7StructD", i64 0, metadata !7, i64 4, metadata !10, i64 28, metadata !4, i64 32, metadata !1}
+// PATH: [[TYPE_CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !3
+// PATH: [[TAG_i32]] = metadata !{metadata [[TYPE_INT:!.*]], metadata [[TYPE_INT]], i64 0}
+// PATH: [[TYPE_INT]] = metadata !{metadata !"int", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_A_f32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_A]] = metadata !{metadata !"_ZTS7StructA", metadata [[TYPE_SHORT:!.*]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_SHORT]], i64 8, metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_SHORT:!.*]] = metadata !{metadata !"short", metadata [[TYPE_CHAR]]
+// PATH: [[TAG_A_f16]] = metadata !{metadata [[TYPE_A]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_B_a_f32]] = metadata !{metadata [[TYPE_B:!.*]], metadata [[TYPE_INT]], i64 8}
+// PATH: [[TYPE_B]] = metadata !{metadata !"_ZTS7StructB", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_A]], i64 4, metadata [[TYPE_INT]], i64 20}
+// PATH: [[TAG_B_a_f16]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_SHORT]], i64 4}
+// PATH: [[TAG_B_f32]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 20}
+// PATH: [[TAG_B_a_f32_2]] = metadata !{metadata [[TYPE_B]], metadata [[TYPE_INT]], i64 16}
+// PATH: [[TAG_S_f32]] = metadata !{metadata [[TYPE_S:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_S]] = metadata !{metadata !"_ZTS7StructS", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4}
+// PATH: [[TAG_S_f16]] = metadata !{metadata [[TYPE_S]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_S2_f32]] = metadata !{metadata [[TYPE_S2:!.*]], metadata [[TYPE_INT]], i64 4}
+// PATH: [[TYPE_S2]] = metadata !{metadata !"_ZTS8StructS2", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_INT]], i64 4}
+// PATH: [[TAG_S2_f16]] = metadata !{metadata [[TYPE_S2]], metadata [[TYPE_SHORT]], i64 0}
+// PATH: [[TAG_C_b_a_f32]] = metadata !{metadata [[TYPE_C:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_C]] = metadata !{metadata !"_ZTS7StructC", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28}
+// PATH: [[TAG_D_b_a_f32]] = metadata !{metadata [[TYPE_D:!.*]], metadata [[TYPE_INT]], i64 12}
+// PATH: [[TYPE_D]] = metadata !{metadata !"_ZTS7StructD", metadata [[TYPE_SHORT]], i64 0, metadata [[TYPE_B]], i64 4, metadata [[TYPE_INT]], i64 28, metadata [[TYPE_CHAR]], i64 32}
+// PATH: [[TAG_five_b]] = metadata !{metadata [[TYPE_five:!.*]], metadata [[TYPE_CHAR]], i64 1}
+// PATH: [[TYPE_five]] = metadata !{metadata !"_ZTS4five", metadata [[TYPE_CHAR]], i64 0, metadata [[TYPE_CHAR]], i64 1, metadata [[TYPE_CHAR]], i64 2}
+// PATH: [[TAG_six_b]] = metadata !{metadata [[TYPE_six:!.*]], metadata [[TYPE_CHAR]], i64 4}
+// PATH: [[TYPE_six]] = metadata !{metadata !"_ZTS3six", metadata [[TYPE_CHAR]], i64 0, metadata [[TYPE_INT]], i64 4, metadata [[TYPE_CHAR]], i64 4, metadata [[TYPE_CHAR]], i64 5}
diff --git a/test/CodeGen/thread-specifier.c b/test/CodeGen/thread-specifier.c
index a2d3e62..8e21651 100644
--- a/test/CodeGen/thread-specifier.c
+++ b/test/CodeGen/thread-specifier.c
@@ -10,6 +10,9 @@
// CHECK: @i = thread_local(initialexec) global
// CHECK: @j = thread_local(localexec) global
+// CHECK-NOT: @_ZTW
+// CHECK-NOT: @_ZTH
+
__thread int a;
extern __thread int b;
int c() { return *&b; }
diff --git a/test/CodeGen/x86_32-arguments-win32.c b/test/CodeGen/x86_32-arguments-win32.c
index f18bb30..77ff9e2 100644
--- a/test/CodeGen/x86_32-arguments-win32.c
+++ b/test/CodeGen/x86_32-arguments-win32.c
@@ -1,7 +1,7 @@
// 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)
+// CHECK: define void @f1_2(%struct.s1* byval align 4 %a0)
struct s1 {
int a;
int b;
@@ -31,7 +31,7 @@ struct s4 {
struct s4 f4_1(void) { while (1) {} }
// CHECK: define i64 @f5_1()
-// CHECK: define void @f5_2(double %a0.0)
+// CHECK: define void @f5_2(%struct.s5* byval align 4)
struct s5 {
double a;
};
@@ -39,7 +39,7 @@ 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)
+// CHECK: define void @f6_2(%struct.s6* byval align 4 %a0)
struct s6 {
float a;
};
OpenPOWER on IntegriCloud