Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / RISCV / GlobalISel / irtranslator / calling-conv-ilp32-ilp32f-ilp32d-common.ll
blob1a3489521af19c2fbf46db280b88e846b23f9b3c
1 ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
2 ; RUN: llc -mtriple=riscv32 \
3 ; RUN:    -global-isel -stop-after=irtranslator -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 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
9 ; RUN:    -global-isel -stop-after=irtranslator -verify-machineinstrs < %s \
10 ; RUN:   | FileCheck -check-prefixes=RV32I,ILP32D %s
12 ; This file contains tests that should have identical output for the ilp32,
13 ; ilp32f, and ilp32d ABIs. i.e. where no arguments are passed according to
14 ; the floating point ABI.
16 ; Check that on RV32, i64 is passed in a pair of registers. Unlike
17 ; the convention for varargs, this need not be an aligned pair.
19 define i32 @callee_i64_in_regs(i32 %a, i64 %b) nounwind {
20   ; RV32I-LABEL: name: callee_i64_in_regs
21   ; RV32I: bb.1 (%ir-block.0):
22   ; RV32I-NEXT:   liveins: $x10, $x11, $x12
23   ; RV32I-NEXT: {{  $}}
24   ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
25   ; RV32I-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
26   ; RV32I-NEXT:   [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
27   ; RV32I-NEXT:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
28   ; RV32I-NEXT:   [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[MV]](s64)
29   ; RV32I-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[TRUNC]]
30   ; RV32I-NEXT:   $x10 = COPY [[ADD]](s32)
31   ; RV32I-NEXT:   PseudoRET implicit $x10
32   %b_trunc = trunc i64 %b to i32
33   %1 = add i32 %a, %b_trunc
34   ret i32 %1
37 define i32 @caller_i64_in_regs() nounwind {
38   ; ILP32-LABEL: name: caller_i64_in_regs
39   ; ILP32: bb.1 (%ir-block.0):
40   ; ILP32-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
41   ; ILP32-NEXT:   [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
42   ; ILP32-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
43   ; ILP32-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
44   ; ILP32-NEXT:   $x10 = COPY [[C]](s32)
45   ; ILP32-NEXT:   $x11 = COPY [[UV]](s32)
46   ; ILP32-NEXT:   $x12 = COPY [[UV1]](s32)
47   ; ILP32-NEXT:   PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
48   ; ILP32-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
49   ; ILP32-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
50   ; ILP32-NEXT:   $x10 = COPY [[COPY]](s32)
51   ; ILP32-NEXT:   PseudoRET implicit $x10
52   ;
53   ; ILP32F-LABEL: name: caller_i64_in_regs
54   ; ILP32F: bb.1 (%ir-block.0):
55   ; ILP32F-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
56   ; ILP32F-NEXT:   [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
57   ; ILP32F-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
58   ; ILP32F-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
59   ; ILP32F-NEXT:   $x10 = COPY [[C]](s32)
60   ; ILP32F-NEXT:   $x11 = COPY [[UV]](s32)
61   ; ILP32F-NEXT:   $x12 = COPY [[UV1]](s32)
62   ; ILP32F-NEXT:   PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
63   ; ILP32F-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
64   ; ILP32F-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
65   ; ILP32F-NEXT:   $x10 = COPY [[COPY]](s32)
66   ; ILP32F-NEXT:   PseudoRET implicit $x10
67   ;
68   ; ILP32D-LABEL: name: caller_i64_in_regs
69   ; ILP32D: bb.1 (%ir-block.0):
70   ; ILP32D-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
71   ; ILP32D-NEXT:   [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
72   ; ILP32D-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
73   ; ILP32D-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C1]](s64)
74   ; ILP32D-NEXT:   $x10 = COPY [[C]](s32)
75   ; ILP32D-NEXT:   $x11 = COPY [[UV]](s32)
76   ; ILP32D-NEXT:   $x12 = COPY [[UV1]](s32)
77   ; ILP32D-NEXT:   PseudoCALL target-flags(riscv-call) @callee_i64_in_regs, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit-def $x10
78   ; ILP32D-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
79   ; ILP32D-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
80   ; ILP32D-NEXT:   $x10 = COPY [[COPY]](s32)
81   ; ILP32D-NEXT:   PseudoRET implicit $x10
82   %1 = call i32 @callee_i64_in_regs(i32 1, i64 2)
83   ret i32 %1
86 ; Check that the stack is used once the GPRs are exhausted
88 define i32 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i64 %d, i32 %e, i32 %f, i64 %g, i32 %h) nounwind {
89   ; RV32I-LABEL: name: callee_many_scalars
90   ; RV32I: bb.1 (%ir-block.0):
91   ; RV32I-NEXT:   liveins: $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17
92   ; RV32I-NEXT: {{  $}}
93   ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
94   ; RV32I-NEXT:   [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
95   ; RV32I-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
96   ; RV32I-NEXT:   [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
97   ; RV32I-NEXT:   [[COPY2:%[0-9]+]]:_(s32) = COPY $x12
98   ; RV32I-NEXT:   [[COPY3:%[0-9]+]]:_(s32) = COPY $x13
99   ; RV32I-NEXT:   [[COPY4:%[0-9]+]]:_(s32) = COPY $x14
100   ; RV32I-NEXT:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY3]](s32), [[COPY4]](s32)
101   ; RV32I-NEXT:   [[COPY5:%[0-9]+]]:_(s32) = COPY $x15
102   ; RV32I-NEXT:   [[COPY6:%[0-9]+]]:_(s32) = COPY $x16
103   ; RV32I-NEXT:   [[COPY7:%[0-9]+]]:_(s32) = COPY $x17
104   ; RV32I-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
105   ; RV32I-NEXT:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %fixed-stack.1, align 16)
106   ; RV32I-NEXT:   [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY7]](s32), [[LOAD]](s32)
107   ; RV32I-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
108   ; RV32I-NEXT:   [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %fixed-stack.0)
109   ; RV32I-NEXT:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8)
110   ; RV32I-NEXT:   [[ZEXT1:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC1]](s16)
111   ; RV32I-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[ZEXT]], [[ZEXT1]]
112   ; RV32I-NEXT:   [[ADD1:%[0-9]+]]:_(s32) = G_ADD [[ADD]], [[COPY2]]
113   ; RV32I-NEXT:   [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[MV]](s64), [[MV1]]
114   ; RV32I-NEXT:   [[ZEXT2:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
115   ; RV32I-NEXT:   [[ADD2:%[0-9]+]]:_(s32) = G_ADD [[ZEXT2]], [[ADD1]]
116   ; RV32I-NEXT:   [[ADD3:%[0-9]+]]:_(s32) = G_ADD [[ADD2]], [[COPY5]]
117   ; RV32I-NEXT:   [[ADD4:%[0-9]+]]:_(s32) = G_ADD [[ADD3]], [[COPY6]]
118   ; RV32I-NEXT:   [[ADD5:%[0-9]+]]:_(s32) = G_ADD [[ADD4]], [[LOAD1]]
119   ; RV32I-NEXT:   $x10 = COPY [[ADD5]](s32)
120   ; RV32I-NEXT:   PseudoRET implicit $x10
121   %a_ext = zext i8 %a to i32
122   %b_ext = zext i16 %b to i32
123   %1 = add i32 %a_ext, %b_ext
124   %2 = add i32 %1, %c
125   %3 = icmp eq i64 %d, %g
126   %4 = zext i1 %3 to i32
127   %5 = add i32 %4, %2
128   %6 = add i32 %5, %e
129   %7 = add i32 %6, %f
130   %8 = add i32 %7, %h
131   ret i32 %8
134 define i32 @caller_many_scalars() nounwind {
135   ; ILP32-LABEL: name: caller_many_scalars
136   ; ILP32: bb.1 (%ir-block.0):
137   ; ILP32-NEXT:   [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
138   ; ILP32-NEXT:   [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
139   ; ILP32-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
140   ; ILP32-NEXT:   [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
141   ; ILP32-NEXT:   [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
142   ; ILP32-NEXT:   [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
143   ; ILP32-NEXT:   [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
144   ; ILP32-NEXT:   [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
145   ; ILP32-NEXT:   ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
146   ; ILP32-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
147   ; ILP32-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
148   ; ILP32-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
149   ; ILP32-NEXT:   [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
150   ; ILP32-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x2
151   ; ILP32-NEXT:   [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
152   ; ILP32-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
153   ; ILP32-NEXT:   G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
154   ; ILP32-NEXT:   [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
155   ; ILP32-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
156   ; ILP32-NEXT:   G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
157   ; ILP32-NEXT:   $x10 = COPY [[ANYEXT]](s32)
158   ; ILP32-NEXT:   $x11 = COPY [[ANYEXT1]](s32)
159   ; ILP32-NEXT:   $x12 = COPY [[C2]](s32)
160   ; ILP32-NEXT:   $x13 = COPY [[UV]](s32)
161   ; ILP32-NEXT:   $x14 = COPY [[UV1]](s32)
162   ; ILP32-NEXT:   $x15 = COPY [[C4]](s32)
163   ; ILP32-NEXT:   $x16 = COPY [[C5]](s32)
164   ; ILP32-NEXT:   $x17 = COPY [[UV2]](s32)
165   ; ILP32-NEXT:   PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32_lp64, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
166   ; ILP32-NEXT:   ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
167   ; ILP32-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
168   ; ILP32-NEXT:   $x10 = COPY [[COPY1]](s32)
169   ; ILP32-NEXT:   PseudoRET implicit $x10
170   ;
171   ; ILP32F-LABEL: name: caller_many_scalars
172   ; ILP32F: bb.1 (%ir-block.0):
173   ; ILP32F-NEXT:   [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
174   ; ILP32F-NEXT:   [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
175   ; ILP32F-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
176   ; ILP32F-NEXT:   [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
177   ; ILP32F-NEXT:   [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
178   ; ILP32F-NEXT:   [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
179   ; ILP32F-NEXT:   [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
180   ; ILP32F-NEXT:   [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
181   ; ILP32F-NEXT:   ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
182   ; ILP32F-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
183   ; ILP32F-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
184   ; ILP32F-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
185   ; ILP32F-NEXT:   [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
186   ; ILP32F-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x2
187   ; ILP32F-NEXT:   [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
188   ; ILP32F-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
189   ; ILP32F-NEXT:   G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
190   ; ILP32F-NEXT:   [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
191   ; ILP32F-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
192   ; ILP32F-NEXT:   G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
193   ; ILP32F-NEXT:   $x10 = COPY [[ANYEXT]](s32)
194   ; ILP32F-NEXT:   $x11 = COPY [[ANYEXT1]](s32)
195   ; ILP32F-NEXT:   $x12 = COPY [[C2]](s32)
196   ; ILP32F-NEXT:   $x13 = COPY [[UV]](s32)
197   ; ILP32F-NEXT:   $x14 = COPY [[UV1]](s32)
198   ; ILP32F-NEXT:   $x15 = COPY [[C4]](s32)
199   ; ILP32F-NEXT:   $x16 = COPY [[C5]](s32)
200   ; ILP32F-NEXT:   $x17 = COPY [[UV2]](s32)
201   ; ILP32F-NEXT:   PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
202   ; ILP32F-NEXT:   ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
203   ; ILP32F-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
204   ; ILP32F-NEXT:   $x10 = COPY [[COPY1]](s32)
205   ; ILP32F-NEXT:   PseudoRET implicit $x10
206   ;
207   ; ILP32D-LABEL: name: caller_many_scalars
208   ; ILP32D: bb.1 (%ir-block.0):
209   ; ILP32D-NEXT:   [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
210   ; ILP32D-NEXT:   [[C1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
211   ; ILP32D-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
212   ; ILP32D-NEXT:   [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
213   ; ILP32D-NEXT:   [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
214   ; ILP32D-NEXT:   [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
215   ; ILP32D-NEXT:   [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 7
216   ; ILP32D-NEXT:   [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
217   ; ILP32D-NEXT:   ADJCALLSTACKDOWN 8, 0, implicit-def $x2, implicit $x2
218   ; ILP32D-NEXT:   [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s8)
219   ; ILP32D-NEXT:   [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[C1]](s16)
220   ; ILP32D-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C3]](s64)
221   ; ILP32D-NEXT:   [[UV2:%[0-9]+]]:_(s32), [[UV3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C6]](s64)
222   ; ILP32D-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x2
223   ; ILP32D-NEXT:   [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
224   ; ILP32D-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C8]](s32)
225   ; ILP32D-NEXT:   G_STORE [[UV3]](s32), [[PTR_ADD]](p0) :: (store (s32) into stack, align 16)
226   ; ILP32D-NEXT:   [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
227   ; ILP32D-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C9]](s32)
228   ; ILP32D-NEXT:   G_STORE [[C7]](s32), [[PTR_ADD1]](p0) :: (store (s32) into stack + 4)
229   ; ILP32D-NEXT:   $x10 = COPY [[ANYEXT]](s32)
230   ; ILP32D-NEXT:   $x11 = COPY [[ANYEXT1]](s32)
231   ; ILP32D-NEXT:   $x12 = COPY [[C2]](s32)
232   ; ILP32D-NEXT:   $x13 = COPY [[UV]](s32)
233   ; ILP32D-NEXT:   $x14 = COPY [[UV1]](s32)
234   ; ILP32D-NEXT:   $x15 = COPY [[C4]](s32)
235   ; ILP32D-NEXT:   $x16 = COPY [[C5]](s32)
236   ; ILP32D-NEXT:   $x17 = COPY [[UV2]](s32)
237   ; ILP32D-NEXT:   PseudoCALL target-flags(riscv-call) @callee_many_scalars, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10, implicit $x11, implicit $x12, implicit $x13, implicit $x14, implicit $x15, implicit $x16, implicit $x17, implicit-def $x10
238   ; ILP32D-NEXT:   ADJCALLSTACKUP 8, 0, implicit-def $x2, implicit $x2
239   ; ILP32D-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x10
240   ; ILP32D-NEXT:   $x10 = COPY [[COPY1]](s32)
241   ; ILP32D-NEXT:   PseudoRET implicit $x10
242   %1 = call i32 @callee_many_scalars(i8 1, i16 2, i32 3, i64 4, i32 5, i32 6, i64 7, i32 8)
243   ret i32 %1
246 ; Check return of 2x xlen scalars
248 define i64 @callee_small_scalar_ret() nounwind {
249   ; RV32I-LABEL: name: callee_small_scalar_ret
250   ; RV32I: bb.1 (%ir-block.0):
251   ; RV32I-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1234567898765
252   ; RV32I-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[C]](s64)
253   ; RV32I-NEXT:   $x10 = COPY [[UV]](s32)
254   ; RV32I-NEXT:   $x11 = COPY [[UV1]](s32)
255   ; RV32I-NEXT:   PseudoRET implicit $x10, implicit $x11
256   ret i64 1234567898765
259 define i32 @caller_small_scalar_ret() nounwind {
260   ; ILP32-LABEL: name: caller_small_scalar_ret
261   ; ILP32: bb.1 (%ir-block.0):
262   ; ILP32-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
263   ; ILP32-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
264   ; ILP32-NEXT:   PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
265   ; ILP32-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
266   ; ILP32-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
267   ; ILP32-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
268   ; ILP32-NEXT:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
269   ; ILP32-NEXT:   [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
270   ; ILP32-NEXT:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
271   ; ILP32-NEXT:   $x10 = COPY [[ZEXT]](s32)
272   ; ILP32-NEXT:   PseudoRET implicit $x10
273   ;
274   ; ILP32F-LABEL: name: caller_small_scalar_ret
275   ; ILP32F: bb.1 (%ir-block.0):
276   ; ILP32F-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
277   ; ILP32F-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
278   ; ILP32F-NEXT:   PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit-def $x10, implicit-def $x11
279   ; ILP32F-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
280   ; ILP32F-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
281   ; ILP32F-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
282   ; ILP32F-NEXT:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
283   ; ILP32F-NEXT:   [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
284   ; ILP32F-NEXT:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
285   ; ILP32F-NEXT:   $x10 = COPY [[ZEXT]](s32)
286   ; ILP32F-NEXT:   PseudoRET implicit $x10
287   ;
288   ; ILP32D-LABEL: name: caller_small_scalar_ret
289   ; ILP32D: bb.1 (%ir-block.0):
290   ; ILP32D-NEXT:   [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 987654321234567
291   ; ILP32D-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
292   ; ILP32D-NEXT:   PseudoCALL target-flags(riscv-call) @callee_small_scalar_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $x10, implicit-def $x11
293   ; ILP32D-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
294   ; ILP32D-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
295   ; ILP32D-NEXT:   [[COPY1:%[0-9]+]]:_(s32) = COPY $x11
296   ; ILP32D-NEXT:   [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY]](s32), [[COPY1]](s32)
297   ; ILP32D-NEXT:   [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[C]](s64), [[MV]]
298   ; ILP32D-NEXT:   [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP]](s1)
299   ; ILP32D-NEXT:   $x10 = COPY [[ZEXT]](s32)
300   ; ILP32D-NEXT:   PseudoRET implicit $x10
301   %1 = call i64 @callee_small_scalar_ret()
302   %2 = icmp eq i64 987654321234567, %1
303   %3 = zext i1 %2 to i32
304   ret i32 %3
307 ; Check return of 2x xlen structs
309 %struct.small = type { i32, ptr }
311 define %struct.small @callee_small_struct_ret() nounwind {
312   ; RV32I-LABEL: name: callee_small_struct_ret
313   ; RV32I: bb.1 (%ir-block.0):
314   ; RV32I-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
315   ; RV32I-NEXT:   [[C1:%[0-9]+]]:_(p0) = G_CONSTANT i32 0
316   ; RV32I-NEXT:   $x10 = COPY [[C]](s32)
317   ; RV32I-NEXT:   $x11 = COPY [[C1]](p0)
318   ; RV32I-NEXT:   PseudoRET implicit $x10, implicit $x11
319   ret %struct.small { i32 1, ptr null }
322 define i32 @caller_small_struct_ret() nounwind {
323   ; ILP32-LABEL: name: caller_small_struct_ret
324   ; ILP32: bb.1 (%ir-block.0):
325   ; ILP32-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
326   ; ILP32-NEXT:   PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32_lp64, implicit-def $x1, implicit-def $x10, implicit-def $x11
327   ; ILP32-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
328   ; ILP32-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
329   ; ILP32-NEXT:   [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
330   ; ILP32-NEXT:   [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
331   ; ILP32-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
332   ; ILP32-NEXT:   $x10 = COPY [[ADD]](s32)
333   ; ILP32-NEXT:   PseudoRET implicit $x10
334   ;
335   ; ILP32F-LABEL: name: caller_small_struct_ret
336   ; ILP32F: bb.1 (%ir-block.0):
337   ; ILP32F-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
338   ; ILP32F-NEXT:   PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit-def $x10, implicit-def $x11
339   ; ILP32F-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
340   ; ILP32F-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
341   ; ILP32F-NEXT:   [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
342   ; ILP32F-NEXT:   [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
343   ; ILP32F-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
344   ; ILP32F-NEXT:   $x10 = COPY [[ADD]](s32)
345   ; ILP32F-NEXT:   PseudoRET implicit $x10
346   ;
347   ; ILP32D-LABEL: name: caller_small_struct_ret
348   ; ILP32D: bb.1 (%ir-block.0):
349   ; ILP32D-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
350   ; ILP32D-NEXT:   PseudoCALL target-flags(riscv-call) @callee_small_struct_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit-def $x10, implicit-def $x11
351   ; ILP32D-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
352   ; ILP32D-NEXT:   [[COPY:%[0-9]+]]:_(s32) = COPY $x10
353   ; ILP32D-NEXT:   [[COPY1:%[0-9]+]]:_(p0) = COPY $x11
354   ; ILP32D-NEXT:   [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[COPY1]](p0)
355   ; ILP32D-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[PTRTOINT]]
356   ; ILP32D-NEXT:   $x10 = COPY [[ADD]](s32)
357   ; ILP32D-NEXT:   PseudoRET implicit $x10
358   %1 = call %struct.small @callee_small_struct_ret()
359   %2 = extractvalue %struct.small %1, 0
360   %3 = extractvalue %struct.small %1, 1
361   %4 = ptrtoint ptr %3 to i32
362   %5 = add i32 %2, %4
363   ret i32 %5
366 ; Check return of >2x xlen structs
368 %struct.large = type { i32, i32, i32, i32 }
370 define void @callee_large_struct_ret(ptr noalias sret(%struct.large) %agg.result) nounwind {
371   ; RV32I-LABEL: name: callee_large_struct_ret
372   ; RV32I: bb.1 (%ir-block.0):
373   ; RV32I-NEXT:   liveins: $x10
374   ; RV32I-NEXT: {{  $}}
375   ; RV32I-NEXT:   [[COPY:%[0-9]+]]:_(p0) = COPY $x10
376   ; RV32I-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
377   ; RV32I-NEXT:   [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
378   ; RV32I-NEXT:   [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
379   ; RV32I-NEXT:   [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
380   ; RV32I-NEXT:   G_STORE [[C]](s32), [[COPY]](p0) :: (store (s32) into %ir.agg.result)
381   ; RV32I-NEXT:   [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
382   ; RV32I-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[COPY]], [[C4]](s32)
383   ; RV32I-NEXT:   G_STORE [[C1]](s32), [[PTR_ADD]](p0) :: (store (s32) into %ir.b)
384   ; RV32I-NEXT:   [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
385   ; RV32I-NEXT:   [[PTR_ADD1:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[COPY]], [[C5]](s32)
386   ; RV32I-NEXT:   G_STORE [[C2]](s32), [[PTR_ADD1]](p0) :: (store (s32) into %ir.c)
387   ; RV32I-NEXT:   [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
388   ; RV32I-NEXT:   [[PTR_ADD2:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[COPY]], [[C6]](s32)
389   ; RV32I-NEXT:   G_STORE [[C3]](s32), [[PTR_ADD2]](p0) :: (store (s32) into %ir.d)
390   ; RV32I-NEXT:   PseudoRET
391   store i32 1, ptr %agg.result, align 4
392   %b = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 1
393   store i32 2, ptr %b, align 4
394   %c = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 2
395   store i32 3, ptr %c, align 4
396   %d = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 3
397   store i32 4, ptr %d, align 4
398   ret void
401 define i32 @caller_large_struct_ret() nounwind {
402   ; ILP32-LABEL: name: caller_large_struct_ret
403   ; ILP32: bb.1 (%ir-block.0):
404   ; ILP32-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
405   ; ILP32-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
406   ; ILP32-NEXT:   $x10 = COPY [[FRAME_INDEX]](p0)
407   ; ILP32-NEXT:   PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32_lp64, implicit-def $x1, implicit $x10
408   ; ILP32-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
409   ; ILP32-NEXT:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
410   ; ILP32-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
411   ; ILP32-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
412   ; ILP32-NEXT:   [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
413   ; ILP32-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
414   ; ILP32-NEXT:   $x10 = COPY [[ADD]](s32)
415   ; ILP32-NEXT:   PseudoRET implicit $x10
416   ;
417   ; ILP32F-LABEL: name: caller_large_struct_ret
418   ; ILP32F: bb.1 (%ir-block.0):
419   ; ILP32F-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
420   ; ILP32F-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
421   ; ILP32F-NEXT:   $x10 = COPY [[FRAME_INDEX]](p0)
422   ; ILP32F-NEXT:   PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32f_lp64f, implicit-def $x1, implicit $x10
423   ; ILP32F-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
424   ; ILP32F-NEXT:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
425   ; ILP32F-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
426   ; ILP32F-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
427   ; ILP32F-NEXT:   [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
428   ; ILP32F-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
429   ; ILP32F-NEXT:   $x10 = COPY [[ADD]](s32)
430   ; ILP32F-NEXT:   PseudoRET implicit $x10
431   ;
432   ; ILP32D-LABEL: name: caller_large_struct_ret
433   ; ILP32D: bb.1 (%ir-block.0):
434   ; ILP32D-NEXT:   [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
435   ; ILP32D-NEXT:   ADJCALLSTACKDOWN 0, 0, implicit-def $x2, implicit $x2
436   ; ILP32D-NEXT:   $x10 = COPY [[FRAME_INDEX]](p0)
437   ; ILP32D-NEXT:   PseudoCALL target-flags(riscv-call) @callee_large_struct_ret, csr_ilp32d_lp64d, implicit-def $x1, implicit $x10
438   ; ILP32D-NEXT:   ADJCALLSTACKUP 0, 0, implicit-def $x2, implicit $x2
439   ; ILP32D-NEXT:   [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load (s32) from %ir.1)
440   ; ILP32D-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
441   ; ILP32D-NEXT:   [[PTR_ADD:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[FRAME_INDEX]], [[C]](s32)
442   ; ILP32D-NEXT:   [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0) :: (dereferenceable load (s32) from %ir.3)
443   ; ILP32D-NEXT:   [[ADD:%[0-9]+]]:_(s32) = G_ADD [[LOAD]], [[LOAD1]]
444   ; ILP32D-NEXT:   $x10 = COPY [[ADD]](s32)
445   ; ILP32D-NEXT:   PseudoRET implicit $x10
446   %1 = alloca %struct.large
447   call void @callee_large_struct_ret(ptr sret(%struct.large) %1)
448   %2 = load i32, ptr %1
449   %3 = getelementptr inbounds %struct.large, ptr %1, i32 0, i32 3
450   %4 = load i32, ptr %3
451   %5 = add i32 %2, %4
452   ret i32 %5