Skip to content

Commit a16f0dc

Browse files
committed
[RISCV][GISel] Allow >2*XLen integers in isSupportedReturnType.
1 parent 4a4b233 commit a16f0dc

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ static bool isSupportedReturnType(Type *T, const RISCVSubtarget &Subtarget,
363363
// TODO: Integers larger than 2*XLen are passed indirectly which is not
364364
// supported yet.
365365
if (T->isIntegerTy())
366-
return T->getIntegerBitWidth() <= Subtarget.getXLen() * 2;
366+
return true;
367367
if (T->isHalfTy() || T->isFloatTy() || T->isDoubleTy())
368368
return true;
369369
if (T->isPointerTy())

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

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,64 @@ define i32 @caller_small_scalar_ret() nounwind {
886886
ret i32 %3
887887
}
888888

889+
; Check return of >2x xlen scalars
890+
891+
define i128 @callee_large_scalar_ret() nounwind {
892+
; RV32I-LABEL: name: callee_large_scalar_ret
893+
; RV32I: bb.1 (%ir-block.0):
894+
; RV32I-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 1234567898765432123456789
895+
; RV32I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
896+
; RV32I-NEXT: G_STORE [[C]](s128), [[FRAME_INDEX]](p0) :: (store (s128) into %stack.0, align 8)
897+
; RV32I-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
898+
; RV32I-NEXT: PseudoRET implicit $x10
899+
ret i128 1234567898765432123456789
900+
}
901+
902+
define i32 @caller_large_scalar_ret() nounwind {
903+
; ILP32-LABEL: name: caller_large_scalar_ret
904+
; ILP32: bb.1 (%ir-block.0):
905+
; ILP32-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 9876543212345678987654321
906+
; ILP32-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
907+
; ILP32-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_scalar_ret, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
908+
; ILP32-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
909+
; ILP32-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
910+
; ILP32-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128), align 8)
911+
; ILP32-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s128), [[LOAD]]
912+
; ILP32-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
913+
; ILP32-NEXT: $x10 = COPY [[ZEXT]](s32)
914+
; ILP32-NEXT: PseudoRET implicit $x10
915+
;
916+
; ILP32F-LABEL: name: caller_large_scalar_ret
917+
; ILP32F: bb.1 (%ir-block.0):
918+
; ILP32F-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 9876543212345678987654321
919+
; ILP32F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
920+
; ILP32F-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_scalar_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit-def $x10
921+
; ILP32F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
922+
; ILP32F-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
923+
; ILP32F-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128), align 8)
924+
; ILP32F-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s128), [[LOAD]]
925+
; ILP32F-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
926+
; ILP32F-NEXT: $x10 = COPY [[ZEXT]](s32)
927+
; ILP32F-NEXT: PseudoRET implicit $x10
928+
;
929+
; ILP32D-LABEL: name: caller_large_scalar_ret
930+
; ILP32D: bb.1 (%ir-block.0):
931+
; ILP32D-NEXT: [[C:%[0-9]+]]:_(s128) = G_CONSTANT i128 9876543212345678987654321
932+
; ILP32D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
933+
; ILP32D-NEXT: PseudoCALL target-flags(riscv-call) @callee_large_scalar_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $x10
934+
; ILP32D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
935+
; ILP32D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
936+
; ILP32D-NEXT: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY]](p0) :: (load (s128), align 8)
937+
; ILP32D-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s128), [[LOAD]]
938+
; ILP32D-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
939+
; ILP32D-NEXT: $x10 = COPY [[ZEXT]](s32)
940+
; ILP32D-NEXT: PseudoRET implicit $x10
941+
%1 = call i128 @callee_large_scalar_ret()
942+
%2 = icmp eq i128 9876543212345678987654321, %1
943+
%3 = zext i1 %2 to i32
944+
ret i32 %3
945+
}
946+
889947
; Check return of 2x xlen structs
890948

891949
%struct.small = type { i32, ptr }

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

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,64 @@ define i64 @caller_small_scalar_ret() nounwind {
541541
ret i64 %3
542542
}
543543

544+
; Check return of >2x xlen scalars
545+
546+
define i256 @callee_large_scalar_ret() nounwind {
547+
; RV64I-LABEL: name: callee_large_scalar_ret
548+
; RV64I: bb.1 (%ir-block.0):
549+
; RV64I-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 -1
550+
; RV64I-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
551+
; RV64I-NEXT: G_STORE [[C]](s256), [[FRAME_INDEX]](p0) :: (store (s256) into %stack.0, align 16)
552+
; RV64I-NEXT: $x10 = COPY [[FRAME_INDEX]](p0)
553+
; RV64I-NEXT: PseudoRET implicit $x10
554+
ret i256 -1
555+
}
556+
557+
define i64 @caller_large_scalar_ret() nounwind {
558+
; LP64-LABEL: name: caller_large_scalar_ret
559+
; LP64: bb.1 (%ir-block.0):
560+
; LP64-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 -2
561+
; LP64-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
562+
; LP64-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10
563+
; LP64-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
564+
; LP64-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
565+
; LP64-NEXT: [[LOAD:%[0-9]+]]:_(s256) = G_LOAD [[COPY]](p0) :: (load (s256), align 16)
566+
; LP64-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s256), [[LOAD]]
567+
; LP64-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[ICMP]](s1)
568+
; LP64-NEXT: $x10 = COPY [[ZEXT]](s64)
569+
; LP64-NEXT: PseudoRET implicit $x10
570+
;
571+
; LP64F-LABEL: name: caller_large_scalar_ret
572+
; LP64F: bb.1 (%ir-block.0):
573+
; LP64F-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 -2
574+
; LP64F-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
575+
; LP64F-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit-def $x10
576+
; LP64F-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
577+
; LP64F-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
578+
; LP64F-NEXT: [[LOAD:%[0-9]+]]:_(s256) = G_LOAD [[COPY]](p0) :: (load (s256), align 16)
579+
; LP64F-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s256), [[LOAD]]
580+
; LP64F-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[ICMP]](s1)
581+
; LP64F-NEXT: $x10 = COPY [[ZEXT]](s64)
582+
; LP64F-NEXT: PseudoRET implicit $x10
583+
;
584+
; LP64D-LABEL: name: caller_large_scalar_ret
585+
; LP64D: bb.1 (%ir-block.0):
586+
; LP64D-NEXT: [[C:%[0-9]+]]:_(s256) = G_CONSTANT i256 -2
587+
; LP64D-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
588+
; LP64D-NEXT: PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $x10
589+
; LP64D-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
590+
; LP64D-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x10
591+
; LP64D-NEXT: [[LOAD:%[0-9]+]]:_(s256) = G_LOAD [[COPY]](p0) :: (load (s256), align 16)
592+
; LP64D-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s256), [[LOAD]]
593+
; LP64D-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[ICMP]](s1)
594+
; LP64D-NEXT: $x10 = COPY [[ZEXT]](s64)
595+
; LP64D-NEXT: PseudoRET implicit $x10
596+
%1 = call i256 @callee_small_scalar_ret()
597+
%2 = icmp eq i256 -2, %1
598+
%3 = zext i1 %2 to i64
599+
ret i64 %3
600+
}
601+
544602
; Check return of 2x xlen structs
545603

546604
%struct.small = type { i64, ptr }

0 commit comments

Comments
 (0)