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