diff options
Diffstat (limited to 'test/CodeGen/unaligned-expr.c')
-rw-r--r-- | test/CodeGen/unaligned-expr.c | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/test/CodeGen/unaligned-expr.c b/test/CodeGen/unaligned-expr.c new file mode 100644 index 000000000000..6e23cbc729fb --- /dev/null +++ b/test/CodeGen/unaligned-expr.c @@ -0,0 +1,217 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s + +// ------------- +// Scalar integer +// ------------- +__unaligned int x; +void test1(void) { + // CHECK: {{%.*}} = load i32, i32* @x, align 1 + // CHECK: store i32 {{%.*}}, i32* @x, align 1 + x++; +} + +void test2(void) { + // CHECK: %y = alloca i32, align 1 + // CHECK: {{%.*}} = load i32, i32* %y, align 1 + // CHECK: store i32 {{%.*}}, i32* %y, align 1 + __unaligned int y; + y++; +} + +void test2_1(void) { + // CHECK: %y = alloca i32, align 1 + // CHECK: store i32 1, i32* %y, align 1 + __unaligned int y = 1; +} + +// ------------- +// Global pointer +// ------------- +int *__unaligned p1; +void test3(void) { + + // CHECK: {{%.*}} = load i32*, i32** @p1, align 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 4 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 4 + (*p1)++; +} + +int __unaligned *p2; +void test4(void) { + // CHECK: {{%.*}} = load i32*, i32** @p2, align 8 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + (*p2)++; +} + +int __unaligned *__unaligned p3; +void test5(void) { + // CHECK: {{%.*}} = load i32*, i32** @p3, align 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + (*p3)++; +} + +// ------------- +// Local pointer +// ------------- +void test6(void) { + // CHECK: %lp1 = alloca i32*, align 1 + // CHECK: {{%.*}} = load i32*, i32** %lp1, align 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 4 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 4 + int *__unaligned lp1; + (*lp1)++; +} + +void test7(void) { + // CHECK: %lp2 = alloca i32*, align 8 + // CHECK: {{%.*}} = load i32*, i32** %lp2, align 8 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + int __unaligned *lp2; + (*lp2)++; +} + +void test8(void) { + // CHECK: %lp3 = alloca i32*, align 1 + // CHECK: {{%.*}} = load i32*, i32** %lp3, align 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + int __unaligned *__unaligned lp3; + (*lp3)++; +} + +// ------------- +// Global array +// ------------- +__unaligned int a[10]; +void test9(void) { + // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @a, i64 0, i64 3), align 1 + // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @a, i64 0, i64 3), align 1 + (a[3])++; +} + +// ------------- +// Local array +// ------------- +void test10(void) { + // CHECK: %la = alloca [10 x i32], align 1 + // CHECK: {{%.*}} = getelementptr inbounds [10 x i32], [10 x i32]* %la, i64 0, i64 3 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + __unaligned int la[10]; + (la[3])++; +} + +// -------- +// Typedefs +// -------- + +typedef __unaligned int UnalignedInt; +void test13() { + // CHECK: %i = alloca i32, align 1 + // CHECK: {{%.*}} = load i32, i32* %i, align 1 + // CHECK: store i32 {{%.*}}, i32* %i, align 1 + UnalignedInt i; + i++; +} + +typedef int Aligned; +typedef __unaligned Aligned UnalignedInt2; +void test14() { + // CHECK: %i = alloca i32, align 1 + // CHECK: {{%.*}} = load i32, i32* %i, align 1 + // CHECK: store i32 {{%.*}}, i32* %i, align 1 + UnalignedInt2 i; + i++; +} + +typedef UnalignedInt UnalignedInt3; +void test15() { + // CHECK: %i = alloca i32, align 1 + // CHECK: {{%.*}} = load i32, i32* %i, align 1 + // CHECK: store i32 {{%.*}}, i32* %i, align 1 + UnalignedInt3 i; + i++; +} + +// ------------- +// Decayed types +// ------------- +void test16(__unaligned int c[10]) { + // CHECK: {{%.*}} = alloca i32*, align 8 + // CHECK: store i32* %c, i32** {{%.*}}, align 8 + // CHECK: {{%.*}} = load i32*, i32** {{%.*}}, align 8 + // CHECK: {{%.*}} = getelementptr inbounds i32, i32* {{%.*}}, i64 3 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + c[3]++; +} + +// ----------- +// __alignof__ +// ----------- +int test17(void) { + // CHECK: ret i32 1 + return __alignof__(__unaligned int); +} + +int test18(void) { + // CHECK: ret i32 1 + __unaligned int a; + return __alignof__(a); +} + +int test19(void) { + // CHECK: ret i32 1 + __unaligned int a[10]; + return __alignof__(a); +} + +// ----------- +// structs +// ----------- +typedef +struct S1 { + char c; + int x; +} S1; + +__unaligned S1 s1; +void test20(void) { + // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds (%struct.S1, %struct.S1* @s1, i32 0, i32 1), align 1 + // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds (%struct.S1, %struct.S1* @s1, i32 0, i32 1), align 1 + s1.x++; +} + +void test21(void) { + // CHECK: {{%.*}} = alloca %struct.S1, align 1 + // CHECK: {{%.*}} = getelementptr inbounds %struct.S1, %struct.S1* {{%.*}}, i32 0, i32 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + __unaligned S1 s1_2; + s1_2.x++; +} + +typedef +struct __attribute__((packed)) S2 { + char c; + int x; +} S2; + +__unaligned S2 s2; +void test22(void) { + // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds (%struct.S2, %struct.S2* @s2, i32 0, i32 1), align 1 + // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds (%struct.S2, %struct.S2* @s2, i32 0, i32 1), align 1 + s2.x++; +} + +void test23(void) { + // CHECK: {{%.*}} = alloca %struct.S2, align 1 + // CHECK: {{%.*}} = getelementptr inbounds %struct.S2, %struct.S2* {{%.*}}, i32 0, i32 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + __unaligned S2 s2_2; + s2_2.x++; +} |