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