diff --git a/llvm/lib/Target/PowerPC/PPCCallingConv.h b/llvm/lib/Target/PowerPC/PPCCallingConv.h --- a/llvm/lib/Target/PowerPC/PPCCallingConv.h +++ b/llvm/lib/Target/PowerPC/PPCCallingConv.h @@ -31,6 +31,9 @@ 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.cpp b/llvm/lib/Target/PowerPC/PPCCallingConv.cpp --- 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 @@ 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.td b/llvm/lib/Target/PowerPC/PPCCallingConv.td --- a/llvm/lib/Target/PowerPC/PPCCallingConv.td +++ b/llvm/lib/Target/PowerPC/PPCCallingConv.td @@ -112,10 +112,46 @@ 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 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -18253,9 +18253,9 @@ 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 --- /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 --- /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 --- /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 --- /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 --- a/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering.ll +++ b/llvm/test/CodeGen/PowerPC/GlobalISel/irtranslator-args-lowering.ll @@ -73,18 +73,21 @@ 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: