llvm/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calls.ll

; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
; RUN: llc -mtriple=riscv32 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
; RUN:   | FileCheck -check-prefix=RV32I %s
; RUN: llc -mtriple=riscv64 -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
; RUN:   | FileCheck -check-prefix=RV64I %s

declare void @void_noargs()

define void @test_call_void_noargs() {

  ; RV32I-LABEL: name: test_call_void_noargs
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @void_noargs, csr_ilp32_lp64, implicit-def $x1
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_void_noargs
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @void_noargs, csr_ilp32_lp64, implicit-def $x1
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @void_noargs()
  ret void
}

declare void @void_args_i8(i8, i8)

define void @test_call_void_args_i8() {

  ; RV32I-LABEL: name: test_call_void_args_i8
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
  ; RV32I-NEXT:   [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
  ; RV32I-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s8)
  ; RV32I-NEXT:   $x10 = COPY [[ANYEXT]](s32)
  ; RV32I-NEXT:   $x11 = COPY [[ANYEXT1]](s32)
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i8, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_void_args_i8
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
  ; RV64I-NEXT:   [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[C]](s8)
  ; RV64I-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[C1]](s8)
  ; RV64I-NEXT:   $x10 = COPY [[ANYEXT]](s64)
  ; RV64I-NEXT:   $x11 = COPY [[ANYEXT1]](s64)
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i8, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @void_args_i8(i8 0, i8 1)
  ret void
}

declare void @void_args_i8_zext(i8 zeroext, i8 zeroext)

define void @test_call_void_args_i8_zext() {

  ; RV32I-LABEL: name: test_call_void_args_i8_zext
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
  ; RV32I-NEXT:   [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[C]](s8)
  ; RV32I-NEXT:   [[ZEXT1:%[0-9]+]]:_(s32) = G_ZEXT [[C1]](s8)
  ; RV32I-NEXT:   $x10 = COPY [[ZEXT]](s32)
  ; RV32I-NEXT:   $x11 = COPY [[ZEXT1]](s32)
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i8_zext, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_void_args_i8_zext
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
  ; RV64I-NEXT:   [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[C]](s8)
  ; RV64I-NEXT:   [[ZEXT1:%[0-9]+]]:_(s64) = G_ZEXT [[C1]](s8)
  ; RV64I-NEXT:   $x10 = COPY [[ZEXT]](s64)
  ; RV64I-NEXT:   $x11 = COPY [[ZEXT1]](s64)
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i8_zext, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @void_args_i8_zext(i8 zeroext 0, i8 zeroext 1)
  ret void
}

declare void @void_args_i16_sext(i16 signext, i16 signext)

define void @test_call_void_args_i16_sext() {

  ; RV32I-LABEL: name: test_call_void_args_i16_sext
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
  ; RV32I-NEXT:   [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[SEXT:%[0-9]+]]:_(s32) = G_SEXT [[C]](s16)
  ; RV32I-NEXT:   [[SEXT1:%[0-9]+]]:_(s32) = G_SEXT [[C1]](s16)
  ; RV32I-NEXT:   $x10 = COPY [[SEXT]](s32)
  ; RV32I-NEXT:   $x11 = COPY [[SEXT1]](s32)
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i16_sext, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_void_args_i16_sext
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
  ; RV64I-NEXT:   [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[SEXT:%[0-9]+]]:_(s64) = G_SEXT [[C]](s16)
  ; RV64I-NEXT:   [[SEXT1:%[0-9]+]]:_(s64) = G_SEXT [[C1]](s16)
  ; RV64I-NEXT:   $x10 = COPY [[SEXT]](s64)
  ; RV64I-NEXT:   $x11 = COPY [[SEXT1]](s64)
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i16_sext, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @void_args_i16_sext(i16 signext 0, i16 signext 1)
  ret void
}

declare void @void_args_i32(i32, i32)

define void @test_call_void_args_i32() {

  ; RV32I-LABEL: name: test_call_void_args_i32
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; RV32I-NEXT:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   $x10 = COPY [[C]](s32)
  ; RV32I-NEXT:   $x11 = COPY [[C1]](s32)
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i32, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_void_args_i32
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
  ; RV64I-NEXT:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[C]](s32)
  ; RV64I-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s64) = G_ANYEXT [[C1]](s32)
  ; RV64I-NEXT:   $x10 = COPY [[ANYEXT]](s64)
  ; RV64I-NEXT:   $x11 = COPY [[ANYEXT1]](s64)
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i32, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @void_args_i32(i32 0, i32 1)
  ret void
}

declare void @void_args_i64(i64, i64)

define void @test_call_void_args_i64() {

  ; RV32I-LABEL: name: test_call_void_args_i64
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
  ; RV32I-NEXT:   [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
  ; RV32I-NEXT:   [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
  ; RV32I-NEXT:   $x10 = COPY [[UV]](s32)
  ; RV32I-NEXT:   $x11 = COPY [[UV1]](s32)
  ; RV32I-NEXT:   $x12 = COPY [[UV2]](s32)
  ; RV32I-NEXT:   $x13 = COPY [[UV3]](s32)
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i64, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_void_args_i64
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
  ; RV64I-NEXT:   [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   $x10 = COPY [[C]](s64)
  ; RV64I-NEXT:   $x11 = COPY [[C1]](s64)
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @void_args_i64, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @void_args_i64(i64 0, i64 1)
  ret void
}

declare i8 @i8_noargs()

define void @test_call_i8_noargs() {

  ; RV32I-LABEL: name: test_call_i8_noargs
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @i8_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
  ; RV32I-NEXT:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_i8_noargs
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @i8_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x10
  ; RV64I-NEXT:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s64)
  ; RV64I-NEXT:   PseudoRET
entry:
  %a = call i8 @i8_noargs()
  ret void
}

declare i16 @i16_noargs()

define void @test_call_i16_noargs() {

  ; RV32I-LABEL: name: test_call_i16_noargs
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @i16_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
  ; RV32I-NEXT:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_i16_noargs
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @i16_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x10
  ; RV64I-NEXT:   [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64)
  ; RV64I-NEXT:   PseudoRET
entry:
  %a = call i16 @i16_noargs()
  ret void
}

declare i32 @i32_noargs()

define void @test_call_i32_noargs() {

  ; RV32I-LABEL: name: test_call_i32_noargs
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @i32_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_i32_noargs
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @i32_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x10
  ; RV64I-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
  ; RV64I-NEXT:   PseudoRET
entry:
  %a = call i32 @i32_noargs()
  ret void
}

declare i64 @i64_noargs()

define void @test_call_i64_noargs() {

  ; RV32I-LABEL: name: test_call_i64_noargs
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @i64_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
  ; RV32I-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
  ; RV32I-NEXT:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_i64_noargs
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @i64_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x10
  ; RV64I-NEXT:   PseudoRET
entry:
  %a = call i64 @i64_noargs()
  ret void
}

declare ptr @ptr_noargs()

define void @test_call_ptr_noargs() {
  ; RV32I-LABEL: name: test_call_ptr_noargs
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @ptr_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x10
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_ptr_noargs
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @ptr_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x10
  ; RV64I-NEXT:   PseudoRET
entry:
  %a = call ptr @ptr_noargs()
  ret void
}

declare [2 x i32] @i32x2_noargs()

define void @test_call_i32x2_noargs() {
  ; RV32I-LABEL: name: test_call_i32x2_noargs
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @i32x2_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
  ; RV32I-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_i32x2_noargs
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @i32x2_noargs, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $x10
  ; RV64I-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
  ; RV64I-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
  ; RV64I-NEXT:   [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
  ; RV64I-NEXT:   PseudoRET
entry:
  %a = call [2 x i32] @i32x2_noargs()
  ret void
}

%struct.Foo = type { i32, i32, i32, i16, i8 }
@foo = global %struct.Foo { i32 1, i32 2, i32 3, i16 4, i8 5 }, align 4

declare void @void_byval_args(ptr byval(%struct.Foo) %f)

define void @test_void_byval_args() {
  ; RV32I-LABEL: name: test_void_byval_args
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @foo
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   $x10 = COPY [[GV]](p0)
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @void_byval_args, csr_ilp32_lp64, implicit-def $x1, implicit $x10
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_void_byval_args
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @foo
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   $x10 = COPY [[GV]](p0)
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @void_byval_args, csr_ilp32_lp64, implicit-def $x1, implicit $x10
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @void_byval_args(ptr byval(%struct.Foo) @foo)
  ret void
}

declare void @void_sret_args(ptr sret(%struct.Foo) %f)

define void @test_void_sret_args() {
  ; RV32I-LABEL: name: test_void_sret_args
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @foo
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   $x10 = COPY [[GV]](p0)
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @void_sret_args, csr_ilp32_lp64, implicit-def $x1, implicit $x10
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_void_sret_args
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @foo
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   $x10 = COPY [[GV]](p0)
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @void_sret_args, csr_ilp32_lp64, implicit-def $x1, implicit $x10
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @void_sret_args(ptr sret(%struct.Foo) @foo)
  ret void
}

declare external void @external_function()

define void @test_call_external() {
  ; RV32I-LABEL: name: test_call_external
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @external_function, csr_ilp32_lp64, implicit-def $x1
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_external
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @external_function, csr_ilp32_lp64, implicit-def $x1
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @external_function()
  ret void
}

declare dso_local void @dso_local_function()

define void @test_call_local() {
  ; RV32I-LABEL: name: test_call_local
  ; RV32I: bb.1.entry:
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALL target-flags(riscv-call) @dso_local_function, csr_ilp32_lp64, implicit-def $x1
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_call_local
  ; RV64I: bb.1.entry:
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALL target-flags(riscv-call) @dso_local_function, csr_ilp32_lp64, implicit-def $x1
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
entry:
  call void @dso_local_function()
  ret void
}

define void @test_indirect_call(ptr %func) {
  ; RV32I-LABEL: name: test_indirect_call
  ; RV32I: bb.1 (%ir-block.0):
  ; RV32I-NEXT:   liveins: $x10
  ; RV32I-NEXT: {{  $}}
  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:gprjalr(p0) = COPY $x10
  ; RV32I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoCALLIndirect [[COPY]](p0), csr_ilp32_lp64, implicit-def $x1
  ; RV32I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV32I-NEXT:   PseudoRET
  ;
  ; RV64I-LABEL: name: test_indirect_call
  ; RV64I: bb.1 (%ir-block.0):
  ; RV64I-NEXT:   liveins: $x10
  ; RV64I-NEXT: {{  $}}
  ; RV64I-NEXT:   [[COPY:%[0-9]+]]:gprjalr(p0) = COPY $x10
  ; RV64I-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoCALLIndirect [[COPY]](p0), csr_ilp32_lp64, implicit-def $x1
  ; RV64I-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
  ; RV64I-NEXT:   PseudoRET
  call void %func()
  ret void
}