Index: lib/CodeGen/SelectionDAG/StatepointLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -478,11 +478,12 @@ SDValue Incoming = Builder.getValue(V); reservePreviousStackSlotForValue(Incoming, Builder); } - for (unsigned i = 0; i < Bases.size() * 2; ++i) { - // Even elements will contain base, odd elements - derived ptr - const Value *V = i % 2 ? Bases[i / 2] : Ptrs[i / 2]; - SDValue Incoming = Builder.getValue(V); - reservePreviousStackSlotForValue(Incoming, Builder); + for (unsigned i = 0; i < Bases.size(); ++i) { + const Value *Base = Bases[i]; + reservePreviousStackSlotForValue(Builder.getValue(Base), Builder); + + const Value *Ptr = Ptrs[i]; + reservePreviousStackSlotForValue(Builder.getValue(Ptr), Builder); } // First, prefix the list with the number of unique values to be @@ -517,11 +518,12 @@ // arrays interwoven with each (lowered) base pointer immediately followed by // it's (lowered) derived pointer. i.e // (base[0], ptr[0], base[1], ptr[1], ...) - for (unsigned i = 0; i < Bases.size() * 2; ++i) { - // Even elements will contain base, odd elements - derived ptr - const Value *V = i % 2 ? Bases[i / 2] : Ptrs[i / 2]; - SDValue Incoming = Builder.getValue(V); - lowerIncomingStatepointValue(Incoming, Ops, Builder); + for (unsigned i = 0; i < Bases.size(); ++i) { + const Value *Base = Bases[i]; + lowerIncomingStatepointValue(Builder.getValue(Base), Ops, Builder); + + const Value *Ptr = Ptrs[i]; + lowerIncomingStatepointValue(Builder.getValue(Ptr), Ops, Builder); } // If there are any explicit spill slots passed to the statepoint, record Index: test/CodeGen/X86/statepoint-stack-usage.ll =================================================================== --- test/CodeGen/X86/statepoint-stack-usage.ll +++ test/CodeGen/X86/statepoint-stack-usage.ll @@ -11,8 +11,8 @@ define i32 @back_to_back_calls(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) #1 gc "statepoint-example" { ; CHECK-LABEL: back_to_back_calls ; The exact stores don't matter, but there need to be three stack slots created -; CHECK: movq %rdx, 16(%rsp) -; CHECK: movq %rdi, 8(%rsp) +; CHECK: movq %rdi, 16(%rsp) +; CHECK: movq %rdx, 8(%rsp) ; CHECK: movq %rsi, (%rsp) %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9) @@ -34,8 +34,8 @@ define i32 @reserve_first(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) #1 gc "statepoint-example" { ; CHECK-LABEL: reserve_first ; The exact stores don't matter, but there need to be three stack slots created -; CHECK: movq %rdx, 16(%rsp) -; CHECK: movq %rdi, 8(%rsp) +; CHECK: movq %rdi, 16(%rsp) +; CHECK: movq %rdx, 8(%rsp) ; CHECK: movq %rsi, (%rsp) %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9) Index: test/CodeGen/X86/statepoint-stackmap-format.ll =================================================================== --- test/CodeGen/X86/statepoint-stackmap-format.ll +++ test/CodeGen/X86/statepoint-stackmap-format.ll @@ -8,23 +8,27 @@ declare zeroext i1 @return_i1() -define i1 @test(i32 addrspace(1)* %ptr) gc "statepoint-example" { +define i1 @test(i32 addrspace(1)* %ptr_base, i32 %arg) + gc "statepoint-example" { ; CHECK-LABEL: test -; Do we see one spill for the local value and the store to the +; Do we see two spills for the local values and the store to the ; alloca? -; CHECK: subq $24, %rsp -; CHECK: movq $0, 8(%rsp) -; CHECK: movq %rdi, (%rsp) +; CHECK: subq $40, %rsp +; CHECK: movq $0, 24(%rsp) +; CHECK: movq %rdi, 16(%rsp) +; CHECK: movq %rax, 8(%rsp) ; CHECK: callq return_i1 -; CHECK: addq $24, %rsp +; CHECK: addq $40, %rsp ; CHECK: retq entry: %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8 store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1 - %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr, i32 addrspace(1)* null, i32 addrspace(1)* %ptr, i32 addrspace(1)* null) + %ptr_derived = getelementptr i32, i32 addrspace(1)* %ptr_base, i32 %arg + %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null) %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 6, i32 6) - %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) + %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 6, i32 7) + %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 8, i32 8) ; ret i1 %call1 } @@ -49,7 +53,7 @@ ; Functions and stack size ; CHECK-NEXT: .quad test -; CHECK-NEXT: .quad 24 +; CHECK-NEXT: .quad 40 ; Large Constants ; Statepoint ID only @@ -59,7 +63,7 @@ ; Constant arguments ; CHECK: .long .Ltmp1-test ; CHECK: .short 0 -; CHECK: .short 8 +; CHECK: .short 10 ; SmallConstant (0) ; CHECK: .byte 4 ; CHECK: .byte 8 @@ -74,7 +78,7 @@ ; CHECK: .byte 2 ; CHECK: .byte 8 ; CHECK: .short 7 -; CHECK: .long 0 +; CHECK: .long 16 ; SmallConstant (0) ; CHECK: .byte 4 ; CHECK: .byte 8 @@ -90,16 +94,26 @@ ; CHECK: .byte 8 ; CHECK: .short 0 ; CHECK: .long 0 -; Direct Spill Slot [RSP+0] +; Direct Spill Slot [RSP+16] ; CHECK: .byte 2 ; CHECK: .byte 8 ; CHECK: .short 7 -; CHECK: .long 0 -; Direct Spill Slot [RSP+0] +; CHECK: .long 16 +; Direct Spill Slot [RSP+8] ; CHECK: .byte 2 ; CHECK: .byte 8 ; CHECK: .short 7 -; CHECK: .long 0 +; CHECK: .long 8 +; Direct Spill Slot [RSP+16] +; CHECK: .byte 2 +; CHECK: .byte 8 +; CHECK: .short 7 +; CHECK: .long 16 +; Direct Spill Slot [RSP+16] +; CHECK: .byte 2 +; CHECK: .byte 8 +; CHECK: .short 7 +; CHECK: .long 16 ; No Padding or LiveOuts ; CHECK: .short 0