1 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s 2 3 // ------------- 4 // Scalar integer 5 // ------------- 6 __unaligned int x; 7 void test1(void) { 8 // CHECK: {{%.*}} = load i32, ptr @x, align 1 9 // CHECK: store i32 {{%.*}}, ptr @x, align 1 10 x++; 11 } 12 13 void test2(void) { 14 // CHECK: %y = alloca i32, align 1 15 // CHECK: {{%.*}} = load i32, ptr %y, align 1 16 // CHECK: store i32 {{%.*}}, ptr %y, align 1 17 __unaligned int y; 18 y++; 19 } 20 21 void test2_1(void) { 22 // CHECK: %y = alloca i32, align 1 23 // CHECK: store i32 1, ptr %y, align 1 24 __unaligned int y = 1; 25 } 26 27 // ------------- 28 // Global pointer 29 // ------------- 30 int *__unaligned p1; 31 void test3(void) { 32 33 // CHECK: {{%.*}} = load ptr, ptr @p1, align 1 34 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 4 35 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 4 36 (*p1)++; 37 } 38 39 int __unaligned *p2; 40 void test4(void) { 41 // CHECK: {{%.*}} = load ptr, ptr @p2, align 8 42 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 1 43 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 1 44 (*p2)++; 45 } 46 47 int __unaligned *__unaligned p3; 48 void test5(void) { 49 // CHECK: {{%.*}} = load ptr, ptr @p3, align 1 50 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 1 51 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 1 52 (*p3)++; 53 } 54 55 // ------------- 56 // Local pointer 57 // ------------- 58 void test6(void) { 59 // CHECK: %lp1 = alloca ptr, align 1 60 // CHECK: {{%.*}} = load ptr, ptr %lp1, align 1 61 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 4 62 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 4 63 int *__unaligned lp1; 64 (*lp1)++; 65 } 66 67 void test7(void) { 68 // CHECK: %lp2 = alloca ptr, align 8 69 // CHECK: {{%.*}} = load ptr, ptr %lp2, align 8 70 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 1 71 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 1 72 int __unaligned *lp2; 73 (*lp2)++; 74 } 75 76 void test8(void) { 77 // CHECK: %lp3 = alloca ptr, align 1 78 // CHECK: {{%.*}} = load ptr, ptr %lp3, align 1 79 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 1 80 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 1 81 int __unaligned *__unaligned lp3; 82 (*lp3)++; 83 } 84 85 // ------------- 86 // Global array 87 // ------------- 88 __unaligned int a[10]; 89 void test9(void) { 90 // CHECK: {{%.*}} = load i32, ptr getelementptr inbounds ([10 x i32], ptr @a, i64 0, i64 3), align 1 91 // CHECK: store i32 {{%.*}}, ptr getelementptr inbounds ([10 x i32], ptr @a, i64 0, i64 3), align 1 92 (a[3])++; 93 } 94 95 // ------------- 96 // Local array 97 // ------------- 98 void test10(void) { 99 // CHECK: %la = alloca [10 x i32], align 1 100 // CHECK: {{%.*}} = getelementptr inbounds [10 x i32], ptr %la, i64 0, i64 3 101 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 1 102 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 1 103 __unaligned int la[10]; 104 (la[3])++; 105 } 106 107 // -------- 108 // Typedefs 109 // -------- 110 111 typedef __unaligned int UnalignedInt; 112 void test13(void) { 113 // CHECK: %i = alloca i32, align 1 114 // CHECK: {{%.*}} = load i32, ptr %i, align 1 115 // CHECK: store i32 {{%.*}}, ptr %i, align 1 116 UnalignedInt i; 117 i++; 118 } 119 120 typedef int Aligned; 121 typedef __unaligned Aligned UnalignedInt2; 122 void test14(void) { 123 // CHECK: %i = alloca i32, align 1 124 // CHECK: {{%.*}} = load i32, ptr %i, align 1 125 // CHECK: store i32 {{%.*}}, ptr %i, align 1 126 UnalignedInt2 i; 127 i++; 128 } 129 130 typedef UnalignedInt UnalignedInt3; 131 void test15(void) { 132 // CHECK: %i = alloca i32, align 1 133 // CHECK: {{%.*}} = load i32, ptr %i, align 1 134 // CHECK: store i32 {{%.*}}, ptr %i, align 1 135 UnalignedInt3 i; 136 i++; 137 } 138 139 // ------------- 140 // Decayed types 141 // ------------- 142 void test16(__unaligned int c[10]) { 143 // CHECK: {{%.*}} = alloca ptr, align 8 144 // CHECK: store ptr %c, ptr {{%.*}}, align 8 145 // CHECK: {{%.*}} = load ptr, ptr {{%.*}}, align 8 146 // CHECK: {{%.*}} = getelementptr inbounds i32, ptr {{%.*}}, i64 3 147 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 1 148 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 1 149 c[3]++; 150 } 151 152 // ----------- 153 // __alignof__ 154 // ----------- 155 int test17(void) { 156 // CHECK: ret i32 1 157 return __alignof__(__unaligned int); 158 } 159 160 int test18(void) { 161 // CHECK: ret i32 1 162 __unaligned int a; 163 return __alignof__(a); 164 } 165 166 int test19(void) { 167 // CHECK: ret i32 1 168 __unaligned int a[10]; 169 return __alignof__(a); 170 } 171 172 // ----------- 173 // structs 174 // ----------- 175 typedef 176 struct S1 { 177 char c; 178 int x; 179 } S1; 180 181 __unaligned S1 s1; 182 void test20(void) { 183 // CHECK: {{%.*}} = load i32, ptr getelementptr inbounds nuw (%struct.S1, ptr @s1, i32 0, i32 1), align 1 184 // CHECK: store i32 {{%.*}}, ptr getelementptr inbounds nuw (%struct.S1, ptr @s1, i32 0, i32 1), align 1 185 s1.x++; 186 } 187 188 void test21(void) { 189 // CHECK: {{%.*}} = alloca %struct.S1, align 1 190 // CHECK: {{%.*}} = getelementptr inbounds nuw %struct.S1, ptr {{%.*}}, i32 0, i32 1 191 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 1 192 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 1 193 __unaligned S1 s1_2; 194 s1_2.x++; 195 } 196 197 typedef 198 struct __attribute__((packed)) S2 { 199 char c; 200 int x; 201 } S2; 202 203 __unaligned S2 s2; 204 void test22(void) { 205 // CHECK: {{%.*}} = load i32, ptr getelementptr inbounds nuw (%struct.S2, ptr @s2, i32 0, i32 1), align 1 206 // CHECK: store i32 {{%.*}}, ptr getelementptr inbounds nuw (%struct.S2, ptr @s2, i32 0, i32 1), align 1 207 s2.x++; 208 } 209 210 void test23(void) { 211 // CHECK: {{%.*}} = alloca %struct.S2, align 1 212 // CHECK: {{%.*}} = getelementptr inbounds nuw %struct.S2, ptr {{%.*}}, i32 0, i32 1 213 // CHECK: {{%.*}} = load i32, ptr {{%.*}}, align 1 214 // CHECK: store i32 {{%.*}}, ptr {{%.*}}, align 1 215 __unaligned S2 s2_2; 216 s2_2.x++; 217 } 218