brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.3 KiB · 787a33a Raw
674 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -verify-machineinstrs -O3 -restrict-statepoint-remat < %s | FileCheck %s3target 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() #07declare void @baz()8 9define void @test1(i32 %a) gc "statepoint-example" {10; CHECK-LABEL: test1:11; CHECK:       ## %bb.0: ## %entry12; CHECK-NEXT:    pushq %rax13; CHECK-NEXT:    .cfi_def_cfa_offset 1614; CHECK-NEXT:    callq _bar15; CHECK-NEXT:  Ltmp0:16; CHECK-NEXT:    popq %rax17; CHECK-NEXT:    retq18entry:19; We expect the argument to be passed in an extra register to bar20  %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 2, i32 0, i32 0) ["deopt"(i32 %a)]21  ret void22}23 24define void @test2(i32 %a, i32 %b) gc "statepoint-example" {25; CHECK-LABEL: test2:26; CHECK:       ## %bb.0: ## %entry27; CHECK-NEXT:    pushq %rbp28; CHECK-NEXT:    .cfi_def_cfa_offset 1629; CHECK-NEXT:    pushq %rbx30; CHECK-NEXT:    .cfi_def_cfa_offset 2431; CHECK-NEXT:    pushq %rax32; CHECK-NEXT:    .cfi_def_cfa_offset 3233; CHECK-NEXT:    .cfi_offset %rbx, -2434; CHECK-NEXT:    .cfi_offset %rbp, -1635; CHECK-NEXT:    movl %esi, %ebx36; CHECK-NEXT:    movl %edi, %ebp37; CHECK-NEXT:    callq _bar38; CHECK-NEXT:  Ltmp1:39; CHECK-NEXT:    callq _bar40; CHECK-NEXT:  Ltmp2:41; CHECK-NEXT:    addq $8, %rsp42; CHECK-NEXT:    popq %rbx43; CHECK-NEXT:    popq %rbp44; CHECK-NEXT:    retq45entry:46; Because the first call clobbers esi, we have to move the values into47; new registers.  Note that they stay in the registers for both calls.48  call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a, i32 %b)]49  call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %b, i32 %a)]50  ret void51}52 53define void @test3(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i) gc "statepoint-example" {54; CHECK-LABEL: test3:55; CHECK:       ## %bb.0: ## %entry56; CHECK-NEXT:    pushq %rax57; CHECK-NEXT:    .cfi_def_cfa_offset 1658; CHECK-NEXT:    callq _bar59; CHECK-NEXT:  Ltmp3:60; CHECK-NEXT:    popq %rax61; CHECK-NEXT:    retq62entry:63; We directly reference the argument slot64  %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 2, i32 0, i32 0) ["deopt"(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i)]65  ret void66}67 68; This case just confirms that we don't crash when given more live values69; than registers.  This is a case where we *have* to use a stack slot.  This70; also ends up being a good test of whether we can fold loads from immutable71; stack slots into the statepoint.72define 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" {73; CHECK-LABEL: test4:74; CHECK:       ## %bb.0: ## %entry75; CHECK-NEXT:    pushq %rax76; CHECK-NEXT:    .cfi_def_cfa_offset 1677; CHECK-NEXT:    callq _bar78; CHECK-NEXT:  Ltmp4:79; CHECK-NEXT:    popq %rax80; CHECK-NEXT:    retq81entry:82  %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 2, 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)]83  ret void84}85 86; A live-through gc-value must be spilled even if it is also a live-in deopt87; value.  For live-in, we could technically report the register copy, but from88; a code quality perspective it's better to reuse the required stack slot so89; as to put less stress on the register allocator for no benefit.90define  ptr addrspace(1) @test5(i32 %a, ptr addrspace(1) %p) gc "statepoint-example" {91; CHECK-LABEL: test5:92; CHECK:       ## %bb.0: ## %entry93; CHECK-NEXT:    pushq %rax94; CHECK-NEXT:    .cfi_def_cfa_offset 1695; CHECK-NEXT:    movq %rsi, (%rsp)96; CHECK-NEXT:    callq _bar97; CHECK-NEXT:  Ltmp5:98; CHECK-NEXT:    movq (%rsp), %rax99; CHECK-NEXT:    popq %rcx100; CHECK-NEXT:    retq101entry:102  %token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %p), "deopt"(i32 %a)]103  %p2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token,  i32 0, i32 0)104  ret ptr addrspace(1) %p2105}106 107; Show the interaction of live-through spilling followed by live-in.108define void @test6(i32 %a) gc "statepoint-example" {109; CHECK-LABEL: test6:110; CHECK:       ## %bb.0: ## %entry111; CHECK-NEXT:    pushq %rbx112; CHECK-NEXT:    .cfi_def_cfa_offset 16113; CHECK-NEXT:    subq $16, %rsp114; CHECK-NEXT:    .cfi_def_cfa_offset 32115; CHECK-NEXT:    .cfi_offset %rbx, -16116; CHECK-NEXT:    movl %edi, %ebx117; CHECK-NEXT:    movl %edi, {{[0-9]+}}(%rsp)118; CHECK-NEXT:    callq _baz119; CHECK-NEXT:  Ltmp6:120; CHECK-NEXT:    callq _bar121; CHECK-NEXT:  Ltmp7:122; CHECK-NEXT:    addq $16, %rsp123; CHECK-NEXT:    popq %rbx124; CHECK-NEXT:    retq125entry:126  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)]127  call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a)]128  ret void129}130 131; A variant of test6 where values are not directly foldable from stack slots.132; This stresses our rematerialization handling.133define 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" {134; The code for this is terrible, check simply for correctness for the moment135; CHECK-LABEL: test7:136; CHECK:       ## %bb.0: ## %entry137; CHECK-NEXT:    pushq %rbp138; CHECK-NEXT:    .cfi_def_cfa_offset 16139; CHECK-NEXT:    pushq %r15140; CHECK-NEXT:    .cfi_def_cfa_offset 24141; CHECK-NEXT:    pushq %r14142; CHECK-NEXT:    .cfi_def_cfa_offset 32143; CHECK-NEXT:    pushq %r13144; CHECK-NEXT:    .cfi_def_cfa_offset 40145; CHECK-NEXT:    pushq %r12146; CHECK-NEXT:    .cfi_def_cfa_offset 48147; CHECK-NEXT:    pushq %rbx148; CHECK-NEXT:    .cfi_def_cfa_offset 56149; CHECK-NEXT:    subq $88, %rsp150; CHECK-NEXT:    .cfi_def_cfa_offset 144151; CHECK-NEXT:    .cfi_offset %rbx, -56152; CHECK-NEXT:    .cfi_offset %r12, -48153; CHECK-NEXT:    .cfi_offset %r13, -40154; CHECK-NEXT:    .cfi_offset %r14, -32155; CHECK-NEXT:    .cfi_offset %r15, -24156; CHECK-NEXT:    .cfi_offset %rbp, -16157; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax158; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill159; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax160; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill161; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax162; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill163; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax164; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill165; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax166; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill167; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax168; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill169; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax170; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill171; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax172; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill173; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax174; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill175; CHECK-NEXT:    movl %edi, %edi176; CHECK-NEXT:    movl %esi, %esi177; CHECK-NEXT:    movl %edx, %edx178; CHECK-NEXT:    movl %ecx, %ecx179; CHECK-NEXT:    movl %r8d, %r8d180; CHECK-NEXT:    movl %r9d, %r9d181; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax182; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill183; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax184; CHECK-NEXT:    movq %rax, (%rsp) ## 8-byte Spill185; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebp186; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r13d187; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r12d188; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r15d189; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r14d190; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebx191; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r11d192; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r10d193; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax194; CHECK-NEXT:    callq _bar ## 88-byte Folded Reload195; CHECK-NEXT:  Ltmp8:196; CHECK-NEXT:    addq $88, %rsp197; CHECK-NEXT:    popq %rbx198; CHECK-NEXT:    popq %r12199; CHECK-NEXT:    popq %r13200; CHECK-NEXT:    popq %r14201; CHECK-NEXT:    popq %r15202; CHECK-NEXT:    popq %rbp203; CHECK-NEXT:    retq204entry:205  %a64 = zext i32 %a to i64206  %b64 = zext i32 %b to i64207  %c64 = zext i32 %c to i64208  %d64 = zext i32 %d to i64209  %e64 = zext i32 %e to i64210  %f64 = zext i32 %f to i64211  %g64 = zext i32 %g to i64212  %h64 = zext i32 %h to i64213  %i64 = zext i32 %i to i64214  %j64 = zext i32 %j to i64215  %k64 = zext i32 %k to i64216  %l64 = zext i32 %l to i64217  %m64 = zext i32 %m to i64218  %n64 = zext i32 %n to i64219  %o64 = zext i32 %o to i64220  %p64 = zext i32 %p to i64221  %q64 = zext i32 %q to i64222  %r64 = zext i32 %r to i64223  %s64 = zext i32 %s to i64224  %t64 = zext i32 %t to i64225  %u64 = zext i32 %u to i64226  %v64 = zext i32 %v to i64227  %w64 = zext i32 %w to i64228  %x64 = zext i32 %x to i64229  %y64 = zext i32 %y to i64230  %z64 = zext i32 %z to i64231  %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 2, 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)]232  ret void233}234 235; a variant of test7 with mixed types chosen to exercise register aliases236define 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" {237; The code for this is terrible, check simply for correctness for the moment238; CHECK-LABEL: test8:239; CHECK:       ## %bb.0: ## %entry240; CHECK-NEXT:    pushq %rbp241; CHECK-NEXT:    .cfi_def_cfa_offset 16242; CHECK-NEXT:    pushq %r15243; CHECK-NEXT:    .cfi_def_cfa_offset 24244; CHECK-NEXT:    pushq %r14245; CHECK-NEXT:    .cfi_def_cfa_offset 32246; CHECK-NEXT:    pushq %r13247; CHECK-NEXT:    .cfi_def_cfa_offset 40248; CHECK-NEXT:    pushq %r12249; CHECK-NEXT:    .cfi_def_cfa_offset 48250; CHECK-NEXT:    pushq %rbx251; CHECK-NEXT:    .cfi_def_cfa_offset 56252; CHECK-NEXT:    subq $72, %rsp253; CHECK-NEXT:    .cfi_def_cfa_offset 128254; CHECK-NEXT:    .cfi_offset %rbx, -56255; CHECK-NEXT:    .cfi_offset %r12, -48256; CHECK-NEXT:    .cfi_offset %r13, -40257; CHECK-NEXT:    .cfi_offset %r14, -32258; CHECK-NEXT:    .cfi_offset %r15, -24259; CHECK-NEXT:    .cfi_offset %rbp, -16260; CHECK-NEXT:    movl %r9d, %r10d261; CHECK-NEXT:    movl %r8d, %r9d262; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax263; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill264; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax265; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill266; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax267; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill268; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax269; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill270; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax271; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill272; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax273; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill274; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax275; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill276; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax277; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill278; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax279; CHECK-NEXT:    movq %rax, (%rsp) ## 8-byte Spill280; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebp281; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r13d282; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r12d283; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r15d284; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r14d285; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebx286; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r11d287; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r8d288; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax289; CHECK-NEXT:    callq _bar ## 72-byte Folded Reload290; CHECK-NEXT:  Ltmp9:291; CHECK-NEXT:    addq $72, %rsp292; CHECK-NEXT:    popq %rbx293; CHECK-NEXT:    popq %r12294; CHECK-NEXT:    popq %r13295; CHECK-NEXT:    popq %r14296; CHECK-NEXT:    popq %r15297; CHECK-NEXT:    popq %rbp298; CHECK-NEXT:    retq299entry:300  %a8 = trunc i32 %a to i8301  %b8 = trunc i32 %b to i8302  %c8 = trunc i32 %c to i8303  %d8 = trunc i32 %d to i8304  %e16 = trunc i32 %e to i16305  %f16 = trunc i32 %f to i16306  %g16 = trunc i32 %g to i16307  %h16 = trunc i32 %h to i16308  %i64 = zext i32 %i to i64309  %j64 = zext i32 %j to i64310  %k64 = zext i32 %k to i64311  %l64 = zext i32 %l to i64312  %m64 = zext i32 %m to i64313  %n64 = zext i32 %n to i64314  %o64 = zext i32 %o to i64315  %p64 = zext i32 %p to i64316  %q64 = zext i32 %q to i64317  %r64 = zext i32 %r to i64318  %s64 = zext i32 %s to i64319  %t64 = zext i32 %t to i64320  %u64 = zext i32 %u to i64321  %v64 = zext i32 %v to i64322  %w64 = zext i32 %w to i64323  %x64 = zext i32 %x to i64324  %y64 = zext i32 %y to i64325  %z64 = zext i32 %z to i64326  %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 2, 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)]327  ret void328}329 330; Test perfect forwarding of argument registers and stack slots to the331; deopt bundle uses332define 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" {333; CHECK-LABEL: test9:334; CHECK:       ## %bb.0: ## %entry335; CHECK-NEXT:    pushq %rax336; CHECK-NEXT:    .cfi_def_cfa_offset 16337; CHECK-NEXT:    callq _bar338; CHECK-NEXT:  Ltmp10:339; CHECK-NEXT:    popq %rax340; CHECK-NEXT:    retq341 342entry:343  %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 2, 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)]344  ret void345}346 347; Test enough folding of argument slots when we have one call which clobbers348; registers before a second which needs them - i.e. we must do something with349; arguments originally passed in registers350define 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" {351; FIXME (minor): It would be better to just spill (and fold reload) for352; argument registers then spill and fill all the CSRs.353; CHECK-LABEL: test10:354; CHECK:       ## %bb.0: ## %entry355; CHECK-NEXT:    pushq %rbp356; CHECK-NEXT:    .cfi_def_cfa_offset 16357; CHECK-NEXT:    pushq %r15358; CHECK-NEXT:    .cfi_def_cfa_offset 24359; CHECK-NEXT:    pushq %r14360; CHECK-NEXT:    .cfi_def_cfa_offset 32361; CHECK-NEXT:    pushq %r13362; CHECK-NEXT:    .cfi_def_cfa_offset 40363; CHECK-NEXT:    pushq %r12364; CHECK-NEXT:    .cfi_def_cfa_offset 48365; CHECK-NEXT:    pushq %rbx366; CHECK-NEXT:    .cfi_def_cfa_offset 56367; CHECK-NEXT:    pushq %rax368; CHECK-NEXT:    .cfi_def_cfa_offset 64369; CHECK-NEXT:    .cfi_offset %rbx, -56370; CHECK-NEXT:    .cfi_offset %r12, -48371; CHECK-NEXT:    .cfi_offset %r13, -40372; CHECK-NEXT:    .cfi_offset %r14, -32373; CHECK-NEXT:    .cfi_offset %r15, -24374; CHECK-NEXT:    .cfi_offset %rbp, -16375; CHECK-NEXT:    movl %r9d, %ebp376; CHECK-NEXT:    movl %r8d, %ebx377; CHECK-NEXT:    movl %ecx, %r14d378; CHECK-NEXT:    movl %edx, %r15d379; CHECK-NEXT:    movl %esi, %r12d380; CHECK-NEXT:    movl %edi, %r13d381; CHECK-NEXT:    callq _bar382; CHECK-NEXT:  Ltmp11:383; CHECK-NEXT:    callq _bar384; CHECK-NEXT:  Ltmp12:385; CHECK-NEXT:    addq $8, %rsp386; CHECK-NEXT:    popq %rbx387; CHECK-NEXT:    popq %r12388; CHECK-NEXT:    popq %r13389; CHECK-NEXT:    popq %r14390; CHECK-NEXT:    popq %r15391; CHECK-NEXT:    popq %rbp392; CHECK-NEXT:    retq393 394entry:395  %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 2, 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)]396  %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 2, 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)]397  ret void398}399 400; Check that we can remat some uses of a def despite not remating before the401; statepoint user.402define 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" {403; FIXME: The codegen for this is correct, but horrible.  Lots of room for404; improvement if we so desire.405; CHECK-LABEL: test11:406; CHECK:       ## %bb.0: ## %entry407; CHECK-NEXT:    pushq %rbp408; CHECK-NEXT:    .cfi_def_cfa_offset 16409; CHECK-NEXT:    pushq %r15410; CHECK-NEXT:    .cfi_def_cfa_offset 24411; CHECK-NEXT:    pushq %r14412; CHECK-NEXT:    .cfi_def_cfa_offset 32413; CHECK-NEXT:    pushq %r13414; CHECK-NEXT:    .cfi_def_cfa_offset 40415; CHECK-NEXT:    pushq %r12416; CHECK-NEXT:    .cfi_def_cfa_offset 48417; CHECK-NEXT:    pushq %rbx418; CHECK-NEXT:    .cfi_def_cfa_offset 56419; CHECK-NEXT:    subq $168, %rsp420; CHECK-NEXT:    .cfi_def_cfa_offset 224421; CHECK-NEXT:    .cfi_offset %rbx, -56422; CHECK-NEXT:    .cfi_offset %r12, -48423; CHECK-NEXT:    .cfi_offset %r13, -40424; CHECK-NEXT:    .cfi_offset %r14, -32425; CHECK-NEXT:    .cfi_offset %r15, -24426; CHECK-NEXT:    .cfi_offset %rbp, -16427; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax428; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill429; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax430; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill431; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax432; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill433; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax434; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill435; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax436; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill437; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax438; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill439; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax440; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill441; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax442; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill443; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax444; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill445; CHECK-NEXT:    movl %edi, %eax446; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill447; CHECK-NEXT:    movl %esi, %eax448; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill449; CHECK-NEXT:    movl %edx, %r14d450; CHECK-NEXT:    movl %ecx, %eax451; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill452; CHECK-NEXT:    movl %r8d, %r15d453; CHECK-NEXT:    movl %r9d, %eax454; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill455; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r13d456; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax457; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill458; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax459; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill460; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax461; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill462; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebp463; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax464; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill465; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax466; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill467; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r12d468; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax469; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill470; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebx471; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax472; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill473; CHECK-NEXT:    callq _bar ## 160-byte Folded Reload474; CHECK-NEXT:  Ltmp13:475; CHECK-NEXT:    movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload476; CHECK-NEXT:    addq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Folded Reload477; CHECK-NEXT:    addq {{[-0-9]+}}(%r{{[sb]}}p), %r14 ## 8-byte Folded Reload478; CHECK-NEXT:    addq %rax, %r14479; CHECK-NEXT:    addq {{[-0-9]+}}(%r{{[sb]}}p), %r15 ## 8-byte Folded Reload480; CHECK-NEXT:    addq %r14, %r15481; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax482; CHECK-NEXT:    addq %rax, %r15483; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax484; CHECK-NEXT:    addq %rax, %rbx485; CHECK-NEXT:    addq %r15, %rbx486; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax487; CHECK-NEXT:    addq %rax, %r12488; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax489; CHECK-NEXT:    addq %rax, %r12490; CHECK-NEXT:    addq %rbx, %r12491; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax492; CHECK-NEXT:    addq %rax, %rbp493; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax494; CHECK-NEXT:    addq %rax, %rbp495; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax496; CHECK-NEXT:    addq %rax, %rbp497; CHECK-NEXT:    addq %r12, %rbp498; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax499; CHECK-NEXT:    addq %rax, %r13500; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax501; CHECK-NEXT:    addq %rax, %r13502; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax503; CHECK-NEXT:    addq %rax, %r13504; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax505; CHECK-NEXT:    addq %rax, %r13506; CHECK-NEXT:    addq %rbp, %r13507; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ecx508; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax509; CHECK-NEXT:    addq %rax, %rcx510; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax511; CHECK-NEXT:    addq %rax, %rcx512; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax513; CHECK-NEXT:    addq %rax, %rcx514; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax515; CHECK-NEXT:    addq %rax, %rcx516; CHECK-NEXT:    addq %r13, %rcx517; CHECK-NEXT:    movq %rcx, %rax518; CHECK-NEXT:    addq $168, %rsp519; CHECK-NEXT:    popq %rbx520; CHECK-NEXT:    popq %r12521; CHECK-NEXT:    popq %r13522; CHECK-NEXT:    popq %r14523; CHECK-NEXT:    popq %r15524; CHECK-NEXT:    popq %rbp525; CHECK-NEXT:    retq526 527entry:528  %a64 = zext i32 %a to i64529  %b64 = zext i32 %b to i64530  %c64 = zext i32 %c to i64531  %d64 = zext i32 %d to i64532  %e64 = zext i32 %e to i64533  %f64 = zext i32 %f to i64534  %g64 = zext i32 %g to i64535  %h64 = zext i32 %h to i64536  %i64 = zext i32 %i to i64537  %j64 = zext i32 %j to i64538  %k64 = zext i32 %k to i64539  %l64 = zext i32 %l to i64540  %m64 = zext i32 %m to i64541  %n64 = zext i32 %n to i64542  %o64 = zext i32 %o to i64543  %p64 = zext i32 %p to i64544  %q64 = zext i32 %q to i64545  %r64 = zext i32 %r to i64546  %s64 = zext i32 %s to i64547  %t64 = zext i32 %t to i64548  %u64 = zext i32 %u to i64549  %v64 = zext i32 %v to i64550  %w64 = zext i32 %w to i64551  %x64 = zext i32 %x to i64552  %y64 = zext i32 %y to i64553  %z64 = zext i32 %z to i64554  call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, 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)]555  %addab = add i64 %a64, %b64556  %addc = add i64 %addab, %c64557  %addd = add i64 %addc, %d64558  %adde = add i64 %addd, %e64559  %addf = add i64 %adde, %f64560  %addg = add i64 %addf, %g64561  %addh = add i64 %addg, %h64562  %addi = add i64 %addh, %i64563  %addj = add i64 %addi, %j64564  %addk = add i64 %addj, %k64565  %addl = add i64 %addk, %l64566  %addm = add i64 %addl, %m64567  %addn = add i64 %addm, %n64568  %addo = add i64 %addn, %o64569  %addp = add i64 %addo, %p64570  %addq = add i64 %addp, %q64571  %addr = add i64 %addq, %r64572  %adds = add i64 %addr, %s64573  %addt = add i64 %adds, %t64574  %addu = add i64 %addt, %u64575  %addv = add i64 %addu, %v64576  %addw = add i64 %addv, %w64577  %addx = add i64 %addw, %x64578  %addy = add i64 %addx, %y64579  %addz = add i64 %addy, %z64580  ret i64 %addz581}582 583; Demonstrate address of a function (w/o spilling)584define void @addr_func() gc "statepoint-example" {585; CHECK-LABEL: addr_func:586; CHECK:       ## %bb.0: ## %entry587; CHECK-NEXT:    pushq %rax588; CHECK-NEXT:    .cfi_def_cfa_offset 16589; CHECK-NEXT:    movq _bar@GOTPCREL(%rip), %rax590; CHECK-NEXT:    callq _bar591; CHECK-NEXT:  Ltmp14:592; CHECK-NEXT:    popq %rax593; CHECK-NEXT:    retq594entry:595  %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 2, i64 0, i64 0) ["deopt"(ptr @bar, ptr @bar, ptr @bar)]596  ret void597}598 599; Demonstrate address of a global (w/o spilling)600@G = external global i32601define void @addr_global() gc "statepoint-example" {602; CHECK-LABEL: addr_global:603; CHECK:       ## %bb.0: ## %entry604; CHECK-NEXT:    pushq %rax605; CHECK-NEXT:    .cfi_def_cfa_offset 16606; CHECK-NEXT:    movq _G@GOTPCREL(%rip), %rax607; CHECK-NEXT:    callq _bar608; CHECK-NEXT:  Ltmp15:609; CHECK-NEXT:    popq %rax610; CHECK-NEXT:    retq611entry:612  %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 2, i64 0, i64 0) ["deopt"(ptr @G, ptr @G, ptr @G)]613  ret void614}615 616define void @addr_alloca(i32 %v) gc "statepoint-example" {617; CHECK-LABEL: addr_alloca:618; CHECK:       ## %bb.0: ## %entry619; CHECK-NEXT:    pushq %rax620; CHECK-NEXT:    .cfi_def_cfa_offset 16621; CHECK-NEXT:    movl %edi, {{[0-9]+}}(%rsp)622; CHECK-NEXT:    callq _bar623; CHECK-NEXT:  Ltmp16:624; CHECK-NEXT:    popq %rax625; CHECK-NEXT:    retq626entry:627  %a = alloca i32628  store i32 %v, ptr %a629  %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 2, i64 0, i64 0) ["deopt"(ptr %a, ptr %a, ptr %a)]630  ret void631}632 633 634; CHECK: Ltmp0-_test1635; CHECK:      .byte	1636; CHECK-NEXT:   .byte   0637; CHECK-NEXT: .short 4638; CHECK-NEXT: .short	5639; CHECK-NEXT:   .short  0640; CHECK-NEXT: .long	0641 642; CHECK: Ltmp1-_test2643; CHECK:      .byte	1644; CHECK-NEXT:   .byte   0645; CHECK-NEXT: .short 4646; CHECK-NEXT: .short	6647; CHECK-NEXT:   .short  0648; CHECK-NEXT: .long	0649; CHECK:      .byte	1650; CHECK-NEXT:   .byte   0651; CHECK-NEXT: .short 4652; CHECK-NEXT: .short	3653; CHECK-NEXT:   .short  0654; CHECK-NEXT: .long	0655; CHECK: Ltmp2-_test2656; CHECK:      .byte	1657; CHECK-NEXT:   .byte   0658; CHECK-NEXT: .short 4659; CHECK-NEXT: .short	3660; CHECK-NEXT:   .short  0661; CHECK-NEXT: .long	0662; CHECK:      .byte	1663; CHECK-NEXT:   .byte   0664; CHECK-NEXT: .short 4665; CHECK-NEXT: .short	6666; CHECK-NEXT:   .short  0667; CHECK-NEXT: .long	0668 669declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)670declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32)671 672attributes #0 = { "deopt-lowering"="live-in" }673attributes #1 = { "deopt-lowering"="live-through" }674