1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=x86_64 -relocation-model=static < %s | FileCheck --check-prefixes=STATIC %s 3; RUN: llc -mtriple=x86_64 -relocation-model=pic < %s | FileCheck --check-prefixes=PIC %s 4; RUN: llc -mtriple=x86_64 -code-model=medium -relocation-model=static < %s | FileCheck --check-prefixes=MSTATIC %s 5; RUN: llc -mtriple=x86_64 -code-model=medium -relocation-model=pic < %s | FileCheck --check-prefixes=MPIC %s 6 7@foo = internal global i32 0 8 9define dso_local i64 @zero() #0 { 10; STATIC-LABEL: zero: 11; STATIC: # %bb.0: # %entry 12; STATIC-NEXT: movl $foo, %eax 13; STATIC-NEXT: retq 14; 15; PIC-LABEL: zero: 16; PIC: # %bb.0: # %entry 17; PIC-NEXT: leaq foo(%rip), %rax 18; PIC-NEXT: retq 19; 20; MSTATIC-LABEL: zero: 21; MSTATIC: # %bb.0: # %entry 22; MSTATIC-NEXT: movabsq $foo, %rax 23; MSTATIC-NEXT: retq 24; 25; MPIC-LABEL: zero: 26; MPIC: # %bb.0: # %entry 27; MPIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx 28; MPIC-NEXT: movabsq $foo@GOTOFF, %rax 29; MPIC-NEXT: addq %rcx, %rax 30; MPIC-NEXT: retq 31entry: 32 ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 0) 33} 34 35define dso_local i64 @one() #0 { 36; STATIC-LABEL: one: 37; STATIC: # %bb.0: # %entry 38; STATIC-NEXT: movl $foo+1, %eax 39; STATIC-NEXT: retq 40; 41; PIC-LABEL: one: 42; PIC: # %bb.0: # %entry 43; PIC-NEXT: leaq foo+1(%rip), %rax 44; PIC-NEXT: retq 45; 46; MSTATIC-LABEL: one: 47; MSTATIC: # %bb.0: # %entry 48; MSTATIC-NEXT: movabsq $foo+1, %rax 49; MSTATIC-NEXT: retq 50; 51; MPIC-LABEL: one: 52; MPIC: # %bb.0: # %entry 53; MPIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax 54; MPIC-NEXT: movabsq $foo@GOTOFF, %rcx 55; MPIC-NEXT: leaq 1(%rax,%rcx), %rax 56; MPIC-NEXT: retq 57entry: 58 ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 1) 59} 60 61;; Check we don't fold a large offset into leaq, otherwise 62;; the large r_addend can easily cause a relocation overflow. 63define dso_local i64 @large() #0 { 64; STATIC-LABEL: large: 65; STATIC: # %bb.0: # %entry 66; STATIC-NEXT: movl $1701208431, %eax # imm = 0x6566616F 67; STATIC-NEXT: leaq foo(%rax), %rax 68; STATIC-NEXT: retq 69; 70; PIC-LABEL: large: 71; PIC: # %bb.0: # %entry 72; PIC-NEXT: leaq foo(%rip), %rax 73; PIC-NEXT: addq $1701208431, %rax # imm = 0x6566616F 74; PIC-NEXT: retq 75; 76; MSTATIC-LABEL: large: 77; MSTATIC: # %bb.0: # %entry 78; MSTATIC-NEXT: movabsq $foo, %rax 79; MSTATIC-NEXT: addq $1701208431, %rax # imm = 0x6566616F 80; MSTATIC-NEXT: retq 81; 82; MPIC-LABEL: large: 83; MPIC: # %bb.0: # %entry 84; MPIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax 85; MPIC-NEXT: movabsq $foo@GOTOFF, %rcx 86; MPIC-NEXT: leaq 1701208431(%rax,%rcx), %rax 87; MPIC-NEXT: retq 88entry: 89 ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 1701208431) 90} 91 92;; Test we don't emit movl foo-1, %eax. ELF R_X86_64_32 does not allow 93;; a negative value. 94define dso_local i64 @neg_1() #0 { 95; STATIC-LABEL: neg_1: 96; STATIC: # %bb.0: # %entry 97; STATIC-NEXT: leaq foo-1(%rip), %rax 98; STATIC-NEXT: retq 99; 100; PIC-LABEL: neg_1: 101; PIC: # %bb.0: # %entry 102; PIC-NEXT: leaq foo-1(%rip), %rax 103; PIC-NEXT: retq 104; 105; MSTATIC-LABEL: neg_1: 106; MSTATIC: # %bb.0: # %entry 107; MSTATIC-NEXT: movabsq $foo, %rax 108; MSTATIC-NEXT: decq %rax 109; MSTATIC-NEXT: retq 110; 111; MPIC-LABEL: neg_1: 112; MPIC: # %bb.0: # %entry 113; MPIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax 114; MPIC-NEXT: movabsq $foo@GOTOFF, %rcx 115; MPIC-NEXT: leaq -1(%rax,%rcx), %rax 116; MPIC-NEXT: retq 117entry: 118 ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -1) 119} 120 121;; Test we don't emit movl foo-2147483648, %eax. ELF R_X86_64_32 does not allow 122;; a negative value. 123define dso_local i64 @neg_0x80000000() #0 { 124; STATIC-LABEL: neg_0x80000000: 125; STATIC: # %bb.0: # %entry 126; STATIC-NEXT: leaq foo-2147483648(%rip), %rax 127; STATIC-NEXT: retq 128; 129; PIC-LABEL: neg_0x80000000: 130; PIC: # %bb.0: # %entry 131; PIC-NEXT: leaq foo-2147483648(%rip), %rax 132; PIC-NEXT: retq 133; 134; MSTATIC-LABEL: neg_0x80000000: 135; MSTATIC: # %bb.0: # %entry 136; MSTATIC-NEXT: movabsq $foo, %rax 137; MSTATIC-NEXT: addq $-2147483648, %rax # imm = 0x80000000 138; MSTATIC-NEXT: retq 139; 140; MPIC-LABEL: neg_0x80000000: 141; MPIC: # %bb.0: # %entry 142; MPIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax 143; MPIC-NEXT: movabsq $foo@GOTOFF, %rcx 144; MPIC-NEXT: leaq -2147483648(%rax,%rcx), %rax 145; MPIC-NEXT: retq 146entry: 147 ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -2147483648) 148} 149 150define dso_local i64 @neg_0x80000001() #0 { 151; STATIC-LABEL: neg_0x80000001: 152; STATIC: # %bb.0: # %entry 153; STATIC-NEXT: movabsq $-2147483649, %rax # imm = 0xFFFFFFFF7FFFFFFF 154; STATIC-NEXT: leaq foo(%rax), %rax 155; STATIC-NEXT: retq 156; 157; PIC-LABEL: neg_0x80000001: 158; PIC: # %bb.0: # %entry 159; PIC-NEXT: leaq foo(%rip), %rcx 160; PIC-NEXT: movabsq $-2147483649, %rax # imm = 0xFFFFFFFF7FFFFFFF 161; PIC-NEXT: addq %rcx, %rax 162; PIC-NEXT: retq 163; 164; MSTATIC-LABEL: neg_0x80000001: 165; MSTATIC: # %bb.0: # %entry 166; MSTATIC-NEXT: movabsq $-2147483649, %rcx # imm = 0xFFFFFFFF7FFFFFFF 167; MSTATIC-NEXT: movabsq $foo, %rax 168; MSTATIC-NEXT: addq %rcx, %rax 169; MSTATIC-NEXT: retq 170; 171; MPIC-LABEL: neg_0x80000001: 172; MPIC: # %bb.0: # %entry 173; MPIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax 174; MPIC-NEXT: movabsq $foo@GOTOFF, %rcx 175; MPIC-NEXT: addq %rax, %rcx 176; MPIC-NEXT: movabsq $-2147483649, %rax # imm = 0xFFFFFFFF7FFFFFFF 177; MPIC-NEXT: addq %rcx, %rax 178; MPIC-NEXT: retq 179entry: 180 ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -2147483649) 181} 182 183define internal void @bar() #0 { 184; STATIC-LABEL: bar: 185; STATIC: # %bb.0: 186; STATIC-NEXT: retq 187; 188; PIC-LABEL: bar: 189; PIC: # %bb.0: 190; PIC-NEXT: retq 191; 192; MSTATIC-LABEL: bar: 193; MSTATIC: # %bb.0: 194; MSTATIC-NEXT: retq 195; 196; MPIC-LABEL: bar: 197; MPIC: # %bb.0: 198; MPIC-NEXT: retq 199 ret void 200} 201 202define dso_local i64 @fun_neg_0xfeffffff() #0 { 203; STATIC-LABEL: fun_neg_0xfeffffff: 204; STATIC: # %bb.0: 205; STATIC-NEXT: movl $bar, %eax 206; STATIC-NEXT: addq $-16777217, %rax # imm = 0xFEFFFFFF 207; STATIC-NEXT: retq 208; 209; PIC-LABEL: fun_neg_0xfeffffff: 210; PIC: # %bb.0: 211; PIC-NEXT: leaq bar-16777217(%rip), %rax 212; PIC-NEXT: retq 213; 214; MSTATIC-LABEL: fun_neg_0xfeffffff: 215; MSTATIC: # %bb.0: 216; MSTATIC-NEXT: movl $bar, %eax 217; MSTATIC-NEXT: addq $-16777217, %rax # imm = 0xFEFFFFFF 218; MSTATIC-NEXT: retq 219; 220; MPIC-LABEL: fun_neg_0xfeffffff: 221; MPIC: # %bb.0: 222; MPIC-NEXT: leaq bar-16777217(%rip), %rax 223; MPIC-NEXT: retq 224 ret i64 add (i64 ptrtoint (ptr @bar to i64), i64 -16777217) 225} 226 227define dso_local i64 @fun_neg_ff000000() #0 { 228; STATIC-LABEL: fun_neg_ff000000: 229; STATIC: # %bb.0: 230; STATIC-NEXT: leaq bar-16777216(%rip), %rax 231; STATIC-NEXT: retq 232; 233; PIC-LABEL: fun_neg_ff000000: 234; PIC: # %bb.0: 235; PIC-NEXT: leaq bar-16777216(%rip), %rax 236; PIC-NEXT: retq 237; 238; MSTATIC-LABEL: fun_neg_ff000000: 239; MSTATIC: # %bb.0: 240; MSTATIC-NEXT: leaq bar-16777216(%rip), %rax 241; MSTATIC-NEXT: retq 242; 243; MPIC-LABEL: fun_neg_ff000000: 244; MPIC: # %bb.0: 245; MPIC-NEXT: leaq bar-16777216(%rip), %rax 246; MPIC-NEXT: retq 247 ret i64 add (i64 ptrtoint (ptr @bar to i64), i64 -16777216) 248} 249 250attributes #0 = { nounwind } 251