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 6@from = common global [500 x i32] zeroinitializer, align 4 7@to = common global [500 x i32] zeroinitializer, align 4 8 9define void @f1() { 10entry: 11 ; CHECK-LABEL: f1 12 13 ; CHECK-IOS: memmove 14 ; CHECK-DARWIN: memmove 15 ; CHECK-EABI: __aeabi_memmove 16 call void @llvm.memmove.p0i8.p0i8.i32(i8* bitcast ([500 x i32]* @from to i8*), i8* bitcast ([500 x i32]* @to to i8*), i32 500, i32 0, i1 false) 17 18 ; CHECK-IOS: memcpy 19 ; CHECK-DARWIN: memcpy 20 ; CHECK-EABI: __aeabi_memcpy 21 call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([500 x i32]* @from to i8*), i8* bitcast ([500 x i32]* @to to i8*), i32 500, i32 0, i1 false) 22 23 ; EABI memset swaps arguments 24 ; CHECK-IOS: mov r1, #0 25 ; CHECK-IOS: memset 26 ; CHECK-DARWIN: movs r1, #0 27 ; CHECK-DARWIN: memset 28 ; CHECK-EABI: mov r2, #0 29 ; CHECK-EABI: __aeabi_memset 30 call void @llvm.memset.p0i8.i32(i8* bitcast ([500 x i32]* @from to i8*), i8 0, i32 500, i32 0, i1 false) 31 unreachable 32} 33 34; Check that alloca arguments to memory intrinsics are automatically aligned if at least 8 bytes in size 35define void @f2(i8* %dest, i32 %n) { 36entry: 37 ; CHECK-LABEL: f2 38 39 ; IOS (ARMv7) should 8-byte align, others should 4-byte align 40 ; CHECK-IOS: add r1, sp, #32 41 ; CHECK-IOS: memmove 42 ; CHECK-DARWIN: add r1, sp, #28 43 ; CHECK-DARWIN: memmove 44 ; CHECK-EABI: add r1, sp, #28 45 ; CHECK-EABI: __aeabi_memmove 46 %arr0 = alloca [9 x i8], align 1 47 %0 = bitcast [9 x i8]* %arr0 to i8* 48 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 49 50 ; CHECK: add r1, sp, #16 51 ; CHECK-IOS: memcpy 52 ; CHECK-DARWIN: memcpy 53 ; CHECK-EABI: __aeabi_memcpy 54 %arr1 = alloca [9 x i8], align 1 55 %1 = bitcast [9 x i8]* %arr1 to i8* 56 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 57 58 ; CHECK-IOS: mov r0, sp 59 ; CHECK-IOS: mov r1, #0 60 ; CHECK-IOS: memset 61 ; CHECK-DARINW: add r0, sp, #4 62 ; CHECK-DARWIN: movs r1, #0 63 ; CHECK-DARWIN: memset 64 ; CHECK-EABI: add r0, sp, #4 65 ; CHECK-EABI: mov r2, #0 66 ; CHECK-EABI: __aeabi_memset 67 %arr2 = alloca [9 x i8], align 1 68 %2 = bitcast [9 x i8]* %arr2 to i8* 69 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false) 70 71 unreachable 72} 73 74; Check that alloca arguments are not aligned if less than 8 bytes in size 75define void @f3(i8* %dest, i32 %n) { 76entry: 77 ; CHECK-LABEL: f3 78 79 ; CHECK: {{add(.w)? r1, sp, #17|sub(.w)? r1, r7, #15}} 80 ; CHECK-IOS: memmove 81 ; CHECK-DARWIN: memmove 82 ; CHECK-EABI: __aeabi_memmove 83 %arr0 = alloca [7 x i8], align 1 84 %0 = bitcast [7 x i8]* %arr0 to i8* 85 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 86 87 ; CHECK: {{add(.w)? r1, sp, #10}} 88 ; CHECK-IOS: memcpy 89 ; CHECK-DARWIN: memcpy 90 ; CHECK-EABI: __aeabi_memcpy 91 %arr1 = alloca [7 x i8], align 1 92 %1 = bitcast [7 x i8]* %arr1 to i8* 93 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 94 95 ; CHECK: {{add(.w)? r0, sp, #3}} 96 ; CHECK-IOS: mov r1, #0 97 ; CHECK-IOS: memset 98 ; CHECK-DARWIN: movs r1, #0 99 ; CHECK-DARWIN: memset 100 ; CHECK-EABI: mov r2, #0 101 ; CHECK-EABI: __aeabi_memset 102 %arr2 = alloca [7 x i8], align 1 103 %2 = bitcast [7 x i8]* %arr2 to i8* 104 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false) 105 106 unreachable 107} 108 109; Check that alloca arguments are not aligned if size+offset is less than 8 bytes 110define void @f4(i8* %dest, i32 %n) { 111entry: 112 ; CHECK-LABEL: f4 113 114 ; CHECK: {{add(.w)? r., sp, #23|sub(.w)? r., r7, #17}} 115 ; CHECK-IOS: memmove 116 ; CHECK-DARWIN: memmove 117 ; CHECK-EABI: __aeabi_memmove 118 %arr0 = alloca [9 x i8], align 1 119 %0 = getelementptr inbounds [9 x i8], [9 x i8]* %arr0, i32 0, i32 4 120 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 121 122 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 123 ; CHECK-IOS: memcpy 124 ; CHECK-DARWIN: memcpy 125 ; CHECK-EABI: __aeabi_memcpy 126 %arr1 = alloca [9 x i8], align 1 127 %1 = getelementptr inbounds [9 x i8], [9 x i8]* %arr1, i32 0, i32 4 128 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 129 130 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 131 ; CHECK-IOS: mov r1, #0 132 ; CHECK-IOS: memset 133 ; CHECK-DARWIN: movs r1, #0 134 ; CHECK-DARWIN: memset 135 ; CHECK-EABI: mov r2, #0 136 ; CHECK-EABI: __aeabi_memset 137 %arr2 = alloca [9 x i8], align 1 138 %2 = getelementptr inbounds [9 x i8], [9 x i8]* %arr2, i32 0, i32 4 139 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false) 140 141 unreachable 142} 143 144; Check that alloca arguments are not aligned if the offset is not a multiple of 4 145define void @f5(i8* %dest, i32 %n) { 146entry: 147 ; CHECK-LABEL: f5 148 149 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}} 150 ; CHECK-IOS: memmove 151 ; CHECK-DARWIN: memmove 152 ; CHECK-EABI: __aeabi_memmove 153 %arr0 = alloca [13 x i8], align 1 154 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 1 155 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 156 157 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 158 ; CHECK-IOS: memcpy 159 ; CHECK-DARWIN: memcpy 160 ; CHECK-EABI: __aeabi_memcpy 161 %arr1 = alloca [13 x i8], align 1 162 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 1 163 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 164 165 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 166 ; CHECK-IOS: mov r1, #0 167 ; CHECK-IOS: memset 168 ; CHECK-DARWIN: movs r1, #0 169 ; CHECK-DARWIN: memset 170 ; CHECK-EABI: mov r2, #0 171 ; CHECK-EABI: __aeabi_memset 172 %arr2 = alloca [13 x i8], align 1 173 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 1 174 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false) 175 176 unreachable 177} 178 179; Check that alloca arguments are not aligned if the offset is unknown 180define void @f6(i8* %dest, i32 %n, i32 %i) { 181entry: 182 ; CHECK-LABEL: f6 183 184 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #25}} 185 ; CHECK-IOS: memmove 186 ; CHECK-DARWIN: memmove 187 ; CHECK-EABI: __aeabi_memmove 188 %arr0 = alloca [13 x i8], align 1 189 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 %i 190 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 191 192 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 193 ; CHECK-IOS: memcpy 194 ; CHECK-DARWIN: memcpy 195 ; CHECK-EABI: __aeabi_memcpy 196 %arr1 = alloca [13 x i8], align 1 197 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 %i 198 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 199 200 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 201 ; CHECK-IOS: mov r1, #0 202 ; CHECK-IOS: memset 203 ; CHECK-DARWIN: movs r1, #0 204 ; CHECK-DARWIN: memset 205 ; CHECK-EABI: mov r2, #0 206 ; CHECK-EABI: __aeabi_memset 207 %arr2 = alloca [13 x i8], align 1 208 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 %i 209 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false) 210 211 unreachable 212} 213 214; Check that alloca arguments are not aligned if the GEP is not inbounds 215define void @f7(i8* %dest, i32 %n) { 216entry: 217 ; CHECK-LABEL: f7 218 219 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}} 220 ; CHECK-IOS: memmove 221 ; CHECK-DARWIN: memmove 222 ; CHECK-EABI: __aeabi_memmove 223 %arr0 = alloca [13 x i8], align 1 224 %0 = getelementptr [13 x i8], [13 x i8]* %arr0, i32 0, i32 4 225 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 226 227 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 228 ; CHECK-IOS: memcpy 229 ; CHECK-DARWIN: memcpy 230 ; CHECK-EABI: __aeabi_memcpy 231 %arr1 = alloca [13 x i8], align 1 232 %1 = getelementptr [13 x i8], [13 x i8]* %arr1, i32 0, i32 4 233 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 234 235 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 236 ; CHECK-IOS: mov r1, #0 237 ; CHECK-IOS: memset 238 ; CHECK-DARWIN: movs r1, #0 239 ; CHECK-DARWIN: memset 240 ; CHECK-EABI: mov r2, #0 241 ; CHECK-EABI: __aeabi_memset 242 %arr2 = alloca [13 x i8], align 1 243 %2 = getelementptr [13 x i8], [13 x i8]* %arr2, i32 0, i32 4 244 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false) 245 246 unreachable 247} 248 249; Check that alloca arguments are not aligned when the offset is past the end of the allocation 250define void @f8(i8* %dest, i32 %n) { 251entry: 252 ; CHECK-LABEL: f8 253 254 ; CHECK: {{add(.w)? r., sp, #27|sub(.w)? r., r7, #21}} 255 ; CHECK-IOS: memmove 256 ; CHECK-DARWIN: memmove 257 ; CHECK-EABI: __aeabi_memmove 258 %arr0 = alloca [13 x i8], align 1 259 %0 = getelementptr inbounds [13 x i8], [13 x i8]* %arr0, i32 0, i32 16 260 call void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %0, i32 %n, i32 0, i1 false) 261 262 ; CHECK: {{add(.w)? r., sp, #(10|14)}} 263 ; CHECK-IOS: memcpy 264 ; CHECK-DARWIN: memcpy 265 ; CHECK-EABI: __aeabi_memcpy 266 %arr1 = alloca [13 x i8], align 1 267 %1 = getelementptr inbounds [13 x i8], [13 x i8]* %arr1, i32 0, i32 16 268 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %1, i32 %n, i32 0, i1 false) 269 270 ; CHECK: {{add(.w)? r., sp, #(1|5)}} 271 ; CHECK-IOS: mov r1, #0 272 ; CHECK-IOS: memset 273 ; CHECK-DARWIN: movs r1, #0 274 ; CHECK-DARWIN: memset 275 ; CHECK-EABI: mov r2, #0 276 ; CHECK-EABI: __aeabi_memset 277 %arr2 = alloca [13 x i8], align 1 278 %2 = getelementptr inbounds [13 x i8], [13 x i8]* %arr2, i32 0, i32 16 279 call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 %n, i32 0, i1 false) 280 281 unreachable 282} 283 284declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind 285declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind 286declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind 287