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