summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-09-05 11:12:01 +0000
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-09-05 11:12:01 +0000
commitd2574d79b64db47051f0ea19de184218302e322a (patch)
treeb4aac8dde0dd740c31c8d7eae04966e741050210
parent071287c5a9320b4bf7892094b619152df424aa1f (diff)
downloadbcm5719-llvm-d2574d79b64db47051f0ea19de184218302e322a.tar.gz
bcm5719-llvm-d2574d79b64db47051f0ea19de184218302e322a.zip
[MIPS GlobalISel] Lower SRet pointer arguments
Instead of returning structure by value clang usually adds pointer to that structure as an argument. Pointers don't require special handling no matter the SRet flag. Remove unsuccessful exit from lowerCall for arguments with SRet flag if they are pointers. Differential Revision: https://reviews.llvm.org/D67179 llvm-svn: 371054
-rw-r--r--llvm/lib/Target/Mips/MipsCallLowering.cpp4
-rw-r--r--llvm/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll39
-rw-r--r--llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/sret_pointer.ll38
3 files changed, 80 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index 0d0e446fee9..aac29967f59 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -508,7 +508,9 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
for (auto &Arg : Info.OrigArgs) {
if (!isSupportedType(Arg.Ty))
return false;
- if (Arg.Flags[0].isByVal() || Arg.Flags[0].isSRet())
+ if (Arg.Flags[0].isByVal())
+ return false;
+ if (Arg.Flags[0].isSRet() && !Arg.Ty->isPointerTy())
return false;
}
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll
new file mode 100644
index 00000000000..aab38d7042e
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+
+%struct.S = type { i32, i32 }
+
+define void @ZeroInit(%struct.S* noalias sret %agg.result) {
+ ; MIPS32-LABEL: name: ZeroInit
+ ; MIPS32: bb.1.entry:
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; MIPS32: [[COPY1:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
+ ; MIPS32: G_STORE [[C]](s32), [[COPY1]](p0) :: (store 4 into %ir.x)
+ ; MIPS32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[COPY]], [[C1]](s32)
+ ; MIPS32: G_STORE [[C]](s32), [[GEP]](p0) :: (store 4 into %ir.y)
+ ; MIPS32: RetRA
+entry:
+ %x = getelementptr inbounds %struct.S, %struct.S* %agg.result, i32 0, i32 0
+ store i32 0, i32* %x, align 4
+ %y = getelementptr inbounds %struct.S, %struct.S* %agg.result, i32 0, i32 1
+ store i32 0, i32* %y, align 4
+ ret void
+}
+
+define void @CallZeroInit(%struct.S* noalias sret %agg.result) {
+ ; MIPS32-LABEL: name: CallZeroInit
+ ; MIPS32: bb.1.entry:
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; MIPS32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+ ; MIPS32: $a0 = COPY [[COPY]](p0)
+ ; MIPS32: JAL @ZeroInit, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0
+ ; MIPS32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+ ; MIPS32: RetRA
+entry:
+ call void @ZeroInit(%struct.S* sret %agg.result)
+ ret void
+}
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/sret_pointer.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/sret_pointer.ll
new file mode 100644
index 00000000000..4e5cbb08fde
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/sret_pointer.ll
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32
+
+%struct.S = type { i32, i32 }
+
+define void @ZeroInit(%struct.S* noalias sret %agg.result) {
+; MIPS32-LABEL: ZeroInit:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: ori $1, $zero, 0
+; MIPS32-NEXT: sw $1, 0($4)
+; MIPS32-NEXT: sw $1, 4($4)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+entry:
+ %x = getelementptr inbounds %struct.S, %struct.S* %agg.result, i32 0, i32 0
+ store i32 0, i32* %x, align 4
+ %y = getelementptr inbounds %struct.S, %struct.S* %agg.result, i32 0, i32 1
+ store i32 0, i32* %y, align 4
+ ret void
+}
+
+define void @CallZeroInit(%struct.S* noalias sret %agg.result) {
+; MIPS32-LABEL: CallZeroInit:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: addiu $sp, $sp, -24
+; MIPS32-NEXT: .cfi_def_cfa_offset 24
+; MIPS32-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
+; MIPS32-NEXT: .cfi_offset 31, -4
+; MIPS32-NEXT: jal ZeroInit
+; MIPS32-NEXT: nop
+; MIPS32-NEXT: lw $ra, 20($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: addiu $sp, $sp, 24
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+entry:
+ call void @ZeroInit(%struct.S* sret %agg.result)
+ ret void
+}
OpenPOWER on IntegriCloud