xref: /llvm-project/llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/calling-conv-ilp32-ilp32f-common.ll (revision 360996ac5ad26714a6ddbee45730fbcfb7dc3eea)
1; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
2; RUN: llc -mtriple=riscv32 -global-isel -stop-after=irtranslator \
3; RUN:    -verify-machineinstrs < %s \
4; RUN:   | FileCheck -check-prefixes=RV32I,ILP32 %s
5; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f \
6; RUN:    -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
7; RUN:   | FileCheck -check-prefixes=RV32I,ILP32F %s
8
9; This file contains tests that should have identical output for the ilp32,
10; and ilp32f.
11
12; Check that on RV32 ilp32[f], double is passed in a pair of registers. Unlike
13; the convention for varargs, this need not be an aligned pair.
14
15define i32 @callee_double_in_regs(i32 %a, double %b) nounwind {
16  ; RV32I-LABEL: name: callee_double_in_regs
17  ; RV32I: bb.1 (%ir-block.0):
18  ; RV32I-NEXT:   liveins: $x10, $x11, $x12
19  ; RV32I-NEXT: {{  $}}
20  ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
21  ; RV32I-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
22  ; RV32I-NEXT:   [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
23  ; RV32I-NEXT:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
24  ; RV32I-NEXT:   [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[MV]](s64)
25  ; RV32I-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[FPTOSI]]
26  ; RV32I-NEXT:   $x10 = COPY [[ADD]](s32)
27  ; RV32I-NEXT:   PseudoRET implicit $x10
28  %b_fptosi = fptosi double %b to i32
29  %1 = add i32 %a, %b_fptosi
30  ret i32 %1
31}
32
33define i32 @caller_double_in_regs() nounwind {
34  ; ILP32-LABEL: name: caller_double_in_regs
35  ; ILP32: bb.1 (%ir-block.0):
36  ; ILP32-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
37  ; ILP32-NEXT:   [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
38  ; ILP32-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
39  ; ILP32-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
40  ; ILP32-NEXT:   $x10 = COPY [[C]](s32)
41  ; ILP32-NEXT:   $x11 = COPY [[UV]](s32)
42  ; ILP32-NEXT:   $x12 = COPY [[UV1]](s32)
43  ; ILP32-NEXT:   PseudoCALL target-flags(riscv-call) @callee_double_in_regs, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
44  ; ILP32-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
45  ; ILP32-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
46  ; ILP32-NEXT:   $x10 = COPY [[COPY]](s32)
47  ; ILP32-NEXT:   PseudoRET implicit $x10
48  ;
49  ; ILP32F-LABEL: name: caller_double_in_regs
50  ; ILP32F: bb.1 (%ir-block.0):
51  ; ILP32F-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
52  ; ILP32F-NEXT:   [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
53  ; ILP32F-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
54  ; ILP32F-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
55  ; ILP32F-NEXT:   $x10 = COPY [[C]](s32)
56  ; ILP32F-NEXT:   $x11 = COPY [[UV]](s32)
57  ; ILP32F-NEXT:   $x12 = COPY [[UV1]](s32)
58  ; ILP32F-NEXT:   PseudoCALL target-flags(riscv-call) @callee_double_in_regs, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
59  ; ILP32F-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
60  ; ILP32F-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
61  ; ILP32F-NEXT:   $x10 = COPY [[COPY]](s32)
62  ; ILP32F-NEXT:   PseudoRET implicit $x10
63  %1 = call i32 @callee_double_in_regs(i32 1, double 2.0)
64  ret i32 %1
65}
66
67define double @callee_small_scalar_ret() nounwind {
68  ; RV32I-LABEL: name: callee_small_scalar_ret
69  ; RV32I: bb.1 (%ir-block.0):
70  ; RV32I-NEXT:   [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
71  ; RV32I-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
72  ; RV32I-NEXT:   $x10 = COPY [[UV]](s32)
73  ; RV32I-NEXT:   $x11 = COPY [[UV1]](s32)
74  ; RV32I-NEXT:   PseudoRET implicit $x10, implicit $x11
75  ret double 1.0
76}
77
78define i64 @caller_small_scalar_ret() nounwind {
79  ; ILP32-LABEL: name: caller_small_scalar_ret
80  ; ILP32: bb.1 (%ir-block.0):
81  ; ILP32-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
82  ; ILP32-NEXT:   PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
83  ; ILP32-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
84  ; ILP32-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
85  ; ILP32-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
86  ; ILP32-NEXT:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
87  ; ILP32-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MV]](s64)
88  ; ILP32-NEXT:   $x10 = COPY [[UV]](s32)
89  ; ILP32-NEXT:   $x11 = COPY [[UV1]](s32)
90  ; ILP32-NEXT:   PseudoRET implicit $x10, implicit $x11
91  ;
92  ; ILP32F-LABEL: name: caller_small_scalar_ret
93  ; ILP32F: bb.1 (%ir-block.0):
94  ; ILP32F-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
95  ; ILP32F-NEXT:   PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit-def $x10, implicit-def $x11
96  ; ILP32F-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
97  ; ILP32F-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
98  ; ILP32F-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
99  ; ILP32F-NEXT:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
100  ; ILP32F-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MV]](s64)
101  ; ILP32F-NEXT:   $x10 = COPY [[UV]](s32)
102  ; ILP32F-NEXT:   $x11 = COPY [[UV1]](s32)
103  ; ILP32F-NEXT:   PseudoRET implicit $x10, implicit $x11
104  %1 = call double @callee_small_scalar_ret()
105  %2 = bitcast double %1 to i64
106  ret i64 %2
107}
108