1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00
llvm-mirror/test/CodeGen/X86/statepoint-vector.ll
Philip Reames 731ed1045b [Statepoint] Factor out logic for non-stack non-vreg lowering [almost NFC]
This is inspired by D81648.  The basic idea is to have the set of SDValues which are lowered as either constants or direct frame references explicit in one place, and to separate them clearly from the spilling logic.

This is not NFC in that the handling of constants larger than > 64 bit has changed.  The old lowering would crash on values which could not be encoded as a sign extended 64 bit value.  The new lowering just spills all constants > 64 bits.  We could be consistent about doing the sext(Con64) optimization, but I happen to know that this code path is utterly unexercised in practice, so simple is better for now.
2020-07-07 13:34:28 -07:00

210 lines
8.8 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -verify-machineinstrs -stack-symbol-ordering=0 -mcpu=nehalem -debug-only=stackmaps < %s | FileCheck %s
; REQUIRES: asserts
target triple = "x86_64-pc-linux-gnu"
; Can we lower a single vector?
define <2 x i8 addrspace(1)*> @test(<2 x i8 addrspace(1)*> %obj) gc "statepoint-example" {
; CHECK-LABEL: test:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subq $24, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: movaps %xmm0, (%rsp)
; CHECK-NEXT: callq do_safepoint
; CHECK-NEXT: .Ltmp0:
; CHECK-NEXT: movaps (%rsp), %xmm0
; CHECK-NEXT: addq $24, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
entry:
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x i8 addrspace(1)*> %obj)]
%obj.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 0, i32 0) ; (%obj, %obj)
ret <2 x i8 addrspace(1)*> %obj.relocated
}
; Can we lower the base, derived pairs if both are vectors?
define <2 x i8 addrspace(1)*> @test2(<2 x i8 addrspace(1)*> %obj, i64 %offset) gc "statepoint-example" {
; CHECK-LABEL: test2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subq $40, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: movq %rdi, %xmm1
; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,1,0,1]
; CHECK-NEXT: paddq %xmm0, %xmm1
; CHECK-NEXT: movdqa %xmm0, {{[0-9]+}}(%rsp)
; CHECK-NEXT: movdqa %xmm1, (%rsp)
; CHECK-NEXT: callq do_safepoint
; CHECK-NEXT: .Ltmp1:
; CHECK-NEXT: movaps (%rsp), %xmm0
; CHECK-NEXT: addq $40, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
entry:
%derived = getelementptr i8, <2 x i8 addrspace(1)*> %obj, i64 %offset
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x i8 addrspace(1)*> %obj, <2 x i8 addrspace(1)*> %derived)]
%derived.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 0, i32 1) ; (%obj, %derived)
ret <2 x i8 addrspace(1)*> %derived.relocated
}
; Originally, this was just a variant of @test2 above, but it ends up
; covering a bunch of interesting missed optimizations. Specifically:
; - We waste a stack slot for a value that a backend transform pass
; CSEd to another spilled one.
; - We don't remove the testb even though it serves no purpose
; - We could in principal reuse the argument memory (%rsi) and do away
; with stack slots entirely.
define <2 x i64 addrspace(1)*> @test3(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
; CHECK-LABEL: test3:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subq $40, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: testb $1, %dil
; CHECK-NEXT: movaps (%rsi), %xmm0
; CHECK-NEXT: movaps %xmm0, (%rsp)
; CHECK-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)
; CHECK-NEXT: callq do_safepoint
; CHECK-NEXT: .Ltmp2:
; CHECK-NEXT: movaps (%rsp), %xmm0
; CHECK-NEXT: addq $40, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
entry:
br i1 %cnd, label %taken, label %untaken
taken: ; preds = %entry
%obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
br label %merge
untaken: ; preds = %entry
%objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
br label %merge
merge: ; preds = %untaken, %taken
%obj.base = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ]
%obj = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ]
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x i64 addrspace(1)*> %obj, <2 x i64 addrspace(1)*> %obj.base)]
%obj.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 1, i32 0) ; (%obj.base, %obj)
%obj.relocated.casted = bitcast <2 x i8 addrspace(1)*> %obj.relocated to <2 x i64 addrspace(1)*>
%obj.base.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 1, i32 1) ; (%obj.base, %obj.base)
%obj.base.relocated.casted = bitcast <2 x i8 addrspace(1)*> %obj.base.relocated to <2 x i64 addrspace(1)*>
ret <2 x i64 addrspace(1)*> %obj.relocated.casted
}
; Can we handle vector constants? At the moment, we don't appear to actually
; get selection dag nodes for these.
define <2 x i8 addrspace(1)*> @test4() gc "statepoint-example" {
; CHECK-LABEL: test4:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subq $24, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: movaps %xmm0, (%rsp)
; CHECK-NEXT: callq do_safepoint
; CHECK-NEXT: .Ltmp3:
; CHECK-NEXT: movaps (%rsp), %xmm0
; CHECK-NEXT: addq $24, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
entry:
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x i8 addrspace(1)*> zeroinitializer)]
%obj.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 0, i32 0)
ret <2 x i8 addrspace(1)*> %obj.relocated
}
; Check that we can lower a constant typed as i128 correctly. We don't have
; a representation of larger than 64 bit constant in the StackMap format. At
; the moment, this simply means spilling them, but there's a potential
; optimization for values representable as sext(Con64).
define void @test5() gc "statepoint-example" {
; CHECK-LABEL: test5:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subq $40, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: movups %xmm0, {{[0-9]+}}(%rsp)
; CHECK-NEXT: movq $-1, {{[0-9]+}}(%rsp)
; CHECK-NEXT: movq $-1, {{[0-9]+}}(%rsp)
; CHECK-NEXT: callq do_safepoint
; CHECK-NEXT: .Ltmp4:
; CHECK-NEXT: addq $40, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: retq
entry:
%safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["deopt" (i128 0, i128 -1)]
ret void
}
; CHECK: __LLVM_StackMaps:
; CHECK: .Ltmp0-test
; Check for the two spill slots
; Stack Maps: Loc 3: Indirect 7+0 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 0]
; Stack Maps: Loc 4: Indirect 7+0 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 0]
; CHECK: .byte 3
; CHECK: .byte 0
; CHECK: .short 16
; CHECK: .short 7
; CHECK: .short 0
; CHECK: .long 0
; CHECK: .byte 3
; CHECK: .byte 0
; CHECK: .short 16
; CHECK: .short 7
; CHECK: .short 0
; CHECK: .long 0
; CHECK: .Ltmp1-test2
; Check for the two spill slots
; Stack Maps: Loc 3: Indirect 7+16 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 16]
; Stack Maps: Loc 4: Indirect 7+0 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 0]
; CHECK: .byte 3
; CHECK: .byte 0
; CHECK: .short 16
; CHECK: .short 7
; CHECK: .short 0
; CHECK: .long 16
; CHECK: .byte 3
; CHECK: .byte 0
; CHECK: .short 16
; CHECK: .short 7
; CHECK: .short 0
; CHECK: .long 0
; CHECK: .Ltmp2-test3
; Check for the four spill slots
; Stack Maps: Loc 3: Indirect 7+16 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 16]
; Stack Maps: Loc 4: Indirect 7+16 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 16]
; Stack Maps: Loc 5: Indirect 7+16 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 16]
; Stack Maps: Loc 6: Indirect 7+0 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 0]
; CHECK: .byte 3
; CHECK: .byte 0
; CHECK: .short 16
; CHECK: .short 7
; CHECK: .short 0
; CHECK: .long 16
; CHECK: .byte 3
; CHECK: .byte 0
; CHECK: .short 16
; CHECK: .short 7
; CHECK: .short 0
; CHECK: .long 16
; CHECK: .byte 3
; CHECK: .byte 0
; CHECK: .short 16
; CHECK: .short 7
; CHECK: .short 0
; CHECK: .long 16
; CHECK: .byte 3
; CHECK: .byte 0
; CHECK: .short 16
; CHECK: .short 7
; CHECK: .short 0
; CHECK: .long 0
declare void @do_safepoint()
declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32)
declare <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token, i32, i32)