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