1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00
llvm-mirror/test/CodeGen/AArch64/GlobalISel/irtranslator-localescape.ll
Matt Arsenault a816bda54e GlobalISel: Handle llvm.localescape
This one is pretty easy and shrinks the list of unhandled
intrinsics. I'm not sure how relevant the insert point is. Using the
insert position of EntryBuilder will place this after
constants. SelectionDAG seems to end up emitting these after argument
copies and before anything else, but I don't think it really
matters. This also ends up emitting these in the opposite order from
SelectionDAG, but I don't think that matters either.

This also needs a fix to stop the later passes dropping this as a dead
instruction. DeadMachineInstructionElim's version of isDead special
cases LOCAL_ESCAPE for some reason, and I'm not sure why it's excluded
from MachineInstr::isLabel (or why isDead doesn't check it).

I also noticed DeadMachineInstructionElim never considers inline asm
as dead, but GlobalISel will drop asm with no constraints.
2020-08-04 15:19:02 -04:00

71 lines
3.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
; RUN: llc -global-isel -mtriple=arm64-windows -stop-after=irtranslator -o - %s | FileCheck %s
define void @local_escape() {
; CHECK-LABEL: name: local_escape
; CHECK: bb.1 (%ir-block.0):
; CHECK: LOCAL_ESCAPE <mcsymbol .Llocal_escape$frame_escape_1>, %stack.1.b
; CHECK: LOCAL_ESCAPE <mcsymbol .Llocal_escape$frame_escape_0>, %stack.0.a
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.a
; CHECK: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.b
; CHECK: G_STORE [[C]](s32), [[FRAME_INDEX]](p0) :: (store 4 into %ir.a)
; CHECK: G_STORE [[C1]](s32), [[FRAME_INDEX1]](p0) :: (store 4 into %ir.b)
; CHECK: RET_ReallyLR
%a = alloca i32
%b = alloca i32, i32 2
call void (...) @llvm.localescape(i32* %a, i32* %b)
store i32 42, i32* %a
store i32 13, i32* %b
ret void
}
; Try some instructions before the localescape, and use a null
define void @local_escape_insert_point() {
; CHECK-LABEL: name: local_escape_insert_point
; CHECK: bb.1 (%ir-block.0):
; CHECK: LOCAL_ESCAPE <mcsymbol .Llocal_escape_insert_point$frame_escape_2>, %stack.1.b
; CHECK: LOCAL_ESCAPE <mcsymbol .Llocal_escape_insert_point$frame_escape_0>, %stack.0.a
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.a
; CHECK: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1.b
; CHECK: G_STORE [[C]](s32), [[FRAME_INDEX]](p0) :: (store 4 into %ir.a)
; CHECK: G_STORE [[C1]](s32), [[FRAME_INDEX1]](p0) :: (store 4 into %ir.b)
; CHECK: RET_ReallyLR
%a = alloca i32
%b = alloca i32, i32 2
store i32 42, i32* %a
store i32 13, i32* %b
call void (...) @llvm.localescape(i32* %a, i32* null, i32* %b)
ret void
}
declare void @foo([128 x i32]*)
; Check a cast of an alloca
define void @local_escape_strip_ptr_cast() {
; CHECK-LABEL: name: local_escape_strip_ptr_cast
; CHECK: bb.1 (%ir-block.0):
; CHECK: LOCAL_ESCAPE <mcsymbol .Llocal_escape_strip_ptr_cast$frame_escape_0>, %stack.0.a
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.a
; CHECK: G_STORE [[C]](s32), [[FRAME_INDEX]](p0) :: (store 4 into %ir.cast)
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
; CHECK: $x0 = COPY [[FRAME_INDEX]](p0)
; CHECK: BL @foo, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
; CHECK: RET_ReallyLR
%a = alloca [128 x i32]
%cast = bitcast [128 x i32]* %a to i32*
store i32 42, i32* %cast
call void (...) @llvm.localescape(i32* %cast, i32* null)
call void @foo([128 x i32]* %a)
ret void
}
declare void @llvm.localescape(...) #0
attributes #0 = { nounwind }