1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs -mtriple=aarch64 -code-model=tiny -relocation-model=pic < %s | FileCheck %s --check-prefix=CHECK-PIC 3; RUN: llc -verify-machineinstrs -mtriple=aarch64 -code-model=tiny -relocation-model=pic -fast-isel < %s | FileCheck %s --check-prefix=CHECK-PIC 4; RUN: llc -verify-machineinstrs -mtriple=aarch64 -code-model=tiny -relocation-model=pic -global-isel < %s | FileCheck %s --check-prefix=CHECK-PIC-GLOBISEL 5 6; Note fast-isel tests here will fall back to isel 7 8@src = external local_unnamed_addr global [65536 x i8], align 1 9@dst = external global [65536 x i8], align 1 10@ptr = external local_unnamed_addr global i8*, align 8 11 12define dso_preemptable void @foo1() { 13; CHECK-LABEL: foo1: 14; CHECK: // %bb.0: // %entry 15; CHECK-NEXT: ldr x8, :got:src 16; CHECK-NEXT: ldrb w8, [x8] 17; CHECK-NEXT: ldr x9, :got:dst 18; CHECK-NEXT: strb w8, [x9] 19; CHECK-NEXT: ret 20; 21; CHECK-GLOBISEL-LABEL: foo1: 22; CHECK-GLOBISEL: // %bb.0: // %entry 23; CHECK-GLOBISEL-NEXT: ldr x8, :got:src 24; CHECK-GLOBISEL-NEXT: ldrb w8, [x8] 25; CHECK-GLOBISEL-NEXT: ldr x9, :got:dst 26; CHECK-GLOBISEL-NEXT: strb w8, [x9] 27; CHECK-GLOBISEL-NEXT: ret 28; 29; CHECK-PIC-LABEL: foo1: 30; CHECK-PIC: // %bb.0: // %entry 31; CHECK-PIC-NEXT: ldr x8, :got:src 32; CHECK-PIC-NEXT: ldrb w8, [x8] 33; CHECK-PIC-NEXT: ldr x9, :got:dst 34; CHECK-PIC-NEXT: strb w8, [x9] 35; CHECK-PIC-NEXT: ret 36; 37; CHECK-PIC-GLOBISEL-LABEL: foo1: 38; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 39; CHECK-PIC-GLOBISEL-NEXT: ldr x8, :got:src 40; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8] 41; CHECK-PIC-GLOBISEL-NEXT: ldr x9, :got:dst 42; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9] 43; CHECK-PIC-GLOBISEL-NEXT: ret 44entry: 45 %0 = load i8, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @src, i64 0, i64 0), align 1 46 store i8 %0, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @dst, i64 0, i64 0), align 1 47 ret void 48} 49 50define dso_preemptable void @foo2() { 51; CHECK-LABEL: foo2: 52; CHECK: // %bb.0: // %entry 53; CHECK-NEXT: ldr x8, :got:ptr 54; CHECK-NEXT: ldr x9, :got:dst 55; CHECK-NEXT: str x9, [x8] 56; CHECK-NEXT: ret 57; 58; CHECK-GLOBISEL-LABEL: foo2: 59; CHECK-GLOBISEL: // %bb.0: // %entry 60; CHECK-GLOBISEL-NEXT: ldr x8, :got:ptr 61; CHECK-GLOBISEL-NEXT: ldr x9, :got:dst 62; CHECK-GLOBISEL-NEXT: str x9, [x8] 63; CHECK-GLOBISEL-NEXT: ret 64; 65; CHECK-PIC-LABEL: foo2: 66; CHECK-PIC: // %bb.0: // %entry 67; CHECK-PIC-NEXT: ldr x8, :got:ptr 68; CHECK-PIC-NEXT: ldr x9, :got:dst 69; CHECK-PIC-NEXT: str x9, [x8] 70; CHECK-PIC-NEXT: ret 71; 72; CHECK-PIC-GLOBISEL-LABEL: foo2: 73; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 74; CHECK-PIC-GLOBISEL-NEXT: ldr x8, :got:ptr 75; CHECK-PIC-GLOBISEL-NEXT: ldr x9, :got:dst 76; CHECK-PIC-GLOBISEL-NEXT: str x9, [x8] 77; CHECK-PIC-GLOBISEL-NEXT: ret 78entry: 79 store i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @dst, i64 0, i64 0), i8** @ptr, align 8 80 ret void 81} 82 83define dso_preemptable void @foo3() { 84; FIXME: Needn't adr ptr 85; 86; CHECK-LABEL: foo3: 87; CHECK: // %bb.0: // %entry 88; CHECK-NEXT: ldr x8, :got:src 89; CHECK-NEXT: ldr x9, :got:ptr 90; CHECK-NEXT: ldrb w8, [x8] 91; CHECK-NEXT: ldr x9, [x9] 92; CHECK-NEXT: strb w8, [x9] 93; CHECK-NEXT: ret 94; 95; CHECK-GLOBISEL-LABEL: foo3: 96; CHECK-GLOBISEL: // %bb.0: // %entry 97; CHECK-GLOBISEL-NEXT: ldr x8, :got:src 98; CHECK-GLOBISEL-NEXT: ldr x9, :got:ptr 99; CHECK-GLOBISEL-NEXT: ldrb w8, [x8] 100; CHECK-GLOBISEL-NEXT: ldr x9, [x9] 101; CHECK-GLOBISEL-NEXT: strb w8, [x9] 102; CHECK-GLOBISEL-NEXT: ret 103; 104; CHECK-PIC-LABEL: foo3: 105; CHECK-PIC: // %bb.0: // %entry 106; CHECK-PIC-NEXT: ldr x8, :got:src 107; CHECK-PIC-NEXT: ldr x9, :got:ptr 108; CHECK-PIC-NEXT: ldrb w8, [x8] 109; CHECK-PIC-NEXT: ldr x9, [x9] 110; CHECK-PIC-NEXT: strb w8, [x9] 111; CHECK-PIC-NEXT: ret 112; 113; CHECK-PIC-GLOBISEL-LABEL: foo3: 114; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 115; CHECK-PIC-GLOBISEL-NEXT: ldr x8, :got:src 116; CHECK-PIC-GLOBISEL-NEXT: ldr x9, :got:ptr 117; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8] 118; CHECK-PIC-GLOBISEL-NEXT: ldr x9, [x9] 119; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9] 120; CHECK-PIC-GLOBISEL-NEXT: ret 121entry: 122 %0 = load i8, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @src, i64 0, i64 0), align 1 123 %1 = load i8*, i8** @ptr, align 8 124 store i8 %0, i8* %1, align 1 125 ret void 126} 127 128@lsrc = internal global i8 0, align 4 129@ldst = internal global i8 0, align 4 130@lptr = internal global i8* null, align 8 131 132define dso_preemptable void @bar1() { 133; CHECK-LABEL: bar1: 134; CHECK: // %bb.0: // %entry 135; CHECK-NEXT: adr x8, lsrc 136; CHECK-NEXT: ldrb w8, [x8] 137; CHECK-NEXT: adr x9, ldst 138; CHECK-NEXT: strb w8, [x9] 139; CHECK-NEXT: ret 140; 141; CHECK-GLOBISEL-LABEL: bar1: 142; CHECK-GLOBISEL: // %bb.0: // %entry 143; CHECK-GLOBISEL-NEXT: adr x8, lsrc 144; CHECK-GLOBISEL-NEXT: ldrb w8, [x8] 145; CHECK-GLOBISEL-NEXT: adr x9, ldst 146; CHECK-GLOBISEL-NEXT: strb w8, [x9] 147; CHECK-GLOBISEL-NEXT: ret 148; 149; CHECK-PIC-LABEL: bar1: 150; CHECK-PIC: // %bb.0: // %entry 151; CHECK-PIC-NEXT: adr x8, lsrc 152; CHECK-PIC-NEXT: adr x9, ldst 153; CHECK-PIC-NEXT: ldrb w8, [x8] 154; CHECK-PIC-NEXT: strb w8, [x9] 155; CHECK-PIC-NEXT: ret 156; 157; CHECK-PIC-GLOBISEL-LABEL: bar1: 158; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 159; CHECK-PIC-GLOBISEL-NEXT: adr x8, lsrc 160; CHECK-PIC-GLOBISEL-NEXT: adr x9, ldst 161; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8] 162; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9] 163; CHECK-PIC-GLOBISEL-NEXT: ret 164entry: 165 %0 = load i8, i8* @lsrc, align 4 166 store i8 %0, i8* @ldst, align 4 167 ret void 168} 169 170define dso_preemptable void @bar2() { 171; CHECK-LABEL: bar2: 172; CHECK: // %bb.0: // %entry 173; CHECK-NEXT: adr x8, lptr 174; CHECK-NEXT: adr x9, ldst 175; CHECK-NEXT: str x9, [x8] 176; CHECK-NEXT: ret 177; 178; CHECK-GLOBISEL-LABEL: bar2: 179; CHECK-GLOBISEL: // %bb.0: // %entry 180; CHECK-GLOBISEL-NEXT: adr x8, lptr 181; CHECK-GLOBISEL-NEXT: adr x9, ldst 182; CHECK-GLOBISEL-NEXT: str x9, [x8] 183; CHECK-GLOBISEL-NEXT: ret 184; 185; CHECK-PIC-LABEL: bar2: 186; CHECK-PIC: // %bb.0: // %entry 187; CHECK-PIC-NEXT: adr x8, lptr 188; CHECK-PIC-NEXT: adr x9, ldst 189; CHECK-PIC-NEXT: str x9, [x8] 190; CHECK-PIC-NEXT: ret 191; 192; CHECK-PIC-GLOBISEL-LABEL: bar2: 193; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 194; CHECK-PIC-GLOBISEL-NEXT: adr x8, lptr 195; CHECK-PIC-GLOBISEL-NEXT: adr x9, ldst 196; CHECK-PIC-GLOBISEL-NEXT: str x9, [x8] 197; CHECK-PIC-GLOBISEL-NEXT: ret 198entry: 199 store i8* @ldst, i8** @lptr, align 8 200 ret void 201} 202 203define dso_preemptable void @bar3() { 204; FIXME: Needn't adr lptr 205; 206; CHECK-LABEL: bar3: 207; CHECK: // %bb.0: // %entry 208; CHECK-NEXT: adr x8, lsrc 209; CHECK-NEXT: ldrb w8, [x8] 210; CHECK-NEXT: ldr x9, lptr 211; CHECK-NEXT: strb w8, [x9] 212; CHECK-NEXT: ret 213; 214; CHECK-GLOBISEL-LABEL: bar3: 215; CHECK-GLOBISEL: // %bb.0: // %entry 216; CHECK-GLOBISEL-NEXT: adr x8, lsrc 217; CHECK-GLOBISEL-NEXT: adr x9, lptr 218; CHECK-GLOBISEL-NEXT: ldrb w8, [x8] 219; CHECK-GLOBISEL-NEXT: ldr x9, [x9] 220; CHECK-GLOBISEL-NEXT: strb w8, [x9] 221; CHECK-GLOBISEL-NEXT: ret 222; 223; CHECK-PIC-LABEL: bar3: 224; CHECK-PIC: // %bb.0: // %entry 225; CHECK-PIC-NEXT: adr x8, lsrc 226; CHECK-PIC-NEXT: ldr x9, lptr 227; CHECK-PIC-NEXT: ldrb w8, [x8] 228; CHECK-PIC-NEXT: strb w8, [x9] 229; CHECK-PIC-NEXT: ret 230; 231; CHECK-PIC-GLOBISEL-LABEL: bar3: 232; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 233; CHECK-PIC-GLOBISEL-NEXT: adr x8, lsrc 234; CHECK-PIC-GLOBISEL-NEXT: adr x9, lptr 235; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8] 236; CHECK-PIC-GLOBISEL-NEXT: ldr x9, [x9] 237; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9] 238; CHECK-PIC-GLOBISEL-NEXT: ret 239entry: 240 %0 = load i8, i8* @lsrc, align 4 241 %1 = load i8*, i8** @lptr, align 8 242 store i8 %0, i8* %1, align 1 243 ret void 244} 245 246 247@lbsrc = internal global [65536 x i8] zeroinitializer, align 4 248@lbdst = internal global [65536 x i8] zeroinitializer, align 4 249 250define dso_preemptable void @baz1() { 251; CHECK-LABEL: baz1: 252; CHECK: // %bb.0: // %entry 253; CHECK-NEXT: adr x8, lbsrc 254; CHECK-NEXT: ldrb w8, [x8] 255; CHECK-NEXT: adr x9, lbdst 256; CHECK-NEXT: strb w8, [x9] 257; CHECK-NEXT: ret 258; 259; CHECK-GLOBISEL-LABEL: baz1: 260; CHECK-GLOBISEL: // %bb.0: // %entry 261; CHECK-GLOBISEL-NEXT: adr x8, lbsrc 262; CHECK-GLOBISEL-NEXT: ldrb w8, [x8] 263; CHECK-GLOBISEL-NEXT: adr x9, lbdst 264; CHECK-GLOBISEL-NEXT: strb w8, [x9] 265; CHECK-GLOBISEL-NEXT: ret 266; 267; CHECK-PIC-LABEL: baz1: 268; CHECK-PIC: // %bb.0: // %entry 269; CHECK-PIC-NEXT: adr x8, lbsrc 270; CHECK-PIC-NEXT: adr x9, lbdst 271; CHECK-PIC-NEXT: ldrb w8, [x8] 272; CHECK-PIC-NEXT: strb w8, [x9] 273; CHECK-PIC-NEXT: ret 274; 275; CHECK-PIC-GLOBISEL-LABEL: baz1: 276; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 277; CHECK-PIC-GLOBISEL-NEXT: adr x8, lbsrc 278; CHECK-PIC-GLOBISEL-NEXT: adr x9, lbdst 279; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8] 280; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9] 281; CHECK-PIC-GLOBISEL-NEXT: ret 282entry: 283 %0 = load i8, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @lbsrc, i64 0, i64 0), align 4 284 store i8 %0, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @lbdst, i64 0, i64 0), align 4 285 ret void 286} 287 288define dso_preemptable void @baz2() { 289; CHECK-LABEL: baz2: 290; CHECK: // %bb.0: // %entry 291; CHECK-NEXT: adr x8, lptr 292; CHECK-NEXT: adr x9, lbdst 293; CHECK-NEXT: str x9, [x8] 294; CHECK-NEXT: ret 295; 296; CHECK-GLOBISEL-LABEL: baz2: 297; CHECK-GLOBISEL: // %bb.0: // %entry 298; CHECK-GLOBISEL-NEXT: adr x8, lptr 299; CHECK-GLOBISEL-NEXT: adr x9, lbdst 300; CHECK-GLOBISEL-NEXT: str x9, [x8] 301; CHECK-GLOBISEL-NEXT: ret 302; 303; CHECK-PIC-LABEL: baz2: 304; CHECK-PIC: // %bb.0: // %entry 305; CHECK-PIC-NEXT: adr x8, lptr 306; CHECK-PIC-NEXT: adr x9, lbdst 307; CHECK-PIC-NEXT: str x9, [x8] 308; CHECK-PIC-NEXT: ret 309; 310; CHECK-PIC-GLOBISEL-LABEL: baz2: 311; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 312; CHECK-PIC-GLOBISEL-NEXT: adr x8, lptr 313; CHECK-PIC-GLOBISEL-NEXT: adr x9, lbdst 314; CHECK-PIC-GLOBISEL-NEXT: str x9, [x8] 315; CHECK-PIC-GLOBISEL-NEXT: ret 316entry: 317 store i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @lbdst, i64 0, i64 0), i8** @lptr, align 8 318 ret void 319} 320 321define dso_preemptable void @baz3() { 322; FIXME: Needn't adr lptr 323; 324; CHECK-LABEL: baz3: 325; CHECK: // %bb.0: // %entry 326; CHECK-NEXT: adr x8, lbsrc 327; CHECK-NEXT: ldrb w8, [x8] 328; CHECK-NEXT: ldr x9, lptr 329; CHECK-NEXT: strb w8, [x9] 330; CHECK-NEXT: ret 331; 332; CHECK-GLOBISEL-LABEL: baz3: 333; CHECK-GLOBISEL: // %bb.0: // %entry 334; CHECK-GLOBISEL-NEXT: adr x8, lbsrc 335; CHECK-GLOBISEL-NEXT: adr x9, lptr 336; CHECK-GLOBISEL-NEXT: ldrb w8, [x8] 337; CHECK-GLOBISEL-NEXT: ldr x9, [x9] 338; CHECK-GLOBISEL-NEXT: strb w8, [x9] 339; CHECK-GLOBISEL-NEXT: ret 340; 341; CHECK-PIC-LABEL: baz3: 342; CHECK-PIC: // %bb.0: // %entry 343; CHECK-PIC-NEXT: adr x8, lbsrc 344; CHECK-PIC-NEXT: ldr x9, lptr 345; CHECK-PIC-NEXT: ldrb w8, [x8] 346; CHECK-PIC-NEXT: strb w8, [x9] 347; CHECK-PIC-NEXT: ret 348; 349; CHECK-PIC-GLOBISEL-LABEL: baz3: 350; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 351; CHECK-PIC-GLOBISEL-NEXT: adr x8, lbsrc 352; CHECK-PIC-GLOBISEL-NEXT: adr x9, lptr 353; CHECK-PIC-GLOBISEL-NEXT: ldrb w8, [x8] 354; CHECK-PIC-GLOBISEL-NEXT: ldr x9, [x9] 355; CHECK-PIC-GLOBISEL-NEXT: strb w8, [x9] 356; CHECK-PIC-GLOBISEL-NEXT: ret 357entry: 358 %0 = load i8, i8* getelementptr inbounds ([65536 x i8], [65536 x i8]* @lbsrc, i64 0, i64 0), align 4 359 %1 = load i8*, i8** @lptr, align 8 360 store i8 %0, i8* %1, align 1 361 ret void 362} 363 364 365declare void @func(...) 366 367define dso_preemptable i8* @externfuncaddr() { 368; CHECK-LABEL: externfuncaddr: 369; CHECK: // %bb.0: // %entry 370; CHECK-NEXT: ldr x0, :got:func 371; CHECK-NEXT: ret 372; 373; CHECK-GLOBISEL-LABEL: externfuncaddr: 374; CHECK-GLOBISEL: // %bb.0: // %entry 375; CHECK-GLOBISEL-NEXT: ldr x0, :got:func 376; CHECK-GLOBISEL-NEXT: ret 377; 378; CHECK-PIC-LABEL: externfuncaddr: 379; CHECK-PIC: // %bb.0: // %entry 380; CHECK-PIC-NEXT: ldr x0, :got:func 381; CHECK-PIC-NEXT: ret 382; 383; CHECK-PIC-GLOBISEL-LABEL: externfuncaddr: 384; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 385; CHECK-PIC-GLOBISEL-NEXT: ldr x0, :got:func 386; CHECK-PIC-GLOBISEL-NEXT: ret 387entry: 388 ret i8* bitcast (void (...)* @func to i8*) 389} 390 391define dso_preemptable i8* @localfuncaddr() { 392; CHECK-LABEL: localfuncaddr: 393; CHECK: // %bb.0: // %entry 394; CHECK-NEXT: adr x0, externfuncaddr 395; CHECK-NEXT: ret 396; 397; CHECK-GLOBISEL-LABEL: localfuncaddr: 398; CHECK-GLOBISEL: // %bb.0: // %entry 399; CHECK-GLOBISEL-NEXT: adr x0, externfuncaddr 400; CHECK-GLOBISEL-NEXT: ret 401; 402; CHECK-PIC-LABEL: localfuncaddr: 403; CHECK-PIC: // %bb.0: // %entry 404; CHECK-PIC-NEXT: ldr x0, :got:externfuncaddr 405; CHECK-PIC-NEXT: ret 406; 407; CHECK-PIC-GLOBISEL-LABEL: localfuncaddr: 408; CHECK-PIC-GLOBISEL: // %bb.0: // %entry 409; CHECK-PIC-GLOBISEL-NEXT: ldr x0, :got:externfuncaddr 410; CHECK-PIC-GLOBISEL-NEXT: ret 411entry: 412 ret i8* bitcast (i8* ()* @externfuncaddr to i8*) 413} 414 415