Files
clang-p2996/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/args.ll
Nitin John Raj af8e386102 [RISCV][GlobalISel] Add lowerFormalArguments for calling convention
This patch adds an IncomingValueHandler and IncomingValueAssigner, and implements minimal support for lowering formal arguments according to the RISC-V calling convention. Simple non-aggregate integer and pointer types are supported.

In the future, we must correctly handle byval and sret pointer arguments, and instances where the number of arguments exceeds the number of registers.

Coauthored By: lewis-revill

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D74977
2023-05-30 13:42:49 -07:00

298 lines
10 KiB
LLVM

; 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
define void @test_args_i8(i8 %a) {
; RV32I-LABEL: name: test_args_i8
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; RV32I-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[C]]
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_i8
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s64)
; RV64I-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[C]]
; RV64I-NEXT: PseudoRET
entry:
%0 = add i8 %a, 1
ret void
}
define void @test_args_i16(i16 %a) {
; RV32I-LABEL: name: test_args_i16
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
; RV32I-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[C]]
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_i16
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64)
; RV64I-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[C]]
; RV64I-NEXT: PseudoRET
entry:
%0 = add i16 %a, 1
ret void
}
define void @test_args_i32(i32 %a) {
; RV32I-LABEL: name: test_args_i32
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
; RV32I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[C]]
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_i32
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
; RV64I-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[C]]
; RV64I-NEXT: PseudoRET
entry:
%0 = add i32 %a, 1
ret void
}
define void @test_args_i64(i64 %a) {
; RV32I-LABEL: name: test_args_i64
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10, $x11
; RV32I-NEXT: {{ $}}
; 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: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[MV]], [[C]]
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_i64
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
; RV64I-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[C]]
; RV64I-NEXT: PseudoRET
entry:
%0 = add i64 %a, 1
ret void
}
define void @test_args_i8_ptr(ptr %a) {
; RV32I-LABEL: name: test_args_i8_ptr
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load (s8) from %ir.a)
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_i8_ptr
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load (s8) from %ir.a)
; RV64I-NEXT: PseudoRET
entry:
%0 = load i8, ptr %a
ret void
}
define void @test_args_2xi8(i8 %a, i8 %b) {
; RV32I-LABEL: name: test_args_2xi8
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10, $x11
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
; RV32I-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC1]]
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_2xi8
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10, $x11
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s64)
; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
; RV64I-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s64)
; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[TRUNC]], [[TRUNC1]]
; RV64I-NEXT: PseudoRET
entry:
%0 = add i8 %a, %b
ret void
}
define void @test_args_2xi16(i16 %a, i16 %b) {
; RV32I-LABEL: name: test_args_2xi16
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10, $x11
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
; RV32I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
; RV32I-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[TRUNC1]]
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_2xi16
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10, $x11
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
; RV64I-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64)
; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
; RV64I-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s64)
; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[TRUNC]], [[TRUNC1]]
; RV64I-NEXT: PseudoRET
entry:
%0 = add i16 %a, %b
ret void
}
define void @test_args_2xi32(i32 %a, i32 %b) {
; RV32I-LABEL: name: test_args_2xi32
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10, $x11
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[COPY1]]
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_2xi32
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10, $x11
; RV64I-NEXT: {{ $}}
; 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: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[TRUNC]], [[TRUNC1]]
; RV64I-NEXT: PseudoRET
entry:
%0 = add i32 %a, %b
ret void
}
define void @test_args_2xi64(i64 %a, i64 %b) {
; RV32I-LABEL: name: test_args_2xi64
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10, $x11, $x12, $x13
; RV32I-NEXT: {{ $}}
; 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: [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
; RV32I-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
; RV32I-NEXT: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY2]](s32), [[COPY3]](s32)
; RV32I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[MV]], [[MV1]]
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_2xi64
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10, $x11
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
; RV64I-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]]
; RV64I-NEXT: PseudoRET
entry:
%0 = add i64 %a, %b
ret void
}
define void @test_args_2xi8_ptr(ptr %a, ptr %b) {
; RV32I-LABEL: name: test_args_2xi8_ptr
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10, $x11
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load (s8) from %ir.a)
; RV32I-NEXT: [[LOAD1:%[0-9]+]]:_(s8) = G_LOAD [[COPY1]](p0) :: (load (s8) from %ir.b)
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_2xi8_ptr
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10, $x11
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (load (s8) from %ir.a)
; RV64I-NEXT: [[LOAD1:%[0-9]+]]:_(s8) = G_LOAD [[COPY1]](p0) :: (load (s8) from %ir.b)
; RV64I-NEXT: PseudoRET
entry:
%0 = load i8, ptr %a
%1 = load i8, ptr %b
ret void
}
define void @test_args_ptr_byval(ptr byval(i8) %a) {
; RV32I-LABEL: name: test_args_ptr_byval
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (dereferenceable load (s8) from %ir.a)
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_ptr_byval
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (dereferenceable load (s8) from %ir.a)
; RV64I-NEXT: PseudoRET
entry:
%0 = load i8, ptr %a
ret void
}
define void @test_args_ptr_sret(ptr sret(i8) %a) {
; RV32I-LABEL: name: test_args_ptr_sret
; RV32I: bb.1.entry:
; RV32I-NEXT: liveins: $x10
; RV32I-NEXT: {{ $}}
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
; RV32I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (dereferenceable load (s8) from %ir.a)
; RV32I-NEXT: PseudoRET
; RV64I-LABEL: name: test_args_ptr_sret
; RV64I: bb.1.entry:
; RV64I-NEXT: liveins: $x10
; RV64I-NEXT: {{ $}}
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
; RV64I-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0) :: (dereferenceable load (s8) from %ir.a)
; RV64I-NEXT: PseudoRET
entry:
%0 = load i8, ptr %a
ret void
}