eda7814e3d5f81dd9515ef130a708fa3f27b31f4
[oota-llvm.git] / test / CodeGen / X86 / statepoint-vector.ll
1 ; RUN: llc -mcpu=core-avx -debug-only=stackmaps < %s | FileCheck %s
2
3 target triple = "x86_64-pc-linux-gnu"
4
5 ; Can we lower a single vector?
6 define <2 x i8 addrspace(1)*> @test(<2 x i8 addrspace(1)*> %obj) gc "statepoint-example" {
7 entry:
8 ; CHECK-LABEL: @test
9 ; CHECK: subq   $24, %rsp
10 ; CHECK: movaps %xmm0, (%rsp)
11 ; CHECK: callq  do_safepoint
12 ; CHECK: movaps (%rsp), %xmm0
13 ; CHECK: addq   $24, %rsp
14   %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, <2 x i8 addrspace(1)*> %obj)
15   %obj.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 7, i32 7) ; (%obj, %obj)
16   ret <2 x i8 addrspace(1)*> %obj.relocated
17 }
18
19 ; Can we lower the base, derived pairs if both are vectors?
20 define <2 x i8 addrspace(1)*> @test2(<2 x i8 addrspace(1)*> %obj, i64 %offset) gc "statepoint-example" {
21 entry:
22 ; CHECK-LABEL: @test2
23 ; CHECK: subq   $40, %rsp
24 ; CHECK: movd   %rdi, %xmm1
25 ; CHECK: pshufd $68, %xmm1, %xmm1       # xmm1 = xmm1[0,1,0,1]
26 ; CHECK: paddq  %xmm0, %xmm1
27 ; CHECK: movdqa %xmm0, 16(%rsp)
28 ; CHECK: movdqa %xmm1, (%rsp)
29 ; CHECK: callq  do_safepoint
30 ; CHECK: movaps (%rsp), %xmm0
31 ; CHECK: addq   $40, %rsp
32   %derived = getelementptr i8, <2 x i8 addrspace(1)*> %obj, i64 %offset
33   %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, <2 x i8 addrspace(1)*> %obj, <2 x i8 addrspace(1)*> %derived)
34   %derived.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 7, i32 8) ; (%obj, %derived)
35   ret <2 x i8 addrspace(1)*> %derived.relocated
36 }
37
38 ; Originally, this was just a variant of @test2 above, but it ends up 
39 ; covering a bunch of interesting missed optimizations.  Specifically:
40 ; - We waste a stack slot for a value that a backend transform pass
41 ;   CSEd to another spilled one.
42 ; - We don't remove the testb even though it serves no purpose
43 ; - We could in principal reuse the argument memory (%rsi) and do away
44 ;   with stack slots entirely.
45 define <2 x i64 addrspace(1)*> @test3(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
46 entry:
47 ; CHECK-LABEL: @test3
48 ; CHECK: subq   $40, %rsp
49 ; CHECK: testb  $1, %dil
50 ; CHECK: movaps (%rsi), %xmm0
51 ; CHECK: movaps %xmm0, 16(%rsp)
52 ; CHECK: movaps %xmm0, (%rsp)
53 ; CHECK: callq  do_safepoint
54 ; CHECK: movaps (%rsp), %xmm0
55 ; CHECK: addq   $40, %rsp
56   br i1 %cnd, label %taken, label %untaken
57
58 taken:                                            ; preds = %entry
59   %obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
60   br label %merge
61
62 untaken:                                          ; preds = %entry
63   %objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
64   br label %merge
65
66 merge:                                            ; preds = %untaken, %taken
67   %obj.base = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ]
68   %obj = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ]
69   %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, <2 x i64 addrspace(1)*> %obj, <2 x i64 addrspace(1)*> %obj.base)
70   %obj.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 8, i32 7) ; (%obj.base, %obj)
71   %obj.relocated.casted = bitcast <2 x i8 addrspace(1)*> %obj.relocated to <2 x i64 addrspace(1)*>
72   %obj.base.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 8, i32 8) ; (%obj.base, %obj.base)
73   %obj.base.relocated.casted = bitcast <2 x i8 addrspace(1)*> %obj.base.relocated to <2 x i64 addrspace(1)*>
74   ret <2 x i64 addrspace(1)*> %obj.relocated.casted
75 }
76
77 ; Can we handle vector constants?  At the moment, we don't appear to actually
78 ; get selection dag nodes for these.
79 define <2 x i8 addrspace(1)*> @test4() gc "statepoint-example" {
80 entry:
81 ; CHECK-LABEL: @test4
82 ; CHECK: subq   $24, %rsp
83 ; CHECK: xorps %xmm0, %xmm0
84 ; CHECK: movaps %xmm0, (%rsp)
85 ; CHECK: callq  do_safepoint
86 ; CHECK: movaps (%rsp), %xmm0
87 ; CHECK: addq   $24, %rsp
88   %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, <2 x i8 addrspace(1)*> zeroinitializer)
89   %obj.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 7, i32 7) ; (%obj, %obj)
90   ret <2 x i8 addrspace(1)*> %obj.relocated
91 }
92
93 ; Check that we can lower a constant typed as i128 correctly.  Note that the
94 ; actual value is representable in 64 bits.  We don't have a representation 
95 ; of larger than 64 bit constant in the StackMap format.
96 define void @test5() gc "statepoint-example" {
97 entry:
98 ; CHECK-LABEL: @test5
99 ; CHECK: push
100 ; CHECK: callq  do_safepoint
101 ; CHECK: pop
102   %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 1, i128 0)
103   ret void
104 }
105
106 ; CHECK: __LLVM_StackMaps:
107
108 ; CHECK: .Ltmp1-test
109 ; Check for the two spill slots
110 ; Stack Maps:           Loc 3: Indirect 7+0     [encoding: .byte 3, .byte 16, .short 7, .int 0]
111 ; Stack Maps:           Loc 4: Indirect 7+0     [encoding: .byte 3, .byte 16, .short 7, .int 0]
112 ; CHECK: .byte  3
113 ; CHECK: .byte  16
114 ; CHECK: .short 7
115 ; CHECK: .long  0
116 ; CHECK: .byte  3
117 ; CHECK: .byte  16
118 ; CHECK: .short 7
119 ; CHECK: .long  0
120
121 ; CHECK: .Ltmp3-test2
122 ; Check for the two spill slots
123 ; Stack Maps:           Loc 3: Indirect 7+16    [encoding: .byte 3, .byte 16, .short 7, .int 16]
124 ; Stack Maps:           Loc 4: Indirect 7+0     [encoding: .byte 3, .byte 16, .short 7, .int 0]
125 ; CHECK: .byte  3
126 ; CHECK: .byte  16
127 ; CHECK: .short 7
128 ; CHECK: .long  16
129 ; CHECK: .byte  3
130 ; CHECK: .byte  16
131 ; CHECK: .short 7
132 ; CHECK: .long  0
133
134 ; CHECK: .Ltmp5-test3
135 ; Check for the four spill slots
136 ; Stack Maps:           Loc 3: Indirect 7+16    [encoding: .byte 3, .byte 16, .short 7, .int 16]
137 ; Stack Maps:           Loc 4: Indirect 7+16    [encoding: .byte 3, .byte 16, .short 7, .int 16]
138 ; Stack Maps:           Loc 5: Indirect 7+16    [encoding: .byte 3, .byte 16, .short 7, .int 16]
139 ; Stack Maps:           Loc 6: Indirect 7+0             [encoding: .byte 3, .byte 16, .short 7, .int 0]
140 ; CHECK: .byte  3
141 ; CHECK: .byte  16
142 ; CHECK: .short 7
143 ; CHECK: .long  16
144 ; CHECK: .byte  3
145 ; CHECK: .byte  16
146 ; CHECK: .short 7
147 ; CHECK: .long  16
148 ; CHECK: .byte  3
149 ; CHECK: .byte  16
150 ; CHECK: .short 7
151 ; CHECK: .long  16
152 ; CHECK: .byte  3
153 ; CHECK: .byte  16
154 ; CHECK: .short 7
155 ; CHECK: .long  0
156
157 declare void @do_safepoint()
158
159 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
160 declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32)
161 declare <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token, i32, i32)