210 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -verify-machineinstrs -stack-symbol-ordering=0 -mcpu=nehalem -debug-only=stackmaps < %s | FileCheck %s3; REQUIRES: asserts4 5target triple = "x86_64-pc-linux-gnu"6 7; Can we lower a single vector?8define <2 x ptr addrspace(1)> @test(<2 x ptr addrspace(1)> %obj) gc "statepoint-example" {9; CHECK-LABEL: test:10; CHECK: # %bb.0: # %entry11; CHECK-NEXT: subq $24, %rsp12; CHECK-NEXT: .cfi_def_cfa_offset 3213; CHECK-NEXT: movaps %xmm0, (%rsp)14; CHECK-NEXT: callq do_safepoint@PLT15; CHECK-NEXT: .Ltmp0:16; CHECK-NEXT: movaps (%rsp), %xmm017; CHECK-NEXT: addq $24, %rsp18; CHECK-NEXT: .cfi_def_cfa_offset 819; CHECK-NEXT: retq20entry:21 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x ptr addrspace(1)> %obj)]22 %obj.relocated = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token %safepoint_token, i32 0, i32 0) ; (%obj, %obj)23 ret <2 x ptr addrspace(1)> %obj.relocated24}25 26; Can we lower the base, derived pairs if both are vectors?27define <2 x ptr addrspace(1)> @test2(<2 x ptr addrspace(1)> %obj, i64 %offset) gc "statepoint-example" {28; CHECK-LABEL: test2:29; CHECK: # %bb.0: # %entry30; CHECK-NEXT: subq $40, %rsp31; CHECK-NEXT: .cfi_def_cfa_offset 4832; CHECK-NEXT: movq %rdi, %xmm133; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,1,0,1]34; CHECK-NEXT: paddq %xmm0, %xmm135; CHECK-NEXT: movdqa %xmm0, (%rsp)36; CHECK-NEXT: movdqa %xmm1, {{[0-9]+}}(%rsp)37; CHECK-NEXT: callq do_safepoint@PLT38; CHECK-NEXT: .Ltmp1:39; CHECK-NEXT: movaps {{[0-9]+}}(%rsp), %xmm040; CHECK-NEXT: addq $40, %rsp41; CHECK-NEXT: .cfi_def_cfa_offset 842; CHECK-NEXT: retq43entry:44 %derived = getelementptr i8, <2 x ptr addrspace(1)> %obj, i64 %offset45 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x ptr addrspace(1)> %obj, <2 x ptr addrspace(1)> %derived)]46 %derived.relocated = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token %safepoint_token, i32 0, i32 1) ; (%obj, %derived)47 ret <2 x ptr addrspace(1)> %derived.relocated48}49 50; Originally, this was just a variant of @test2 above, but it ends up51; covering a bunch of interesting missed optimizations. Specifically:52; - We waste a stack slot for a value that a backend transform pass53; CSEd to another spilled one.54; - We don't remove the testb even though it serves no purpose55; - We could in principal reuse the argument memory (%rsi) and do away56; with stack slots entirely.57define <2 x ptr addrspace(1)> @test3(i1 %cnd, ptr %ptr) gc "statepoint-example" {58; CHECK-LABEL: test3:59; CHECK: # %bb.0: # %entry60; CHECK-NEXT: testb $1, %dil61; CHECK-NEXT: movaps (%rsi), %xmm062; CHECK-NEXT: subq $40, %rsp63; CHECK-NEXT: .cfi_def_cfa_offset 4864; CHECK-NEXT: movaps %xmm0, (%rsp)65; CHECK-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)66; CHECK-NEXT: callq do_safepoint@PLT67; CHECK-NEXT: .Ltmp2:68; CHECK-NEXT: movaps (%rsp), %xmm069; CHECK-NEXT: addq $40, %rsp70; CHECK-NEXT: .cfi_def_cfa_offset 871; CHECK-NEXT: retq72entry:73 br i1 %cnd, label %taken, label %untaken74 75taken: ; preds = %entry76 %obja = load <2 x ptr addrspace(1)>, ptr %ptr77 br label %merge78 79untaken: ; preds = %entry80 %objb = load <2 x ptr addrspace(1)>, ptr %ptr81 br label %merge82 83merge: ; preds = %untaken, %taken84 %obj.base = phi <2 x ptr addrspace(1)> [ %obja, %taken ], [ %objb, %untaken ]85 %obj = phi <2 x ptr addrspace(1)> [ %obja, %taken ], [ %objb, %untaken ]86 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x ptr addrspace(1)> %obj, <2 x ptr addrspace(1)> %obj.base)]87 %obj.relocated = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token %safepoint_token, i32 1, i32 0) ; (%obj.base, %obj)88 %obj.relocated.casted = bitcast <2 x ptr addrspace(1)> %obj.relocated to <2 x ptr addrspace(1)>89 %obj.base.relocated = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token %safepoint_token, i32 1, i32 1) ; (%obj.base, %obj.base)90 %obj.base.relocated.casted = bitcast <2 x ptr addrspace(1)> %obj.base.relocated to <2 x ptr addrspace(1)>91 ret <2 x ptr addrspace(1)> %obj.relocated.casted92}93 94; Can we handle vector constants? At the moment, we don't appear to actually95; get selection dag nodes for these.96define <2 x ptr addrspace(1)> @test4() gc "statepoint-example" {97; CHECK-LABEL: test4:98; CHECK: # %bb.0: # %entry99; CHECK-NEXT: subq $24, %rsp100; CHECK-NEXT: .cfi_def_cfa_offset 32101; CHECK-NEXT: xorps %xmm0, %xmm0102; CHECK-NEXT: movaps %xmm0, (%rsp)103; CHECK-NEXT: callq do_safepoint@PLT104; CHECK-NEXT: .Ltmp3:105; CHECK-NEXT: movaps (%rsp), %xmm0106; CHECK-NEXT: addq $24, %rsp107; CHECK-NEXT: .cfi_def_cfa_offset 8108; CHECK-NEXT: retq109entry:110 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x ptr addrspace(1)> zeroinitializer)]111 %obj.relocated = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token %safepoint_token, i32 0, i32 0)112 ret <2 x ptr addrspace(1)> %obj.relocated113}114 115; Check that we can lower a constant typed as i128 correctly. We don't have116; a representation of larger than 64 bit constant in the StackMap format. At117; the moment, this simply means spilling them, but there's a potential118; optimization for values representable as sext(Con64).119define void @test5() gc "statepoint-example" {120; CHECK-LABEL: test5:121; CHECK: # %bb.0: # %entry122; CHECK-NEXT: subq $40, %rsp123; CHECK-NEXT: .cfi_def_cfa_offset 48124; CHECK-NEXT: xorps %xmm0, %xmm0125; CHECK-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp)126; CHECK-NEXT: movq $-1, {{[0-9]+}}(%rsp)127; CHECK-NEXT: movq $-1, (%rsp)128; CHECK-NEXT: callq do_safepoint@PLT129; CHECK-NEXT: .Ltmp4:130; CHECK-NEXT: addq $40, %rsp131; CHECK-NEXT: .cfi_def_cfa_offset 8132; CHECK-NEXT: retq133entry:134 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) ["deopt" (i128 0, i128 -1)]135 ret void136}137 138; CHECK: __LLVM_StackMaps:139 140; CHECK: .Ltmp0-test141; Check for the two spill slots142; Stack Maps: Loc 3: Indirect 7+0 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 0]143; Stack Maps: Loc 4: Indirect 7+0 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 0]144; CHECK: .byte 3145; CHECK: .byte 0146; CHECK: .short 16147; CHECK: .short 7148; CHECK: .short 0149; CHECK: .long 0150; CHECK: .byte 3151; CHECK: .byte 0152; CHECK: .short 16153; CHECK: .short 7154; CHECK: .short 0155; CHECK: .long 0156 157; CHECK: .Ltmp1-test2158; Check for the two spill slots159; Stack Maps: Loc 3: Indirect 7+16 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 16]160; Stack Maps: Loc 4: Indirect 7+0 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 0]161; CHECK: .byte 3162; CHECK: .byte 0163; CHECK: .short 16164; CHECK: .short 7165; CHECK: .short 0166; CHECK: .long 0167; CHECK: .byte 3168; CHECK: .byte 0169; CHECK: .short 16170; CHECK: .short 7171; CHECK: .short 0172; CHECK: .long 16173 174; CHECK: .Ltmp2-test3175; Check for the four spill slots176; Stack Maps: Loc 3: Indirect 7+16 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 16]177; Stack Maps: Loc 4: Indirect 7+16 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 16]178; Stack Maps: Loc 5: Indirect 7+16 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 16]179; Stack Maps: Loc 6: Indirect 7+0 [encoding: .byte 3, .byte 0, .short 16, .short 7, .short 0, .int 0]180; CHECK: .byte 3181; CHECK: .byte 0182; CHECK: .short 16183; CHECK: .short 7184; CHECK: .short 0185; CHECK: .long 16186; CHECK: .byte 3187; CHECK: .byte 0188; CHECK: .short 16189; CHECK: .short 7190; CHECK: .short 0191; CHECK: .long 16192; CHECK: .byte 3193; CHECK: .byte 0194; CHECK: .short 16195; CHECK: .short 7196; CHECK: .short 0197; CHECK: .long 16198; CHECK: .byte 3199; CHECK: .byte 0200; CHECK: .short 16201; CHECK: .short 7202; CHECK: .short 0203; CHECK: .long 0204 205declare void @do_safepoint()206 207declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)208declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32)209declare <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token, i32, i32)210