[llvm] [X86][GlobalISel] Support StructRet arguments (PR #96629)
Evgenii Kudriashov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 1 18:29:54 PDT 2024
https://github.com/e-kud updated https://github.com/llvm/llvm-project/pull/96629
>From 6308e3b24d62d18dfb3b92c20105bebde5cf509c Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Mon, 24 Jun 2024 18:52:34 -0700
Subject: [PATCH] [X86][GlobalISel] Support StructRet arguments
We follow SelectionDAG and FastISel manner: set a register during formal
arguments lowering. And use this register to insert a copy of StructRet
argument to RAX register during return lowering.
Fix a minor difference betwen GlobalISel and SelectionDAG when RAX
register wasn't used and copy instruction may be deleted.
---
llvm/lib/Target/X86/GISel/X86CallLowering.cpp | 20 +++++++++---
.../GlobalISel/irtranslator-callingconv.ll | 32 +++++++++++++++++--
llvm/test/CodeGen/X86/isel-buildvector-sse.ll | 26 ++++++++-------
.../test/CodeGen/X86/isel-buildvector-sse2.ll | 23 ++++++-------
4 files changed, 72 insertions(+), 29 deletions(-)
diff --git a/llvm/lib/Target/X86/GISel/X86CallLowering.cpp b/llvm/lib/Target/X86/GISel/X86CallLowering.cpp
index 48830769fdf6c..4975582e89e31 100644
--- a/llvm/lib/Target/X86/GISel/X86CallLowering.cpp
+++ b/llvm/lib/Target/X86/GISel/X86CallLowering.cpp
@@ -16,6 +16,7 @@
#include "X86CallingConv.h"
#include "X86ISelLowering.h"
#include "X86InstrInfo.h"
+#include "X86MachineFunctionInfo.h"
#include "X86RegisterInfo.h"
#include "X86Subtarget.h"
#include "llvm/ADT/ArrayRef.h"
@@ -147,12 +148,17 @@ bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
"Return value without a vreg");
MachineFunction &MF = MIRBuilder.getMF();
auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0);
- const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
- bool Is64Bit = STI.is64Bit();
+ auto FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
+ const auto &STI = MF.getSubtarget<X86Subtarget>();
+ Register RetReg = STI.is64Bit() ? X86::RAX : X86::EAX;
if (!FLI.CanLowerReturn) {
insertSRetStores(MIRBuilder, Val->getType(), VRegs, FLI.DemoteRegister);
- MIRBuilder.buildCopy(Is64Bit ? X86::RAX : X86::EAX, FLI.DemoteRegister);
+ MIRBuilder.buildCopy(RetReg, FLI.DemoteRegister);
+ MIB.addReg(RetReg);
+ } else if (Register Reg = FuncInfo->getSRetReturnReg()) {
+ MIRBuilder.buildCopy(RetReg, Reg);
+ MIB.addReg(RetReg);
} else if (!VRegs.empty()) {
const Function &F = MF.getFunction();
MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -258,6 +264,7 @@ bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
MachineFunction &MF = MIRBuilder.getMF();
MachineRegisterInfo &MRI = MF.getRegInfo();
auto DL = MF.getDataLayout();
+ auto FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
SmallVector<ArgInfo, 8> SplitArgs;
@@ -273,12 +280,17 @@ bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
// TODO: handle not simple cases.
if (Arg.hasAttribute(Attribute::ByVal) ||
Arg.hasAttribute(Attribute::InReg) ||
- Arg.hasAttribute(Attribute::StructRet) ||
Arg.hasAttribute(Attribute::SwiftSelf) ||
Arg.hasAttribute(Attribute::SwiftError) ||
Arg.hasAttribute(Attribute::Nest) || VRegs[Idx].size() > 1)
return false;
+ if (Arg.hasAttribute(Attribute::StructRet)) {
+ assert(VRegs[Idx].size() == 1 &&
+ "Unexpected amount of registers for sret argument.");
+ FuncInfo->setSRetReturnReg(VRegs[Idx][0]);
+ }
+
ArgInfo OrigArg(VRegs[Idx], Arg.getType(), Idx);
setArgFlags(OrigArg, Idx + AttributeList::FirstArgIndex, DL, F);
splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv());
diff --git a/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll b/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll
index 55e73dc5d29ec..a797c235c46f4 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/irtranslator-callingconv.ll
@@ -5,6 +5,7 @@
@a1_8bit = external global i8
@a7_8bit = external global i8
@a8_8bit = external global i8
+%struct.all = type { i8, i16, i32, i8, i16, i32, i64, float, double }
define i8 @test_i8_args_8(i8 %arg1, i8 %arg2, i8 %arg3, i8 %arg4, i8 %arg5, i8 %arg6, i8 %arg7, i8 %arg8) {
; X86-LABEL: name: test_i8_args_8
@@ -745,7 +746,7 @@ define <32 x float> @test_return_v32f32() {
; X86-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<32 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
; X86-NEXT: G_STORE [[BUILD_VECTOR]](<32 x s32>), [[LOAD]](p0) :: (store (<32 x s32>))
; X86-NEXT: $eax = COPY [[LOAD]](p0)
- ; X86-NEXT: RET 0
+ ; X86-NEXT: RET 0, $eax
;
; X64-LABEL: name: test_return_v32f32
; X64: bb.1 (%ir-block.0):
@@ -756,7 +757,7 @@ define <32 x float> @test_return_v32f32() {
; X64-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<32 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
; X64-NEXT: G_STORE [[BUILD_VECTOR]](<32 x s32>), [[COPY]](p0) :: (store (<32 x s32>))
; X64-NEXT: $rax = COPY [[COPY]](p0)
- ; X64-NEXT: RET 0
+ ; X64-NEXT: RET 0, $rax
ret <32 x float> zeroinitializer
}
@@ -793,3 +794,30 @@ define float @test_call_v32f32() {
%elt = extractelement <32 x float> %vect, i32 7
ret float %elt
}
+
+define void @test_sret(ptr sret(%struct.all) align 8 %result) #0 {
+ ; X86-LABEL: name: test_sret
+ ; X86: bb.1.entry:
+ ; X86-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; X86-NEXT: [[LOAD:%[0-9]+]]:_(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (p0) from %fixed-stack.0, align 16)
+ ; X86-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 104
+ ; X86-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY [[LOAD]](p0)
+ ; X86-NEXT: G_STORE [[C]](s8), [[COPY]](p0) :: (store (s8) into %ir.c, align 8)
+ ; X86-NEXT: $eax = COPY [[LOAD]](p0)
+ ; X86-NEXT: RET 0, $eax
+ ;
+ ; X64-LABEL: name: test_sret
+ ; X64: bb.1.entry:
+ ; X64-NEXT: liveins: $rdi
+ ; X64-NEXT: {{ $}}
+ ; X64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $rdi
+ ; X64-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 104
+ ; X64-NEXT: [[COPY1:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
+ ; X64-NEXT: G_STORE [[C]](s8), [[COPY1]](p0) :: (store (s8) into %ir.c, align 8)
+ ; X64-NEXT: $rax = COPY [[COPY]](p0)
+ ; X64-NEXT: RET 0, $rax
+entry:
+ %c = getelementptr inbounds %struct.all, ptr %result, i32 0, i32 0
+ store i8 104, ptr %c, align 8
+ ret void
+}
diff --git a/llvm/test/CodeGen/X86/isel-buildvector-sse.ll b/llvm/test/CodeGen/X86/isel-buildvector-sse.ll
index 5b96d57cf019b..7f580aad78764 100644
--- a/llvm/test/CodeGen/X86/isel-buildvector-sse.ll
+++ b/llvm/test/CodeGen/X86/isel-buildvector-sse.ll
@@ -22,22 +22,23 @@ define <8 x i32> @test_vector_v8i32() {
;
; SSE-X64-GISEL-LABEL: test_vector_v8i32:
; SSE-X64-GISEL: # %bb.0:
-; SSE-X64-GISEL-NEXT: movl $128100944, %eax # imm = 0x7A2AA50
-; SSE-X64-GISEL-NEXT: movl $-632258670, %ecx # imm = 0xDA507F92
-; SSE-X64-GISEL-NEXT: movl $-408980432, %edx # imm = 0xE79F7430
-; SSE-X64-GISEL-NEXT: movl $708630551, %esi # imm = 0x2A3CD817
+; SSE-X64-GISEL-NEXT: movq %rdi, %rax
+; SSE-X64-GISEL-NEXT: movl $128100944, %ecx # imm = 0x7A2AA50
+; SSE-X64-GISEL-NEXT: movl $-632258670, %edx # imm = 0xDA507F92
+; SSE-X64-GISEL-NEXT: movl $-408980432, %esi # imm = 0xE79F7430
+; SSE-X64-GISEL-NEXT: movl $708630551, %edi # imm = 0x2A3CD817
; SSE-X64-GISEL-NEXT: movl $-871899055, %r8d # imm = 0xCC07E051
; SSE-X64-GISEL-NEXT: movl $-633489957, %r9d # imm = 0xDA3DB5DB
; SSE-X64-GISEL-NEXT: movl $591019567, %r10d # imm = 0x233A3E2F
; SSE-X64-GISEL-NEXT: movl $708632899, %r11d # imm = 0x2A3CE143
-; SSE-X64-GISEL-NEXT: movl %eax, (%rdi)
-; SSE-X64-GISEL-NEXT: movl %ecx, 4(%rdi)
-; SSE-X64-GISEL-NEXT: movl %edx, 8(%rdi)
-; SSE-X64-GISEL-NEXT: movl %esi, 12(%rdi)
-; SSE-X64-GISEL-NEXT: movl %r8d, 16(%rdi)
-; SSE-X64-GISEL-NEXT: movl %r9d, 20(%rdi)
-; SSE-X64-GISEL-NEXT: movl %r10d, 24(%rdi)
-; SSE-X64-GISEL-NEXT: movl %r11d, 28(%rdi)
+; SSE-X64-GISEL-NEXT: movl %ecx, (%rax)
+; SSE-X64-GISEL-NEXT: movl %edx, 4(%rax)
+; SSE-X64-GISEL-NEXT: movl %esi, 8(%rax)
+; SSE-X64-GISEL-NEXT: movl %edi, 12(%rax)
+; SSE-X64-GISEL-NEXT: movl %r8d, 16(%rax)
+; SSE-X64-GISEL-NEXT: movl %r9d, 20(%rax)
+; SSE-X64-GISEL-NEXT: movl %r10d, 24(%rax)
+; SSE-X64-GISEL-NEXT: movl %r11d, 28(%rax)
; SSE-X64-GISEL-NEXT: retq
;
; SSE-X86-LABEL: test_vector_v8i32:
@@ -88,6 +89,7 @@ define <4 x i32> @test_vector_v4i32() {
;
; SSE-X64-GISEL-LABEL: test_vector_v4i32:
; SSE-X64-GISEL: # %bb.0:
+; SSE-X64-GISEL-NEXT: movq %rdi, %rax
; SSE-X64-GISEL-NEXT: movaps {{.*#+}} xmm0 = [128100944,3662708626,3885986864,708630551]
; SSE-X64-GISEL-NEXT: movaps %xmm0, (%rdi)
; SSE-X64-GISEL-NEXT: retq
diff --git a/llvm/test/CodeGen/X86/isel-buildvector-sse2.ll b/llvm/test/CodeGen/X86/isel-buildvector-sse2.ll
index 88e0ede0d4b6f..da089dda6d03d 100644
--- a/llvm/test/CodeGen/X86/isel-buildvector-sse2.ll
+++ b/llvm/test/CodeGen/X86/isel-buildvector-sse2.ll
@@ -19,20 +19,21 @@ define <7 x i8> @test_vector_v7i8() {
;
; SSE2-GISEL-LABEL: test_vector_v7i8:
; SSE2-GISEL: # %bb.0:
-; SSE2-GISEL-NEXT: movb $4, %al
-; SSE2-GISEL-NEXT: movb $8, %cl
-; SSE2-GISEL-NEXT: movb $15, %dl
-; SSE2-GISEL-NEXT: movb $16, %sil
+; SSE2-GISEL-NEXT: movq %rdi, %rax
+; SSE2-GISEL-NEXT: movb $4, %cl
+; SSE2-GISEL-NEXT: movb $8, %dl
+; SSE2-GISEL-NEXT: movb $15, %sil
+; SSE2-GISEL-NEXT: movb $16, %dil
; SSE2-GISEL-NEXT: movb $23, %r8b
; SSE2-GISEL-NEXT: movb $42, %r9b
; SSE2-GISEL-NEXT: movb $63, %r10b
-; SSE2-GISEL-NEXT: movb %al, (%rdi)
-; SSE2-GISEL-NEXT: movb %cl, 1(%rdi)
-; SSE2-GISEL-NEXT: movb %dl, 2(%rdi)
-; SSE2-GISEL-NEXT: movb %sil, 3(%rdi)
-; SSE2-GISEL-NEXT: movb %r8b, 4(%rdi)
-; SSE2-GISEL-NEXT: movb %r9b, 5(%rdi)
-; SSE2-GISEL-NEXT: movb %r10b, 6(%rdi)
+; SSE2-GISEL-NEXT: movb %cl, (%rax)
+; SSE2-GISEL-NEXT: movb %dl, 1(%rax)
+; SSE2-GISEL-NEXT: movb %sil, 2(%rax)
+; SSE2-GISEL-NEXT: movb %dil, 3(%rax)
+; SSE2-GISEL-NEXT: movb %r8b, 4(%rax)
+; SSE2-GISEL-NEXT: movb %r9b, 5(%rax)
+; SSE2-GISEL-NEXT: movb %r10b, 6(%rax)
; SSE2-GISEL-NEXT: retq
ret <7 x i8> <i8 4, i8 8, i8 15, i8 16, i8 23, i8 42, i8 63>
}
More information about the llvm-commits
mailing list