The delayed stack protector feature which is currently used for SDAG (and thus allows for more commonly generating tail calls) depends on being able to extract the tail call into a separate return block. To do this it also has to extract the vreg->physreg copies that set up the call's arguments, since if it doesn't then the call inst ends up using undefined physregs in it's new spliced block. SelectionDAG implementations can do this because they delay emitting register copies until *after* the stack arguments are set up. GISel however just processes and emits the arguments in IR order, so stack arguments always end up last, and thus this breaks the code that looks for any register arg copies that precede the call instruction. This patch adds a thunk argument to the assignValueToReg() and custom assignment hooks. For outgoing arguments, register assignments use this return param to return a thunk that does the actual generating of the copies. We collect these until all the outgoing stack assignments have been done and then execute them, so that the copies (and perhaps some artifacts like G_SEXTs) are placed after any stores. Differential Revision: https://reviews.llvm.org/D110610
313 lines
16 KiB
LLVM
313 lines
16 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
|
|
|
|
|
|
define signext i8 @sext_arg_i8(i8 signext %a) {
|
|
; MIPS32-LABEL: name: sext_arg_i8
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY]], 8
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_SEXT]](s32)
|
|
; MIPS32-NEXT: [[SEXT:%[0-9]+]]:_(s32) = G_SEXT [[TRUNC]](s8)
|
|
; MIPS32-NEXT: $v0 = COPY [[SEXT]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
ret i8 %a
|
|
}
|
|
|
|
define zeroext i8 @zext_arg_i8(i8 zeroext %a) {
|
|
; MIPS32-LABEL: name: zext_arg_i8
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[COPY]], 8
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_ZEXT]](s32)
|
|
; MIPS32-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
|
|
; MIPS32-NEXT: $v0 = COPY [[ZEXT]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
ret i8 %a
|
|
}
|
|
|
|
define i8 @aext_arg_i8(i8 %a) {
|
|
; MIPS32-LABEL: name: aext_arg_i8
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
|
|
; MIPS32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s8)
|
|
; MIPS32-NEXT: $v0 = COPY [[ANYEXT]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
ret i8 %a
|
|
}
|
|
|
|
declare signext i8 @sext_stack_arg_i8(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i8 %a)
|
|
declare zeroext i8 @zext_stack_arg_i8(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i8 %a)
|
|
declare i8 @aext_stack_arg_i8(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i8 %a)
|
|
|
|
define signext i8 @call_sext_stack_arg_i8(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i8 signext %a) {
|
|
; MIPS32-LABEL: name: call_sext_stack_arg_i8
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0, $a1, $a2, $a3
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
|
|
; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
|
|
; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
|
|
; MIPS32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
|
; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 8)
|
|
; MIPS32-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[LOAD]], 8
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_SEXT]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[SEXT:%[0-9]+]]:_(s32) = G_SEXT [[TRUNC]](s8)
|
|
; MIPS32-NEXT: [[COPY4:%[0-9]+]]:_(p0) = COPY $sp
|
|
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
|
|
; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY4]], [[C]](s32)
|
|
; MIPS32-NEXT: G_STORE [[SEXT]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack + 16, align 8)
|
|
; MIPS32-NEXT: $a0 = COPY [[COPY]](s32)
|
|
; MIPS32-NEXT: $a1 = COPY [[COPY1]](s32)
|
|
; MIPS32-NEXT: $a2 = COPY [[COPY2]](s32)
|
|
; MIPS32-NEXT: $a3 = COPY [[COPY3]](s32)
|
|
; MIPS32-NEXT: JAL @sext_stack_arg_i8, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
|
; MIPS32-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
|
|
; MIPS32-NEXT: [[ASSERT_SEXT1:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY5]], 8
|
|
; MIPS32-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_SEXT1]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[SEXT1:%[0-9]+]]:_(s32) = G_SEXT [[TRUNC1]](s8)
|
|
; MIPS32-NEXT: $v0 = COPY [[SEXT1]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
%call = call signext i8 @sext_stack_arg_i8(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i8 signext %a)
|
|
ret i8 %call
|
|
}
|
|
|
|
define zeroext i8 @call_zext_stack_arg_i8(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i8 zeroext %a) {
|
|
; MIPS32-LABEL: name: call_zext_stack_arg_i8
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0, $a1, $a2, $a3
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
|
|
; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
|
|
; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
|
|
; MIPS32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
|
; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 8)
|
|
; MIPS32-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[LOAD]], 8
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_ZEXT]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
|
|
; MIPS32-NEXT: [[COPY4:%[0-9]+]]:_(p0) = COPY $sp
|
|
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
|
|
; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY4]], [[C]](s32)
|
|
; MIPS32-NEXT: G_STORE [[ZEXT]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack + 16, align 8)
|
|
; MIPS32-NEXT: $a0 = COPY [[COPY]](s32)
|
|
; MIPS32-NEXT: $a1 = COPY [[COPY1]](s32)
|
|
; MIPS32-NEXT: $a2 = COPY [[COPY2]](s32)
|
|
; MIPS32-NEXT: $a3 = COPY [[COPY3]](s32)
|
|
; MIPS32-NEXT: JAL @zext_stack_arg_i8, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
|
; MIPS32-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
|
|
; MIPS32-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[COPY5]], 8
|
|
; MIPS32-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ASSERT_ZEXT1]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[ZEXT1:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC1]](s8)
|
|
; MIPS32-NEXT: $v0 = COPY [[ZEXT1]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
%call = call zeroext i8 @zext_stack_arg_i8(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i8 zeroext %a)
|
|
ret i8 %call
|
|
}
|
|
|
|
define i8 @call_aext_stack_arg_i8(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i8 %a) {
|
|
; MIPS32-LABEL: name: call_aext_stack_arg_i8
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0, $a1, $a2, $a3
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
|
|
; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
|
|
; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
|
|
; MIPS32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
|
; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 8)
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[LOAD]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s8)
|
|
; MIPS32-NEXT: [[COPY4:%[0-9]+]]:_(p0) = COPY $sp
|
|
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
|
|
; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY4]], [[C]](s32)
|
|
; MIPS32-NEXT: G_STORE [[ANYEXT]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack + 16, align 8)
|
|
; MIPS32-NEXT: $a0 = COPY [[COPY]](s32)
|
|
; MIPS32-NEXT: $a1 = COPY [[COPY1]](s32)
|
|
; MIPS32-NEXT: $a2 = COPY [[COPY2]](s32)
|
|
; MIPS32-NEXT: $a3 = COPY [[COPY3]](s32)
|
|
; MIPS32-NEXT: JAL @aext_stack_arg_i8, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
|
; MIPS32-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
|
|
; MIPS32-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY5]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC1]](s8)
|
|
; MIPS32-NEXT: $v0 = COPY [[ANYEXT1]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
%call = call i8 @aext_stack_arg_i8(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i8 %a)
|
|
ret i8 %call
|
|
}
|
|
|
|
|
|
define signext i16 @sext_arg_i16(i16 signext %a) {
|
|
; MIPS32-LABEL: name: sext_arg_i16
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY]], 16
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[ASSERT_SEXT]](s32)
|
|
; MIPS32-NEXT: [[SEXT:%[0-9]+]]:_(s32) = G_SEXT [[TRUNC]](s16)
|
|
; MIPS32-NEXT: $v0 = COPY [[SEXT]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
ret i16 %a
|
|
}
|
|
|
|
define zeroext i16 @zext_arg_i16(i16 zeroext %a) {
|
|
; MIPS32-LABEL: name: zext_arg_i16
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[COPY]], 16
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[ASSERT_ZEXT]](s32)
|
|
; MIPS32-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s16)
|
|
; MIPS32-NEXT: $v0 = COPY [[ZEXT]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
ret i16 %a
|
|
}
|
|
|
|
define i16 @aext_arg_i16(i16 %a) {
|
|
; MIPS32-LABEL: name: aext_arg_i16
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
|
|
; MIPS32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
|
|
; MIPS32-NEXT: $v0 = COPY [[ANYEXT]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
ret i16 %a
|
|
}
|
|
|
|
declare signext i16 @sext_stack_arg_i16(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i16 %a)
|
|
declare zeroext i16 @zext_stack_arg_i16(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i16 %a)
|
|
declare i16 @aext_stack_arg_i16(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i16 %a)
|
|
|
|
define signext i16 @call_sext_stack_arg_i16(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i16 signext %a) {
|
|
; MIPS32-LABEL: name: call_sext_stack_arg_i16
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0, $a1, $a2, $a3
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
|
|
; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
|
|
; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
|
|
; MIPS32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
|
; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 8)
|
|
; MIPS32-NEXT: [[ASSERT_SEXT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[LOAD]], 16
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[ASSERT_SEXT]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[SEXT:%[0-9]+]]:_(s32) = G_SEXT [[TRUNC]](s16)
|
|
; MIPS32-NEXT: [[COPY4:%[0-9]+]]:_(p0) = COPY $sp
|
|
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
|
|
; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY4]], [[C]](s32)
|
|
; MIPS32-NEXT: G_STORE [[SEXT]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack + 16, align 8)
|
|
; MIPS32-NEXT: $a0 = COPY [[COPY]](s32)
|
|
; MIPS32-NEXT: $a1 = COPY [[COPY1]](s32)
|
|
; MIPS32-NEXT: $a2 = COPY [[COPY2]](s32)
|
|
; MIPS32-NEXT: $a3 = COPY [[COPY3]](s32)
|
|
; MIPS32-NEXT: JAL @sext_stack_arg_i16, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
|
; MIPS32-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
|
|
; MIPS32-NEXT: [[ASSERT_SEXT1:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[COPY5]], 16
|
|
; MIPS32-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[ASSERT_SEXT1]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[SEXT1:%[0-9]+]]:_(s32) = G_SEXT [[TRUNC1]](s16)
|
|
; MIPS32-NEXT: $v0 = COPY [[SEXT1]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
%call = call signext i16 @sext_stack_arg_i16(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i16 signext %a)
|
|
ret i16 %call
|
|
}
|
|
|
|
define zeroext i16 @call_zext_stack_arg_i16(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i16 zeroext %a) {
|
|
; MIPS32-LABEL: name: call_zext_stack_arg_i16
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0, $a1, $a2, $a3
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
|
|
; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
|
|
; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
|
|
; MIPS32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
|
; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 8)
|
|
; MIPS32-NEXT: [[ASSERT_ZEXT:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[LOAD]], 16
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[ASSERT_ZEXT]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s16)
|
|
; MIPS32-NEXT: [[COPY4:%[0-9]+]]:_(p0) = COPY $sp
|
|
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
|
|
; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY4]], [[C]](s32)
|
|
; MIPS32-NEXT: G_STORE [[ZEXT]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack + 16, align 8)
|
|
; MIPS32-NEXT: $a0 = COPY [[COPY]](s32)
|
|
; MIPS32-NEXT: $a1 = COPY [[COPY1]](s32)
|
|
; MIPS32-NEXT: $a2 = COPY [[COPY2]](s32)
|
|
; MIPS32-NEXT: $a3 = COPY [[COPY3]](s32)
|
|
; MIPS32-NEXT: JAL @zext_stack_arg_i16, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
|
; MIPS32-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
|
|
; MIPS32-NEXT: [[ASSERT_ZEXT1:%[0-9]+]]:_(s32) = G_ASSERT_ZEXT [[COPY5]], 16
|
|
; MIPS32-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[ASSERT_ZEXT1]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[ZEXT1:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC1]](s16)
|
|
; MIPS32-NEXT: $v0 = COPY [[ZEXT1]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
%call = call zeroext i16 @zext_stack_arg_i16(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i16 zeroext %a)
|
|
ret i16 %call
|
|
}
|
|
|
|
define i16 @call_aext_stack_arg_i16(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i16 %a) {
|
|
; MIPS32-LABEL: name: call_aext_stack_arg_i16
|
|
; MIPS32: bb.1.entry:
|
|
; MIPS32-NEXT: liveins: $a0, $a1, $a2, $a3
|
|
; MIPS32-NEXT: {{ $}}
|
|
; MIPS32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
|
|
; MIPS32-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
|
|
; MIPS32-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
|
|
; MIPS32-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
|
|
; MIPS32-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
|
; MIPS32-NEXT: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.0, align 8)
|
|
; MIPS32-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[LOAD]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKDOWN 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16)
|
|
; MIPS32-NEXT: [[COPY4:%[0-9]+]]:_(p0) = COPY $sp
|
|
; MIPS32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16
|
|
; MIPS32-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY4]], [[C]](s32)
|
|
; MIPS32-NEXT: G_STORE [[ANYEXT]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack + 16, align 8)
|
|
; MIPS32-NEXT: $a0 = COPY [[COPY]](s32)
|
|
; MIPS32-NEXT: $a1 = COPY [[COPY1]](s32)
|
|
; MIPS32-NEXT: $a2 = COPY [[COPY2]](s32)
|
|
; MIPS32-NEXT: $a3 = COPY [[COPY3]](s32)
|
|
; MIPS32-NEXT: JAL @aext_stack_arg_i16, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit $a1, implicit $a2, implicit $a3, implicit-def $v0
|
|
; MIPS32-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $v0
|
|
; MIPS32-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY5]](s32)
|
|
; MIPS32-NEXT: ADJCALLSTACKUP 24, 0, implicit-def $sp, implicit $sp
|
|
; MIPS32-NEXT: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC1]](s16)
|
|
; MIPS32-NEXT: $v0 = COPY [[ANYEXT1]](s32)
|
|
; MIPS32-NEXT: RetRA implicit $v0
|
|
entry:
|
|
%call = call i16 @aext_stack_arg_i16(i32 %x1, i32 %x2, i32 %x3, i32 %x4, i16 %a)
|
|
ret i16 %call
|
|
}
|