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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a, i32 %b)] 50 call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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, %r14d 79; CHECK-NEXT: movl %r8d, %r15d 80; CHECK-NEXT: movl %ecx, %r12d 81; CHECK-NEXT: movl %edx, %r13d 82; CHECK-NEXT: movl %esi, %ebx 83; CHECK-NEXT: movl %edi, %ebp 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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, %r14d 127; CHECK-NEXT: movl %r8d, %r15d 128; CHECK-NEXT: movl %ecx, %r12d 129; CHECK-NEXT: movl %edx, %r13d 130; CHECK-NEXT: movl %esi, %ebx 131; CHECK-NEXT: movl %edi, %ebp 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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 i32 addrspace(1)* @test5(i32 %a, i32 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %p, i32 addrspace(1)* %p), "deopt"(i32 %a)] 168 %p2 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %token, i32 1, i32 1) 169 %token2 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %p2, i32 addrspace(1)* %p2), "deopt"(i32 %a)] 170 %p3 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %token2, i32 1, i32 1) 171 ret i32 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @baz, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a)] 190 call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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, %r13d 238; CHECK-NEXT: movl %esi, %ebx 239; CHECK-NEXT: movl %edx, %ebp 240; CHECK-NEXT: movl %ecx, %r14d 241; CHECK-NEXT: movl %r8d, %r15d 242; CHECK-NEXT: movl %r9d, %r12d 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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, %r12d 334; CHECK-NEXT: movl %edx, %r13d 335; CHECK-NEXT: movl %esi, %ebx 336; CHECK-NEXT: movl %edi, %ebp 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), %r14d 370; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r15d 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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, %r14d 438; CHECK-NEXT: movl %r8d, %r15d 439; CHECK-NEXT: movl %ecx, %r12d 440; CHECK-NEXT: movl %edx, %r13d 441; CHECK-NEXT: movl %esi, %ebx 442; CHECK-NEXT: movl %edi, %ebp 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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, %r15d 488; CHECK-NEXT: movl %r8d, %r14d 489; CHECK-NEXT: movl %ecx, %r12d 490; CHECK-NEXT: movl %edx, %r13d 491; CHECK-NEXT: movl %esi, %ebx 492; CHECK-NEXT: movl %edi, %ebp 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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, %ebx 558; CHECK-NEXT: movl %esi, %r15d 559; CHECK-NEXT: movl %edx, %r12d 560; CHECK-NEXT: movl %ecx, %r13d 561; CHECK-NEXT: movl %r8d, %ebp 562; CHECK-NEXT: movl %r9d, %r14d 563; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 564; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 565; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 566; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 567; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 568; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 569; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 570; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 571; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 572; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 573; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 574; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 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), %eax 580; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 581; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 582; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill 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: addq %r15, %rbx 588; CHECK-NEXT: addq %r12, %rbx 589; CHECK-NEXT: addq %r13, %rbx 590; CHECK-NEXT: addq %rbp, %rbx 591; CHECK-NEXT: addq %r14, %rbx 592; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 593; CHECK-NEXT: addq %rax, %rbx 594; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 595; CHECK-NEXT: addq %rax, %rbx 596; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 597; CHECK-NEXT: addq %rax, %rbx 598; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 599; CHECK-NEXT: addq %rax, %rbx 600; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 601; CHECK-NEXT: addq %rax, %rbx 602; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 603; CHECK-NEXT: addq %rax, %rbx 604; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 605; CHECK-NEXT: addq %rax, %rbx 606; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 607; CHECK-NEXT: addq %rax, %rbx 608; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 609; CHECK-NEXT: addq %rax, %rbx 610; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 611; CHECK-NEXT: addq %rax, %rbx 612; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 613; CHECK-NEXT: addq %rax, %rbx 614; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 615; CHECK-NEXT: addq %rax, %rbx 616; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 617; CHECK-NEXT: addq %rax, %rbx 618; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 619; CHECK-NEXT: addq %rax, %rbx 620; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 621; CHECK-NEXT: addq %rax, %rbx 622; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 623; CHECK-NEXT: addq %rax, %rbx 624; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 625; CHECK-NEXT: addq %rax, %rbx 626; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 627; CHECK-NEXT: addq %rax, %rbx 628; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 629; CHECK-NEXT: addq %rax, %rbx 630; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax 631; CHECK-NEXT: addq %rax, %rbx 632; CHECK-NEXT: movq %rbx, %rax 633; CHECK-NEXT: addq $168, %rsp 634; CHECK-NEXT: popq %rbx 635; CHECK-NEXT: popq %r12 636; CHECK-NEXT: popq %r13 637; CHECK-NEXT: popq %r14 638; CHECK-NEXT: popq %r15 639; CHECK-NEXT: popq %rbp 640; CHECK-NEXT: retq 641 642entry: 643 %a64 = zext i32 %a to i64 644 %b64 = zext i32 %b to i64 645 %c64 = zext i32 %c to i64 646 %d64 = zext i32 %d to i64 647 %e64 = zext i32 %e to i64 648 %f64 = zext i32 %f to i64 649 %g64 = zext i32 %g to i64 650 %h64 = zext i32 %h to i64 651 %i64 = zext i32 %i to i64 652 %j64 = zext i32 %j to i64 653 %k64 = zext i32 %k to i64 654 %l64 = zext i32 %l to i64 655 %m64 = zext i32 %m to i64 656 %n64 = zext i32 %n to i64 657 %o64 = zext i32 %o to i64 658 %p64 = zext i32 %p to i64 659 %q64 = zext i32 %q to i64 660 %r64 = zext i32 %r to i64 661 %s64 = zext i32 %s to i64 662 %t64 = zext i32 %t to i64 663 %u64 = zext i32 %u to i64 664 %v64 = zext i32 %v to i64 665 %w64 = zext i32 %w to i64 666 %x64 = zext i32 %x to i64 667 %y64 = zext i32 %y to i64 668 %z64 = zext i32 %z to i64 669 call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, 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)] 670 %addab = add i64 %a64, %b64 671 %addc = add i64 %addab, %c64 672 %addd = add i64 %addc, %d64 673 %adde = add i64 %addd, %e64 674 %addf = add i64 %adde, %f64 675 %addg = add i64 %addf, %g64 676 %addh = add i64 %addg, %h64 677 %addi = add i64 %addh, %i64 678 %addj = add i64 %addi, %j64 679 %addk = add i64 %addj, %k64 680 %addl = add i64 %addk, %l64 681 %addm = add i64 %addl, %m64 682 %addn = add i64 %addm, %n64 683 %addo = add i64 %addn, %o64 684 %addp = add i64 %addo, %p64 685 %addq = add i64 %addp, %q64 686 %addr = add i64 %addq, %r64 687 %adds = add i64 %addr, %s64 688 %addt = add i64 %adds, %t64 689 %addu = add i64 %addt, %u64 690 %addv = add i64 %addu, %v64 691 %addw = add i64 %addv, %w64 692 %addx = add i64 %addw, %x64 693 %addy = add i64 %addx, %y64 694 %addz = add i64 %addy, %z64 695 ret i64 %addz 696} 697 698; Demonstrate address of a function (w/ spilling due to caller saved register is used) 699define void @addr_func() gc "statepoint-example" { 700; CHECK-LABEL: addr_func: 701; CHECK: ## %bb.0: ## %entry 702; CHECK-NEXT: pushq %rbx 703; CHECK-NEXT: .cfi_def_cfa_offset 16 704; CHECK-NEXT: .cfi_offset %rbx, -16 705; CHECK-NEXT: movq _bar@GOTPCREL(%rip), %rbx 706; CHECK-NEXT: callq _bar 707; CHECK-NEXT: Ltmp15: 708; CHECK-NEXT: popq %rbx 709; CHECK-NEXT: retq 710entry: 711 %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i64 0, i64 0) ["deopt" (void ()* @bar, void ()* @bar, void ()* @bar)] 712 ret void 713} 714 715; Demonstrate address of a global (w/ spilling due to caller saved register is used) 716@G = external global i32 717define void @addr_global() gc "statepoint-example" { 718; CHECK-LABEL: addr_global: 719; CHECK: ## %bb.0: ## %entry 720; CHECK-NEXT: pushq %rbx 721; CHECK-NEXT: .cfi_def_cfa_offset 16 722; CHECK-NEXT: .cfi_offset %rbx, -16 723; CHECK-NEXT: movq _G@GOTPCREL(%rip), %rbx 724; CHECK-NEXT: callq _bar 725; CHECK-NEXT: Ltmp16: 726; CHECK-NEXT: popq %rbx 727; CHECK-NEXT: retq 728entry: 729 %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i64 0, i64 0) ["deopt" (i32* @G, i32* @G, i32* @G)] 730 ret void 731} 732 733define void @addr_alloca(i32 %v) gc "statepoint-example" { 734; CHECK-LABEL: addr_alloca: 735; CHECK: ## %bb.0: ## %entry 736; CHECK-NEXT: pushq %rax 737; CHECK-NEXT: .cfi_def_cfa_offset 16 738; CHECK-NEXT: movl %edi, {{[0-9]+}}(%rsp) 739; CHECK-NEXT: callq _bar 740; CHECK-NEXT: Ltmp17: 741; CHECK-NEXT: popq %rax 742; CHECK-NEXT: retq 743entry: 744 %a = alloca i32 745 store i32 %v, i32* %a 746 %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i64 0, i64 0) ["deopt" (i32* %a, i32* %a, i32* %a)] 747 ret void 748} 749 750define i32 addrspace(1)* @test_fpconst_deopt(i32 addrspace(1)* %in) gc "statepoint-example" { 751; CHECK-LABEL: test_fpconst_deopt: 752; CHECK: ## %bb.0: 753; CHECK-NEXT: pushq %rax 754; CHECK-NEXT: .cfi_def_cfa_offset 16 755; CHECK-NEXT: movq %rdi, (%rsp) 756; CHECK-NEXT: nopl 8(%rax,%rax) 757; CHECK-NEXT: Ltmp18: 758; CHECK-NEXT: movq (%rsp), %rax 759; CHECK-NEXT: popq %rcx 760; CHECK-NEXT: retq 761 %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2, i32 5, void ()* nonnull @bar, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %in), "deopt" ( 762 float 0x40421A1CA0000000, float 0x40459A1CA0000000, float 0x40401A1CA0000000, float 0x40479A1CA0000000, float 0x403C343940000000, 763 float 0x403E343940000000, float 0x40469A1CA0000000, float 0x40489A1CA0000000, float 0x404A9A1CA0000000, float 0x40499A1CA0000000, 764 float 0xC05FCD2F20000000, float 0xC05C0D2F20000000, float 0xC060269780000000, float 0xC05B8D2F20000000, float 0xC060669780000000, 765 float 0xC05B0D2F20000000, float 0xC060A69780000000, float 0xC05A8D2F20000000, float 0xC060E69780000000, float 0x40439A1CA0000000)] 766 %out = call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %statepoint_token, i32 0, i32 0) 767 ret i32 addrspace(1)* %out 768} 769 770; CHECK-LABEL: __LLVM_StackMaps: 771; CHECK: .long Ltmp18-_test_fpconst_deopt 772; CHECK-NEXT: .short 0 773; CHECK-NEXT: .short 25 774; CHECK-NEXT: .byte 4 775; CHECK-NEXT: .byte 0 776; CHECK-NEXT: .short 8 777; CHECK-NEXT: .short 0 778; CHECK-NEXT: .short 0 779; CHECK-NEXT: .long 0 780; CHECK-NEXT: .byte 4 781; CHECK-NEXT: .byte 0 782; CHECK-NEXT: .short 8 783; CHECK-NEXT: .short 0 784; CHECK-NEXT: .short 0 785; CHECK-NEXT: .long 0 786; CHECK-NEXT: .byte 4 787; CHECK-NEXT: .byte 0 788; CHECK-NEXT: .short 8 789; CHECK-NEXT: .short 0 790; CHECK-NEXT: .short 0 791; CHECK-NEXT: .long 20 792; CHECK: .byte 4 793; CHECK: .byte 0 794; CHECK: .short 8 795; CHECK: .short 0 796; CHECK: .short 0 797; CHECK: .long 1108398309 798; CHECK: .byte 4 799; CHECK: .byte 0 800; CHECK: .short 8 801; CHECK: .short 0 802; CHECK: .short 0 803; CHECK: .long 1110233317 804; CHECK: .byte 4 805; CHECK: .byte 0 806; CHECK: .short 8 807; CHECK: .short 0 808; CHECK: .short 0 809; CHECK: .long 1107349733 810; CHECK: .byte 4 811; CHECK: .byte 0 812; CHECK: .short 8 813; CHECK: .short 0 814; CHECK: .short 0 815; CHECK: .long 1111281893 816; CHECK: .byte 4 817; CHECK: .byte 0 818; CHECK: .short 8 819; CHECK: .short 0 820; CHECK: .short 0 821; CHECK: .long 1105306058 822; CHECK: .byte 4 823; CHECK: .byte 0 824; CHECK: .short 8 825; CHECK: .short 0 826; CHECK: .short 0 827; CHECK: .long 1106354634 828; CHECK: .byte 4 829; CHECK: .byte 0 830; CHECK: .short 8 831; CHECK: .short 0 832; CHECK: .short 0 833; CHECK: .long 1110757605 834; CHECK: .byte 4 835; CHECK: .byte 0 836; CHECK: .short 8 837; CHECK: .short 0 838; CHECK: .short 0 839; CHECK: .long 1111806181 840; CHECK: .byte 4 841; CHECK: .byte 0 842; CHECK: .short 8 843; CHECK: .short 0 844; CHECK: .short 0 845; CHECK: .long 1112854757 846; CHECK: .byte 4 847; CHECK: .byte 0 848; CHECK: .short 8 849; CHECK: .short 0 850; CHECK: .short 0 851; CHECK: .long 1112330469 852; CHECK: .byte 5 853; CHECK: .byte 0 854; CHECK: .short 8 855; CHECK: .short 0 856; CHECK: .short 0 857; CHECK: .long 0 858; CHECK: .byte 5 859; CHECK: .byte 0 860; CHECK: .short 8 861; CHECK: .short 0 862; CHECK: .short 0 863; CHECK: .long 1 864; CHECK: .byte 5 865; CHECK: .byte 0 866; CHECK: .short 8 867; CHECK: .short 0 868; CHECK: .short 0 869; CHECK: .long 2 870; CHECK: .byte 5 871; CHECK: .byte 0 872; CHECK: .short 8 873; CHECK: .short 0 874; CHECK: .short 0 875; CHECK: .long 3 876; CHECK: .byte 5 877; CHECK: .byte 0 878; CHECK: .short 8 879; CHECK: .short 0 880; CHECK: .short 0 881; CHECK: .long 4 882; CHECK: .byte 5 883; CHECK: .byte 0 884; CHECK: .short 8 885; CHECK: .short 0 886; CHECK: .short 0 887; CHECK: .long 5 888; CHECK: .byte 5 889; CHECK: .byte 0 890; CHECK: .short 8 891; CHECK: .short 0 892; CHECK: .short 0 893; CHECK: .long 6 894; CHECK: .byte 5 895; CHECK: .byte 0 896; CHECK: .short 8 897; CHECK: .short 0 898; CHECK: .short 0 899; CHECK: .long 7 900; CHECK: .byte 5 901; CHECK: .byte 0 902; CHECK: .short 8 903; CHECK: .short 0 904; CHECK: .short 0 905; CHECK: .long 8 906; CHECK: .byte 4 907; CHECK: .byte 0 908; CHECK: .short 8 909; CHECK: .short 0 910; CHECK: .short 0 911; CHECK: .long 1109184741 912 913declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) 914declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) 915 916attributes #0 = { "deopt-lowering"="live-in" } 917attributes #1 = { "deopt-lowering"="live-through" } 918