From 6126356d829be32e2195b8ddf8b908ab417ff7f5 Mon Sep 17 00:00:00 2001 From: Amy Kwan Date: Sat, 25 Mar 2023 23:03:10 -0500 Subject: [PATCH] [PowerPC] Implement 64-bit ELFv2 Calling Convention in TableGen (for integers/floats/vectors in registers) This patch partially implements the parameter passing rules outlined in the ELFv2 ABI within TableGen. Specifically, it implements the parameter assignment of integers, floats, and vectors within registers - where the GPR numbering will be "skipped" depending on the ordering of floats and vectors that appear within a parameter list. As we begin to adopt GlobalISel to the PowerPC backend, there is a need for a TableGen definition that encapsulates the ELFv2 parameter passing rules. Thus, this patch also changes the default calling convention that is returned within the ccAssignFnForCall() function used in our GlobalISel implementation, and also adds some additional testing of the calling convention that is implemented. Future patches that build on top of this initial TableGen definition will aim to add more of the ABI complexities, including support for additional types and also in-memory arguments. Differential Revision: https://reviews.llvm.org/D137504 --- llvm/lib/Target/PowerPC/PPCCallingConv.cpp | 38 +++- llvm/lib/Target/PowerPC/PPCCallingConv.h | 3 + llvm/lib/Target/PowerPC/PPCCallingConv.td | 44 +++- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 4 +- .../GlobalISel/irtranslator-args-lowering-fp128.ll | 122 +++++++++++ .../irtranslator-args-lowering-mixed-types.ll | 235 +++++++++++++++++++++ .../irtranslator-args-lowering-scalar.ll | 170 +++++++++++++++ .../irtranslator-args-lowering-vectors.ll | 159 ++++++++++++++ .../GlobalISel/irtranslator-args-lowering.ll | 11 +- 9 files changed, 775 insertions(+), 11 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-fp128.ll create mode 100644 llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-mixed-types.ll create mode 100644 llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-scalar.ll create mode 100644 llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-vectors.ll diff --git a/llvm/lib/Target/PowerPC/PPCCallingConv.cpp b/llvm/lib/Target/PowerPC/PPCCallingConv.cpp index ff792fd..188fc96 100644 --- a/llvm/lib/Target/PowerPC/PPCCallingConv.cpp +++ b/llvm/lib/Target/PowerPC/PPCCallingConv.cpp @@ -1,4 +1,4 @@ -//===-- PPCCallingConv.h - --------------------------------------*- C++ -*-===// +//===-- PPCCallingConv.cpp - ------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -21,6 +21,42 @@ inline bool CC_PPC_AnyReg_Error(unsigned &, MVT &, MVT &, return false; } +// This function handles the shadowing of GPRs for fp and vector types, +// and is a depiction of the algorithm described in the ELFv2 ABI, +// Section 2.2.4.1: Parameter Passing Register Selection Algorithm. +inline bool CC_PPC64_ELF_Shadow_GPR_Regs(unsigned &ValNo, MVT &ValVT, + MVT &LocVT, + CCValAssign::LocInfo &LocInfo, + ISD::ArgFlagsTy &ArgFlags, + CCState &State) { + + // The 64-bit ELFv2 ABI-defined parameter passing general purpose registers. + static const MCPhysReg ELF64ArgGPRs[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6, + PPC::X7, PPC::X8, PPC::X9, PPC::X10}; + const unsigned ELF64NumArgGPRs = std::size(ELF64ArgGPRs); + + unsigned FirstUnallocGPR = State.getFirstUnallocated(ELF64ArgGPRs); + if (FirstUnallocGPR == ELF64NumArgGPRs) + return false; + + // As described in 2.2.4.1 under the "float" section, shadow a single GPR + // for single/double precision. ppcf128 gets broken up into two doubles + // and will also shadow GPRs within this section. + if (LocVT == MVT::f32 || LocVT == MVT::f64) + State.AllocateReg(ELF64ArgGPRs); + else if (LocVT.is128BitVector() || (LocVT == MVT::f128)) { + // For vector and __float128 (which is represents the "vector" section + // in 2.2.4.1), shadow two even GPRs (skipping the odd one if it is next + // in the allocation order). To check if the GPR is even, the specific + // condition checks if the register allocated is odd, because the even + // physical registers are odd values. + if ((State.AllocateReg(ELF64ArgGPRs) - PPC::X3) % 2 == 1) + State.AllocateReg(ELF64ArgGPRs); + State.AllocateReg(ELF64ArgGPRs); + } + return false; +} + static bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, diff --git a/llvm/lib/Target/PowerPC/PPCCallingConv.h b/llvm/lib/Target/PowerPC/PPCCallingConv.h index 03d9be0..ab61472 100644 --- a/llvm/lib/Target/PowerPC/PPCCallingConv.h +++ b/llvm/lib/Target/PowerPC/PPCCallingConv.h @@ -31,6 +31,9 @@ bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State); +bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, + CCState &State); bool CC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State); diff --git a/llvm/lib/Target/PowerPC/PPCCallingConv.td b/llvm/lib/Target/PowerPC/PPCCallingConv.td index 9df1b1d..825c1a2 100644 --- a/llvm/lib/Target/PowerPC/PPCCallingConv.td +++ b/llvm/lib/Target/PowerPC/PPCCallingConv.td @@ -112,10 +112,46 @@ def CC_PPC64_AnyReg : CallingConv<[ CCCustom<"CC_PPC_AnyReg_Error"> ]>; -// Note that we don't currently have calling conventions for 64-bit -// PowerPC, but handle all the complexities of the ABI in the lowering -// logic. FIXME: See if the logic can be simplified with use of CCs. -// This may require some extensions to current table generation. +// Calling Convention corresponding to the 64-bit PowerPC ELFv2 ABI. +// This calling convention currently only handles integers, floats and +// vectors within registers, as well as it handles the shadowing of GPRs +// when floating point and vector arguments are used. +// FIXME: This calling convention needs to be extended to handle all types and +// complexities of the ABI. +let Entry = 1 in +def CC_PPC64_ELF : CallingConv<[ + CCIfCC<"CallingConv::AnyReg", CCDelegateTo>, + + CCIfType<[i1], CCPromoteToType>, + CCIfType<[i8], CCPromoteToType>, + CCIfType<[i16], CCPromoteToType>, + CCIfType<[i32], CCPromoteToType>, + CCIfType<[i64], CCAssignToReg<[X3, X4, X5, X6, X7, X8, X9, X10]>>, + + // Handle fp types and shadow the corresponding registers as necessary. + CCIfType<[f32, f64], CCIfNotVarArg>>, + CCIfType<[f32, f64], + CCIfNotVarArg>>, + + // f128 is handled through vector registers instead of fp registers. + CCIfType<[f128], + CCIfSubtarget<"hasAltivec()", + CCIfNotVarArg>>>, + CCIfType<[f128], + CCIfSubtarget<"hasAltivec()", + CCIfNotVarArg>>>, + + // Handle support for vector types, and shadow GPRs as necessary. + CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v1i128], + CCIfSubtarget<"hasAltivec()", + CCIfNotVarArg>>>, + CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v1i128], + CCIfSubtarget<"hasAltivec()", + CCIfNotVarArg>>>, +]>; // Simple calling convention for 64-bit ELF PowerPC fast isel. // Only handle ints and floats. All ints are promoted to i64. diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 7670d4d..ea2a5d6 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -18253,9 +18253,9 @@ CCAssignFn *PPCTargetLowering::ccAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const { switch (CC) { case CallingConv::Cold: - return (Return ? RetCC_PPC_Cold : CC_PPC64_ELF_FIS); + return (Return ? RetCC_PPC_Cold : CC_PPC64_ELF); default: - return CC_PPC64_ELF_FIS; + return CC_PPC64_ELF; } } diff --git a/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-fp128.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-fp128.ll new file mode 100644 index 0000000..021a709 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-fp128.ll @@ -0,0 +1,122 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -global-isel \ +; RUN: -verify-machineinstrs -stop-after=irtranslator < %s | FileCheck %s + +; Passing ppc_fp128 in registers (in fp registers as f64) +define void @test_ppc_fp128_1(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c, ppc_fp128 %d, ppc_fp128 %e) { + ; CHECK-LABEL: name: test_ppc_fp128_1 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $f3, $f4, $f5, $f6, $f7, $f8, $f9, $f10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f1 + ; CHECK-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $f3 + ; CHECK-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY2]](s64), [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $f6 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f5 + ; CHECK-NEXT: [[MV2:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY4]](s64), [[COPY5]](s64) + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $f8 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $f7 + ; CHECK-NEXT: [[MV3:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY6]](s64), [[COPY7]](s64) + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f10 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(s64) = COPY $f9 + ; CHECK-NEXT: [[MV4:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY8]](s64), [[COPY9]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_ppc_fp128_2(i32 %a, i32 %b, ppc_fp128 %c, i32 %d) { + ; CHECK-LABEL: name: test_ppc_fp128_2 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $x3, $x4, $x7 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f2 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $f1 + ; CHECK-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY2]](s64), [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY4]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_ppc_fp128_3(ppc_fp128 %a, i32 %b, ppc_fp128 %c, i32 %d, i32 %e) { + ; CHECK-LABEL: name: test_ppc_fp128_3 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $f3, $f4, $x5, $x8, $x9 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f1 + ; CHECK-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $f4 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $f3 + ; CHECK-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY3]](s64), [[COPY4]](s64) + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x8 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY5]](s64) + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY6]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +; Passing fp128 in registers (in vector registers) +define void @test_fp128_1(fp128 %a, fp128 %b, fp128 %c, fp128 %d, fp128 %e) { + ; CHECK-LABEL: name: test_fp128_1 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $v3, $v4, $v5, $v6 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s128) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s128) = COPY $v4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s128) = COPY $v5 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s128) = COPY $v6 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_fp128_2(i32 %a, i32 %b, fp128 %c, i32 %d) { + ; CHECK-LABEL: name: test_fp128_2 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $x3, $x4, $x7 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s128) = COPY $v2 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_fp128_3(fp128 %a, i32 %b, fp128 %c, i32 %d, i32 %e) { + ; CHECK-LABEL: name: test_fp128_3 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $v3, $x5, $x9, $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s128) = COPY $v3 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x10 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY4]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + diff --git a/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-mixed-types.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-mixed-types.ll new file mode 100644 index 0000000..26a2457 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-mixed-types.ll @@ -0,0 +1,235 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -global-isel \ +; RUN: -verify-machineinstrs -stop-after=irtranslator < %s | FileCheck %s + +; Mixed parameter passing involving integers, floats, vectors (all in registers). +define void @test_mixed_arg1(i32 %a, i32 %b, i32 %c, <4 x i32> %d) { + ; CHECK-LABEL: name: test_mixed_arg1 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $x3, $x4, $x5 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<4 x s32>) = COPY $v2 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg2(i32 %a, i32 %b, <4 x i32> %c, i32 %d) { + ; CHECK-LABEL: name: test_mixed_arg2 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $x3, $x4, $x7 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(<4 x s32>) = COPY $v2 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg3(i32 %a, i32 %b, i32 %c, <4 x i32> %d, i32 %e) { + ; CHECK-LABEL: name: test_mixed_arg3 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $x3, $x4, $x5, $x9 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<4 x s32>) = COPY $v2 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s32) = G_TRUNC [[COPY4]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg4(<2 x double> %a, <4 x i32> %b, <4 x i32> %c, i32 %d, i64 %e, double %f) { + ; CHECK-LABEL: name: test_mixed_arg4 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $v2, $v3, $v4, $x9, $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(<4 x s32>) = COPY $v4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x10 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f1 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg5(float %a, i32 %b, <2 x i64> %c, i64 %d, double %e, <4 x float> %f) { + ; CHECK-LABEL: name: test_mixed_arg5 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $v2, $v3, $x4, $x7 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $f1 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $v2 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $f2 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg6(i64 %a, double %b, i32 %c, i32 %d, <2 x i64> %e, <4 x i32> %f, <4 x i32> %g, <4 x float> %h) { + ; CHECK-LABEL: name: test_mixed_arg6 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $v2, $v3, $v4, $v5, $x3, $x5, $x6 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $v2 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(<4 x s32>) = COPY $v4 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(<4 x s32>) = COPY $v5 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg7(i32 %a, float %b, i32 %c, float %d, <4 x float> %e, <4 x i32> %f) { + ; CHECK-LABEL: name: test_mixed_arg7 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $v2, $v3, $x3, $x5 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $f2 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<4 x s32>) = COPY $v2 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg8(<4 x i32> %a, float %b, i32 %c, i64 %d, <2 x double> %e, double %f) { + ; CHECK-LABEL: name: test_mixed_arg8 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $v2, $v3, $x6, $x7 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $v3 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f2 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg9(<4 x float> %a, i32 %b, i32 %c, <4 x i32> %d, i32 %e, double %f) { + ; CHECK-LABEL: name: test_mixed_arg9 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $v2, $v3, $x5, $x6, $x9 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY4]](s64) + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f1 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg10(i32 %a, float %b, i64 %c, <2 x double> %d, <4 x float> %e, double %f) { + ; CHECK-LABEL: name: test_mixed_arg10 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $v2, $v3, $x3, $x5 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $v2 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f2 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg11(double %a, float %b, i32 %c, i64 %d, i32 %e, double %f, <4 x i32> %g) { + ; CHECK-LABEL: name: test_mixed_arg11 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $f3, $v2, $x5, $x6, $x7 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f1 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f2 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY4]](s64) + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f3 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(<4 x s32>) = COPY $v2 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg12(<2 x double> %a, <4 x i32> %b, i32 %c, i32 %d, i64 %e, float %f) { + ; CHECK-LABEL: name: test_mixed_arg12 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $v2, $v3, $x7, $x8, $x9 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x8 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $f1 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_mixed_arg13(i8 %a, <2 x double> %b, i64 %c, <4 x i32> %d, double %e) { + ; CHECK-LABEL: name: test_mixed_arg13 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $v2, $v3, $x3, $x7 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $v2 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $f1 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} diff --git a/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-scalar.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-scalar.ll new file mode 100644 index 0000000..4aa55a9 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-scalar.ll @@ -0,0 +1,170 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -global-isel \ +; RUN: -verify-machineinstrs -stop-after=irtranslator < %s | FileCheck %s + +; Pass up to eight integer arguments in registers. +define void @test_scalar1(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) { + ; CHECK-LABEL: name: test_scalar1 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s32) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[TRUNC4:%[0-9]+]]:_(s32) = G_TRUNC [[COPY4]](s64) + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x8 + ; CHECK-NEXT: [[TRUNC5:%[0-9]+]]:_(s32) = G_TRUNC [[COPY5]](s64) + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[TRUNC6:%[0-9]+]]:_(s32) = G_TRUNC [[COPY6]](s64) + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x10 + ; CHECK-NEXT: [[TRUNC7:%[0-9]+]]:_(s32) = G_TRUNC [[COPY7]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_scalar2(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64 %g, i64 %h) { + ; CHECK-LABEL: name: test_scalar2 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x8 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x10 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_scalar3(i8 %a, i8 %b, i8 %c, i8 %d, i8 %e, i8 %f, i8 %g, i8 %h) { + ; CHECK-LABEL: name: test_scalar3 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s8) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s8) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[TRUNC4:%[0-9]+]]:_(s8) = G_TRUNC [[COPY4]](s64) + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x8 + ; CHECK-NEXT: [[TRUNC5:%[0-9]+]]:_(s8) = G_TRUNC [[COPY5]](s64) + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[TRUNC6:%[0-9]+]]:_(s8) = G_TRUNC [[COPY6]](s64) + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x10 + ; CHECK-NEXT: [[TRUNC7:%[0-9]+]]:_(s8) = G_TRUNC [[COPY7]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_scalar4(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e, i16 %f, i16 %g, i16 %h) { + ; CHECK-LABEL: name: test_scalar4 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:_(s16) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:_(s16) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[TRUNC4:%[0-9]+]]:_(s16) = G_TRUNC [[COPY4]](s64) + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x8 + ; CHECK-NEXT: [[TRUNC5:%[0-9]+]]:_(s16) = G_TRUNC [[COPY5]](s64) + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[TRUNC6:%[0-9]+]]:_(s16) = G_TRUNC [[COPY6]](s64) + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x10 + ; CHECK-NEXT: [[TRUNC7:%[0-9]+]]:_(s16) = G_TRUNC [[COPY7]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_scalar5(i128 %a, i128 %b, i128 %c, i128 %d) { + ; CHECK-LABEL: name: test_scalar5 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK-NEXT: [[MV:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY]](s64), [[COPY1]](s64) + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK-NEXT: [[MV1:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY2]](s64), [[COPY3]](s64) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $x8 + ; CHECK-NEXT: [[MV2:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY4]](s64), [[COPY5]](s64) + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $x9 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $x10 + ; CHECK-NEXT: [[MV3:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY6]](s64), [[COPY7]](s64) + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +; Pass up to thirteen fp arguments in registers. +define void @test_scalar6(float %a, float %b, float %c, float %d, float %e, float %f, float %g, float %h, float %i, float %j, float %k, float %l, float %m) { + ; CHECK-LABEL: name: test_scalar6 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $f3, $f4, $f5, $f6, $f7, $f8, $f9, $f10, $f11, $f12, $f13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $f1 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $f2 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $f3 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $f4 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s32) = COPY $f5 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s32) = COPY $f6 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s32) = COPY $f7 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s32) = COPY $f8 + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(s32) = COPY $f9 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(s32) = COPY $f10 + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(s32) = COPY $f11 + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:_(s32) = COPY $f12 + ; CHECK-NEXT: [[COPY12:%[0-9]+]]:_(s32) = COPY $f13 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_scalar7(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, double %j, double %k, double %l, double %m) { + ; CHECK-LABEL: name: test_scalar7 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $f1, $f2, $f3, $f4, $f5, $f6, $f7, $f8, $f9, $f10, $f11, $f12, $f13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $f1 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $f2 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $f3 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $f4 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $f5 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s64) = COPY $f6 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s64) = COPY $f7 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s64) = COPY $f8 + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(s64) = COPY $f9 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(s64) = COPY $f10 + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(s64) = COPY $f11 + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:_(s64) = COPY $f12 + ; CHECK-NEXT: [[COPY12:%[0-9]+]]:_(s64) = COPY $f13 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + diff --git a/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-vectors.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-vectors.ll new file mode 100644 index 0000000..9d0188e --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering-vectors.ll @@ -0,0 +1,159 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -global-isel \ +; RUN: -verify-machineinstrs -stop-after=irtranslator < %s | FileCheck %s + +; Pass up to twelve vector arguments in registers. +define void @test_vec1(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d, <4 x i32> %e, <4 x i32> %f, <4 x i32> %g, <4 x i32> %h, <4 x i32> %i, <4 x i32> %j, <4 x i32> %k, <4 x i32> %l) { + ; CHECK-LABEL: name: test_vec1 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $v3, $v4, $v5, $v6, $v7, $v8, $v9, $v10, $v11, $v12, $v13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(<4 x s32>) = COPY $v4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<4 x s32>) = COPY $v5 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<4 x s32>) = COPY $v6 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(<4 x s32>) = COPY $v7 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(<4 x s32>) = COPY $v8 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(<4 x s32>) = COPY $v9 + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(<4 x s32>) = COPY $v10 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(<4 x s32>) = COPY $v11 + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(<4 x s32>) = COPY $v12 + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:_(<4 x s32>) = COPY $v13 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_vec2(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c, <2 x i64> %d, <2 x i64> %e, <2 x i64> %f, <2 x i64> %g, <2 x i64> %h, <2 x i64> %i, <2 x i64> %j, <2 x i64> %k, <2 x i64> %l) { + ; CHECK-LABEL: name: test_vec2 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $v3, $v4, $v5, $v6, $v7, $v8, $v9, $v10, $v11, $v12, $v13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $v4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $v5 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $v6 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $v7 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $v8 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $v9 + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(<2 x s64>) = COPY $v10 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(<2 x s64>) = COPY $v11 + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(<2 x s64>) = COPY $v12 + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:_(<2 x s64>) = COPY $v13 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_vec3(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c, <8 x i16> %d, <8 x i16> %e, <8 x i16> %f, <8 x i16> %g, <8 x i16> %h, <8 x i16> %i, <8 x i16> %j, <8 x i16> %k, <8 x i16> %l) { + ; CHECK-LABEL: name: test_vec3 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $v3, $v4, $v5, $v6, $v7, $v8, $v9, $v10, $v11, $v12, $v13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s16>) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(<8 x s16>) = COPY $v4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<8 x s16>) = COPY $v5 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<8 x s16>) = COPY $v6 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(<8 x s16>) = COPY $v7 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(<8 x s16>) = COPY $v8 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(<8 x s16>) = COPY $v9 + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(<8 x s16>) = COPY $v10 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(<8 x s16>) = COPY $v11 + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(<8 x s16>) = COPY $v12 + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:_(<8 x s16>) = COPY $v13 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_vec4(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c, <16 x i8> %d, <16 x i8> %e, <16 x i8> %f, <16 x i8> %g, <16 x i8> %h, <16 x i8> %i, <16 x i8> %j, <16 x i8> %k, <16 x i8> %l) { + ; CHECK-LABEL: name: test_vec4 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $v3, $v4, $v5, $v6, $v7, $v8, $v9, $v10, $v11, $v12, $v13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x s8>) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(<16 x s8>) = COPY $v4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<16 x s8>) = COPY $v5 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<16 x s8>) = COPY $v6 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(<16 x s8>) = COPY $v7 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(<16 x s8>) = COPY $v8 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(<16 x s8>) = COPY $v9 + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(<16 x s8>) = COPY $v10 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(<16 x s8>) = COPY $v11 + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(<16 x s8>) = COPY $v12 + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:_(<16 x s8>) = COPY $v13 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_vec5(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x float> %d, <4 x float> %e, <4 x float> %f, <4 x float> %g, <4 x float> %h, <4 x float> %i, <4 x float> %j, <4 x float> %k, <4 x float> %l) { + ; CHECK-LABEL: name: test_vec5 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $v3, $v4, $v5, $v6, $v7, $v8, $v9, $v10, $v11, $v12, $v13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(<4 x s32>) = COPY $v4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<4 x s32>) = COPY $v5 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<4 x s32>) = COPY $v6 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(<4 x s32>) = COPY $v7 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(<4 x s32>) = COPY $v8 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(<4 x s32>) = COPY $v9 + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(<4 x s32>) = COPY $v10 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(<4 x s32>) = COPY $v11 + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(<4 x s32>) = COPY $v12 + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:_(<4 x s32>) = COPY $v13 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_vec6(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %d, <2 x double> %e, <2 x double> %f, <2 x double> %g, <2 x double> %h, <2 x double> %i, <2 x double> %j, <2 x double> %k, <2 x double> %l) { + ; CHECK-LABEL: name: test_vec6 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $v3, $v4, $v5, $v6, $v7, $v8, $v9, $v10, $v11, $v12, $v13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(<2 x s64>) = COPY $v4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(<2 x s64>) = COPY $v5 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(<2 x s64>) = COPY $v6 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(<2 x s64>) = COPY $v7 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(<2 x s64>) = COPY $v8 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(<2 x s64>) = COPY $v9 + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(<2 x s64>) = COPY $v10 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(<2 x s64>) = COPY $v11 + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(<2 x s64>) = COPY $v12 + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:_(<2 x s64>) = COPY $v13 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + +define void @test_vec7(<1 x i128> %a, <1 x i128> %b, <1 x i128> %c, <1 x i128> %d, <1 x i128> %e, <1 x i128> %f, <1 x i128> %g, <1 x i128> %h, <1 x i128> %i, <1 x i128> %j, <1 x i128> %k, <1 x i128> %l) { + ; CHECK-LABEL: name: test_vec7 + ; CHECK: bb.1.entry: + ; CHECK-NEXT: liveins: $v2, $v3, $v4, $v5, $v6, $v7, $v8, $v9, $v10, $v11, $v12, $v13 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $v2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s128) = COPY $v3 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s128) = COPY $v4 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s128) = COPY $v5 + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s128) = COPY $v6 + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:_(s128) = COPY $v7 + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:_(s128) = COPY $v8 + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:_(s128) = COPY $v9 + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:_(s128) = COPY $v10 + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:_(s128) = COPY $v11 + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:_(s128) = COPY $v12 + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:_(s128) = COPY $v13 + ; CHECK-NEXT: BLR8 implicit $lr8, implicit $rm +entry: + ret void +} + diff --git a/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering.ll b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering.ll index 2396a52..a3c909c 100644 --- a/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering.ll +++ b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering.ll @@ -73,18 +73,21 @@ define void @foo_pt(ptr %x) { ret void } +; TODO: The correct registers used to pass struct arguments in this example +; are R3, R4 and R5. Currently, the calling convention used for GlobalISel +; does not handle passing structs and will need to implemented at a later time. define dso_local void @foo_struct(%struct.A %a) #0 { ; CHECK-LABEL: name: foo_struct ; CHECK: bb.1.entry: - ; CHECK: liveins: $f1, $x3, $x4, $x5, $x6 + ; CHECK: liveins: $f1, $x3, $x5, $x6, $x7 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x3 ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s64) ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $f1 - ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x5 ; CHECK: [[TRUNC2:%[0-9]+]]:_(s32) = G_TRUNC [[COPY2]](s64) - ; CHECK: [[COPY3:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK: [[COPY3:%[0-9]+]]:_(s64) = COPY $x6 ; CHECK: [[TRUNC3:%[0-9]+]]:_(s32) = G_TRUNC [[COPY3]](s64) - ; CHECK: [[COPY4:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK: [[COPY4:%[0-9]+]]:_(s64) = COPY $x7 ; CHECK: [[TRUNC4:%[0-9]+]]:_(s32) = G_TRUNC [[COPY4]](s64) ; CHECK: BLR8 implicit $lr8, implicit $rm entry: -- 2.7.4