Skip to content

Commit 41c33cb

Browse files
committed
[RISCV][GISel] Enable support for ArrayType arguments if the element type is also supported.
This allows us to handle small coerced structs that are passed as [2 x i64]. This is one of the last big reasons for -O0 fallbacks in some of my testing.
1 parent 409edc6 commit 41c33cb

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ static bool isSupportedArgumentType(Type *T, const RISCVSubtarget &Subtarget,
354354
return true;
355355
if (T->isPointerTy())
356356
return true;
357+
if (T->isArrayTy())
358+
return isSupportedArgumentType(T->getArrayElementType(), Subtarget,
359+
IsLowerArgs);
357360
// TODO: Support fixed vector types.
358361
if (IsLowerArgs && T->isVectorTy() && Subtarget.hasVInstructions() &&
359362
T->isScalableTy() &&

llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-ilp32d-common.ll

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,69 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind {
10551055
ret i32 %1
10561056
}
10571057

1058+
; Check passing of coerced integer arrays
1059+
1060+
define i32 @callee_small_coerced_struct([2 x i32] %a.coerce) nounwind {
1061+
; RV32I-LABEL: name: callee_small_coerced_struct
1062+
; RV32I: bb.1 (%ir-block.0):
1063+
; RV32I-NEXT: liveins: $x10, $x11
1064+
; RV32I-NEXT: {{ $}}
1065+
; RV32I-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
1066+
; RV32I-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
1067+
; RV32I-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s32), [[COPY1]]
1068+
; RV32I-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
1069+
; RV32I-NEXT: $x10 = COPY [[ZEXT]](s32)
1070+
; RV32I-NEXT: PseudoRET implicit $x10
1071+
%1 = extractvalue [2 x i32] %a.coerce, 0
1072+
%2 = extractvalue [2 x i32] %a.coerce, 1
1073+
%3 = icmp eq i32 %1, %2
1074+
%4 = zext i1 %3 to i32
1075+
ret i32 %4
1076+
}
1077+
1078+
define i32 @caller_small_coerced_struct() nounwind {
1079+
; ILP32-LABEL: name: caller_small_coerced_struct
1080+
; ILP32: bb.1 (%ir-block.0):
1081+
; ILP32-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1082+
; ILP32-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1083+
; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
1084+
; ILP32-NEXT: $x10 = COPY [[C]](s32)
1085+
; ILP32-NEXT: $x11 = COPY [[C1]](s32)
1086+
; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
1087+
; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
1088+
; ILP32-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
1089+
; ILP32-NEXT: $x10 = COPY [[COPY]](s32)
1090+
; ILP32-NEXT: PseudoRET implicit $x10
1091+
;
1092+
; ILP32F-LABEL: name: caller_small_coerced_struct
1093+
; ILP32F: bb.1 (%ir-block.0):
1094+
; ILP32F-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1095+
; ILP32F-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1096+
; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
1097+
; ILP32F-NEXT: $x10 = COPY [[C]](s32)
1098+
; ILP32F-NEXT: $x11 = COPY [[C1]](s32)
1099+
; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
1100+
; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
1101+
; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
1102+
; ILP32F-NEXT: $x10 = COPY [[COPY]](s32)
1103+
; ILP32F-NEXT: PseudoRET implicit $x10
1104+
;
1105+
; ILP32D-LABEL: name: caller_small_coerced_struct
1106+
; ILP32D: bb.1 (%ir-block.0):
1107+
; ILP32D-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1108+
; ILP32D-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1109+
; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
1110+
; ILP32D-NEXT: $x10 = COPY [[C]](s32)
1111+
; ILP32D-NEXT: $x11 = COPY [[C1]](s32)
1112+
; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
1113+
; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
1114+
; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $x10
1115+
; ILP32D-NEXT: $x10 = COPY [[COPY]](s32)
1116+
; ILP32D-NEXT: PseudoRET implicit $x10
1117+
%1 = call i32 @callee_small_coerced_struct([2 x i32] [i32 1, i32 2])
1118+
ret i32 %1
1119+
}
1120+
10581121
; Check return of 2x xlen scalars
10591122

10601123
define i64 @callee_small_scalar_ret() nounwind {

llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-lp64-lp64f-lp64d-common.ll

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,69 @@ define i64 @caller_large_scalars_exhausted_regs() nounwind {
783783
ret i64 %1
784784
}
785785

786+
; Check passing of coerced integer arrays
787+
788+
define i64 @callee_small_coerced_struct([2 x i64] %a.coerce) nounwind {
789+
; RV64I-LABEL: name: callee_small_coerced_struct
790+
; RV64I: bb.1 (%ir-block.0):
791+
; RV64I-NEXT: liveins: $x10, $x11
792+
; RV64I-NEXT: {{ $}}
793+
; RV64I-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
794+
; RV64I-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
795+
; RV64I-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY]](s64), [[COPY1]]
796+
; RV64I-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[ICMP]](s1)
797+
; RV64I-NEXT: $x10 = COPY [[ZEXT]](s64)
798+
; RV64I-NEXT: PseudoRET implicit $x10
799+
%1 = extractvalue [2 x i64] %a.coerce, 0
800+
%2 = extractvalue [2 x i64] %a.coerce, 1
801+
%3 = icmp eq i64 %1, %2
802+
%4 = zext i1 %3 to i64
803+
ret i64 %4
804+
}
805+
806+
define i64 @caller_small_coerced_struct() nounwind {
807+
; LP64-LABEL: name: caller_small_coerced_struct
808+
; LP64: bb.1 (%ir-block.0):
809+
; LP64-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
810+
; LP64-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
811+
; LP64-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
812+
; LP64-NEXT: $x10 = COPY [[C]](s64)
813+
; LP64-NEXT: $x11 = COPY [[C1]](s64)
814+
; LP64-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
815+
; LP64-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
816+
; LP64-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
817+
; LP64-NEXT: $x10 = COPY [[COPY]](s64)
818+
; LP64-NEXT: PseudoRET implicit $x10
819+
;
820+
; LP64F-LABEL: name: caller_small_coerced_struct
821+
; LP64F: bb.1 (%ir-block.0):
822+
; LP64F-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
823+
; LP64F-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
824+
; LP64F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
825+
; LP64F-NEXT: $x10 = COPY [[C]](s64)
826+
; LP64F-NEXT: $x11 = COPY [[C1]](s64)
827+
; LP64F-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
828+
; LP64F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
829+
; LP64F-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
830+
; LP64F-NEXT: $x10 = COPY [[COPY]](s64)
831+
; LP64F-NEXT: PseudoRET implicit $x10
832+
;
833+
; LP64D-LABEL: name: caller_small_coerced_struct
834+
; LP64D: bb.1 (%ir-block.0):
835+
; LP64D-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
836+
; LP64D-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
837+
; LP64D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
838+
; LP64D-NEXT: $x10 = COPY [[C]](s64)
839+
; LP64D-NEXT: $x11 = COPY [[C1]](s64)
840+
; LP64D-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_coerced_struct, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit-def $x10
841+
; LP64D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
842+
; LP64D-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
843+
; LP64D-NEXT: $x10 = COPY [[COPY]](s64)
844+
; LP64D-NEXT: PseudoRET implicit $x10
845+
%1 = call i64 @callee_small_coerced_struct([2 x i64] [i64 1, i64 2])
846+
ret i64 %1
847+
}
848+
786849
; Check return of 2x xlen scalars
787850

788851
define i128 @callee_small_scalar_ret() nounwind {

0 commit comments

Comments
 (0)