1 ; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM 2 ; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM 3 ; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=THUMB 4 ; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG 5 ; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG 6 ; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=THUMB-LONG 7 8 ; Note that some of these tests assume that relocations are either 9 ; movw/movt or constant pool loads. Different platforms will select 10 ; different approaches. 11 12 @message1 = global [60 x i8] c"The LLVM Compiler Infrastructure\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 1 13 @temp = common global [60 x i8] zeroinitializer, align 1 14 15 define void @t1() nounwind ssp { 16 ; ARM-LABEL: t1: 17 ; ARM: {{(movw r0, :lower16:_?message1)|(ldr r0, .LCPI)}} 18 ; ARM: {{(movt r0, :upper16:_?message1)|(ldr r0, \[r0\])}} 19 ; ARM: add r0, r0, #5 20 ; ARM: movw r1, #64 21 ; ARM: movw r2, #10 22 ; ARM: and r1, r1, #255 23 ; ARM: bl {{_?}}memset 24 ; ARM-LONG-LABEL: t1: 25 ; ARM-LONG: {{(movw r3, :lower16:L_memset\$non_lazy_ptr)|(ldr r3, .LCPI)}} 26 ; ARM-LONG: {{(movt r3, :upper16:L_memset\$non_lazy_ptr)?}} 27 ; ARM-LONG: ldr r3, [r3] 28 ; ARM-LONG: blx r3 29 ; THUMB-LABEL: t1: 30 ; THUMB: {{(movw r0, :lower16:_?message1)|(ldr.n r0, .LCPI)}} 31 ; THUMB: {{(movt r0, :upper16:_?message1)|(ldr r0, \[r0\])}} 32 ; THUMB: adds r0, #5 33 ; THUMB: movs r1, #64 34 ; THUMB: movs r2, #10 35 ; THUMB: and r1, r1, #255 36 ; THUMB: bl {{_?}}memset 37 ; THUMB-LONG-LABEL: t1: 38 ; THUMB-LONG: movw r3, :lower16:L_memset$non_lazy_ptr 39 ; THUMB-LONG: movt r3, :upper16:L_memset$non_lazy_ptr 40 ; THUMB-LONG: ldr r3, [r3] 41 ; THUMB-LONG: blx r3 42 call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @message1, i32 0, i32 5), i8 64, i32 10, i32 4, i1 false) 43 ret void 44 } 45 46 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind 47 48 define void @t2() nounwind ssp { 49 ; ARM-LABEL: t2: 50 ; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}} 51 ; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 52 ; ARM: ldr r0, [r0] 53 ; ARM: add r1, r0, #4 54 ; ARM: add r0, r0, #16 55 ; ARM: movw r2, #17 56 ; ARM: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill 57 ; ARM: mov r0, r1 58 ; ARM: ldr r1, [sp[[SLOT]]] @ 4-byte Reload 59 ; ARM: bl {{_?}}memcpy 60 ; ARM-LONG-LABEL: t2: 61 ; ARM-LONG: {{(movw r3, :lower16:L_memcpy\$non_lazy_ptr)|(ldr r3, .LCPI)}} 62 ; ARM-LONG: {{(movt r3, :upper16:L_memcpy\$non_lazy_ptr)?}} 63 ; ARM-LONG: ldr r3, [r3] 64 ; ARM-LONG: blx r3 65 ; THUMB-LABEL: t2: 66 ; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}} 67 ; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 68 ; THUMB: ldr r0, [r0] 69 ; THUMB: adds r1, r0, #4 70 ; THUMB: adds r0, #16 71 ; THUMB: movs r2, #17 72 ; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill 73 ; THUMB: mov r0, r1 74 ; THUMB: ldr r1, [sp[[SLOT]]] @ 4-byte Reload 75 ; THUMB: bl {{_?}}memcpy 76 ; THUMB-LONG-LABEL: t2: 77 ; THUMB-LONG: movw r3, :lower16:L_memcpy$non_lazy_ptr 78 ; THUMB-LONG: movt r3, :upper16:L_memcpy$non_lazy_ptr 79 ; THUMB-LONG: ldr r3, [r3] 80 ; THUMB-LONG: blx r3 81 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 17, i32 4, i1 false) 82 ret void 83 } 84 85 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind 86 87 define void @t3() nounwind ssp { 88 ; ARM-LABEL: t3: 89 ; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}} 90 ; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 91 ; ARM: ldr r0, [r0] 92 ; ARM: add r1, r0, #4 93 ; ARM: add r0, r0, #16 94 ; ARM: movw r2, #10 95 ; ARM: mov r0, r1 96 ; ARM: bl {{_?}}memmove 97 ; ARM-LONG-LABEL: t3: 98 ; ARM-LONG: {{(movw r3, :lower16:L_memmove\$non_lazy_ptr)|(ldr r3, .LCPI)}} 99 ; ARM-LONG: {{(movt r3, :upper16:L_memmove\$non_lazy_ptr)?}} 100 ; ARM-LONG: ldr r3, [r3] 101 ; ARM-LONG: blx r3 102 ; THUMB-LABEL: t3: 103 ; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}} 104 ; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 105 ; THUMB: ldr r0, [r0] 106 ; THUMB: adds r1, r0, #4 107 ; THUMB: adds r0, #16 108 ; THUMB: movs r2, #10 109 ; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill 110 ; THUMB: mov r0, r1 111 ; THUMB: ldr r1, [sp[[SLOT]]] @ 4-byte Reload 112 ; THUMB: bl {{_?}}memmove 113 ; THUMB-LONG-LABEL: t3: 114 ; THUMB-LONG: movw r3, :lower16:L_memmove$non_lazy_ptr 115 ; THUMB-LONG: movt r3, :upper16:L_memmove$non_lazy_ptr 116 ; THUMB-LONG: ldr r3, [r3] 117 ; THUMB-LONG: blx r3 118 call void @llvm.memmove.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 1, i1 false) 119 ret void 120 } 121 122 define void @t4() nounwind ssp { 123 ; ARM-LABEL: t4: 124 ; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}} 125 ; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 126 ; ARM: ldr r0, [r0] 127 ; ARM: ldr r1, [r0, #16] 128 ; ARM: str r1, [r0, #4] 129 ; ARM: ldr r1, [r0, #20] 130 ; ARM: str r1, [r0, #8] 131 ; ARM: ldrh r1, [r0, #24] 132 ; ARM: strh r1, [r0, #12] 133 ; ARM: bx lr 134 ; THUMB-LABEL: t4: 135 ; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}} 136 ; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 137 ; THUMB: ldr r0, [r0] 138 ; THUMB: ldr r1, [r0, #16] 139 ; THUMB: str r1, [r0, #4] 140 ; THUMB: ldr r1, [r0, #20] 141 ; THUMB: str r1, [r0, #8] 142 ; THUMB: ldrh r1, [r0, #24] 143 ; THUMB: strh r1, [r0, #12] 144 ; THUMB: bx lr 145 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 4, i1 false) 146 ret void 147 } 148 149 declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind 150 151 define void @t5() nounwind ssp { 152 ; ARM-LABEL: t5: 153 ; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}} 154 ; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 155 ; ARM: ldr r0, [r0] 156 ; ARM: ldrh r1, [r0, #16] 157 ; ARM: strh r1, [r0, #4] 158 ; ARM: ldrh r1, [r0, #18] 159 ; ARM: strh r1, [r0, #6] 160 ; ARM: ldrh r1, [r0, #20] 161 ; ARM: strh r1, [r0, #8] 162 ; ARM: ldrh r1, [r0, #22] 163 ; ARM: strh r1, [r0, #10] 164 ; ARM: ldrh r1, [r0, #24] 165 ; ARM: strh r1, [r0, #12] 166 ; ARM: bx lr 167 ; THUMB-LABEL: t5: 168 ; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}} 169 ; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 170 ; THUMB: ldr r0, [r0] 171 ; THUMB: ldrh r1, [r0, #16] 172 ; THUMB: strh r1, [r0, #4] 173 ; THUMB: ldrh r1, [r0, #18] 174 ; THUMB: strh r1, [r0, #6] 175 ; THUMB: ldrh r1, [r0, #20] 176 ; THUMB: strh r1, [r0, #8] 177 ; THUMB: ldrh r1, [r0, #22] 178 ; THUMB: strh r1, [r0, #10] 179 ; THUMB: ldrh r1, [r0, #24] 180 ; THUMB: strh r1, [r0, #12] 181 ; THUMB: bx lr 182 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 2, i1 false) 183 ret void 184 } 185 186 define void @t6() nounwind ssp { 187 ; ARM-LABEL: t6: 188 ; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}} 189 ; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 190 ; ARM: ldr r0, [r0] 191 ; ARM: ldrb r1, [r0, #16] 192 ; ARM: strb r1, [r0, #4] 193 ; ARM: ldrb r1, [r0, #17] 194 ; ARM: strb r1, [r0, #5] 195 ; ARM: ldrb r1, [r0, #18] 196 ; ARM: strb r1, [r0, #6] 197 ; ARM: ldrb r1, [r0, #19] 198 ; ARM: strb r1, [r0, #7] 199 ; ARM: ldrb r1, [r0, #20] 200 ; ARM: strb r1, [r0, #8] 201 ; ARM: ldrb r1, [r0, #21] 202 ; ARM: strb r1, [r0, #9] 203 ; ARM: ldrb r1, [r0, #22] 204 ; ARM: strb r1, [r0, #10] 205 ; ARM: ldrb r1, [r0, #23] 206 ; ARM: strb r1, [r0, #11] 207 ; ARM: ldrb r1, [r0, #24] 208 ; ARM: strb r1, [r0, #12] 209 ; ARM: ldrb r1, [r0, #25] 210 ; ARM: strb r1, [r0, #13] 211 ; ARM: bx lr 212 ; THUMB-LABEL: t6: 213 ; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}} 214 ; THUMB: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}} 215 ; THUMB: ldr r0, [r0] 216 ; THUMB: ldrb r1, [r0, #16] 217 ; THUMB: strb r1, [r0, #4] 218 ; THUMB: ldrb r1, [r0, #17] 219 ; THUMB: strb r1, [r0, #5] 220 ; THUMB: ldrb r1, [r0, #18] 221 ; THUMB: strb r1, [r0, #6] 222 ; THUMB: ldrb r1, [r0, #19] 223 ; THUMB: strb r1, [r0, #7] 224 ; THUMB: ldrb r1, [r0, #20] 225 ; THUMB: strb r1, [r0, #8] 226 ; THUMB: ldrb r1, [r0, #21] 227 ; THUMB: strb r1, [r0, #9] 228 ; THUMB: ldrb r1, [r0, #22] 229 ; THUMB: strb r1, [r0, #10] 230 ; THUMB: ldrb r1, [r0, #23] 231 ; THUMB: strb r1, [r0, #11] 232 ; THUMB: ldrb r1, [r0, #24] 233 ; THUMB: strb r1, [r0, #12] 234 ; THUMB: ldrb r1, [r0, #25] 235 ; THUMB: strb r1, [r0, #13] 236 ; THUMB: bx lr 237 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 10, i32 1, i1 false) 238 ret void 239 } 240 241 ; rdar://13202135 242 define void @t7() nounwind ssp { 243 ; Just make sure this doesn't assert when we have an odd length and an alignment of 2. 244 call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 4), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @temp, i32 0, i32 16), i32 3, i32 2, i1 false) 245 ret void 246 } 247 248 define i32 @t8(i32 %x) nounwind { 249 entry: 250 ; ARM-LABEL: t8: 251 ; ARM-NOT: FastISel missed call: %expval = call i32 @llvm.expect.i32(i32 %x, i32 1) 252 ; THUMB-LABEL: t8: 253 ; THUMB-NOT: FastISel missed call: %expval = call i32 @llvm.expect.i32(i32 %x, i32 1) 254 %expval = call i32 @llvm.expect.i32(i32 %x, i32 1) 255 ret i32 %expval 256 } 257 258 declare i32 @llvm.expect.i32(i32, i32) nounwind readnone 259