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 15define 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 46declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind 47 48define 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 85declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind 86 87define 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 122define 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 149declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind 150 151define 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 186define 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 242define 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 248define i32 @t8(i32 %x) nounwind { 249entry: 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 258declare i32 @llvm.expect.i32(i32, i32) nounwind readnone 259