summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/Mips
diff options
context:
space:
mode:
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-09-26 10:48:07 +0000
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-09-26 10:48:07 +0000
commited3051917ef565ec85f2f16031e0856be8cc1c69 (patch)
treed34e069681f0e254cb76fa8939a6cabac81f7287 /llvm/test/CodeGen/Mips
parent39e3b7062a2be938e8bbeb6fa0ab2d7a4efdd7a3 (diff)
downloadbcm5719-llvm-ed3051917ef565ec85f2f16031e0856be8cc1c69.tar.gz
bcm5719-llvm-ed3051917ef565ec85f2f16031e0856be8cc1c69.zip
[MIPS GlobalISel] Lower aggregate structure return arguments
Implement aggregate structure split to simpler types in splitToValueTypes. splitToValueTypes is used for return values. According to MipsABIInfo from clang/lib/CodeGen/TargetInfo.cpp, aggregate structure arguments for O32 always get simplified and thus will remain unsupported by the MIPS GlobalISel for the time being. For O32, aggregate structures can be encountered only for complex number returns e.g. 'complex float' or 'complex double' from <complex.h>. Differential Revision: https://reviews.llvm.org/D67963 llvm-svn: 372957
Diffstat (limited to 'llvm/test/CodeGen/Mips')
-rw-r--r--llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll132
-rw-r--r--llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/aggregate_struct_return.ll114
2 files changed, 246 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll
new file mode 100644
index 00000000000..16c6b3089fa
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll
@@ -0,0 +1,132 @@
+; 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
+
+define { float, float } @add_complex_float({ float, float }* %a, { float, float }* %b) {
+ ; MIPS32-LABEL: name: add_complex_float
+ ; MIPS32: bb.1.entry:
+ ; MIPS32: liveins: $a0, $a1
+ ; MIPS32: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; MIPS32: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+ ; MIPS32: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
+ ; MIPS32: [[COPY2:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[COPY2]](p0) :: (load 4 from %ir..realp)
+ ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[COPY]], [[C]](s32)
+ ; MIPS32: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[GEP]](p0) :: (load 4 from %ir..imagp)
+ ; MIPS32: [[COPY3:%[0-9]+]]:_(p0) = COPY [[COPY1]](p0)
+ ; MIPS32: [[LOAD2:%[0-9]+]]:_(s32) = G_LOAD [[COPY3]](p0) :: (load 4 from %ir..realp1)
+ ; MIPS32: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[COPY1]], [[C]](s32)
+ ; MIPS32: [[LOAD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir..imagp3)
+ ; MIPS32: [[FADD:%[0-9]+]]:_(s32) = G_FADD [[LOAD]], [[LOAD2]]
+ ; MIPS32: [[FADD1:%[0-9]+]]:_(s32) = G_FADD [[LOAD1]], [[LOAD3]]
+ ; MIPS32: $f0 = COPY [[FADD]](s32)
+ ; MIPS32: $f2 = COPY [[FADD1]](s32)
+ ; MIPS32: RetRA implicit $f0, implicit $f2
+entry:
+ %.realp = getelementptr inbounds { float, float }, { float, float }* %a, i32 0, i32 0
+ %.real = load float, float* %.realp, align 4
+ %.imagp = getelementptr inbounds { float, float }, { float, float }* %a, i32 0, i32 1
+ %.imag = load float, float* %.imagp, align 4
+ %.realp1 = getelementptr inbounds { float, float }, { float, float }* %b, i32 0, i32 0
+ %.real2 = load float, float* %.realp1, align 4
+ %.imagp3 = getelementptr inbounds { float, float }, { float, float }* %b, i32 0, i32 1
+ %.imag4 = load float, float* %.imagp3, align 4
+ %add.r = fadd float %.real, %.real2
+ %add.i = fadd float %.imag, %.imag4
+ %.fca.0.insert = insertvalue { float, float } undef, float %add.r, 0
+ %.fca.1.insert = insertvalue { float, float } %.fca.0.insert, float %add.i, 1
+ ret { float, float } %.fca.1.insert
+}
+
+define { double, double } @add_complex_double({ double, double }* %a, { double, double }* %b) {
+ ; MIPS32-LABEL: name: add_complex_double
+ ; MIPS32: bb.1.entry:
+ ; MIPS32: liveins: $a0, $a1
+ ; MIPS32: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; MIPS32: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+ ; MIPS32: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
+ ; MIPS32: [[COPY2:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[COPY2]](p0) :: (load 8 from %ir..realp)
+ ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[COPY]], [[C]](s32)
+ ; MIPS32: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[GEP]](p0) :: (load 8 from %ir..imagp)
+ ; MIPS32: [[COPY3:%[0-9]+]]:_(p0) = COPY [[COPY1]](p0)
+ ; MIPS32: [[LOAD2:%[0-9]+]]:_(s64) = G_LOAD [[COPY3]](p0) :: (load 8 from %ir..realp1)
+ ; MIPS32: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[COPY1]], [[C]](s32)
+ ; MIPS32: [[LOAD3:%[0-9]+]]:_(s64) = G_LOAD [[GEP1]](p0) :: (load 8 from %ir..imagp3)
+ ; MIPS32: [[FADD:%[0-9]+]]:_(s64) = G_FADD [[LOAD]], [[LOAD2]]
+ ; MIPS32: [[FADD1:%[0-9]+]]:_(s64) = G_FADD [[LOAD1]], [[LOAD3]]
+ ; MIPS32: $d0 = COPY [[FADD]](s64)
+ ; MIPS32: $d1 = COPY [[FADD1]](s64)
+ ; MIPS32: RetRA implicit $d0, implicit $d1
+entry:
+ %.realp = getelementptr inbounds { double, double }, { double, double }* %a, i32 0, i32 0
+ %.real = load double, double* %.realp, align 8
+ %.imagp = getelementptr inbounds { double, double }, { double, double }* %a, i32 0, i32 1
+ %.imag = load double, double* %.imagp, align 8
+ %.realp1 = getelementptr inbounds { double, double }, { double, double }* %b, i32 0, i32 0
+ %.real2 = load double, double* %.realp1, align 8
+ %.imagp3 = getelementptr inbounds { double, double }, { double, double }* %b, i32 0, i32 1
+ %.imag4 = load double, double* %.imagp3, align 8
+ %add.r = fadd double %.real, %.real2
+ %add.i = fadd double %.imag, %.imag4
+ %.fca.0.insert = insertvalue { double, double } undef, double %add.r, 0
+ %.fca.1.insert = insertvalue { double, double } %.fca.0.insert, double %add.i, 1
+ ret { double, double } %.fca.1.insert
+}
+
+declare { float, float } @ret_complex_float()
+define void @call_ret_complex_float({ float, float }* %z) {
+ ; MIPS32-LABEL: name: call_ret_complex_float
+ ; MIPS32: bb.1.entry:
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; MIPS32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+ ; MIPS32: JAL @ret_complex_float, csr_o32, implicit-def $ra, implicit-def $sp, implicit-def $f0, implicit-def $f2
+ ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $f0
+ ; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY $f2
+ ; MIPS32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+ ; MIPS32: [[COPY3:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
+ ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
+ ; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[COPY]], [[C]](s32)
+ ; MIPS32: G_STORE [[COPY1]](s32), [[COPY3]](p0) :: (store 4 into %ir..realp)
+ ; MIPS32: G_STORE [[COPY2]](s32), [[GEP]](p0) :: (store 4 into %ir..imagp)
+ ; MIPS32: RetRA
+entry:
+ %call = call { float, float } @ret_complex_float()
+ %0 = extractvalue { float, float } %call, 0
+ %1 = extractvalue { float, float } %call, 1
+ %.realp = getelementptr inbounds { float, float }, { float, float }* %z, i32 0, i32 0
+ %.imagp = getelementptr inbounds { float, float }, { float, float }* %z, i32 0, i32 1
+ store float %0, float* %.realp, align 4
+ store float %1, float* %.imagp, align 4
+ ret void
+}
+
+declare { double, double } @ret_complex_double()
+define void @call_ret_complex_double({ double, double }* %z) {
+ ; MIPS32-LABEL: name: call_ret_complex_double
+ ; MIPS32: bb.1.entry:
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; MIPS32: ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+ ; MIPS32: JAL @ret_complex_double, csr_o32, implicit-def $ra, implicit-def $sp, implicit-def $d0, implicit-def $d1
+ ; MIPS32: [[COPY1:%[0-9]+]]:_(s64) = COPY $d0
+ ; MIPS32: [[COPY2:%[0-9]+]]:_(s64) = COPY $d1
+ ; MIPS32: ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+ ; MIPS32: [[COPY3:%[0-9]+]]:_(p0) = COPY [[COPY]](p0)
+ ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+ ; MIPS32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[COPY]], [[C]](s32)
+ ; MIPS32: G_STORE [[COPY1]](s64), [[COPY3]](p0) :: (store 8 into %ir..realp)
+ ; MIPS32: G_STORE [[COPY2]](s64), [[GEP]](p0) :: (store 8 into %ir..imagp)
+ ; MIPS32: RetRA
+entry:
+ %call = call { double, double } @ret_complex_double()
+ %0 = extractvalue { double, double } %call, 0
+ %1 = extractvalue { double, double } %call, 1
+ %.realp = getelementptr inbounds { double, double }, { double, double }* %z, i32 0, i32 0
+ %.imagp = getelementptr inbounds { double, double }, { double, double }* %z, i32 0, i32 1
+ store double %0, double* %.realp, align 8
+ store double %1, double* %.imagp, align 8
+ ret void
+}
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/aggregate_struct_return.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/aggregate_struct_return.ll
new file mode 100644
index 00000000000..a9f49c025b9
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/aggregate_struct_return.ll
@@ -0,0 +1,114 @@
+; 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
+
+define { float, float } @add_complex_float({ float, float }* %a, { float, float }* %b) {
+; MIPS32-LABEL: add_complex_float:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lwc1 $f0, 0($4)
+; MIPS32-NEXT: lwc1 $f1, 4($4)
+; MIPS32-NEXT: lwc1 $f2, 0($5)
+; MIPS32-NEXT: lwc1 $f3, 4($5)
+; MIPS32-NEXT: add.s $f0, $f0, $f2
+; MIPS32-NEXT: add.s $f2, $f1, $f3
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+entry:
+ %.realp = getelementptr inbounds { float, float }, { float, float }* %a, i32 0, i32 0
+ %.real = load float, float* %.realp, align 4
+ %.imagp = getelementptr inbounds { float, float }, { float, float }* %a, i32 0, i32 1
+ %.imag = load float, float* %.imagp, align 4
+ %.realp1 = getelementptr inbounds { float, float }, { float, float }* %b, i32 0, i32 0
+ %.real2 = load float, float* %.realp1, align 4
+ %.imagp3 = getelementptr inbounds { float, float }, { float, float }* %b, i32 0, i32 1
+ %.imag4 = load float, float* %.imagp3, align 4
+ %add.r = fadd float %.real, %.real2
+ %add.i = fadd float %.imag, %.imag4
+ %.fca.0.insert = insertvalue { float, float } undef, float %add.r, 0
+ %.fca.1.insert = insertvalue { float, float } %.fca.0.insert, float %add.i, 1
+ ret { float, float } %.fca.1.insert
+}
+
+define { double, double } @add_complex_double({ double, double }* %a, { double, double }* %b) {
+; MIPS32-LABEL: add_complex_double:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: ldc1 $f0, 0($4)
+; MIPS32-NEXT: ldc1 $f2, 8($4)
+; MIPS32-NEXT: ldc1 $f4, 0($5)
+; MIPS32-NEXT: ldc1 $f6, 8($5)
+; MIPS32-NEXT: add.d $f0, $f0, $f4
+; MIPS32-NEXT: add.d $f2, $f2, $f6
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+entry:
+ %.realp = getelementptr inbounds { double, double }, { double, double }* %a, i32 0, i32 0
+ %.real = load double, double* %.realp, align 8
+ %.imagp = getelementptr inbounds { double, double }, { double, double }* %a, i32 0, i32 1
+ %.imag = load double, double* %.imagp, align 8
+ %.realp1 = getelementptr inbounds { double, double }, { double, double }* %b, i32 0, i32 0
+ %.real2 = load double, double* %.realp1, align 8
+ %.imagp3 = getelementptr inbounds { double, double }, { double, double }* %b, i32 0, i32 1
+ %.imag4 = load double, double* %.imagp3, align 8
+ %add.r = fadd double %.real, %.real2
+ %add.i = fadd double %.imag, %.imag4
+ %.fca.0.insert = insertvalue { double, double } undef, double %add.r, 0
+ %.fca.1.insert = insertvalue { double, double } %.fca.0.insert, double %add.i, 1
+ ret { double, double } %.fca.1.insert
+}
+
+declare { float, float } @ret_complex_float()
+define void @call_ret_complex_float({ float, float }* %z) {
+; MIPS32-LABEL: call_ret_complex_float:
+; 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: sw $4, 16($sp) # 4-byte Folded Spill
+; MIPS32-NEXT: jal ret_complex_float
+; MIPS32-NEXT: nop
+; MIPS32-NEXT: lw $1, 16($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: swc1 $f0, 0($1)
+; MIPS32-NEXT: swc1 $f2, 4($1)
+; 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 = call { float, float } @ret_complex_float()
+ %0 = extractvalue { float, float } %call, 0
+ %1 = extractvalue { float, float } %call, 1
+ %.realp = getelementptr inbounds { float, float }, { float, float }* %z, i32 0, i32 0
+ %.imagp = getelementptr inbounds { float, float }, { float, float }* %z, i32 0, i32 1
+ store float %0, float* %.realp, align 4
+ store float %1, float* %.imagp, align 4
+ ret void
+}
+
+declare { double, double } @ret_complex_double()
+define void @call_ret_complex_double({ double, double }* %z) {
+; MIPS32-LABEL: call_ret_complex_double:
+; 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: sw $4, 16($sp) # 4-byte Folded Spill
+; MIPS32-NEXT: jal ret_complex_double
+; MIPS32-NEXT: nop
+; MIPS32-NEXT: lw $1, 16($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: sdc1 $f0, 0($1)
+; MIPS32-NEXT: sdc1 $f2, 8($1)
+; 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 = call { double, double } @ret_complex_double()
+ %0 = extractvalue { double, double } %call, 0
+ %1 = extractvalue { double, double } %call, 1
+ %.realp = getelementptr inbounds { double, double }, { double, double }* %z, i32 0, i32 0
+ %.imagp = getelementptr inbounds { double, double }, { double, double }* %z, i32 0, i32 1
+ store double %0, double* %.realp, align 8
+ store double %1, double* %.imagp, align 8
+ ret void
+}
OpenPOWER on IntegriCloud