]> granicus.if.org Git - llvm/commitdiff
[MIPS GlobalISel] Lower SRet pointer arguments
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>
Thu, 5 Sep 2019 11:12:01 +0000 (11:12 +0000)
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>
Thu, 5 Sep 2019 11:12:01 +0000 (11:12 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@371054 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsCallLowering.cpp
test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll [new file with mode: 0644]
test/CodeGen/Mips/GlobalISel/llvm-ir/sret_pointer.ll [new file with mode: 0644]

index 0d0e446fee917f335d35612a978f1081ac37c2bb..aac29967f599c98214a32e4f85e6fc4594795554 100644 (file)
@@ -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/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll b/test/CodeGen/Mips/GlobalISel/irtranslator/sret_pointer.ll
new file mode 100644 (file)
index 0000000..aab38d7
--- /dev/null
@@ -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/test/CodeGen/Mips/GlobalISel/llvm-ir/sret_pointer.ll b/test/CodeGen/Mips/GlobalISel/llvm-ir/sret_pointer.ll
new file mode 100644 (file)
index 0000000..4e5cbb0
--- /dev/null
@@ -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
+}