1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs -O3 -use-registers-for-deopt-values -restrict-statepoint-remat=true < %s | FileCheck %s 3target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 4target triple = "x86_64-apple-macosx10.11.0" 5 6declare void @bar() #0 7declare void @baz() 8 9; Spill caller saved register for %a. 10define void @test1(i32 %a) gc "statepoint-example" { 11; CHECK-LABEL: test1: 12; CHECK: ## %bb.0: ## %entry 13; CHECK-NEXT: pushq %rbx 14; CHECK-NEXT: .cfi_def_cfa_offset 16 15; CHECK-NEXT: .cfi_offset %rbx, -16 16; CHECK-NEXT: movl %edi, %ebx 17; CHECK-NEXT: callq _bar 18; CHECK-NEXT: Ltmp0: 19; CHECK-NEXT: popq %rbx 20; CHECK-NEXT: retq 21entry: 22 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a)] 23 ret void 24} 25 26; Callee save registers are ok. 27define void @test2(i32 %a, i32 %b) gc "statepoint-example" { 28; CHECK-LABEL: test2: 29; CHECK: ## %bb.0: ## %entry 30; CHECK-NEXT: pushq %rbp 31; CHECK-NEXT: .cfi_def_cfa_offset 16 32; CHECK-NEXT: pushq %rbx 33; CHECK-NEXT: .cfi_def_cfa_offset 24 34; CHECK-NEXT: pushq %rax 35; CHECK-NEXT: .cfi_def_cfa_offset 32 36; CHECK-NEXT: .cfi_offset %rbx, -24 37; CHECK-NEXT: .cfi_offset %rbp, -16 38; CHECK-NEXT: movl %esi, %ebx 39; CHECK-NEXT: movl %edi, %ebp 40; CHECK-NEXT: callq _bar 41; CHECK-NEXT: Ltmp1: 42; CHECK-NEXT: callq _bar 43; CHECK-NEXT: Ltmp2: 44; CHECK-NEXT: addq $8, %rsp 45; CHECK-NEXT: popq %rbx 46; CHECK-NEXT: popq %rbp 47; CHECK-NEXT: retq 48entry: 49 call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a, i32 %b)] 50 call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %b, i32 %a)] 51 ret void 52} 53 54; Arguments in caller saved registers, so they must be spilled. 55define void @test3(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i) gc "statepoint-example" { 56; CHECK-LABEL: test3: 57; CHECK: ## %bb.0: ## %entry 58; CHECK-NEXT: pushq %rbp 59; CHECK-NEXT: .cfi_def_cfa_offset 16 60; CHECK-NEXT: pushq %r15 61; CHECK-NEXT: .cfi_def_cfa_offset 24 62; CHECK-NEXT: pushq %r14 63; CHECK-NEXT: .cfi_def_cfa_offset 32 64; CHECK-NEXT: pushq %r13 65; CHECK-NEXT: .cfi_def_cfa_offset 40 66; CHECK-NEXT: pushq %r12 67; CHECK-NEXT: .cfi_def_cfa_offset 48 68; CHECK-NEXT: pushq %rbx 69; CHECK-NEXT: .cfi_def_cfa_offset 56 70; CHECK-NEXT: pushq %rax 71; CHECK-NEXT: .cfi_def_cfa_offset 64 72; CHECK-NEXT: .cfi_offset %rbx, -56 73; CHECK-NEXT: .cfi_offset %r12, -48 74; CHECK-NEXT: .cfi_offset %r13, -40 75; CHECK-NEXT: .cfi_offset %r14, -32 76; CHECK-NEXT: .cfi_offset %r15, -24 77; CHECK-NEXT: .cfi_offset %rbp, -16 78; CHECK-NEXT: movl %r9d, %ebx 79; CHECK-NEXT: movl %r8d, %ebp 80; CHECK-NEXT: movl %ecx, %r14d 81; CHECK-NEXT: movl %edx, %r15d 82; CHECK-NEXT: movl %esi, %r12d 83; CHECK-NEXT: movl %edi, %r13d 84; CHECK-NEXT: callq _bar 85; CHECK-NEXT: Ltmp3: 86; CHECK-NEXT: addq $8, %rsp 87; CHECK-NEXT: popq %rbx 88; CHECK-NEXT: popq %r12 89; CHECK-NEXT: popq %r13 90; CHECK-NEXT: popq %r14 91; CHECK-NEXT: popq %r15 92; CHECK-NEXT: popq %rbp 93; CHECK-NEXT: retq 94entry: 95 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i)] 96 ret void 97} 98 99; This case just confirms that we don't crash when given more live values 100; than registers. This is a case where we *have* to use a stack slot. This 101; also ends up being a good test of whether we can fold loads from immutable 102; stack slots into the statepoint. 103define void @test4(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" { 104; CHECK-LABEL: test4: 105; CHECK: ## %bb.0: ## %entry 106; CHECK-NEXT: pushq %rbp 107; CHECK-NEXT: .cfi_def_cfa_offset 16 108; CHECK-NEXT: pushq %r15 109; CHECK-NEXT: .cfi_def_cfa_offset 24 110; CHECK-NEXT: pushq %r14 111; CHECK-NEXT: .cfi_def_cfa_offset 32 112; CHECK-NEXT: pushq %r13 113; CHECK-NEXT: .cfi_def_cfa_offset 40 114; CHECK-NEXT: pushq %r12 115; CHECK-NEXT: .cfi_def_cfa_offset 48 116; CHECK-NEXT: pushq %rbx 117; CHECK-NEXT: .cfi_def_cfa_offset 56 118; CHECK-NEXT: pushq %rax 119; CHECK-NEXT: .cfi_def_cfa_offset 64 120; CHECK-NEXT: .cfi_offset %rbx, -56 121; CHECK-NEXT: .cfi_offset %r12, -48 122; CHECK-NEXT: .cfi_offset %r13, -40 123; CHECK-NEXT: .cfi_offset %r14, -32 124; CHECK-NEXT: .cfi_offset %r15, -24 125; CHECK-NEXT: .cfi_offset %rbp, -16 126; CHECK-NEXT: movl %r9d, %ebx 127; CHECK-NEXT: movl %r8d, %ebp 128; CHECK-NEXT: movl %ecx, %r14d 129; CHECK-NEXT: movl %edx, %r15d 130; CHECK-NEXT: movl %esi, %r12d 131; CHECK-NEXT: movl %edi, %r13d 132; CHECK-NEXT: callq _bar 133; CHECK-NEXT: Ltmp4: 134; CHECK-NEXT: addq $8, %rsp 135; CHECK-NEXT: popq %rbx 136; CHECK-NEXT: popq %r12 137; CHECK-NEXT: popq %r13 138; CHECK-NEXT: popq %r14 139; CHECK-NEXT: popq %r15 140; CHECK-NEXT: popq %rbp 141; CHECK-NEXT: retq 142entry: 143 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z)] 144 ret void 145} 146 147; A gc-value must be spilled even if it is also a deopt value. 148define ptr addrspace(1) @test5(i32 %a, ptr addrspace(1) %p) gc "statepoint-example" { 149; CHECK-LABEL: test5: 150; CHECK: ## %bb.0: ## %entry 151; CHECK-NEXT: pushq %rbx 152; CHECK-NEXT: .cfi_def_cfa_offset 16 153; CHECK-NEXT: subq $16, %rsp 154; CHECK-NEXT: .cfi_def_cfa_offset 32 155; CHECK-NEXT: .cfi_offset %rbx, -16 156; CHECK-NEXT: movl %edi, %ebx 157; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp) 158; CHECK-NEXT: callq _bar 159; CHECK-NEXT: Ltmp5: 160; CHECK-NEXT: callq _bar 161; CHECK-NEXT: Ltmp6: 162; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax 163; CHECK-NEXT: addq $16, %rsp 164; CHECK-NEXT: popq %rbx 165; CHECK-NEXT: retq 166entry: 167 %token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %p, ptr addrspace(1) %p), "deopt"(i32 %a)] 168 %p2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token, i32 1, i32 1) 169 %token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %p2, ptr addrspace(1) %p2), "deopt"(i32 %a)] 170 %p3 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token2, i32 1, i32 1) 171 ret ptr addrspace(1) %p3 172} 173 174; Callee saved are ok again. 175define void @test6(i32 %a) gc "statepoint-example" { 176; CHECK-LABEL: test6: 177; CHECK: ## %bb.0: ## %entry 178; CHECK-NEXT: pushq %rbx 179; CHECK-NEXT: .cfi_def_cfa_offset 16 180; CHECK-NEXT: .cfi_offset %rbx, -16 181; CHECK-NEXT: movl %edi, %ebx 182; CHECK-NEXT: callq _baz 183; CHECK-NEXT: Ltmp7: 184; CHECK-NEXT: callq _bar 185; CHECK-NEXT: Ltmp8: 186; CHECK-NEXT: popq %rbx 187; CHECK-NEXT: retq 188entry: 189 call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @baz, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a)] 190 call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a)] 191 ret void 192} 193 194; Many deopt values. 195define void @test7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" { 196; The code for this is terrible, check simply for correctness for the moment 197; CHECK-LABEL: test7: 198; CHECK: ## %bb.0: ## %entry 199; CHECK-NEXT: pushq %rbp 200; CHECK-NEXT: .cfi_def_cfa_offset 16 201; CHECK-NEXT: pushq %r15 202; CHECK-NEXT: .cfi_def_cfa_offset 24 203; CHECK-NEXT: pushq %r14 204; CHECK-NEXT: .cfi_def_cfa_offset 32 205; CHECK-NEXT: pushq %r13 206; CHECK-NEXT: .cfi_def_cfa_offset 40 207; CHECK-NEXT: pushq %r12 208; CHECK-NEXT: .cfi_def_cfa_offset 48 209; CHECK-NEXT: pushq %rbx 210; CHECK-NEXT: .cfi_def_cfa_offset 56 211; CHECK-NEXT: subq $168, %rsp 212; CHECK-NEXT: .cfi_def_cfa_offset 224 213; CHECK-NEXT: .cfi_offset %rbx, -56 214; CHECK-NEXT: .cfi_offset %r12, -48 215; CHECK-NEXT: .cfi_offset %r13, -40 216; CHECK-NEXT: .cfi_offset %r14, -32 217; CHECK-NEXT: .cfi_offset %r15, -24 218; CHECK-NEXT: .cfi_offset %rbp, -16 219; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 220; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 221; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 222; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 223; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 224; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 225; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 226; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 227; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 228; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 229; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 230; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 231; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 232; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 233; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 234; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 235; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 236; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 237; CHECK-NEXT: movl %edi, %r12d 238; CHECK-NEXT: movl %esi, %r13d 239; CHECK-NEXT: movl %edx, %ebp 240; CHECK-NEXT: movl %ecx, %ebx 241; CHECK-NEXT: movl %r8d, %r14d 242; CHECK-NEXT: movl %r9d, %r15d 243; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 244; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 245; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 246; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 247; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 248; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 249; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 250; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 251; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 252; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 253; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 254; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 255; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 256; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 257; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 258; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 259; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 260; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 261; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 262; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 263; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 264; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 265; CHECK-NEXT: callq _bar ## 160-byte Folded Reload 266; CHECK-NEXT: Ltmp9: 267; CHECK-NEXT: addq $168, %rsp 268; CHECK-NEXT: popq %rbx 269; CHECK-NEXT: popq %r12 270; CHECK-NEXT: popq %r13 271; CHECK-NEXT: popq %r14 272; CHECK-NEXT: popq %r15 273; CHECK-NEXT: popq %rbp 274; CHECK-NEXT: retq 275entry: 276 %a64 = zext i32 %a to i64 277 %b64 = zext i32 %b to i64 278 %c64 = zext i32 %c to i64 279 %d64 = zext i32 %d to i64 280 %e64 = zext i32 %e to i64 281 %f64 = zext i32 %f to i64 282 %g64 = zext i32 %g to i64 283 %h64 = zext i32 %h to i64 284 %i64 = zext i32 %i to i64 285 %j64 = zext i32 %j to i64 286 %k64 = zext i32 %k to i64 287 %l64 = zext i32 %l to i64 288 %m64 = zext i32 %m to i64 289 %n64 = zext i32 %n to i64 290 %o64 = zext i32 %o to i64 291 %p64 = zext i32 %p to i64 292 %q64 = zext i32 %q to i64 293 %r64 = zext i32 %r to i64 294 %s64 = zext i32 %s to i64 295 %t64 = zext i32 %t to i64 296 %u64 = zext i32 %u to i64 297 %v64 = zext i32 %v to i64 298 %w64 = zext i32 %w to i64 299 %x64 = zext i32 %x to i64 300 %y64 = zext i32 %y to i64 301 %z64 = zext i32 %z to i64 302 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i64 %a64, i64 %b64, i64 %c64, i64 %d64, i64 %e64, i64 %f64, i64 %g64, i64 %h64, i64 %i64, i64 %j64, i64 %k64, i64 %l64, i64 %m64, i64 %n64, i64 %o64, i64 %p64, i64 %q64, i64 %r64, i64 %s64, i64 %t64, i64 %u64, i64 %v64, i64 %w64, i64 %x64, i64 %y64, i64 %z64)] 303 ret void 304} 305 306; a variant of test7 with mixed types chosen to exercise register aliases 307define void @test8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" { 308; The code for this is terrible, check simply for correctness for the moment 309; CHECK-LABEL: test8: 310; CHECK: ## %bb.0: ## %entry 311; CHECK-NEXT: pushq %rbp 312; CHECK-NEXT: .cfi_def_cfa_offset 16 313; CHECK-NEXT: pushq %r15 314; CHECK-NEXT: .cfi_def_cfa_offset 24 315; CHECK-NEXT: pushq %r14 316; CHECK-NEXT: .cfi_def_cfa_offset 32 317; CHECK-NEXT: pushq %r13 318; CHECK-NEXT: .cfi_def_cfa_offset 40 319; CHECK-NEXT: pushq %r12 320; CHECK-NEXT: .cfi_def_cfa_offset 48 321; CHECK-NEXT: pushq %rbx 322; CHECK-NEXT: .cfi_def_cfa_offset 56 323; CHECK-NEXT: subq $136, %rsp 324; CHECK-NEXT: .cfi_def_cfa_offset 192 325; CHECK-NEXT: .cfi_offset %rbx, -56 326; CHECK-NEXT: .cfi_offset %r12, -48 327; CHECK-NEXT: .cfi_offset %r13, -40 328; CHECK-NEXT: .cfi_offset %r14, -32 329; CHECK-NEXT: .cfi_offset %r15, -24 330; CHECK-NEXT: .cfi_offset %rbp, -16 331; CHECK-NEXT: movl %r9d, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill 332; CHECK-NEXT: movl %r8d, (%rsp) ## 4-byte Spill 333; CHECK-NEXT: movl %ecx, %r14d 334; CHECK-NEXT: movl %edx, %r15d 335; CHECK-NEXT: movl %esi, %r12d 336; CHECK-NEXT: movl %edi, %r13d 337; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 338; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 339; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 340; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 341; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 342; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 343; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 344; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 345; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 346; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 347; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 348; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 349; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 350; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 351; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 352; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 353; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 354; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 355; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 356; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 357; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 358; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 359; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 360; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 361; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 362; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 363; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 364; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 365; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 366; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 367; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 368; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 369; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebx 370; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebp 371; CHECK-NEXT: callq _bar ## 132-byte Folded Reload 372; CHECK-NEXT: Ltmp10: 373; CHECK-NEXT: addq $136, %rsp 374; CHECK-NEXT: popq %rbx 375; CHECK-NEXT: popq %r12 376; CHECK-NEXT: popq %r13 377; CHECK-NEXT: popq %r14 378; CHECK-NEXT: popq %r15 379; CHECK-NEXT: popq %rbp 380; CHECK-NEXT: retq 381entry: 382 %a8 = trunc i32 %a to i8 383 %b8 = trunc i32 %b to i8 384 %c8 = trunc i32 %c to i8 385 %d8 = trunc i32 %d to i8 386 %e16 = trunc i32 %e to i16 387 %f16 = trunc i32 %f to i16 388 %g16 = trunc i32 %g to i16 389 %h16 = trunc i32 %h to i16 390 %i64 = zext i32 %i to i64 391 %j64 = zext i32 %j to i64 392 %k64 = zext i32 %k to i64 393 %l64 = zext i32 %l to i64 394 %m64 = zext i32 %m to i64 395 %n64 = zext i32 %n to i64 396 %o64 = zext i32 %o to i64 397 %p64 = zext i32 %p to i64 398 %q64 = zext i32 %q to i64 399 %r64 = zext i32 %r to i64 400 %s64 = zext i32 %s to i64 401 %t64 = zext i32 %t to i64 402 %u64 = zext i32 %u to i64 403 %v64 = zext i32 %v to i64 404 %w64 = zext i32 %w to i64 405 %x64 = zext i32 %x to i64 406 %y64 = zext i32 %y to i64 407 %z64 = zext i32 %z to i64 408 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i8 %a8, i8 %b8, i8 %c8, i8 %d8, i16 %e16, i16 %f16, i16 %g16, i16 %h16, i64 %i64, i64 %j64, i64 %k64, i64 %l64, i64 %m64, i64 %n64, i64 %o64, i64 %p64, i64 %q64, i64 %r64, i64 %s64, i64 %t64, i64 %u64, i64 %v64, i64 %w64, i64 %x64, i64 %y64, i64 %z64)] 409 ret void 410} 411 412; Test perfect forwarding of argument registers and stack slots to the 413; deopt bundle uses 414define void @test9(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" { 415; CHECK-LABEL: test9: 416; CHECK: ## %bb.0: ## %entry 417; CHECK-NEXT: pushq %rbp 418; CHECK-NEXT: .cfi_def_cfa_offset 16 419; CHECK-NEXT: pushq %r15 420; CHECK-NEXT: .cfi_def_cfa_offset 24 421; CHECK-NEXT: pushq %r14 422; CHECK-NEXT: .cfi_def_cfa_offset 32 423; CHECK-NEXT: pushq %r13 424; CHECK-NEXT: .cfi_def_cfa_offset 40 425; CHECK-NEXT: pushq %r12 426; CHECK-NEXT: .cfi_def_cfa_offset 48 427; CHECK-NEXT: pushq %rbx 428; CHECK-NEXT: .cfi_def_cfa_offset 56 429; CHECK-NEXT: pushq %rax 430; CHECK-NEXT: .cfi_def_cfa_offset 64 431; CHECK-NEXT: .cfi_offset %rbx, -56 432; CHECK-NEXT: .cfi_offset %r12, -48 433; CHECK-NEXT: .cfi_offset %r13, -40 434; CHECK-NEXT: .cfi_offset %r14, -32 435; CHECK-NEXT: .cfi_offset %r15, -24 436; CHECK-NEXT: .cfi_offset %rbp, -16 437; CHECK-NEXT: movl %r9d, %ebx 438; CHECK-NEXT: movl %r8d, %ebp 439; CHECK-NEXT: movl %ecx, %r14d 440; CHECK-NEXT: movl %edx, %r15d 441; CHECK-NEXT: movl %esi, %r12d 442; CHECK-NEXT: movl %edi, %r13d 443; CHECK-NEXT: callq _bar 444; CHECK-NEXT: Ltmp11: 445; CHECK-NEXT: addq $8, %rsp 446; CHECK-NEXT: popq %rbx 447; CHECK-NEXT: popq %r12 448; CHECK-NEXT: popq %r13 449; CHECK-NEXT: popq %r14 450; CHECK-NEXT: popq %r15 451; CHECK-NEXT: popq %rbp 452; CHECK-NEXT: retq 453 454entry: 455 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z)] 456 ret void 457} 458 459; Test enough folding of argument slots when we have one call which clobbers 460; registers before a second which needs them - i.e. we must do something with 461; arguments originally passed in registers 462define void @test10(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" { 463; FIXME (minor): It would be better to just spill (and fold reload) for 464; argument registers then spill and fill all the CSRs. 465; CHECK-LABEL: test10: 466; CHECK: ## %bb.0: ## %entry 467; CHECK-NEXT: pushq %rbp 468; CHECK-NEXT: .cfi_def_cfa_offset 16 469; CHECK-NEXT: pushq %r15 470; CHECK-NEXT: .cfi_def_cfa_offset 24 471; CHECK-NEXT: pushq %r14 472; CHECK-NEXT: .cfi_def_cfa_offset 32 473; CHECK-NEXT: pushq %r13 474; CHECK-NEXT: .cfi_def_cfa_offset 40 475; CHECK-NEXT: pushq %r12 476; CHECK-NEXT: .cfi_def_cfa_offset 48 477; CHECK-NEXT: pushq %rbx 478; CHECK-NEXT: .cfi_def_cfa_offset 56 479; CHECK-NEXT: pushq %rax 480; CHECK-NEXT: .cfi_def_cfa_offset 64 481; CHECK-NEXT: .cfi_offset %rbx, -56 482; CHECK-NEXT: .cfi_offset %r12, -48 483; CHECK-NEXT: .cfi_offset %r13, -40 484; CHECK-NEXT: .cfi_offset %r14, -32 485; CHECK-NEXT: .cfi_offset %r15, -24 486; CHECK-NEXT: .cfi_offset %rbp, -16 487; CHECK-NEXT: movl %r9d, %ebp 488; CHECK-NEXT: movl %r8d, %ebx 489; CHECK-NEXT: movl %ecx, %r14d 490; CHECK-NEXT: movl %edx, %r15d 491; CHECK-NEXT: movl %esi, %r12d 492; CHECK-NEXT: movl %edi, %r13d 493; CHECK-NEXT: callq _bar 494; CHECK-NEXT: Ltmp12: 495; CHECK-NEXT: callq _bar 496; CHECK-NEXT: Ltmp13: 497; CHECK-NEXT: addq $8, %rsp 498; CHECK-NEXT: popq %rbx 499; CHECK-NEXT: popq %r12 500; CHECK-NEXT: popq %r13 501; CHECK-NEXT: popq %r14 502; CHECK-NEXT: popq %r15 503; CHECK-NEXT: popq %rbp 504; CHECK-NEXT: retq 505 506entry: 507 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z)] 508 %statepoint_token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z)] 509 ret void 510} 511 512; Check that we can remat some uses of a def despite not remating before the 513; statepoint user. 514define i64 @test11(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" { 515; FIXME: The codegen for this is correct, but horrible. Lots of room for 516; improvement if we so desire. 517; CHECK-LABEL: test11: 518; CHECK: ## %bb.0: ## %entry 519; CHECK-NEXT: pushq %rbp 520; CHECK-NEXT: .cfi_def_cfa_offset 16 521; CHECK-NEXT: pushq %r15 522; CHECK-NEXT: .cfi_def_cfa_offset 24 523; CHECK-NEXT: pushq %r14 524; CHECK-NEXT: .cfi_def_cfa_offset 32 525; CHECK-NEXT: pushq %r13 526; CHECK-NEXT: .cfi_def_cfa_offset 40 527; CHECK-NEXT: pushq %r12 528; CHECK-NEXT: .cfi_def_cfa_offset 48 529; CHECK-NEXT: pushq %rbx 530; CHECK-NEXT: .cfi_def_cfa_offset 56 531; CHECK-NEXT: subq $168, %rsp 532; CHECK-NEXT: .cfi_def_cfa_offset 224 533; CHECK-NEXT: .cfi_offset %rbx, -56 534; CHECK-NEXT: .cfi_offset %r12, -48 535; CHECK-NEXT: .cfi_offset %r13, -40 536; CHECK-NEXT: .cfi_offset %r14, -32 537; CHECK-NEXT: .cfi_offset %r15, -24 538; CHECK-NEXT: .cfi_offset %rbp, -16 539; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 540; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 541; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 542; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 543; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 544; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 545; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 546; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 547; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 548; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 549; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 550; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 551; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 552; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 553; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 554; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 555; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 556; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 557; CHECK-NEXT: movl %edi, %eax 558; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 559; CHECK-NEXT: movl %esi, %eax 560; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 561; CHECK-NEXT: movl %edx, %r14d 562; CHECK-NEXT: movl %ecx, %eax 563; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 564; CHECK-NEXT: movl %r8d, %r15d 565; CHECK-NEXT: movl %r9d, %eax 566; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 567; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r13d 568; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 569; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 570; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 571; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 572; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 573; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 574; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebp 575; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 576; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 577; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 578; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 579; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r12d 580; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 581; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 582; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebx 583; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 584; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 585; CHECK-NEXT: callq _bar ## 160-byte Folded Reload 586; CHECK-NEXT: Ltmp14: 587; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload 588; CHECK-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Folded Reload 589; CHECK-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r14 ## 8-byte Folded Reload 590; CHECK-NEXT: addq %rax, %r14 591; CHECK-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r15 ## 8-byte Folded Reload 592; CHECK-NEXT: addq %r14, %r15 593; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 594; CHECK-NEXT: addq %rax, %r15 595; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 596; CHECK-NEXT: addq %rax, %rbx 597; CHECK-NEXT: addq %r15, %rbx 598; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 599; CHECK-NEXT: addq %rax, %r12 600; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 601; CHECK-NEXT: addq %rax, %r12 602; CHECK-NEXT: addq %rbx, %r12 603; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 604; CHECK-NEXT: addq %rax, %rbp 605; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 606; CHECK-NEXT: addq %rax, %rbp 607; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 608; CHECK-NEXT: addq %rax, %rbp 609; CHECK-NEXT: addq %r12, %rbp 610; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 611; CHECK-NEXT: addq %rax, %r13 612; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 613; CHECK-NEXT: addq %rax, %r13 614; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 615; CHECK-NEXT: addq %rax, %r13 616; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 617; CHECK-NEXT: addq %rax, %r13 618; CHECK-NEXT: addq %rbp, %r13 619; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ecx 620; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 621; CHECK-NEXT: addq %rax, %rcx 622; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 623; CHECK-NEXT: addq %rax, %rcx 624; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 625; CHECK-NEXT: addq %rax, %rcx 626; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 627; CHECK-NEXT: addq %rax, %rcx 628; CHECK-NEXT: addq %r13, %rcx 629; CHECK-NEXT: movq %rcx, %rax 630; CHECK-NEXT: addq $168, %rsp 631; CHECK-NEXT: popq %rbx 632; CHECK-NEXT: popq %r12 633; CHECK-NEXT: popq %r13 634; CHECK-NEXT: popq %r14 635; CHECK-NEXT: popq %r15 636; CHECK-NEXT: popq %rbp 637; CHECK-NEXT: retq 638 639entry: 640 %a64 = zext i32 %a to i64 641 %b64 = zext i32 %b to i64 642 %c64 = zext i32 %c to i64 643 %d64 = zext i32 %d to i64 644 %e64 = zext i32 %e to i64 645 %f64 = zext i32 %f to i64 646 %g64 = zext i32 %g to i64 647 %h64 = zext i32 %h to i64 648 %i64 = zext i32 %i to i64 649 %j64 = zext i32 %j to i64 650 %k64 = zext i32 %k to i64 651 %l64 = zext i32 %l to i64 652 %m64 = zext i32 %m to i64 653 %n64 = zext i32 %n to i64 654 %o64 = zext i32 %o to i64 655 %p64 = zext i32 %p to i64 656 %q64 = zext i32 %q to i64 657 %r64 = zext i32 %r to i64 658 %s64 = zext i32 %s to i64 659 %t64 = zext i32 %t to i64 660 %u64 = zext i32 %u to i64 661 %v64 = zext i32 %v to i64 662 %w64 = zext i32 %w to i64 663 %x64 = zext i32 %x to i64 664 %y64 = zext i32 %y to i64 665 %z64 = zext i32 %z to i64 666 call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i64 0, i64 0) ["deopt" (i64 %a64, i64 %b64, i64 %c64, i64 %d64, i64 %e64, i64 %f64, i64 %g64, i64 %h64, i64 %i64, i64 %j64, i64 %k64, i64 %l64, i64 %m64, i64 %n64, i64 %o64, i64 %p64, i64 %q64, i64 %r64, i64 %s64, i64 %t64, i64 %u64, i64 %v64, i64 %w64, i64 %x64, i64 %y64, i64 %z64)] 667 %addab = add i64 %a64, %b64 668 %addc = add i64 %addab, %c64 669 %addd = add i64 %addc, %d64 670 %adde = add i64 %addd, %e64 671 %addf = add i64 %adde, %f64 672 %addg = add i64 %addf, %g64 673 %addh = add i64 %addg, %h64 674 %addi = add i64 %addh, %i64 675 %addj = add i64 %addi, %j64 676 %addk = add i64 %addj, %k64 677 %addl = add i64 %addk, %l64 678 %addm = add i64 %addl, %m64 679 %addn = add i64 %addm, %n64 680 %addo = add i64 %addn, %o64 681 %addp = add i64 %addo, %p64 682 %addq = add i64 %addp, %q64 683 %addr = add i64 %addq, %r64 684 %adds = add i64 %addr, %s64 685 %addt = add i64 %adds, %t64 686 %addu = add i64 %addt, %u64 687 %addv = add i64 %addu, %v64 688 %addw = add i64 %addv, %w64 689 %addx = add i64 %addw, %x64 690 %addy = add i64 %addx, %y64 691 %addz = add i64 %addy, %z64 692 ret i64 %addz 693} 694 695; Demonstrate address of a function (w/ spilling due to caller saved register is used) 696define void @addr_func() gc "statepoint-example" { 697; CHECK-LABEL: addr_func: 698; CHECK: ## %bb.0: ## %entry 699; CHECK-NEXT: pushq %rbx 700; CHECK-NEXT: .cfi_def_cfa_offset 16 701; CHECK-NEXT: .cfi_offset %rbx, -16 702; CHECK-NEXT: movq _bar@GOTPCREL(%rip), %rbx 703; CHECK-NEXT: callq _bar 704; CHECK-NEXT: Ltmp15: 705; CHECK-NEXT: popq %rbx 706; CHECK-NEXT: retq 707entry: 708 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i64 0, i64 0) ["deopt" (ptr @bar, ptr @bar, ptr @bar)] 709 ret void 710} 711 712; Demonstrate address of a global (w/ spilling due to caller saved register is used) 713@G = external global i32 714define void @addr_global() gc "statepoint-example" { 715; CHECK-LABEL: addr_global: 716; CHECK: ## %bb.0: ## %entry 717; CHECK-NEXT: pushq %rbx 718; CHECK-NEXT: .cfi_def_cfa_offset 16 719; CHECK-NEXT: .cfi_offset %rbx, -16 720; CHECK-NEXT: movq _G@GOTPCREL(%rip), %rbx 721; CHECK-NEXT: callq _bar 722; CHECK-NEXT: Ltmp16: 723; CHECK-NEXT: popq %rbx 724; CHECK-NEXT: retq 725entry: 726 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i64 0, i64 0) ["deopt" (ptr @G, ptr @G, ptr @G)] 727 ret void 728} 729 730define void @addr_alloca(i32 %v) gc "statepoint-example" { 731; CHECK-LABEL: addr_alloca: 732; CHECK: ## %bb.0: ## %entry 733; CHECK-NEXT: pushq %rax 734; CHECK-NEXT: .cfi_def_cfa_offset 16 735; CHECK-NEXT: movl %edi, {{[0-9]+}}(%rsp) 736; CHECK-NEXT: callq _bar 737; CHECK-NEXT: Ltmp17: 738; CHECK-NEXT: popq %rax 739; CHECK-NEXT: retq 740entry: 741 %a = alloca i32 742 store i32 %v, ptr %a 743 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 0, i64 0, i64 0) ["deopt" (ptr %a, ptr %a, ptr %a)] 744 ret void 745} 746 747define ptr addrspace(1) @test_fpconst_deopt(ptr addrspace(1) %in) gc "statepoint-example" { 748; CHECK-LABEL: test_fpconst_deopt: 749; CHECK: ## %bb.0: 750; CHECK-NEXT: pushq %rax 751; CHECK-NEXT: .cfi_def_cfa_offset 16 752; CHECK-NEXT: movq %rdi, (%rsp) 753; CHECK-NEXT: nopl 8(%rax,%rax) 754; CHECK-NEXT: Ltmp18: 755; CHECK-NEXT: movq (%rsp), %rax 756; CHECK-NEXT: popq %rcx 757; CHECK-NEXT: retq 758 %statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 5, ptr nonnull elementtype(void ()) @bar, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %in), "deopt" ( 759 float 0x40421A1CA0000000, float 0x40459A1CA0000000, float 0x40401A1CA0000000, float 0x40479A1CA0000000, float 0x403C343940000000, 760 float 0x403E343940000000, float 0x40469A1CA0000000, float 0x40489A1CA0000000, float 0x404A9A1CA0000000, float 0x40499A1CA0000000, 761 float 0xC05FCD2F20000000, float 0xC05C0D2F20000000, float 0xC060269780000000, float 0xC05B8D2F20000000, float 0xC060669780000000, 762 float 0xC05B0D2F20000000, float 0xC060A69780000000, float 0xC05A8D2F20000000, float 0xC060E69780000000, float 0x40439A1CA0000000)] 763 %out = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 0, i32 0) 764 ret ptr addrspace(1) %out 765} 766 767; CHECK-LABEL: __LLVM_StackMaps: 768; CHECK: .long Ltmp18-_test_fpconst_deopt 769; CHECK-NEXT: .short 0 770; CHECK-NEXT: .short 25 771; CHECK-NEXT: .byte 4 772; CHECK-NEXT: .byte 0 773; CHECK-NEXT: .short 8 774; CHECK-NEXT: .short 0 775; CHECK-NEXT: .short 0 776; CHECK-NEXT: .long 0 777; CHECK-NEXT: .byte 4 778; CHECK-NEXT: .byte 0 779; CHECK-NEXT: .short 8 780; CHECK-NEXT: .short 0 781; CHECK-NEXT: .short 0 782; CHECK-NEXT: .long 0 783; CHECK-NEXT: .byte 4 784; CHECK-NEXT: .byte 0 785; CHECK-NEXT: .short 8 786; CHECK-NEXT: .short 0 787; CHECK-NEXT: .short 0 788; CHECK-NEXT: .long 20 789; CHECK: .byte 4 790; CHECK: .byte 0 791; CHECK: .short 8 792; CHECK: .short 0 793; CHECK: .short 0 794; CHECK: .long 1108398309 795; CHECK: .byte 4 796; CHECK: .byte 0 797; CHECK: .short 8 798; CHECK: .short 0 799; CHECK: .short 0 800; CHECK: .long 1110233317 801; CHECK: .byte 4 802; CHECK: .byte 0 803; CHECK: .short 8 804; CHECK: .short 0 805; CHECK: .short 0 806; CHECK: .long 1107349733 807; CHECK: .byte 4 808; CHECK: .byte 0 809; CHECK: .short 8 810; CHECK: .short 0 811; CHECK: .short 0 812; CHECK: .long 1111281893 813; CHECK: .byte 4 814; CHECK: .byte 0 815; CHECK: .short 8 816; CHECK: .short 0 817; CHECK: .short 0 818; CHECK: .long 1105306058 819; CHECK: .byte 4 820; CHECK: .byte 0 821; CHECK: .short 8 822; CHECK: .short 0 823; CHECK: .short 0 824; CHECK: .long 1106354634 825; CHECK: .byte 4 826; CHECK: .byte 0 827; CHECK: .short 8 828; CHECK: .short 0 829; CHECK: .short 0 830; CHECK: .long 1110757605 831; CHECK: .byte 4 832; CHECK: .byte 0 833; CHECK: .short 8 834; CHECK: .short 0 835; CHECK: .short 0 836; CHECK: .long 1111806181 837; CHECK: .byte 4 838; CHECK: .byte 0 839; CHECK: .short 8 840; CHECK: .short 0 841; CHECK: .short 0 842; CHECK: .long 1112854757 843; CHECK: .byte 4 844; CHECK: .byte 0 845; CHECK: .short 8 846; CHECK: .short 0 847; CHECK: .short 0 848; CHECK: .long 1112330469 849; CHECK: .byte 5 850; CHECK: .byte 0 851; CHECK: .short 8 852; CHECK: .short 0 853; CHECK: .short 0 854; CHECK: .long 0 855; CHECK: .byte 5 856; CHECK: .byte 0 857; CHECK: .short 8 858; CHECK: .short 0 859; CHECK: .short 0 860; CHECK: .long 1 861; CHECK: .byte 5 862; CHECK: .byte 0 863; CHECK: .short 8 864; CHECK: .short 0 865; CHECK: .short 0 866; CHECK: .long 2 867; CHECK: .byte 5 868; CHECK: .byte 0 869; CHECK: .short 8 870; CHECK: .short 0 871; CHECK: .short 0 872; CHECK: .long 3 873; CHECK: .byte 5 874; CHECK: .byte 0 875; CHECK: .short 8 876; CHECK: .short 0 877; CHECK: .short 0 878; CHECK: .long 4 879; CHECK: .byte 5 880; CHECK: .byte 0 881; CHECK: .short 8 882; CHECK: .short 0 883; CHECK: .short 0 884; CHECK: .long 5 885; CHECK: .byte 5 886; CHECK: .byte 0 887; CHECK: .short 8 888; CHECK: .short 0 889; CHECK: .short 0 890; CHECK: .long 6 891; CHECK: .byte 5 892; CHECK: .byte 0 893; CHECK: .short 8 894; CHECK: .short 0 895; CHECK: .short 0 896; CHECK: .long 7 897; CHECK: .byte 5 898; CHECK: .byte 0 899; CHECK: .short 8 900; CHECK: .short 0 901; CHECK: .short 0 902; CHECK: .long 8 903; CHECK: .byte 4 904; CHECK: .byte 0 905; CHECK: .short 8 906; CHECK: .short 0 907; CHECK: .short 0 908; CHECK: .long 1109184741 909 910declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...) 911declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32) 912 913attributes #0 = { "deopt-lowering"="live-in" } 914attributes #1 = { "deopt-lowering"="live-through" } 915