mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 11:02:59 +02:00
[WebAssembly] Put __stack_pointer in the offset field of loads and stores.
Instead of this: i32.const $push10=, __stack_pointer i32.load $push11=, 0($pop10) Emit this: i32.const $push10=, 0 i32.load $push11=, __stack_pointer($pop10) It's not currently clear which is better, though there's a chance the second form may be better at overall compression. We can revisit this when we have more data; for now it makes sense to make PEI consistent with isel. Differential Revision: http://reviews.llvm.org/D20411 llvm-svn: 270635
This commit is contained in:
parent
785d92e27f
commit
e46ddfaa34
@ -87,18 +87,18 @@ static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
const TargetRegisterClass *PtrRC =
|
||||
MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
|
||||
unsigned SPAddr = MRI.createVirtualRegister(PtrRC);
|
||||
unsigned Zero = MRI.createVirtualRegister(PtrRC);
|
||||
unsigned Drop = MRI.createVirtualRegister(PtrRC);
|
||||
const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
|
||||
|
||||
BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), SPAddr)
|
||||
.addExternalSymbol(SPSymbol);
|
||||
BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), Zero)
|
||||
.addImm(0);
|
||||
auto *MMO = new MachineMemOperand(MachinePointerInfo(MF.getPSVManager()
|
||||
.getExternalSymbolCallEntry(ES)),
|
||||
MachineMemOperand::MOStore, 4, 4);
|
||||
BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32), Drop)
|
||||
.addImm(0)
|
||||
.addReg(SPAddr)
|
||||
.addExternalSymbol(SPSymbol)
|
||||
.addReg(Zero)
|
||||
.addImm(2) // p2align
|
||||
.addReg(SrcReg)
|
||||
.addMemOperand(MMO);
|
||||
@ -137,20 +137,20 @@ void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
|
||||
|
||||
const TargetRegisterClass *PtrRC =
|
||||
MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
|
||||
unsigned SPAddr = MRI.createVirtualRegister(PtrRC);
|
||||
unsigned Zero = MRI.createVirtualRegister(PtrRC);
|
||||
unsigned SPReg = MRI.createVirtualRegister(PtrRC);
|
||||
const char *ES = "__stack_pointer";
|
||||
auto *SPSymbol = MF.createExternalSymbolName(ES);
|
||||
BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), SPAddr)
|
||||
.addExternalSymbol(SPSymbol);
|
||||
BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), Zero)
|
||||
.addImm(0);
|
||||
auto *LoadMMO = new MachineMemOperand(MachinePointerInfo(MF.getPSVManager()
|
||||
.getExternalSymbolCallEntry(ES)),
|
||||
MachineMemOperand::MOLoad, 4, 4);
|
||||
// Load the SP value.
|
||||
BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32),
|
||||
StackSize ? SPReg : (unsigned)WebAssembly::SP32)
|
||||
.addImm(0) // offset
|
||||
.addReg(SPAddr) // addr
|
||||
.addExternalSymbol(SPSymbol)
|
||||
.addReg(Zero) // addr
|
||||
.addImm(2) // p2align
|
||||
.addMemOperand(LoadMMO);
|
||||
|
||||
|
@ -23,14 +23,14 @@ declare void @ext_byval_func_empty(%EmptyStruct* byval)
|
||||
; CHECK-LABEL: byval_arg
|
||||
define void @byval_arg(%SmallStruct* %ptr) {
|
||||
; CHECK: .param i32
|
||||
; CHECK: i32.const $push[[L4:.+]]=, __stack_pointer
|
||||
; CHECK: i32.const $push[[L4:.+]]=, 0
|
||||
; Subtract 16 from SP (SP is 16-byte aligned)
|
||||
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.load $push[[L2:.+]]=, 0($pop[[L1]])
|
||||
; CHECK: i32.const $push[[L1:.+]]=, 0
|
||||
; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]])
|
||||
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
|
||||
; CHECK-NEXT: i32.sub $push[[L10:.+]]=, $pop[[L2]], $pop[[L3]]
|
||||
; Ensure SP is stored back before the call
|
||||
; CHECK-NEXT: i32.store $push[[L12:.+]]=, 0($pop[[L4]]), $pop[[L10]]{{$}}
|
||||
; CHECK-NEXT: i32.store $push[[L12:.+]]=, __stack_pointer($pop[[L4]]), $pop[[L10]]{{$}}
|
||||
; CHECK-NEXT: tee_local $push[[L11:.+]]=, $[[SP:.+]]=, $pop[[L12]]{{$}}
|
||||
; Copy the SmallStruct argument to the stack (SP+12, original SP-4)
|
||||
; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0)
|
||||
@ -41,10 +41,10 @@ define void @byval_arg(%SmallStruct* %ptr) {
|
||||
; CHECK-NEXT: call ext_byval_func@FUNCTION, $pop[[ARG]]{{$}}
|
||||
call void @ext_byval_func(%SmallStruct* byval %ptr)
|
||||
; Restore the stack
|
||||
; CHECK-NEXT: i32.const $push[[L7:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.const $push[[L7:.+]]=, 0
|
||||
; CHECK-NEXT: i32.const $push[[L6:.+]]=, 16
|
||||
; CHECK-NEXT: i32.add $push[[L8:.+]]=, $[[SP]], $pop[[L6]]
|
||||
; CHECK-NEXT: i32.store {{.*}}=, 0($pop[[L7]]), $pop[[L8]]
|
||||
; CHECK-NEXT: i32.store {{.*}}=, __stack_pointer($pop[[L7]]), $pop[[L8]]
|
||||
; CHECK-NEXT: return
|
||||
ret void
|
||||
}
|
||||
@ -55,7 +55,7 @@ define void @byval_arg_align8(%SmallStruct* %ptr) {
|
||||
; Don't check the entire SP sequence, just enough to get the alignment.
|
||||
; CHECK: i32.const $push[[L1:.+]]=, 16
|
||||
; CHECK-NEXT: i32.sub $push[[L10:.+]]=, {{.+}}, $pop[[L1]]
|
||||
; CHECK-NEXT: i32.store $push[[L12:.+]]=, 0($pop{{.+}}), $pop[[L10]]{{$}}
|
||||
; CHECK-NEXT: i32.store $push[[L12:.+]]=, __stack_pointer($pop{{.+}}), $pop[[L10]]{{$}}
|
||||
; CHECK-NEXT: tee_local $push[[L11:.+]]=, $[[SP:.+]]=, $pop[[L12]]{{$}}
|
||||
; Copy the SmallStruct argument to the stack (SP+8, original SP-8)
|
||||
; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0){{$}}
|
||||
@ -113,12 +113,12 @@ define void @byval_empty_callee(%EmptyStruct* byval %ptr) {
|
||||
|
||||
; Call memcpy for "big" byvals.
|
||||
; CHECK-LABEL: big_byval:
|
||||
; CHECK: i32.const $push[[L4:.+]]=, __stack_pointer
|
||||
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.load $push[[L2:.+]]=, 0($pop[[L1]])
|
||||
; CHECK: i32.const $push[[L4:.+]]=, 0
|
||||
; CHECK: i32.const $push[[L1:.+]]=, 0
|
||||
; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]])
|
||||
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 131072
|
||||
; CHECK-NEXT: i32.sub $push[[L8:.+]]=, $pop[[L2]], $pop[[L3]]
|
||||
; CHECK-NEXT: i32.store $push[[L12:.+]]=, 0($pop[[L4]]), $pop[[L8]]{{$}}
|
||||
; CHECK-NEXT: i32.store $push[[L12:.+]]=, __stack_pointer($pop[[L4]]), $pop[[L8]]{{$}}
|
||||
; CHECK-NEXT: i32.const $push[[L0:.+]]=, 131072
|
||||
; CHECK-NEXT: i32.call $push[[L11:.+]]=, memcpy@FUNCTION, $pop{{.+}}, ${{.+}}, $pop{{.+}}
|
||||
; CHECK-NEXT: tee_local $push[[L9:.+]]=, $[[SP:.+]]=, $pop[[L11]]{{$}}
|
||||
|
@ -449,8 +449,8 @@ bb10: ; preds = %bb9, %bb
|
||||
|
||||
; CHECK-LABEL: stackpointer_dependency:
|
||||
; CHECK: call {{.+}}, stackpointer_callee@FUNCTION,
|
||||
; CHECK: i32.const $push[[L0:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.store $drop=, 0($pop[[L0]]),
|
||||
; CHECK: i32.const $push[[L0:.+]]=, 0
|
||||
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L0]]),
|
||||
declare i32 @stackpointer_callee(i8* readnone, i8* readnone)
|
||||
declare i8* @llvm.frameaddress(i32)
|
||||
define i32 @stackpointer_dependency(i8* readnone) {
|
||||
|
@ -10,29 +10,29 @@ declare void @ext_func_i32(i32* %ptr)
|
||||
; Check that there is an extra local for the stack pointer.
|
||||
; CHECK: .local i32{{$}}
|
||||
define void @alloca32() noredzone {
|
||||
; CHECK: i32.const $push[[L4:.+]]=, __stack_pointer{{$}}
|
||||
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer{{$}}
|
||||
; CHECK-NEXT: i32.load $push[[L2:.+]]=, 0($pop[[L1]])
|
||||
; CHECK: i32.const $push[[L4:.+]]=, 0{{$}}
|
||||
; CHECK: i32.const $push[[L1:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.load $push[[L2:.+]]=, __stack_pointer($pop[[L1]])
|
||||
; CHECK-NEXT: i32.const $push[[L3:.+]]=, 16
|
||||
; CHECK-NEXT: i32.sub $push[[L8:.+]]=, $pop[[L2]], $pop[[L3]]
|
||||
; CHECK-NEXT: i32.store $push[[L10:.+]]=, 0($pop[[L4]]), $pop[[L8]]{{$}}
|
||||
; CHECK-NEXT: i32.store $push[[L10:.+]]=, __stack_pointer($pop[[L4]]), $pop[[L8]]{{$}}
|
||||
; CHECK-NEXT: tee_local $push[[L9:.+]]=, $[[SP:.+]]=, $pop[[L10]]{{$}}
|
||||
%retval = alloca i32
|
||||
; CHECK: i32.const $push[[L0:.+]]=, 0
|
||||
; CHECK: i32.store {{.*}}=, 12($pop[[L9]]), $pop[[L0]]
|
||||
store i32 0, i32* %retval
|
||||
; CHECK: i32.const $push[[L6:.+]]=, __stack_pointer
|
||||
; CHECK: i32.const $push[[L6:.+]]=, 0
|
||||
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 16
|
||||
; CHECK-NEXT: i32.add $push[[L7:.+]]=, $[[SP]], $pop[[L5]]
|
||||
; CHECK-NEXT: i32.store $drop=, 0($pop[[L6]]), $pop[[L7]]
|
||||
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L6]]), $pop[[L7]]
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: alloca3264:
|
||||
; CHECK: .local i32{{$}}
|
||||
define void @alloca3264() {
|
||||
; CHECK: i32.const $push[[L2:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.load $push[[L3:.+]]=, 0($pop[[L2]])
|
||||
; CHECK: i32.const $push[[L2:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.load $push[[L3:.+]]=, __stack_pointer($pop[[L2]])
|
||||
; CHECK-NEXT: i32.const $push[[L4:.+]]=, 16
|
||||
; CHECK-NEXT: i32.sub $push[[L6:.+]]=, $pop[[L3]], $pop[[L4]]
|
||||
; CHECK-NEXT: tee_local $push[[L5:.+]]=, $[[SP:.+]]=, $pop[[L6]]
|
||||
@ -51,12 +51,12 @@ define void @alloca3264() {
|
||||
; CHECK-LABEL: allocarray:
|
||||
; CHECK: .local i32{{$}}
|
||||
define void @allocarray() {
|
||||
; CHECK: i32.const $push[[L7:.+]]=, __stack_pointer
|
||||
; CHECK: i32.const $push[[L4:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.load $push[[L5:.+]]=, 0($pop[[L4]])
|
||||
; CHECK: i32.const $push[[L7:.+]]=, 0{{$}}
|
||||
; CHECK: i32.const $push[[L4:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.load $push[[L5:.+]]=, __stack_pointer($pop[[L4]])
|
||||
; CHECK-NEXT: i32.const $push[[L6:.+]]=, 144{{$}}
|
||||
; CHECK-NEXT: i32.sub $push[[L11:.+]]=, $pop[[L5]], $pop[[L6]]
|
||||
; CHECK-NEXT: i32.store ${{.+}}=, 0($pop[[L7]]), $pop[[L11]]
|
||||
; CHECK-NEXT: i32.store ${{.+}}=, __stack_pointer($pop[[L7]]), $pop[[L11]]
|
||||
%r = alloca [33 x i32]
|
||||
|
||||
; CHECK: i32.const $push{{.+}}=, 24
|
||||
@ -69,10 +69,10 @@ define void @allocarray() {
|
||||
%p2 = getelementptr [33 x i32], [33 x i32]* %r, i32 0, i32 3
|
||||
store i32 1, i32* %p2
|
||||
|
||||
; CHECK: i32.const $push[[L10:.+]]=, __stack_pointer
|
||||
; CHECK: i32.const $push[[L10:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.const $push[[L8:.+]]=, 144
|
||||
; CHECK-NEXT: i32.add $push[[L19:.+]]=, $[[SP]], $pop[[L8]]
|
||||
; CHECK-NEXT: i32.store $drop=, 0($pop[[L10]]), $pop[[L9]]
|
||||
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L10]]), $pop[[L9]]
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -106,12 +106,12 @@ define void @non_mem_use(i8** %addr) {
|
||||
; CHECK-LABEL: allocarray_inbounds:
|
||||
; CHECK: .local i32{{$}}
|
||||
define void @allocarray_inbounds() {
|
||||
; CHECK: i32.const $push[[L6:.+]]=, __stack_pointer
|
||||
; CHECK: i32.const $push[[L3:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.load $push[[L4:.+]]=, 0($pop[[L3]])
|
||||
; CHECK: i32.const $push[[L6:.+]]=, 0{{$}}
|
||||
; CHECK: i32.const $push[[L3:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.load $push[[L4:.+]]=, __stack_pointer($pop[[L3]])
|
||||
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 32{{$}}
|
||||
; CHECK-NEXT: i32.sub $push[[L10:.+]]=, $pop[[L4]], $pop[[L5]]
|
||||
; CHECK-NEXT: i32.store ${{.+}}=, 0($pop[[L6]]), $pop[[L10]]{{$}}
|
||||
; CHECK-NEXT: i32.store ${{.+}}=, __stack_pointer($pop[[L6]]), $pop[[L10]]{{$}}
|
||||
%r = alloca [5 x i32]
|
||||
; CHECK: i32.const $push[[L3:.+]]=, 1
|
||||
; CHECK-DAG: i32.store $push{{.*}}=, 24(${{.+}}), $pop[[L3]]
|
||||
@ -122,36 +122,37 @@ define void @allocarray_inbounds() {
|
||||
%p2 = getelementptr inbounds [5 x i32], [5 x i32]* %r, i32 0, i32 3
|
||||
store i32 1, i32* %p2
|
||||
call void @ext_func(i64* null);
|
||||
; CHECK: i32.const $push[[L6:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 32
|
||||
; CHECK: call ext_func
|
||||
; CHECK: i32.const $push[[L6:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.const $push[[L5:.+]]=, 32{{$}}
|
||||
; CHECK-NEXT: i32.add $push[[L7:.+]]=, ${{.+}}, $pop[[L5]]
|
||||
; CHECK-NEXT: i32.store $drop=, 0($pop[[L6]]), $pop[[L7]]
|
||||
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L6]]), $pop[[L7]]
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: dynamic_alloca:
|
||||
define void @dynamic_alloca(i32 %alloc) {
|
||||
; CHECK: i32.const $push[[L7:.+]]=, __stack_pointer
|
||||
; CHECK: i32.const $push[[L1:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.load $push[[L13:.+]]=, 0($pop[[L1]])
|
||||
; CHECK: i32.const $push[[L7:.+]]=, 0{{$}}
|
||||
; CHECK: i32.const $push[[L1:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.load $push[[L13:.+]]=, __stack_pointer($pop[[L1]])
|
||||
; CHECK-NEXT: tee_local $push[[L12:.+]]=, [[SP:.+]], $pop[[L13]]{{$}}
|
||||
; Target independent codegen bumps the stack pointer.
|
||||
; CHECK: i32.sub
|
||||
; Check that SP is written back to memory after decrement
|
||||
; CHECK: i32.store $drop=, 0($pop{{.+}}),
|
||||
; CHECK: i32.store $drop=, __stack_pointer($pop{{.+}}),
|
||||
%r = alloca i32, i32 %alloc
|
||||
; Target-independent codegen also calculates the store addr
|
||||
; CHECK: call ext_func_i32@FUNCTION
|
||||
call void @ext_func_i32(i32* %r)
|
||||
; CHECK: i32.const $push[[L3:.+]]=, __stack_pointer
|
||||
; CHECK: i32.store $drop=, 0($pop[[L3]]), $pop{{.+}}
|
||||
; CHECK: i32.const $push[[L3:.+]]=, 0{{$}}
|
||||
; CHECK: i32.store $drop=, __stack_pointer($pop[[L3]]), $pop{{.+}}
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: dynamic_alloca_redzone:
|
||||
define void @dynamic_alloca_redzone(i32 %alloc) {
|
||||
; CHECK: i32.const $push[[L8:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.load $push[[L13:.+]]=, 0($pop[[L1]])
|
||||
; CHECK: i32.const $push[[L8:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.load $push[[L13:.+]]=, __stack_pointer($pop[[L1]])
|
||||
; CHECK-NEXT: tee_local $push[[L12:.+]]=, [[SP:.+]], $pop[[L13]]{{$}}
|
||||
; CHECK-NEXT: copy_local [[FP:.+]]=, $pop[[L12]]{{$}}
|
||||
; Target independent codegen bumps the stack pointer
|
||||
@ -169,18 +170,18 @@ define void @dynamic_alloca_redzone(i32 %alloc) {
|
||||
; CHECK-LABEL: dynamic_static_alloca:
|
||||
define void @dynamic_static_alloca(i32 %alloc) noredzone {
|
||||
; Decrement SP in the prolog by the static amount and writeback to memory.
|
||||
; CHECK: i32.const $push[[L7:.+]]=, __stack_pointer
|
||||
; CHECK: i32.const $push[[L8:.+]]=, __stack_pointer
|
||||
; CHECK: i32.const $push[[L9:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.load $push[[L10:.+]]=, 0($pop[[L9]])
|
||||
; CHECK: i32.const $push[[L7:.+]]=, 0{{$}}
|
||||
; CHECK: i32.const $push[[L8:.+]]=, 0{{$}}
|
||||
; CHECK: i32.const $push[[L9:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.load $push[[L10:.+]]=, __stack_pointer($pop[[L9]])
|
||||
; CHECK-NEXT: i32.const $push[[L11:.+]]=, 16
|
||||
; CHECK-NEXT: i32.sub $push[[L20:.+]]=, $pop[[L10]], $pop[[L11]]
|
||||
; CHECK-NEXT: tee_local $push[[L19:.+]]=, $[[FP:.+]]=, $pop[[L20]]
|
||||
; CHECK: i32.store $push[[L0:.+]]=, 0($pop{{.+}}), $pop{{.+}}
|
||||
; CHECK: i32.store $push[[L0:.+]]=, __stack_pointer($pop{{.+}}), $pop{{.+}}
|
||||
; Decrement SP in the body by the dynamic amount.
|
||||
; CHECK: i32.sub
|
||||
; Writeback to memory.
|
||||
; CHECK: i32.store $drop=, 0($pop{{.+}}), $pop{{.+}}
|
||||
; CHECK: i32.store $drop=, __stack_pointer($pop{{.+}}), $pop{{.+}}
|
||||
%r1 = alloca i32
|
||||
%r = alloca i32, i32 %alloc
|
||||
store i32 0, i32* %r
|
||||
@ -214,13 +215,13 @@ declare i8* @llvm.frameaddress(i32)
|
||||
|
||||
; Test __builtin_frame_address(0).
|
||||
; CHECK-LABEL: frameaddress_0:
|
||||
; CHECK: i32.const $push[[L0:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.load $push[[L3:.+]]=, 0($pop[[L0]])
|
||||
; CHECK: i32.const $push[[L0:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.load $push[[L3:.+]]=, __stack_pointer($pop[[L0]])
|
||||
; CHECK-NEXT: copy_local $push[[L4:.+]]=, $pop[[L3]]{{$}}
|
||||
; CHECK-NEXT: tee_local $push[[L2:.+]]=, $[[FP:.+]]=, $pop[[L4]]{{$}}
|
||||
; CHECK-NEXT: call use_i8_star@FUNCTION, $pop[[L2]]
|
||||
; CHECK-NEXT: i32.const $push[[L1:.+]]=, __stack_pointer
|
||||
; CHECK-NEXT: i32.store $drop=, 0($pop[[L1]]), $[[FP]]
|
||||
; CHECK-NEXT: i32.const $push[[L1:.+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.store $drop=, __stack_pointer($pop[[L1]]), $[[FP]]
|
||||
define void @frameaddress_0() {
|
||||
%t = call i8* @llvm.frameaddress(i32 0)
|
||||
call void @use_i8_star(i8* %t)
|
||||
|
Loading…
Reference in New Issue
Block a user