1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; Run with --no_x86_scrub_rip because we care a lot about how globals are 3; accessed in the code model. 4 5; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-STATIC 6; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-STATIC 7; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-STATIC 8; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-PIC 9; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-PIC 10; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-PIC 11 12; Generated from this C source: 13; 14; static int static_data[10]; 15; int global_data[10] = {1, 2}; 16; extern int extern_data[10]; 17; 18; int *lea_static_data() { return &static_data[0]; } 19; int *lea_global_data() { return &global_data[0]; } 20; int *lea_extern_data() { return &extern_data[0]; } 21; 22; static void static_fn(void) {} 23; void global_fn(void) {} 24; void extern_fn(void); 25; 26; typedef void (*void_fn)(void); 27; void_fn lea_static_fn() { return &static_fn; } 28; void_fn lea_global_fn() { return &global_fn; } 29; void_fn lea_extern_fn() { return &extern_fn; } 30 31 32; ModuleID = 'model.c' 33source_filename = "model.c" 34target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 35target triple = "x86_64--linux" 36 37@global_data = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0], align 16 38@static_data = internal global [10 x i32] zeroinitializer, align 16 39@extern_data = external global [10 x i32], align 16 40@thread_data = external thread_local global i32, align 4 41 42 43define dso_local i32* @lea_static_data() #0 { 44; SMALL-STATIC-LABEL: lea_static_data: 45; SMALL-STATIC: # %bb.0: 46; SMALL-STATIC-NEXT: movl $static_data, %eax 47; SMALL-STATIC-NEXT: retq 48; 49; MEDIUM-STATIC-LABEL: lea_static_data: 50; MEDIUM-STATIC: # %bb.0: 51; MEDIUM-STATIC-NEXT: movabsq $static_data, %rax 52; MEDIUM-STATIC-NEXT: retq 53; 54; LARGE-STATIC-LABEL: lea_static_data: 55; LARGE-STATIC: # %bb.0: 56; LARGE-STATIC-NEXT: movabsq $static_data, %rax 57; LARGE-STATIC-NEXT: retq 58; 59; SMALL-PIC-LABEL: lea_static_data: 60; SMALL-PIC: # %bb.0: 61; SMALL-PIC-NEXT: leaq {{.*}}(%rip), %rax 62; SMALL-PIC-NEXT: retq 63; 64; MEDIUM-PIC-LABEL: lea_static_data: 65; MEDIUM-PIC: # %bb.0: 66; MEDIUM-PIC-NEXT: leaq {{.*}}(%rip), %rcx 67; MEDIUM-PIC-NEXT: movabsq $static_data@GOTOFF, %rax 68; MEDIUM-PIC-NEXT: addq %rcx, %rax 69; MEDIUM-PIC-NEXT: retq 70; 71; LARGE-PIC-LABEL: lea_static_data: 72; LARGE-PIC: # %bb.0: 73; LARGE-PIC-NEXT: .L0$pb: 74; LARGE-PIC-NEXT: leaq .L0${{.*}}(%rip), %rax 75; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L0$pb, %rcx 76; LARGE-PIC-NEXT: addq %rax, %rcx 77; LARGE-PIC-NEXT: movabsq $static_data@GOTOFF, %rax 78; LARGE-PIC-NEXT: addq %rcx, %rax 79; LARGE-PIC-NEXT: retq 80 ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @static_data, i64 0, i64 0) 81} 82 83define dso_local i32* @lea_global_data() #0 { 84; SMALL-STATIC-LABEL: lea_global_data: 85; SMALL-STATIC: # %bb.0: 86; SMALL-STATIC-NEXT: movl $global_data, %eax 87; SMALL-STATIC-NEXT: retq 88; 89; MEDIUM-STATIC-LABEL: lea_global_data: 90; MEDIUM-STATIC: # %bb.0: 91; MEDIUM-STATIC-NEXT: movabsq $global_data, %rax 92; MEDIUM-STATIC-NEXT: retq 93; 94; LARGE-STATIC-LABEL: lea_global_data: 95; LARGE-STATIC: # %bb.0: 96; LARGE-STATIC-NEXT: movabsq $global_data, %rax 97; LARGE-STATIC-NEXT: retq 98; 99; SMALL-PIC-LABEL: lea_global_data: 100; SMALL-PIC: # %bb.0: 101; SMALL-PIC-NEXT: leaq {{.*}}(%rip), %rax 102; SMALL-PIC-NEXT: retq 103; 104; MEDIUM-PIC-LABEL: lea_global_data: 105; MEDIUM-PIC: # %bb.0: 106; MEDIUM-PIC-NEXT: leaq {{.*}}(%rip), %rcx 107; MEDIUM-PIC-NEXT: movabsq $global_data@GOTOFF, %rax 108; MEDIUM-PIC-NEXT: addq %rcx, %rax 109; MEDIUM-PIC-NEXT: retq 110; 111; LARGE-PIC-LABEL: lea_global_data: 112; LARGE-PIC: # %bb.0: 113; LARGE-PIC-NEXT: .L1$pb: 114; LARGE-PIC-NEXT: leaq .L1${{.*}}(%rip), %rax 115; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx 116; LARGE-PIC-NEXT: addq %rax, %rcx 117; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax 118; LARGE-PIC-NEXT: addq %rcx, %rax 119; LARGE-PIC-NEXT: retq 120 ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @global_data, i64 0, i64 0) 121} 122 123define dso_local i32* @lea_extern_data() #0 { 124; SMALL-STATIC-LABEL: lea_extern_data: 125; SMALL-STATIC: # %bb.0: 126; SMALL-STATIC-NEXT: movq extern_data@{{.*}}(%rip), %rax 127; SMALL-STATIC-NEXT: retq 128; 129; MEDIUM-STATIC-LABEL: lea_extern_data: 130; MEDIUM-STATIC: # %bb.0: 131; MEDIUM-STATIC-NEXT: movq extern_data@{{.*}}(%rip), %rax 132; MEDIUM-STATIC-NEXT: retq 133; 134; LARGE-STATIC-LABEL: lea_extern_data: 135; LARGE-STATIC: # %bb.0: 136; LARGE-STATIC-NEXT: movabsq $extern_data, %rax 137; LARGE-STATIC-NEXT: retq 138; 139; SMALL-PIC-LABEL: lea_extern_data: 140; SMALL-PIC: # %bb.0: 141; SMALL-PIC-NEXT: movq extern_data@{{.*}}(%rip), %rax 142; SMALL-PIC-NEXT: retq 143; 144; MEDIUM-PIC-LABEL: lea_extern_data: 145; MEDIUM-PIC: # %bb.0: 146; MEDIUM-PIC-NEXT: movq extern_data@{{.*}}(%rip), %rax 147; MEDIUM-PIC-NEXT: retq 148; 149; LARGE-PIC-LABEL: lea_extern_data: 150; LARGE-PIC: # %bb.0: 151; LARGE-PIC-NEXT: .L2$pb: 152; LARGE-PIC-NEXT: leaq .L2${{.*}}(%rip), %rax 153; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx 154; LARGE-PIC-NEXT: addq %rax, %rcx 155; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax 156; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax 157; LARGE-PIC-NEXT: retq 158 ret i32* getelementptr inbounds ([10 x i32], [10 x i32]* @extern_data, i64 0, i64 0) 159} 160 161define dso_local i32 @load_global_data() #0 { 162; SMALL-STATIC-LABEL: load_global_data: 163; SMALL-STATIC: # %bb.0: 164; SMALL-STATIC-NEXT: movl global_data+{{.*}}(%rip), %eax 165; SMALL-STATIC-NEXT: retq 166; 167; MEDIUM-STATIC-LABEL: load_global_data: 168; MEDIUM-STATIC: # %bb.0: 169; MEDIUM-STATIC-NEXT: movabsq $global_data, %rax 170; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax 171; MEDIUM-STATIC-NEXT: retq 172; 173; LARGE-STATIC-LABEL: load_global_data: 174; LARGE-STATIC: # %bb.0: 175; LARGE-STATIC-NEXT: movabsq $global_data, %rax 176; LARGE-STATIC-NEXT: movl 8(%rax), %eax 177; LARGE-STATIC-NEXT: retq 178; 179; SMALL-PIC-LABEL: load_global_data: 180; SMALL-PIC: # %bb.0: 181; SMALL-PIC-NEXT: movl global_data+{{.*}}(%rip), %eax 182; SMALL-PIC-NEXT: retq 183; 184; MEDIUM-PIC-LABEL: load_global_data: 185; MEDIUM-PIC: # %bb.0: 186; MEDIUM-PIC-NEXT: leaq {{.*}}(%rip), %rax 187; MEDIUM-PIC-NEXT: movabsq $global_data@GOTOFF, %rcx 188; MEDIUM-PIC-NEXT: movl 8(%rax,%rcx), %eax 189; MEDIUM-PIC-NEXT: retq 190; 191; LARGE-PIC-LABEL: load_global_data: 192; LARGE-PIC: # %bb.0: 193; LARGE-PIC-NEXT: .L3$pb: 194; LARGE-PIC-NEXT: leaq .L3${{.*}}(%rip), %rax 195; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx 196; LARGE-PIC-NEXT: addq %rax, %rcx 197; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax 198; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax 199; LARGE-PIC-NEXT: retq 200 %rv = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @global_data, i64 0, i64 2) 201 ret i32 %rv 202} 203 204define dso_local i32 @load_extern_data() #0 { 205; SMALL-STATIC-LABEL: load_extern_data: 206; SMALL-STATIC: # %bb.0: 207; SMALL-STATIC-NEXT: movq extern_data@{{.*}}(%rip), %rax 208; SMALL-STATIC-NEXT: movl 8(%rax), %eax 209; SMALL-STATIC-NEXT: retq 210; 211; MEDIUM-STATIC-LABEL: load_extern_data: 212; MEDIUM-STATIC: # %bb.0: 213; MEDIUM-STATIC-NEXT: movq extern_data@{{.*}}(%rip), %rax 214; MEDIUM-STATIC-NEXT: movl 8(%rax), %eax 215; MEDIUM-STATIC-NEXT: retq 216; 217; LARGE-STATIC-LABEL: load_extern_data: 218; LARGE-STATIC: # %bb.0: 219; LARGE-STATIC-NEXT: movabsq $extern_data, %rax 220; LARGE-STATIC-NEXT: movl 8(%rax), %eax 221; LARGE-STATIC-NEXT: retq 222; 223; SMALL-PIC-LABEL: load_extern_data: 224; SMALL-PIC: # %bb.0: 225; SMALL-PIC-NEXT: movq extern_data@{{.*}}(%rip), %rax 226; SMALL-PIC-NEXT: movl 8(%rax), %eax 227; SMALL-PIC-NEXT: retq 228; 229; MEDIUM-PIC-LABEL: load_extern_data: 230; MEDIUM-PIC: # %bb.0: 231; MEDIUM-PIC-NEXT: movq extern_data@{{.*}}(%rip), %rax 232; MEDIUM-PIC-NEXT: movl 8(%rax), %eax 233; MEDIUM-PIC-NEXT: retq 234; 235; LARGE-PIC-LABEL: load_extern_data: 236; LARGE-PIC: # %bb.0: 237; LARGE-PIC-NEXT: .L4$pb: 238; LARGE-PIC-NEXT: leaq .L4${{.*}}(%rip), %rax 239; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx 240; LARGE-PIC-NEXT: addq %rax, %rcx 241; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax 242; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax 243; LARGE-PIC-NEXT: movl 8(%rax), %eax 244; LARGE-PIC-NEXT: retq 245 %rv = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @extern_data, i64 0, i64 2) 246 ret i32 %rv 247} 248 249define dso_local void @global_fn() #0 { 250; CHECK-LABEL: global_fn: 251; CHECK: # %bb.0: 252; CHECK-NEXT: retq 253 ret void 254} 255 256define internal void @static_fn() #0 { 257; CHECK-LABEL: static_fn: 258; CHECK: # %bb.0: 259; CHECK-NEXT: retq 260 ret void 261} 262 263declare void @extern_fn() 264 265define dso_local void ()* @lea_static_fn() #0 { 266; SMALL-STATIC-LABEL: lea_static_fn: 267; SMALL-STATIC: # %bb.0: 268; SMALL-STATIC-NEXT: movl $static_fn, %eax 269; SMALL-STATIC-NEXT: retq 270; 271; MEDIUM-STATIC-LABEL: lea_static_fn: 272; MEDIUM-STATIC: # %bb.0: 273; MEDIUM-STATIC-NEXT: movabsq $static_fn, %rax 274; MEDIUM-STATIC-NEXT: retq 275; 276; LARGE-STATIC-LABEL: lea_static_fn: 277; LARGE-STATIC: # %bb.0: 278; LARGE-STATIC-NEXT: movabsq $static_fn, %rax 279; LARGE-STATIC-NEXT: retq 280; 281; SMALL-PIC-LABEL: lea_static_fn: 282; SMALL-PIC: # %bb.0: 283; SMALL-PIC-NEXT: leaq {{.*}}(%rip), %rax 284; SMALL-PIC-NEXT: retq 285; 286; MEDIUM-PIC-LABEL: lea_static_fn: 287; MEDIUM-PIC: # %bb.0: 288; MEDIUM-PIC-NEXT: movabsq $static_fn, %rax 289; MEDIUM-PIC-NEXT: retq 290; 291; LARGE-PIC-LABEL: lea_static_fn: 292; LARGE-PIC: # %bb.0: 293; LARGE-PIC-NEXT: .L7$pb: 294; LARGE-PIC-NEXT: leaq .L7${{.*}}(%rip), %rax 295; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L7$pb, %rcx 296; LARGE-PIC-NEXT: addq %rax, %rcx 297; LARGE-PIC-NEXT: movabsq $static_fn@GOTOFF, %rax 298; LARGE-PIC-NEXT: addq %rcx, %rax 299; LARGE-PIC-NEXT: retq 300 ret void ()* @static_fn 301} 302 303define dso_local void ()* @lea_global_fn() #0 { 304; SMALL-STATIC-LABEL: lea_global_fn: 305; SMALL-STATIC: # %bb.0: 306; SMALL-STATIC-NEXT: movl $global_fn, %eax 307; SMALL-STATIC-NEXT: retq 308; 309; MEDIUM-STATIC-LABEL: lea_global_fn: 310; MEDIUM-STATIC: # %bb.0: 311; MEDIUM-STATIC-NEXT: movabsq $global_fn, %rax 312; MEDIUM-STATIC-NEXT: retq 313; 314; LARGE-STATIC-LABEL: lea_global_fn: 315; LARGE-STATIC: # %bb.0: 316; LARGE-STATIC-NEXT: movabsq $global_fn, %rax 317; LARGE-STATIC-NEXT: retq 318; 319; SMALL-PIC-LABEL: lea_global_fn: 320; SMALL-PIC: # %bb.0: 321; SMALL-PIC-NEXT: leaq {{.*}}(%rip), %rax 322; SMALL-PIC-NEXT: retq 323; 324; MEDIUM-PIC-LABEL: lea_global_fn: 325; MEDIUM-PIC: # %bb.0: 326; MEDIUM-PIC-NEXT: movabsq $global_fn, %rax 327; MEDIUM-PIC-NEXT: retq 328; 329; LARGE-PIC-LABEL: lea_global_fn: 330; LARGE-PIC: # %bb.0: 331; LARGE-PIC-NEXT: .L8$pb: 332; LARGE-PIC-NEXT: leaq .L8${{.*}}(%rip), %rax 333; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L8$pb, %rcx 334; LARGE-PIC-NEXT: addq %rax, %rcx 335; LARGE-PIC-NEXT: movabsq $global_fn@GOTOFF, %rax 336; LARGE-PIC-NEXT: addq %rcx, %rax 337; LARGE-PIC-NEXT: retq 338 ret void ()* @global_fn 339} 340 341define dso_local void ()* @lea_extern_fn() #0 { 342; SMALL-STATIC-LABEL: lea_extern_fn: 343; SMALL-STATIC: # %bb.0: 344; SMALL-STATIC-NEXT: movq extern_fn@{{.*}}(%rip), %rax 345; SMALL-STATIC-NEXT: retq 346; 347; MEDIUM-STATIC-LABEL: lea_extern_fn: 348; MEDIUM-STATIC: # %bb.0: 349; MEDIUM-STATIC-NEXT: movq extern_fn@{{.*}}(%rip), %rax 350; MEDIUM-STATIC-NEXT: retq 351; 352; LARGE-STATIC-LABEL: lea_extern_fn: 353; LARGE-STATIC: # %bb.0: 354; LARGE-STATIC-NEXT: movabsq $extern_fn, %rax 355; LARGE-STATIC-NEXT: retq 356; 357; SMALL-PIC-LABEL: lea_extern_fn: 358; SMALL-PIC: # %bb.0: 359; SMALL-PIC-NEXT: movq extern_fn@{{.*}}(%rip), %rax 360; SMALL-PIC-NEXT: retq 361; 362; MEDIUM-PIC-LABEL: lea_extern_fn: 363; MEDIUM-PIC: # %bb.0: 364; MEDIUM-PIC-NEXT: movq extern_fn@{{.*}}(%rip), %rax 365; MEDIUM-PIC-NEXT: retq 366; 367; LARGE-PIC-LABEL: lea_extern_fn: 368; LARGE-PIC: # %bb.0: 369; LARGE-PIC-NEXT: .L9$pb: 370; LARGE-PIC-NEXT: leaq .L9${{.*}}(%rip), %rax 371; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L9$pb, %rcx 372; LARGE-PIC-NEXT: addq %rax, %rcx 373; LARGE-PIC-NEXT: movabsq $extern_fn@GOT, %rax 374; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax 375; LARGE-PIC-NEXT: retq 376 ret void ()* @extern_fn 377} 378 379; FIXME: The result is same for small, medium and large model, because we 380; specify pie option in the test case. And the type of tls is initial exec tls. 381; For pic code. The large model code for pic tls should be emitted as below. 382 383; .L3: 384; leaq .L3(%rip), %rbx 385; movabsq $_GLOBAL_OFFSET_TABLE_-.L3, %r11 386; addq %r11, %rbx 387; leaq thread_data@TLSGD(%rip), %rdi 388; movabsq $__tls_get_addr@PLTOFF, %rax 389; addq %rbx, %rax 390; call *%rax 391; movl (%rax), %eax 392 393; The medium and small model code for pic tls should be emitted as below. 394; data16 395; leaq thread_data@TLSGD(%rip), %rdi 396; data16 397; data16 398; rex64 399; callq __tls_get_addr@PLT 400; movl (%rax), %eax 401 402define dso_local i32 @load_thread_data() #0 { 403; CHECK-LABEL: load_thread_data: 404; CHECK: # %bb.0: 405; CHECK-NEXT: movq thread_data@{{.*}}(%rip), %rax 406; CHECK-NEXT: movl %fs:(%rax), %eax 407; CHECK-NEXT: retq 408 %1 = load i32, i32* @thread_data, align 4 409 ret i32 %1 410} 411 412define dso_local float @load_constant_pool(float %x) #0 { 413; SMALL-STATIC-LABEL: load_constant_pool: 414; SMALL-STATIC: # %bb.0: 415; SMALL-STATIC-NEXT: addss {{.*}}(%rip), %xmm0 416; SMALL-STATIC-NEXT: retq 417; 418; MEDIUM-STATIC-LABEL: load_constant_pool: 419; MEDIUM-STATIC: # %bb.0: 420; MEDIUM-STATIC-NEXT: movabsq ${{\.LCPI.*}}, %rax 421; MEDIUM-STATIC-NEXT: addss (%rax), %xmm0 422; MEDIUM-STATIC-NEXT: retq 423; 424; LARGE-STATIC-LABEL: load_constant_pool: 425; LARGE-STATIC: # %bb.0: 426; LARGE-STATIC-NEXT: movabsq ${{\.LCPI.*}}, %rax 427; LARGE-STATIC-NEXT: addss (%rax), %xmm0 428; LARGE-STATIC-NEXT: retq 429; 430; SMALL-PIC-LABEL: load_constant_pool: 431; SMALL-PIC: # %bb.0: 432; SMALL-PIC-NEXT: addss {{.*}}(%rip), %xmm0 433; SMALL-PIC-NEXT: retq 434; 435; MEDIUM-PIC-LABEL: load_constant_pool: 436; MEDIUM-PIC: # %bb.0: 437; MEDIUM-PIC-NEXT: leaq {{.*}}(%rip), %rax 438; MEDIUM-PIC-NEXT: movabsq ${{\.LCPI.*}}@GOTOFF, %rcx 439; MEDIUM-PIC-NEXT: addss (%rax,%rcx), %xmm0 440; MEDIUM-PIC-NEXT: retq 441; 442; LARGE-PIC-LABEL: load_constant_pool: 443; LARGE-PIC: # %bb.0: 444; LARGE-PIC-NEXT: .L11$pb: 445; LARGE-PIC-NEXT: leaq .L11${{.*}}(%rip), %rax 446; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L11$pb, %rcx 447; LARGE-PIC-NEXT: addq %rax, %rcx 448; LARGE-PIC-NEXT: movabsq ${{\.LCPI.*}}@GOTOFF, %rax 449; LARGE-PIC-NEXT: addss (%rcx,%rax), %xmm0 450; LARGE-PIC-NEXT: retq 451 %a = fadd float %x, 1.0 452 ret float %a 453} 454 455attributes #0 = { noinline nounwind uwtable } 456 457!llvm.module.flags = !{!0, !1, !2} 458!llvm.ident = !{!3} 459 460!0 = !{i32 1, !"wchar_size", i32 4} 461!1 = !{i32 7, !"PIC Level", i32 2} 462!2 = !{i32 7, !"PIE Level", i32 2} 463!3 = !{!"clang version 7.0.0 "} 464