1; RUN: llc < %s -mtriple=armv7-apple-ios -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-IOS --check-prefix=CHECK 2; RUN: llc < %s -mtriple=thumbv7m-none-macho -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-DARWIN --check-prefix=CHECK 3; RUN: llc < %s -mtriple=arm-none-eabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK 4; RUN: llc < %s -mtriple=arm-none-eabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK 5 6define void @f1(i8* %dest, i8* %src) { 7entry: 8 ; CHECK-LABEL: f1 9 10 ; CHECK-IOS: memmove 11 ; CHECK-DARWIN: memmove 12 ; CHECK-EABI: __aeabi_memmove 13 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false) 14 15 ; CHECK-IOS: memcpy 16 ; CHECK-DARWIN: memcpy 17 ; CHECK-EABI: __aeabi_memcpy 18 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 0, i1 false) 19 20 ; EABI memset swaps arguments 21 ; CHECK-IOS: mov r1, #1 22 ; CHECK-IOS: memset 23 ; CHECK-DARWIN: movs r1, #1 24 ; CHECK-DARWIN: memset 25 ; CHECK-EABI: mov r2, #1 26 ; CHECK-EABI: __aeabi_memset 27 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 0, i1 false) 28 29 ; EABI uses memclr if value set to 0 30 ; CHECK-IOS: mov r1, #0 31 ; CHECK-IOS: memset 32 ; CHECK-DARWIN: movs r1, #0 33 ; CHECK-DARWIN: memset 34 ; CHECK-EABI: __aeabi_memclr 35 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 0, i1 false) 36 37 ; EABI uses aligned function variants if possible 38 39 ; CHECK-IOS: memmove 40 ; CHECK-DARWIN: memmove 41 ; CHECK-EABI: __aeabi_memmove4 42 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false) 43 44 ; CHECK-IOS: memcpy 45 ; CHECK-DARWIN: memcpy 46 ; CHECK-EABI: __aeabi_memcpy4 47 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 4, i1 false) 48 49 ; CHECK-IOS: memset 50 ; CHECK-DARWIN: memset 51 ; CHECK-EABI: __aeabi_memset4 52 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 4, i1 false) 53 54 ; CHECK-IOS: memset 55 ; CHECK-DARWIN: memset 56 ; CHECK-EABI: __aeabi_memclr4 57 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 4, i1 false) 58 59 ; CHECK-IOS: memmove 60 ; CHECK-DARWIN: memmove 61 ; CHECK-EABI: __aeabi_memmove8 62 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false) 63 64 ; CHECK-IOS: memcpy 65 ; CHECK-DARWIN: memcpy 66 ; CHECK-EABI: __aeabi_memcpy8 67 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 500, i32 8, i1 false) 68 69 ; CHECK-IOS: memset 70 ; CHECK-DARWIN: memset 71 ; CHECK-EABI: __aeabi_memset8 72 call void @llvm.memset.p0i8.i32(i8* %dest, i8 1, i32 500, i32 8, i1 false) 73 74 ; CHECK-IOS: memset 75 ; CHECK-DARWIN: memset 76 ; CHECK-EABI: __aeabi_memclr8 77 call void @llvm.memset.p0i8.i32(i8* %dest, i8 0, i32 500, i32 8, i1 false) 78 79 unreachable 80} 81 82; Check that alloca arguments to memory intrinsics are automatically aligned if at least 8 bytes in size 83define void @f2(i8* %dest, i32 %n) { 84entry: 85 ; CHECK-LABEL: f2 86 87 ; IOS (ARMv7) should 8-byte align, others should 4-byte align 88 ; CHECK-IOS: add r1, sp, #32 89 ; CHECK-IOS: memmove 90 ; CHECK-DARWIN: add r1, sp, #28 91 ; CHECK-DARWIN: memmove 92 ; CHECK-EABI: add r1, sp, #28 93 ; CHECK-EABI: __aeabi_memmove 94 %arr0 = alloca [9 x i8], align 1 95 %0 = bitcast [9 x i8]* %arr0 to i8* 96 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 97 98 ; CHECK: add r1, sp, #16 99 ; CHECK-IOS: memcpy 100 ; CHECK-DARWIN: memcpy 101 ; CHECK-EABI: __aeabi_memcpy 102 %arr1 = alloca [9 x i8], align 1 103 %1 = bitcast [9 x i8]* %arr1 to i8* 104 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 105 106 ; CHECK-IOS: mov r0, sp 107 ; CHECK-IOS: mov r1, #1 108 ; CHECK-IOS: memset 109 ; CHECK-DARWIN: add r0, sp, #4 110 ; CHECK-DARWIN: movs r1, #1 111 ; CHECK-DARWIN: memset 112 ; CHECK-EABI: add r0, sp, #4 113 ; CHECK-EABI: mov r2, #1 114 ; CHECK-EABI: __aeabi_memset 115 %arr2 = alloca [9 x i8], align 1 116 %2 = bitcast [9 x i8]* %arr2 to i8* 117 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false) 118 119 unreachable 120} 121 122; Check that alloca arguments are not aligned if less than 8 bytes in size 123define void @f3(i8* %dest, i32 %n) { 124entry: 125 ; CHECK-LABEL: f3 126 127 ; CHECK: {{add(.w)? r1, sp, #17|sub(.w)? r1, r7, #15}} 128 ; CHECK-IOS: memmove 129 ; CHECK-DARWIN: memmove 130 ; CHECK-EABI: __aeabi_memmove 131 %arr0 = alloca [7 x i8], align 1 132 %0 = bitcast [7 x i8]* %arr0 to i8* 133 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 134 135 ; CHECK: {{add(.w)? r1, sp, #10}} 136 ; CHECK-IOS: memcpy 137 ; CHECK-DARWIN: memcpy 138 ; CHECK-EABI: __aeabi_memcpy 139 %arr1 = alloca [7 x i8], align 1 140 %1 = bitcast [7 x i8]* %arr1 to i8* 141 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 142 143 ; CHECK: {{add(.w)? r0, sp, #3}} 144 ; CHECK-IOS: mov r1, #1 145 ; CHECK-IOS: memset 146 ; CHECK-DARWIN: movs r1, #1 147 ; CHECK-DARWIN: memset 148 ; CHECK-EABI: mov r2, #1 149 ; CHECK-EABI: __aeabi_memset 150 %arr2 = alloca [7 x i8], align 1 151 %2 = bitcast [7 x i8]* %arr2 to i8* 152 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false) 153 154 unreachable 155} 156 157; Check that alloca arguments are not aligned if size+offset is less than 8 bytes 158define void @f4(i8* %dest, i32 %n) { 159entry: 160 ; CHECK-LABEL: f4 161 162 ; CHECK: {{add(.w)? r., sp, #23|sub(.w)? r., r7, #17}} 163 ; CHECK-IOS: memmove 164 ; CHECK-DARWIN: memmove 165 ; CHECK-EABI: __aeabi_memmove 166 %arr0 = alloca [9 x i8], align 1 167 %0 = getelementptr inbounds [9 x i8], [9 x i8]* %arr0, i32 0, i32 4 168 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 169 170 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 171 ; CHECK-IOS: memcpy 172 ; CHECK-DARWIN: memcpy 173 ; CHECK-EABI: __aeabi_memcpy 174 %arr1 = alloca [9 x i8], align 1 175 %1 = getelementptr inbounds [9 x i8], [9 x i8]* %arr1, i32 0, i32 4 176 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 177 178 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 179 ; CHECK-IOS: mov r1, #1 180 ; CHECK-IOS: memset 181 ; CHECK-DARWIN: movs r1, #1 182 ; CHECK-DARWIN: memset 183 ; CHECK-EABI: mov r2, #1 184 ; CHECK-EABI: __aeabi_memset 185 %arr2 = alloca [9 x i8], align 1 186 %2 = getelementptr inbounds [9 x i8], [9 x i8]* %arr2, i32 0, i32 4 187 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false) 188 189 unreachable 190} 191 192; Check that alloca arguments are not aligned if the offset is not a multiple of 4 193define void @f5(i8* %dest, i32 %n) { 194entry: 195 ; CHECK-LABEL: f5 196 197 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}} 198 ; CHECK-IOS: memmove 199 ; CHECK-DARWIN: memmove 200 ; CHECK-EABI: __aeabi_memmove 201 %arr0 = alloca [13 x i8], align 1 202 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 1 203 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 204 205 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 206 ; CHECK-IOS: memcpy 207 ; CHECK-DARWIN: memcpy 208 ; CHECK-EABI: __aeabi_memcpy 209 %arr1 = alloca [13 x i8], align 1 210 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 1 211 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 212 213 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 214 ; CHECK-IOS: mov r1, #1 215 ; CHECK-IOS: memset 216 ; CHECK-DARWIN: movs r1, #1 217 ; CHECK-DARWIN: memset 218 ; CHECK-EABI: mov r2, #1 219 ; CHECK-EABI: __aeabi_memset 220 %arr2 = alloca [13 x i8], align 1 221 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 1 222 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false) 223 224 unreachable 225} 226 227; Check that alloca arguments are not aligned if the offset is unknown 228define void @f6(i8* %dest, i32 %n, i32 %i) { 229entry: 230 ; CHECK-LABEL: f6 231 232 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #25}} 233 ; CHECK-IOS: memmove 234 ; CHECK-DARWIN: memmove 235 ; CHECK-EABI: __aeabi_memmove 236 %arr0 = alloca [13 x i8], align 1 237 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 %i 238 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 239 240 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 241 ; CHECK-IOS: memcpy 242 ; CHECK-DARWIN: memcpy 243 ; CHECK-EABI: __aeabi_memcpy 244 %arr1 = alloca [13 x i8], align 1 245 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 %i 246 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 247 248 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 249 ; CHECK-IOS: mov r1, #1 250 ; CHECK-IOS: memset 251 ; CHECK-DARWIN: movs r1, #1 252 ; CHECK-DARWIN: memset 253 ; CHECK-EABI: mov r2, #1 254 ; CHECK-EABI: __aeabi_memset 255 %arr2 = alloca [13 x i8], align 1 256 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 %i 257 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false) 258 259 unreachable 260} 261 262; Check that alloca arguments are not aligned if the GEP is not inbounds 263define void @f7(i8* %dest, i32 %n) { 264entry: 265 ; CHECK-LABEL: f7 266 267 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}} 268 ; CHECK-IOS: memmove 269 ; CHECK-DARWIN: memmove 270 ; CHECK-EABI: __aeabi_memmove 271 %arr0 = alloca [13 x i8], align 1 272 %0 = getelementptr [13 x i8], [13 x i8]* %arr0, i32 0, i32 4 273 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 274 275 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 276 ; CHECK-IOS: memcpy 277 ; CHECK-DARWIN: memcpy 278 ; CHECK-EABI: __aeabi_memcpy 279 %arr1 = alloca [13 x i8], align 1 280 %1 = getelementptr [13 x i8], [13 x i8]* %arr1, i32 0, i32 4 281 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 282 283 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 284 ; CHECK-IOS: mov r1, #1 285 ; CHECK-IOS: memset 286 ; CHECK-DARWIN: movs r1, #1 287 ; CHECK-DARWIN: memset 288 ; CHECK-EABI: mov r2, #1 289 ; CHECK-EABI: __aeabi_memset 290 %arr2 = alloca [13 x i8], align 1 291 %2 = getelementptr [13 x i8], [13 x i8]* %arr2, i32 0, i32 4 292 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false) 293 294 unreachable 295} 296 297; Check that alloca arguments are not aligned when the offset is past the end of the allocation 298define void @f8(i8* %dest, i32 %n) { 299entry: 300 ; CHECK-LABEL: f8 301 302 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}} 303 ; CHECK-IOS: memmove 304 ; CHECK-DARWIN: memmove 305 ; CHECK-EABI: __aeabi_memmove 306 %arr0 = alloca [13 x i8], align 1 307 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 16 308 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 309 310 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 311 ; CHECK-IOS: memcpy 312 ; CHECK-DARWIN: memcpy 313 ; CHECK-EABI: __aeabi_memcpy 314 %arr1 = alloca [13 x i8], align 1 315 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 16 316 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 317 318 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 319 ; CHECK-IOS: mov r1, #1 320 ; CHECK-IOS: memset 321 ; CHECK-DARWIN: movs r1, #1 322 ; CHECK-DARWIN: memset 323 ; CHECK-EABI: mov r2, #1 324 ; CHECK-EABI: __aeabi_memset 325 %arr2 = alloca [13 x i8], align 1 326 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 16 327 call void @llvm.memset.p0i8.i32(i8* %2, i8 1, i32 %n, i32 0, i1 false) 328 329 unreachable 330} 331 332; Check that global variables are aligned if they are large enough, but only if 333; they are defined in this object and don't have an explicit section. 334@arr1 = global [7 x i8] c"\01\02\03\04\05\06\07", align 1 335@arr2 = global [8 x i8] c"\01\02\03\04\05\06\07\08", align 1 336@arr3 = global [7 x i8] c"\01\02\03\04\05\06\07", section "foo,bar", align 1 337@arr4 = global [8 x i8] c"\01\02\03\04\05\06\07\08", section "foo,bar", align 1 338@arr5 = weak global [7 x i8] c"\01\02\03\04\05\06\07", align 1 339@arr6 = weak_odr global [7 x i8] c"\01\02\03\04\05\06\07", align 1 340@arr7 = external global [7 x i8], align 1 341define void @f9(i8* %dest, i32 %n) { 342entry: 343 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr1, i32 0, i32 0), i32 %n, i32 1, i1 false) 344 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @arr2, i32 0, i32 0), i32 %n, i32 1, i1 false) 345 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr3, i32 0, i32 0), i32 %n, i32 1, i1 false) 346 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @arr4, i32 0, i32 0), i32 %n, i32 1, i1 false) 347 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr5, i32 0, i32 0), i32 %n, i32 1, i1 false) 348 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr6, i32 0, i32 0), i32 %n, i32 1, i1 false) 349 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr7, i32 0, i32 0), i32 %n, i32 1, i1 false) 350 351 unreachable 352} 353 354; CHECK: {{\.data|\.section.+data}} 355; CHECK-NOT: .align 356; CHECK: arr1: 357; CHECK-IOS: .align 3 358; CHECK-DARWIN: .align 2 359; CHECK-EABI: .align 2 360; CHECK: arr2: 361; CHECK: {{\.section.+foo,bar}} 362; CHECK-NOT: .align 363; CHECK: arr3: 364; CHECK-NOT: .align 365; CHECK: arr4: 366; CHECK: {{\.data|\.section.+data}} 367; CHECK-NOT: .align 368; CHECK: arr5: 369; CHECK-NOT: .align 370; CHECK: arr6: 371; CHECK-NOT: arr7: 372 373declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind 374declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind 375declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind 376