llvm.org GIT mirror llvm / 62531b9
[RISCV] Add codegen support for ilp32f, ilp32d, lp64f, and lp64d ("hard float") ABIs This patch adds support for the RISC-V hard float ABIs, building on top of rL355771, which added basic target-abi parsing and MC layer support. It also builds on some re-organisations and expansion of the upstream ABI and calling convention tests which were recently committed directly upstream. A number of aspects of the RISC-V float hard float ABIs require frontend support (e.g. flattening of structs and passing int+fp for fp+fp structs in a pair of registers), and will be addressed in a Clang patch. As can be seen from the tests, it would be worthwhile extending RISCVMergeBaseOffsets to handle constant pool as well as global accesses. Differential Revision: https://reviews.llvm.org/D59357 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357352 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Bradbury 1 year, 8 months ago
14 changed file(s) with 870 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
1414
1515 def CSR_ILP32_LP64
1616 : CalleeSavedRegs<(add X1, X3, X4, X8, X9, (sequence "X%u", 18, 27))>;
17
18 def CSR_ILP32F_LP64F
19 : CalleeSavedRegs<(add CSR_ILP32_LP64,
20 F8_32, F9_32, (sequence "F%u_32", 18, 27))>;
21
22 def CSR_ILP32D_LP64D
23 : CalleeSavedRegs<(add CSR_ILP32_LP64,
24 F8_64, F9_64, (sequence "F%u_64", 18, 27))>;
1725
1826 // Needed for implementation of RISCVRegisterInfo::getNoPreservedMask()
1927 def CSR_NoRegs : CalleeSavedRegs<(add)>;
4848 RISCVABI::ABI ABI = Subtarget.getTargetABI();
4949 assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI");
5050
51 if (ABI != RISCVABI::ABI_ILP32 && ABI != RISCVABI::ABI_LP64)
51 switch (ABI) {
52 default:
5253 report_fatal_error("Don't know how to lower this ABI");
54 case RISCVABI::ABI_ILP32:
55 case RISCVABI::ABI_ILP32F:
56 case RISCVABI::ABI_ILP32D:
57 case RISCVABI::ABI_LP64:
58 case RISCVABI::ABI_LP64F:
59 case RISCVABI::ABI_LP64D:
60 break;
61 }
5362
5463 MVT XLenVT = Subtarget.getXLenVT();
5564
980989 RISCV::X10, RISCV::X11, RISCV::X12, RISCV::X13,
981990 RISCV::X14, RISCV::X15, RISCV::X16, RISCV::X17
982991 };
992 static const MCPhysReg ArgFPR32s[] = {
993 RISCV::F10_32, RISCV::F11_32, RISCV::F12_32, RISCV::F13_32,
994 RISCV::F14_32, RISCV::F15_32, RISCV::F16_32, RISCV::F17_32
995 };
996 static const MCPhysReg ArgFPR64s[] = {
997 RISCV::F10_64, RISCV::F11_64, RISCV::F12_64, RISCV::F13_64,
998 RISCV::F14_64, RISCV::F15_64, RISCV::F16_64, RISCV::F17_64
999 };
9831000
9841001 // Pass a 2*XLEN argument that has been split into two XLEN values through
9851002 // registers or the stack as necessary.
10201037 }
10211038
10221039 // Implements the RISC-V calling convention. Returns true upon failure.
1023 static bool CC_RISCV(const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT,
1024 CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
1025 CCState &State, bool IsFixed, bool IsRet, Type *OrigTy) {
1040 static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
1041 MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo,
1042 ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed,
1043 bool IsRet, Type *OrigTy) {
10261044 unsigned XLen = DL.getLargestLegalIntTypeSizeInBits();
10271045 assert(XLen == 32 || XLen == 64);
10281046 MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64;
10321050 if (IsRet && ValNo > 1)
10331051 return true;
10341052
1035 if (ValVT == MVT::f32) {
1053 // UseGPRForF32 if targeting one of the soft-float ABIs, if passing a
1054 // variadic argument, or if no F32 argument registers are available.
1055 bool UseGPRForF32 = true;
1056 // UseGPRForF64 if targeting soft-float ABIs or an FLEN=32 ABI, if passing a
1057 // variadic argument, or if no F64 argument registers are available.
1058 bool UseGPRForF64 = true;
1059
1060 switch (ABI) {
1061 default:
1062 llvm_unreachable("Unexpected ABI");
1063 case RISCVABI::ABI_ILP32:
1064 case RISCVABI::ABI_LP64:
1065 break;
1066 case RISCVABI::ABI_ILP32F:
1067 case RISCVABI::ABI_LP64F:
1068 UseGPRForF32 = !IsFixed;
1069 break;
1070 case RISCVABI::ABI_ILP32D:
1071 case RISCVABI::ABI_LP64D:
1072 UseGPRForF32 = !IsFixed;
1073 UseGPRForF64 = !IsFixed;
1074 break;
1075 }
1076
1077 if (State.getFirstUnallocated(ArgFPR32s) == array_lengthof(ArgFPR32s))
1078 UseGPRForF32 = true;
1079 if (State.getFirstUnallocated(ArgFPR64s) == array_lengthof(ArgFPR64s))
1080 UseGPRForF64 = true;
1081
1082 // From this point on, rely on UseGPRForF32, UseGPRForF64 and similar local
1083 // variables rather than directly checking against the target ABI.
1084
1085 if (UseGPRForF32 && ValVT == MVT::f32) {
10361086 LocVT = XLenVT;
10371087 LocInfo = CCValAssign::BCvt;
1038 } else if (XLen == 64 && ValVT == MVT::f64) {
1088 } else if (UseGPRForF64 && XLen == 64 && ValVT == MVT::f64) {
10391089 LocVT = MVT::i64;
10401090 LocInfo = CCValAssign::BCvt;
10411091 }
10631113 assert(PendingLocs.size() == PendingArgFlags.size() &&
10641114 "PendingLocs and PendingArgFlags out of sync");
10651115
1066 // Handle passing f64 on RV32D with a soft float ABI.
1067 if (XLen == 32 && ValVT == MVT::f64) {
1116 // Handle passing f64 on RV32D with a soft float ABI or when floating point
1117 // registers are exhausted.
1118 if (UseGPRForF64 && XLen == 32 && ValVT == MVT::f64) {
10681119 assert(!ArgFlags.isSplit() && PendingLocs.empty() &&
10691120 "Can't lower f64 if it is split");
10701121 // Depending on available argument GPRS, f64 may be passed in a pair of
11131164 }
11141165
11151166 // Allocate to a register if possible, or else a stack slot.
1116 unsigned Reg = State.AllocateReg(ArgGPRs);
1167 unsigned Reg;
1168 if (ValVT == MVT::f32 && !UseGPRForF32)
1169 Reg = State.AllocateReg(ArgFPR32s, ArgFPR64s);
1170 else if (ValVT == MVT::f64 && !UseGPRForF64)
1171 Reg = State.AllocateReg(ArgFPR64s, ArgFPR32s);
1172 else
1173 Reg = Reg = State.AllocateReg(ArgGPRs);
11171174 unsigned StackOffset = Reg ? 0 : State.AllocateStack(XLen / 8, XLen / 8);
11181175
11191176 // If we reach this point and PendingLocs is non-empty, we must be at the
11341191 return false;
11351192 }
11361193
1137 assert(LocVT == XLenVT && "Expected an XLenVT at this stage");
1194 assert((!UseGPRForF32 || !UseGPRForF64 || LocVT == XLenVT) &&
1195 "Expected an XLenVT at this stage");
11381196
11391197 if (Reg) {
11401198 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
11661224 else if (Ins[i].isOrigArg())
11671225 ArgTy = FType->getParamType(Ins[i].getOrigArgIndex());
11681226
1169 if (CC_RISCV(MF.getDataLayout(), i, ArgVT, ArgVT, CCValAssign::Full,
1227 RISCVABI::ABI ABI = MF.getSubtarget().getTargetABI();
1228 if (CC_RISCV(MF.getDataLayout(), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
11701229 ArgFlags, CCInfo, /*IsRet=*/true, IsRet, ArgTy)) {
11711230 LLVM_DEBUG(dbgs() << "InputArg #" << i << " has unhandled type "
11721231 << EVT(ArgVT).getEVTString() << '\n');
11861245 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
11871246 Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty : nullptr;
11881247
1189 if (CC_RISCV(MF.getDataLayout(), i, ArgVT, ArgVT, CCValAssign::Full,
1248 RISCVABI::ABI ABI = MF.getSubtarget().getTargetABI();
1249 if (CC_RISCV(MF.getDataLayout(), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
11901250 ArgFlags, CCInfo, Outs[i].IsFixed, IsRet, OrigTy)) {
11911251 LLVM_DEBUG(dbgs() << "OutputArg #" << i << " has unhandled type "
11921252 << EVT(ArgVT).getEVTString() << "\n");
12231283 MachineRegisterInfo &RegInfo = MF.getRegInfo();
12241284 EVT LocVT = VA.getLocVT();
12251285 SDValue Val;
1226
1227 unsigned VReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
1286 const TargetRegisterClass *RC;
1287
1288 switch (LocVT.getSimpleVT().SimpleTy) {
1289 default:
1290 llvm_unreachable("Unexpected register type");
1291 case MVT::i32:
1292 case MVT::i64:
1293 RC = &RISCV::GPRRegClass;
1294 break;
1295 case MVT::f32:
1296 RC = &RISCV::FPR32RegClass;
1297 break;
1298 case MVT::f64:
1299 RC = &RISCV::FPR64RegClass;
1300 break;
1301 }
1302
1303 unsigned VReg = RegInfo.createVirtualRegister(RC);
12281304 RegInfo.addLiveIn(VA.getLocReg(), VReg);
12291305 Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
12301306
18011877 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
18021878 MVT VT = Outs[i].VT;
18031879 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
1804 if (CC_RISCV(MF.getDataLayout(), i, VT, VT, CCValAssign::Full, ArgFlags,
1805 CCInfo, /*IsFixed=*/true, /*IsRet=*/true, nullptr))
1880 RISCVABI::ABI ABI = MF.getSubtarget().getTargetABI();
1881 if (CC_RISCV(MF.getDataLayout(), ABI, i, VT, VT, CCValAssign::Full,
1882 ArgFlags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true, nullptr))
18061883 return false;
18071884 }
18081885 return true;
3939 return CSR_XLEN_F32_Interrupt_SaveList;
4040 return CSR_Interrupt_SaveList;
4141 }
42 return CSR_ILP32_LP64_SaveList;
42
43 switch (Subtarget.getTargetABI()) {
44 default:
45 llvm_unreachable("Unrecognized ABI");
46 case RISCVABI::ABI_ILP32:
47 case RISCVABI::ABI_LP64:
48 return CSR_ILP32_LP64_SaveList;
49 case RISCVABI::ABI_ILP32F:
50 case RISCVABI::ABI_LP64F:
51 return CSR_ILP32F_LP64F_SaveList;
52 case RISCVABI::ABI_ILP32D:
53 case RISCVABI::ABI_LP64D:
54 return CSR_ILP32D_LP64D_SaveList;
55 }
4356 }
4457
4558 BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
126139 return CSR_XLEN_F32_Interrupt_RegMask;
127140 return CSR_Interrupt_RegMask;
128141 }
129 return CSR_ILP32_LP64_RegMask;
142
143 switch (Subtarget.getTargetABI()) {
144 default:
145 llvm_unreachable("Unrecognized ABI");
146 case RISCVABI::ABI_ILP32:
147 case RISCVABI::ABI_LP64:
148 return CSR_ILP32_LP64_RegMask;
149 case RISCVABI::ABI_ILP32F:
150 case RISCVABI::ABI_LP64F:
151 return CSR_ILP32F_LP64F_RegMask;
152 case RISCVABI::ABI_ILP32D:
153 case RISCVABI::ABI_LP64D:
154 return CSR_ILP32D_LP64D_RegMask;
155 }
130156 }
11 ; RUN: | FileCheck %s -check-prefix=ILP32-LP64
22 ; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
33 ; RUN: | FileCheck %s -check-prefix=ILP32-LP64
4 ; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefix=ILP32F-LP64F
6 ; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi lp64f -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s -check-prefix=ILP32F-LP64F
8 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d -verify-machineinstrs < %s \
9 ; RUN: | FileCheck %s -check-prefix=ILP32D-LP64D
10 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d -verify-machineinstrs < %s \
11 ; RUN: | FileCheck %s -check-prefix=ILP32D-LP64D
412
513 @var = global [32 x float] zeroinitializer
614
715 ; All floating point registers are temporaries for the ilp32 and lp64 ABIs.
16 ; fs0-fs11 are callee-saved for the ilp32f, ilp32d, lp64f, and lp64d ABIs.
817
918 ; This function tests that RISCVRegisterInfo::getCalleeSavedRegs returns
1019 ; something appropriate.
7988 ; ILP32-LP64-NEXT: fsw ft1, 4(a1)
8089 ; ILP32-LP64-NEXT: fsw ft0, %lo(var)(a0)
8190 ; ILP32-LP64-NEXT: ret
91 ;
92 ; ILP32F-LP64F-LABEL: callee:
93 ; ILP32F-LP64F: # %bb.0:
94 ; ILP32F-LP64F-NEXT: addi sp, sp, -48
95 ; ILP32F-LP64F-NEXT: fsw fs0, 44(sp)
96 ; ILP32F-LP64F-NEXT: fsw fs1, 40(sp)
97 ; ILP32F-LP64F-NEXT: fsw fs2, 36(sp)
98 ; ILP32F-LP64F-NEXT: fsw fs3, 32(sp)
99 ; ILP32F-LP64F-NEXT: fsw fs4, 28(sp)
100 ; ILP32F-LP64F-NEXT: fsw fs5, 24(sp)
101 ; ILP32F-LP64F-NEXT: fsw fs6, 20(sp)
102 ; ILP32F-LP64F-NEXT: fsw fs7, 16(sp)
103 ; ILP32F-LP64F-NEXT: fsw fs8, 12(sp)
104 ; ILP32F-LP64F-NEXT: fsw fs9, 8(sp)
105 ; ILP32F-LP64F-NEXT: fsw fs10, 4(sp)
106 ; ILP32F-LP64F-NEXT: fsw fs11, 0(sp)
107 ; ILP32F-LP64F-NEXT: lui a0, %hi(var)
108 ; ILP32F-LP64F-NEXT: addi a1, a0, %lo(var)
109 ;
110 ; ILP32D-LP64D-LABEL: callee:
111 ; ILP32D-LP64D: # %bb.0:
112 ; ILP32D-LP64D-NEXT: addi sp, sp, -96
113 ; ILP32D-LP64D-NEXT: fsd fs0, 88(sp)
114 ; ILP32D-LP64D-NEXT: fsd fs1, 80(sp)
115 ; ILP32D-LP64D-NEXT: fsd fs2, 72(sp)
116 ; ILP32D-LP64D-NEXT: fsd fs3, 64(sp)
117 ; ILP32D-LP64D-NEXT: fsd fs4, 56(sp)
118 ; ILP32D-LP64D-NEXT: fsd fs5, 48(sp)
119 ; ILP32D-LP64D-NEXT: fsd fs6, 40(sp)
120 ; ILP32D-LP64D-NEXT: fsd fs7, 32(sp)
121 ; ILP32D-LP64D-NEXT: fsd fs8, 24(sp)
122 ; ILP32D-LP64D-NEXT: fsd fs9, 16(sp)
123 ; ILP32D-LP64D-NEXT: fsd fs10, 8(sp)
124 ; ILP32D-LP64D-NEXT: fsd fs11, 0(sp)
125 ; ILP32D-LP64D-NEXT: lui a0, %hi(var)
126 ; ILP32D-LP64D-NEXT: addi a1, a0, %lo(var)
82127 %val = load [32 x float], [32 x float]* @var
83128 store volatile [32 x float] %val, [32 x float]* @var
84129 ret void
88133 ; something appropriate.
89134 ;
90135 ; For the soft float ABIs, no floating point registers are preserved, and
91 ; codegen will use only ft0 in the body of caller.
136 ; codegen will use only ft0 in the body of caller. For the 'f' and 'd ABIs,
137 ; fs0-fs11 are preserved across calls.
92138
93139 define void @caller() {
94140 ; ILP32-LP64-LABEL: caller:
95141 ; ILP32-LP64-NOT: ft{{[1-9][0-9]*}}
96142 ; ILP32-LP64-NOT: fs{{[0-9]+}}
97143 ; ILP32-LP64-NOT: fa{{[0-9]+}}
98 ; ILP32-LP64: ret
144 ; ILP32-LP64: call callee
99145 ; ILP32-LP64-NOT: ft{{[1-9][0-9]*}}
100146 ; ILP32-LP64-NOT: fs{{[0-9]+}}
101147 ; ILP32-LP64-NOT: fa{{[0-9]+}}
148 ; ILP32-LP64: ret
149 ;
150 ; ILP32F-LP64F-LABEL: caller:
151 ; ILP32F-LP64F: flw fs8, 80(s1)
152 ; ILP32F-LP64F-NEXT: flw fs9, 84(s1)
153 ; ILP32F-LP64F-NEXT: flw fs10, 88(s1)
154 ; ILP32F-LP64F-NEXT: flw fs11, 92(s1)
155 ; ILP32F-LP64F-NEXT: flw fs0, 96(s1)
156 ; ILP32F-LP64F-NEXT: flw fs1, 100(s1)
157 ; ILP32F-LP64F-NEXT: flw fs2, 104(s1)
158 ; ILP32F-LP64F-NEXT: flw fs3, 108(s1)
159 ; ILP32F-LP64F-NEXT: flw fs4, 112(s1)
160 ; ILP32F-LP64F-NEXT: flw fs5, 116(s1)
161 ; ILP32F-LP64F-NEXT: flw fs6, 120(s1)
162 ; ILP32F-LP64F-NEXT: flw fs7, 124(s1)
163 ; ILP32F-LP64F-NEXT: call callee
164 ; ILP32F-LP64F-NEXT: fsw fs7, 124(s1)
165 ; ILP32F-LP64F-NEXT: fsw fs6, 120(s1)
166 ; ILP32F-LP64F-NEXT: fsw fs5, 116(s1)
167 ; ILP32F-LP64F-NEXT: fsw fs4, 112(s1)
168 ; ILP32F-LP64F-NEXT: fsw fs3, 108(s1)
169 ; ILP32F-LP64F-NEXT: fsw fs2, 104(s1)
170 ; ILP32F-LP64F-NEXT: fsw fs1, 100(s1)
171 ; ILP32F-LP64F-NEXT: fsw fs0, 96(s1)
172 ; ILP32F-LP64F-NEXT: fsw fs11, 92(s1)
173 ; ILP32F-LP64F-NEXT: fsw fs10, 88(s1)
174 ; ILP32F-LP64F-NEXT: fsw fs9, 84(s1)
175 ; ILP32F-LP64F-NEXT: fsw fs8, 80(s1)
176 ; ILP32F-LP64F-NEXT: lw ft0, {{[0-9]+}}(sp)
177 ;
178 ; ILP32D-LP64D-LABEL: caller:
179 ; ILP32D-LP64D: flw fs8, 80(s1)
180 ; ILP32D-LP64D-NEXT: flw fs9, 84(s1)
181 ; ILP32D-LP64D-NEXT: flw fs10, 88(s1)
182 ; ILP32D-LP64D-NEXT: flw fs11, 92(s1)
183 ; ILP32D-LP64D-NEXT: flw fs0, 96(s1)
184 ; ILP32D-LP64D-NEXT: flw fs1, 100(s1)
185 ; ILP32D-LP64D-NEXT: flw fs2, 104(s1)
186 ; ILP32D-LP64D-NEXT: flw fs3, 108(s1)
187 ; ILP32D-LP64D-NEXT: flw fs4, 112(s1)
188 ; ILP32D-LP64D-NEXT: flw fs5, 116(s1)
189 ; ILP32D-LP64D-NEXT: flw fs6, 120(s1)
190 ; ILP32D-LP64D-NEXT: flw fs7, 124(s1)
191 ; ILP32D-LP64D-NEXT: call callee
192 ; ILP32D-LP64D-NEXT: fsw fs7, 124(s1)
193 ; ILP32D-LP64D-NEXT: fsw fs6, 120(s1)
194 ; ILP32D-LP64D-NEXT: fsw fs5, 116(s1)
195 ; ILP32D-LP64D-NEXT: fsw fs4, 112(s1)
196 ; ILP32D-LP64D-NEXT: fsw fs3, 108(s1)
197 ; ILP32D-LP64D-NEXT: fsw fs2, 104(s1)
198 ; ILP32D-LP64D-NEXT: fsw fs1, 100(s1)
199 ; ILP32D-LP64D-NEXT: fsw fs0, 96(s1)
200 ; ILP32D-LP64D-NEXT: fsw fs11, 92(s1)
201 ; ILP32D-LP64D-NEXT: fsw fs10, 88(s1)
202 ; ILP32D-LP64D-NEXT: fsw fs9, 84(s1)
203 ; ILP32D-LP64D-NEXT: fsw fs8, 80(s1)
204 ; ILP32D-LP64D-NEXT: flw ft0, {{[0-9]+}}(sp)
102205 %val = load [32 x float], [32 x float]* @var
103206 call void @callee()
104207 store volatile [32 x float] %val, [32 x float]* @var
None ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
21 ; RUN: | FileCheck %s -check-prefix=ILP32-LP64
32 ; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
43 ; RUN: | FileCheck %s -check-prefix=ILP32-LP64
4 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefix=ILP32D-LP64D
6 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s -check-prefix=ILP32D-LP64D
58
69 @var = global [32 x double] zeroinitializer
710
811 ; All floating point registers are temporaries for the ilp32 and lp64 ABIs.
12 ; fs0-fs11 are callee-saved for the ilp32f, ilp32d, lp64f, and lp64d ABIs.
913
1014 ; This function tests that RISCVRegisterInfo::getCalleeSavedRegs returns
1115 ; something appropriate.
8084 ; ILP32-LP64-NEXT: fsd ft1, 8(a1)
8185 ; ILP32-LP64-NEXT: fsd ft0, %lo(var)(a0)
8286 ; ILP32-LP64-NEXT: ret
87 ;
88 ; ILP32D-LP64D-LABEL: callee:
89 ; ILP32D-LP64D: # %bb.0:
90 ; ILP32D-LP64D-NEXT: addi sp, sp, -96
91 ; ILP32D-LP64D-NEXT: fsd fs0, 88(sp)
92 ; ILP32D-LP64D-NEXT: fsd fs1, 80(sp)
93 ; ILP32D-LP64D-NEXT: fsd fs2, 72(sp)
94 ; ILP32D-LP64D-NEXT: fsd fs3, 64(sp)
95 ; ILP32D-LP64D-NEXT: fsd fs4, 56(sp)
96 ; ILP32D-LP64D-NEXT: fsd fs5, 48(sp)
97 ; ILP32D-LP64D-NEXT: fsd fs6, 40(sp)
98 ; ILP32D-LP64D-NEXT: fsd fs7, 32(sp)
99 ; ILP32D-LP64D-NEXT: fsd fs8, 24(sp)
100 ; ILP32D-LP64D-NEXT: fsd fs9, 16(sp)
101 ; ILP32D-LP64D-NEXT: fsd fs10, 8(sp)
102 ; ILP32D-LP64D-NEXT: fsd fs11, 0(sp)
103 ; ILP32D-LP64D-NEXT: lui a0, %hi(var)
104 ; ILP32D-LP64D-NEXT: addi a1, a0, %lo(var)
83105 %val = load [32 x double], [32 x double]* @var
84106 store volatile [32 x double] %val, [32 x double]* @var
85107 ret void
89111 ; something appropriate.
90112 ;
91113 ; For the soft float ABIs, no floating point registers are preserved, and
92 ; codegen will use only ft0 in the body of caller.
114 ; codegen will use only ft0 in the body of caller. For the 'f' and 'd ABIs,
115 ; fs0-fs11 are preserved across calls.
93116
94117 define void @caller() {
95118 ; ILP32-LP64-LABEL: caller:
96119 ; ILP32-LP64-NOT: ft{{[1-9][0-9]*}}
97120 ; ILP32-LP64-NOT: fs{{[0-9]+}}
98121 ; ILP32-LP64-NOT: fa{{[0-9]+}}
99 ; ILP32-LP64: ret
122 ; ILP32-LP64: call callee
100123 ; ILP32-LP64-NOT: ft{{[1-9][0-9]*}}
101124 ; ILP32-LP64-NOT: fs{{[0-9]+}}
102125 ; ILP32-LP64-NOT: fa{{[0-9]+}}
126 ; ILP32-LP64: ret
127 ;
128 ; ILP32F-LP64D-LABEL: caller:
129 ; ILP32D-LP64D: fld fs8, 160(s1)
130 ; ILP32D-LP64D-NEXT: fld fs9, 168(s1)
131 ; ILP32D-LP64D-NEXT: fld fs10, 176(s1)
132 ; ILP32D-LP64D-NEXT: fld fs11, 184(s1)
133 ; ILP32D-LP64D-NEXT: fld fs0, 192(s1)
134 ; ILP32D-LP64D-NEXT: fld fs1, 200(s1)
135 ; ILP32D-LP64D-NEXT: fld fs2, 208(s1)
136 ; ILP32D-LP64D-NEXT: fld fs3, 216(s1)
137 ; ILP32D-LP64D-NEXT: fld fs4, 224(s1)
138 ; ILP32D-LP64D-NEXT: fld fs5, 232(s1)
139 ; ILP32D-LP64D-NEXT: fld fs6, 240(s1)
140 ; ILP32D-LP64D-NEXT: fld fs7, 248(s1)
141 ; ILP32D-LP64D-NEXT: call callee
142 ; ILP32D-LP64D-NEXT: fsd fs7, 248(s1)
143 ; ILP32D-LP64D-NEXT: fsd fs6, 240(s1)
144 ; ILP32D-LP64D-NEXT: fsd fs5, 232(s1)
145 ; ILP32D-LP64D-NEXT: fsd fs4, 224(s1)
146 ; ILP32D-LP64D-NEXT: fsd fs3, 216(s1)
147 ; ILP32D-LP64D-NEXT: fsd fs2, 208(s1)
148 ; ILP32D-LP64D-NEXT: fsd fs1, 200(s1)
149 ; ILP32D-LP64D-NEXT: fsd fs0, 192(s1)
150 ; ILP32D-LP64D-NEXT: fsd fs11, 184(s1)
151 ; ILP32D-LP64D-NEXT: fsd fs10, 176(s1)
152 ; ILP32D-LP64D-NEXT: fsd fs9, 168(s1)
153 ; ILP32D-LP64D-NEXT: fsd fs8, 160(s1)
154 ; ILP32D-LP64D-NEXT: fld ft0, {{[0-9]+}}(sp)
103155 %val = load [32 x double], [32 x double]* @var
104156 call void @callee()
105157 store volatile [32 x double] %val, [32 x double]* @var
0 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
1 ; RUN: | FileCheck %s -check-prefix=RV32I
2 ; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s -check-prefix=RV32I
4 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32f -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefix=RV32I
6 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d -verify-machineinstrs < %s \
17 ; RUN: | FileCheck %s -check-prefix=RV32I
28 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \
39 ; RUN: | FileCheck %s -check-prefix=RV32I-WITH-FP
410 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
11 ; RUN: | FileCheck %s -check-prefix=RV64I
12 ; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi ilp32f -verify-machineinstrs < %s \
13 ; RUN: | FileCheck %s -check-prefix=RV64I
14 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi ilp32f -verify-machineinstrs < %s \
15 ; RUN: | FileCheck %s -check-prefix=RV64I
16 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi ilp32d -verify-machineinstrs < %s \
517 ; RUN: | FileCheck %s -check-prefix=RV64I
618 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs -frame-pointer=all < %s \
719 ; RUN: | FileCheck %s -check-prefix=RV64I-WITH-FP
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
11 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
22 ; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
3 ; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f \
4 ; RUN: -verify-machineinstrs < %s \
5 ; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
36 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \
7 ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
8 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \
9 ; RUN: -mattr=+f -target-abi ilp32f < %s \
410 ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
511
612 ; This file contains tests that should have identical output for the ilp32,
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
11 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
22 ; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
3 ; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f \
4 ; RUN: -verify-machineinstrs < %s \
5 ; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
6 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
7 ; RUN: -verify-machineinstrs < %s \
8 ; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
39 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \
10 ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
11 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \
12 ; RUN: -mattr=+f -target-abi ilp32f < %s \
13 ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
14 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \
15 ; RUN: -mattr=+d -target-abi ilp32d < %s \
416 ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
517
618 ; This file contains tests that should have identical output for the ilp32,
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+d \
2 ; RUN: -target-abi ilp32d < %s \
3 ; RUN: | FileCheck -check-prefix=RV32-ILP32D %s
4
5 ; This file contains tests that will have differing output for the ilp32 and
6 ; ilp32f ABIs.
7
8 define i32 @callee_double_in_fpr(i32 %a, double %b) nounwind {
9 ; RV32-ILP32D-LABEL: callee_double_in_fpr:
10 ; RV32-ILP32D: # %bb.0:
11 ; RV32-ILP32D-NEXT: fcvt.w.d a1, fa0, rtz
12 ; RV32-ILP32D-NEXT: add a0, a0, a1
13 ; RV32-ILP32D-NEXT: ret
14 %b_fptosi = fptosi double %b to i32
15 %1 = add i32 %a, %b_fptosi
16 ret i32 %1
17 }
18
19 define i32 @caller_double_in_fpr() nounwind {
20 ; RV32-ILP32D-LABEL: caller_double_in_fpr:
21 ; RV32-ILP32D: # %bb.0:
22 ; RV32-ILP32D-NEXT: addi sp, sp, -16
23 ; RV32-ILP32D-NEXT: sw ra, 12(sp)
24 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI1_0)
25 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI1_0)
26 ; RV32-ILP32D-NEXT: fld fa0, 0(a0)
27 ; RV32-ILP32D-NEXT: addi a0, zero, 1
28 ; RV32-ILP32D-NEXT: call callee_double_in_fpr
29 ; RV32-ILP32D-NEXT: lw ra, 12(sp)
30 ; RV32-ILP32D-NEXT: addi sp, sp, 16
31 ; RV32-ILP32D-NEXT: ret
32 %1 = call i32 @callee_double_in_fpr(i32 1, double 2.0)
33 ret i32 %1
34 }
35
36 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
37 define i32 @callee_double_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, double %f) nounwind {
38 ; RV32-ILP32D-LABEL: callee_double_in_fpr_exhausted_gprs:
39 ; RV32-ILP32D: # %bb.0:
40 ; RV32-ILP32D-NEXT: fcvt.w.d a0, fa0, rtz
41 ; RV32-ILP32D-NEXT: lw a1, 0(sp)
42 ; RV32-ILP32D-NEXT: add a0, a1, a0
43 ; RV32-ILP32D-NEXT: ret
44 %f_fptosi = fptosi double %f to i32
45 %1 = add i32 %e, %f_fptosi
46 ret i32 %1
47 }
48
49 define i32 @caller_double_in_fpr_exhausted_gprs() nounwind {
50 ; RV32-ILP32D-LABEL: caller_double_in_fpr_exhausted_gprs:
51 ; RV32-ILP32D: # %bb.0:
52 ; RV32-ILP32D-NEXT: addi sp, sp, -16
53 ; RV32-ILP32D-NEXT: sw ra, 12(sp)
54 ; RV32-ILP32D-NEXT: addi a0, zero, 5
55 ; RV32-ILP32D-NEXT: sw a0, 0(sp)
56 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI3_0)
57 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI3_0)
58 ; RV32-ILP32D-NEXT: fld fa0, 0(a0)
59 ; RV32-ILP32D-NEXT: addi a0, zero, 1
60 ; RV32-ILP32D-NEXT: mv a1, zero
61 ; RV32-ILP32D-NEXT: addi a2, zero, 2
62 ; RV32-ILP32D-NEXT: mv a3, zero
63 ; RV32-ILP32D-NEXT: addi a4, zero, 3
64 ; RV32-ILP32D-NEXT: mv a5, zero
65 ; RV32-ILP32D-NEXT: addi a6, zero, 4
66 ; RV32-ILP32D-NEXT: mv a7, zero
67 ; RV32-ILP32D-NEXT: call callee_double_in_fpr_exhausted_gprs
68 ; RV32-ILP32D-NEXT: lw ra, 12(sp)
69 ; RV32-ILP32D-NEXT: addi sp, sp, 16
70 ; RV32-ILP32D-NEXT: ret
71 %1 = call i32 @callee_double_in_fpr_exhausted_gprs(
72 i64 1, i64 2, i64 3, i64 4, i32 5, double 6.0)
73 ret i32 %1
74 }
75
76 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
77 define i32 @callee_double_in_gpr_exhausted_fprs(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i) nounwind {
78 ; RV32-ILP32D-LABEL: callee_double_in_gpr_exhausted_fprs:
79 ; RV32-ILP32D: # %bb.0:
80 ; RV32-ILP32D-NEXT: addi sp, sp, -16
81 ; RV32-ILP32D-NEXT: sw a0, 8(sp)
82 ; RV32-ILP32D-NEXT: sw a1, 12(sp)
83 ; RV32-ILP32D-NEXT: fld ft0, 8(sp)
84 ; RV32-ILP32D-NEXT: fcvt.w.d a0, ft0, rtz
85 ; RV32-ILP32D-NEXT: fcvt.w.d a1, fa7, rtz
86 ; RV32-ILP32D-NEXT: add a0, a1, a0
87 ; RV32-ILP32D-NEXT: addi sp, sp, 16
88 ; RV32-ILP32D-NEXT: ret
89 %h_fptosi = fptosi double %h to i32
90 %i_fptosi = fptosi double %i to i32
91 %1 = add i32 %h_fptosi, %i_fptosi
92 ret i32 %1
93 }
94
95 define i32 @caller_double_in_gpr_exhausted_fprs() nounwind {
96 ; RV32-ILP32D-LABEL: caller_double_in_gpr_exhausted_fprs:
97 ; RV32-ILP32D: # %bb.0:
98 ; RV32-ILP32D-NEXT: addi sp, sp, -16
99 ; RV32-ILP32D-NEXT: sw ra, 12(sp)
100 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_0)
101 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI5_0)
102 ; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI5_1)
103 ; RV32-ILP32D-NEXT: addi a1, a1, %lo(.LCPI5_1)
104 ; RV32-ILP32D-NEXT: lui a2, %hi(.LCPI5_2)
105 ; RV32-ILP32D-NEXT: addi a2, a2, %lo(.LCPI5_2)
106 ; RV32-ILP32D-NEXT: lui a3, %hi(.LCPI5_3)
107 ; RV32-ILP32D-NEXT: addi a3, a3, %lo(.LCPI5_3)
108 ; RV32-ILP32D-NEXT: lui a4, %hi(.LCPI5_4)
109 ; RV32-ILP32D-NEXT: addi a4, a4, %lo(.LCPI5_4)
110 ; RV32-ILP32D-NEXT: lui a5, %hi(.LCPI5_5)
111 ; RV32-ILP32D-NEXT: addi a5, a5, %lo(.LCPI5_5)
112 ; RV32-ILP32D-NEXT: fld fa0, 0(a5)
113 ; RV32-ILP32D-NEXT: fld fa1, 0(a4)
114 ; RV32-ILP32D-NEXT: fld fa2, 0(a3)
115 ; RV32-ILP32D-NEXT: fld fa3, 0(a2)
116 ; RV32-ILP32D-NEXT: fld fa4, 0(a1)
117 ; RV32-ILP32D-NEXT: fld fa5, 0(a0)
118 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_6)
119 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI5_6)
120 ; RV32-ILP32D-NEXT: fld fa6, 0(a0)
121 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_7)
122 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI5_7)
123 ; RV32-ILP32D-NEXT: fld fa7, 0(a0)
124 ; RV32-ILP32D-NEXT: mv a0, zero
125 ; RV32-ILP32D-NEXT: lui a1, 262688
126 ; RV32-ILP32D-NEXT: call callee_double_in_gpr_exhausted_fprs
127 ; RV32-ILP32D-NEXT: lw ra, 12(sp)
128 ; RV32-ILP32D-NEXT: addi sp, sp, 16
129 ; RV32-ILP32D-NEXT: ret
130 %1 = call i32 @callee_double_in_gpr_exhausted_fprs(
131 double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0,
132 double 7.0, double 8.0, double 9.0)
133 ret i32 %1
134 }
135
136 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
137 define i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i32 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
138 ; RV32-ILP32D-LABEL: callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs:
139 ; RV32-ILP32D: # %bb.0:
140 ; RV32-ILP32D-NEXT: addi sp, sp, -16
141 ; RV32-ILP32D-NEXT: lw a0, 16(sp)
142 ; RV32-ILP32D-NEXT: sw a7, 8(sp)
143 ; RV32-ILP32D-NEXT: sw a0, 12(sp)
144 ; RV32-ILP32D-NEXT: fld ft0, 8(sp)
145 ; RV32-ILP32D-NEXT: fcvt.w.d a0, ft0, rtz
146 ; RV32-ILP32D-NEXT: add a0, a6, a0
147 ; RV32-ILP32D-NEXT: addi sp, sp, 16
148 ; RV32-ILP32D-NEXT: ret
149 %m_fptosi = fptosi double %m to i32
150 %1 = add i32 %g, %m_fptosi
151 ret i32 %1
152 }
153
154 define i32 @caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind {
155 ; RV32-ILP32D-LABEL: caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs:
156 ; RV32-ILP32D: # %bb.0:
157 ; RV32-ILP32D-NEXT: addi sp, sp, -16
158 ; RV32-ILP32D-NEXT: sw ra, 12(sp)
159 ; RV32-ILP32D-NEXT: lui a0, 262816
160 ; RV32-ILP32D-NEXT: sw a0, 0(sp)
161 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI7_0)
162 ; RV32-ILP32D-NEXT: addi a6, a0, %lo(.LCPI7_0)
163 ; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI7_1)
164 ; RV32-ILP32D-NEXT: addi a1, a1, %lo(.LCPI7_1)
165 ; RV32-ILP32D-NEXT: lui a2, %hi(.LCPI7_2)
166 ; RV32-ILP32D-NEXT: addi a2, a2, %lo(.LCPI7_2)
167 ; RV32-ILP32D-NEXT: lui a3, %hi(.LCPI7_3)
168 ; RV32-ILP32D-NEXT: addi a3, a3, %lo(.LCPI7_3)
169 ; RV32-ILP32D-NEXT: lui a4, %hi(.LCPI7_4)
170 ; RV32-ILP32D-NEXT: addi a4, a4, %lo(.LCPI7_4)
171 ; RV32-ILP32D-NEXT: lui a5, %hi(.LCPI7_5)
172 ; RV32-ILP32D-NEXT: addi a5, a5, %lo(.LCPI7_5)
173 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI7_6)
174 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI7_6)
175 ; RV32-ILP32D-NEXT: fld fa0, 0(a0)
176 ; RV32-ILP32D-NEXT: fld fa1, 0(a5)
177 ; RV32-ILP32D-NEXT: fld fa2, 0(a4)
178 ; RV32-ILP32D-NEXT: fld fa3, 0(a3)
179 ; RV32-ILP32D-NEXT: fld fa4, 0(a2)
180 ; RV32-ILP32D-NEXT: fld fa5, 0(a1)
181 ; RV32-ILP32D-NEXT: fld fa6, 0(a6)
182 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI7_7)
183 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI7_7)
184 ; RV32-ILP32D-NEXT: fld fa7, 0(a0)
185 ; RV32-ILP32D-NEXT: addi a0, zero, 1
186 ; RV32-ILP32D-NEXT: mv a1, zero
187 ; RV32-ILP32D-NEXT: addi a2, zero, 3
188 ; RV32-ILP32D-NEXT: mv a3, zero
189 ; RV32-ILP32D-NEXT: addi a4, zero, 5
190 ; RV32-ILP32D-NEXT: mv a5, zero
191 ; RV32-ILP32D-NEXT: addi a6, zero, 7
192 ; RV32-ILP32D-NEXT: mv a7, zero
193 ; RV32-ILP32D-NEXT: call callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs
194 ; RV32-ILP32D-NEXT: lw ra, 12(sp)
195 ; RV32-ILP32D-NEXT: addi sp, sp, 16
196 ; RV32-ILP32D-NEXT: ret
197 %1 = call i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(
198 i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i32 7, double 8.0,
199 double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
200 ret i32 %1
201 }
202
203
204 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
205 define i32 @callee_double_on_stack_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i64 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
206 ; RV32-ILP32D-LABEL: callee_double_on_stack_exhausted_gprs_fprs:
207 ; RV32-ILP32D: # %bb.0:
208 ; RV32-ILP32D-NEXT: fld ft0, 0(sp)
209 ; RV32-ILP32D-NEXT: fcvt.w.d a0, ft0, rtz
210 ; RV32-ILP32D-NEXT: add a0, a6, a0
211 ; RV32-ILP32D-NEXT: ret
212 %g_trunc = trunc i64 %g to i32
213 %m_fptosi = fptosi double %m to i32
214 %1 = add i32 %g_trunc, %m_fptosi
215 ret i32 %1
216 }
217
218 define i32 @caller_double_on_stack_exhausted_gprs_fprs() nounwind {
219 ; RV32-ILP32D-LABEL: caller_double_on_stack_exhausted_gprs_fprs:
220 ; RV32-ILP32D: # %bb.0:
221 ; RV32-ILP32D-NEXT: addi sp, sp, -16
222 ; RV32-ILP32D-NEXT: sw ra, 12(sp)
223 ; RV32-ILP32D-NEXT: lui a0, 262816
224 ; RV32-ILP32D-NEXT: sw a0, 4(sp)
225 ; RV32-ILP32D-NEXT: sw zero, 0(sp)
226 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI9_0)
227 ; RV32-ILP32D-NEXT: addi a6, a0, %lo(.LCPI9_0)
228 ; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI9_1)
229 ; RV32-ILP32D-NEXT: addi a1, a1, %lo(.LCPI9_1)
230 ; RV32-ILP32D-NEXT: lui a2, %hi(.LCPI9_2)
231 ; RV32-ILP32D-NEXT: addi a2, a2, %lo(.LCPI9_2)
232 ; RV32-ILP32D-NEXT: lui a3, %hi(.LCPI9_3)
233 ; RV32-ILP32D-NEXT: addi a3, a3, %lo(.LCPI9_3)
234 ; RV32-ILP32D-NEXT: lui a4, %hi(.LCPI9_4)
235 ; RV32-ILP32D-NEXT: addi a4, a4, %lo(.LCPI9_4)
236 ; RV32-ILP32D-NEXT: lui a5, %hi(.LCPI9_5)
237 ; RV32-ILP32D-NEXT: addi a5, a5, %lo(.LCPI9_5)
238 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI9_6)
239 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI9_6)
240 ; RV32-ILP32D-NEXT: fld fa0, 0(a0)
241 ; RV32-ILP32D-NEXT: fld fa1, 0(a5)
242 ; RV32-ILP32D-NEXT: fld fa2, 0(a4)
243 ; RV32-ILP32D-NEXT: fld fa3, 0(a3)
244 ; RV32-ILP32D-NEXT: fld fa4, 0(a2)
245 ; RV32-ILP32D-NEXT: fld fa5, 0(a1)
246 ; RV32-ILP32D-NEXT: fld fa6, 0(a6)
247 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI9_7)
248 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI9_7)
249 ; RV32-ILP32D-NEXT: fld fa7, 0(a0)
250 ; RV32-ILP32D-NEXT: addi a0, zero, 1
251 ; RV32-ILP32D-NEXT: mv a1, zero
252 ; RV32-ILP32D-NEXT: addi a2, zero, 3
253 ; RV32-ILP32D-NEXT: mv a3, zero
254 ; RV32-ILP32D-NEXT: addi a4, zero, 5
255 ; RV32-ILP32D-NEXT: mv a5, zero
256 ; RV32-ILP32D-NEXT: addi a6, zero, 7
257 ; RV32-ILP32D-NEXT: mv a7, zero
258 ; RV32-ILP32D-NEXT: call callee_double_on_stack_exhausted_gprs_fprs
259 ; RV32-ILP32D-NEXT: lw ra, 12(sp)
260 ; RV32-ILP32D-NEXT: addi sp, sp, 16
261 ; RV32-ILP32D-NEXT: ret
262 %1 = call i32 @callee_double_on_stack_exhausted_gprs_fprs(
263 i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i64 7, double 8.0,
264 double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
265 ret i32 %1
266 }
267
268 define double @callee_double_ret() nounwind {
269 ; RV32-ILP32D-LABEL: callee_double_ret:
270 ; RV32-ILP32D: # %bb.0:
271 ; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI10_0)
272 ; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI10_0)
273 ; RV32-ILP32D-NEXT: fld fa0, 0(a0)
274 ; RV32-ILP32D-NEXT: ret
275 ret double 1.0
276 }
277
278 define i32 @caller_double_ret() nounwind {
279 ; RV32-ILP32D-LABEL: caller_double_ret:
280 ; RV32-ILP32D: # %bb.0:
281 ; RV32-ILP32D-NEXT: addi sp, sp, -16
282 ; RV32-ILP32D-NEXT: sw ra, 12(sp)
283 ; RV32-ILP32D-NEXT: call callee_double_ret
284 ; RV32-ILP32D-NEXT: fsd fa0, 0(sp)
285 ; RV32-ILP32D-NEXT: lw a0, 0(sp)
286 ; RV32-ILP32D-NEXT: lw ra, 12(sp)
287 ; RV32-ILP32D-NEXT: addi sp, sp, 16
288 ; RV32-ILP32D-NEXT: ret
289 %1 = call double @callee_double_ret()
290 %2 = bitcast double %1 to i64
291 %3 = trunc i64 %2 to i32
292 ret i32 %3
293 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f \
2 ; RUN: -target-abi ilp32f < %s \
3 ; RUN: | FileCheck -check-prefix=RV32-ILP32FD %s
4 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+d \
5 ; RUN: -target-abi ilp32d < %s \
6 ; RUN: | FileCheck -check-prefix=RV32-ILP32FD %s
7
8 ; This file contains tests that should have identical output for the ilp32f
9 ; and ilp32d ABIs.
10
11 define i32 @callee_float_in_fpr(i32 %a, float %b) nounwind {
12 ; RV32-ILP32FD-LABEL: callee_float_in_fpr:
13 ; RV32-ILP32FD: # %bb.0:
14 ; RV32-ILP32FD-NEXT: fcvt.w.s a1, fa0, rtz
15 ; RV32-ILP32FD-NEXT: add a0, a0, a1
16 ; RV32-ILP32FD-NEXT: ret
17 %b_fptosi = fptosi float %b to i32
18 %1 = add i32 %a, %b_fptosi
19 ret i32 %1
20 }
21
22 define i32 @caller_float_in_fpr() nounwind {
23 ; RV32-ILP32FD-LABEL: caller_float_in_fpr:
24 ; RV32-ILP32FD: # %bb.0:
25 ; RV32-ILP32FD-NEXT: addi sp, sp, -16
26 ; RV32-ILP32FD-NEXT: sw ra, 12(sp)
27 ; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI1_0)
28 ; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI1_0)
29 ; RV32-ILP32FD-NEXT: flw fa0, 0(a0)
30 ; RV32-ILP32FD-NEXT: addi a0, zero, 1
31 ; RV32-ILP32FD-NEXT: call callee_float_in_fpr
32 ; RV32-ILP32FD-NEXT: lw ra, 12(sp)
33 ; RV32-ILP32FD-NEXT: addi sp, sp, 16
34 ; RV32-ILP32FD-NEXT: ret
35 %1 = call i32 @callee_float_in_fpr(i32 1, float 2.0)
36 ret i32 %1
37 }
38
39 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
40 define i32 @callee_float_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, float %f) nounwind {
41 ; RV32-ILP32FD-LABEL: callee_float_in_fpr_exhausted_gprs:
42 ; RV32-ILP32FD: # %bb.0:
43 ; RV32-ILP32FD-NEXT: fcvt.w.s a0, fa0, rtz
44 ; RV32-ILP32FD-NEXT: lw a1, 0(sp)
45 ; RV32-ILP32FD-NEXT: add a0, a1, a0
46 ; RV32-ILP32FD-NEXT: ret
47 %f_fptosi = fptosi float %f to i32
48 %1 = add i32 %e, %f_fptosi
49 ret i32 %1
50 }
51
52 define i32 @caller_float_in_fpr_exhausted_gprs() nounwind {
53 ; RV32-ILP32FD-LABEL: caller_float_in_fpr_exhausted_gprs:
54 ; RV32-ILP32FD: # %bb.0:
55 ; RV32-ILP32FD-NEXT: addi sp, sp, -16
56 ; RV32-ILP32FD-NEXT: sw ra, 12(sp)
57 ; RV32-ILP32FD-NEXT: addi a0, zero, 5
58 ; RV32-ILP32FD-NEXT: sw a0, 0(sp)
59 ; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI3_0)
60 ; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI3_0)
61 ; RV32-ILP32FD-NEXT: flw fa0, 0(a0)
62 ; RV32-ILP32FD-NEXT: addi a0, zero, 1
63 ; RV32-ILP32FD-NEXT: mv a1, zero
64 ; RV32-ILP32FD-NEXT: addi a2, zero, 2
65 ; RV32-ILP32FD-NEXT: mv a3, zero
66 ; RV32-ILP32FD-NEXT: addi a4, zero, 3
67 ; RV32-ILP32FD-NEXT: mv a5, zero
68 ; RV32-ILP32FD-NEXT: addi a6, zero, 4
69 ; RV32-ILP32FD-NEXT: mv a7, zero
70 ; RV32-ILP32FD-NEXT: call callee_float_in_fpr_exhausted_gprs
71 ; RV32-ILP32FD-NEXT: lw ra, 12(sp)
72 ; RV32-ILP32FD-NEXT: addi sp, sp, 16
73 ; RV32-ILP32FD-NEXT: ret
74 %1 = call i32 @callee_float_in_fpr_exhausted_gprs(
75 i64 1, i64 2, i64 3, i64 4, i32 5, float 6.0)
76 ret i32 %1
77 }
78
79 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
80 define i32 @callee_float_in_gpr_exhausted_fprs(float %a, float %b, float %c, float %d, float %e, float %f, float %g, float %h, float %i) nounwind {
81 ; RV32-ILP32FD-LABEL: callee_float_in_gpr_exhausted_fprs:
82 ; RV32-ILP32FD: # %bb.0:
83 ; RV32-ILP32FD-NEXT: fcvt.w.s a1, fa7, rtz
84 ; RV32-ILP32FD-NEXT: fmv.w.x ft0, a0
85 ; RV32-ILP32FD-NEXT: fcvt.w.s a0, ft0, rtz
86 ; RV32-ILP32FD-NEXT: add a0, a1, a0
87 ; RV32-ILP32FD-NEXT: ret
88 %h_fptosi = fptosi float %h to i32
89 %i_fptosi = fptosi float %i to i32
90 %1 = add i32 %h_fptosi, %i_fptosi
91 ret i32 %1
92 }
93
94 define i32 @caller_float_in_gpr_exhausted_fprs() nounwind {
95 ; RV32-ILP32FD-LABEL: caller_float_in_gpr_exhausted_fprs:
96 ; RV32-ILP32FD: # %bb.0:
97 ; RV32-ILP32FD-NEXT: addi sp, sp, -16
98 ; RV32-ILP32FD-NEXT: sw ra, 12(sp)
99 ; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI5_0)
100 ; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI5_0)
101 ; RV32-ILP32FD-NEXT: lui a1, %hi(.LCPI5_1)
102 ; RV32-ILP32FD-NEXT: addi a1, a1, %lo(.LCPI5_1)
103 ; RV32-ILP32FD-NEXT: lui a2, %hi(.LCPI5_2)
104 ; RV32-ILP32FD-NEXT: addi a2, a2, %lo(.LCPI5_2)
105 ; RV32-ILP32FD-NEXT: lui a3, %hi(.LCPI5_3)
106 ; RV32-ILP32FD-NEXT: addi a3, a3, %lo(.LCPI5_3)
107 ; RV32-ILP32FD-NEXT: lui a4, %hi(.LCPI5_4)
108 ; RV32-ILP32FD-NEXT: addi a4, a4, %lo(.LCPI5_4)
109 ; RV32-ILP32FD-NEXT: lui a5, %hi(.LCPI5_5)
110 ; RV32-ILP32FD-NEXT: addi a5, a5, %lo(.LCPI5_5)
111 ; RV32-ILP32FD-NEXT: flw fa0, 0(a5)
112 ; RV32-ILP32FD-NEXT: flw fa1, 0(a4)
113 ; RV32-ILP32FD-NEXT: flw fa2, 0(a3)
114 ; RV32-ILP32FD-NEXT: flw fa3, 0(a2)
115 ; RV32-ILP32FD-NEXT: flw fa4, 0(a1)
116 ; RV32-ILP32FD-NEXT: flw fa5, 0(a0)
117 ; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI5_6)
118 ; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI5_6)
119 ; RV32-ILP32FD-NEXT: flw fa6, 0(a0)
120 ; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI5_7)
121 ; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI5_7)
122 ; RV32-ILP32FD-NEXT: flw fa7, 0(a0)
123 ; RV32-ILP32FD-NEXT: lui a0, 266496
124 ; RV32-ILP32FD-NEXT: call callee_float_in_gpr_exhausted_fprs
125 ; RV32-ILP32FD-NEXT: lw ra, 12(sp)
126 ; RV32-ILP32FD-NEXT: addi sp, sp, 16
127 ; RV32-ILP32FD-NEXT: ret
128 %1 = call i32 @callee_float_in_gpr_exhausted_fprs(
129 float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, float 6.0,
130 float 7.0, float 8.0, float 9.0)
131 ret i32 %1
132 }
133
134 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
135 define i32 @callee_float_on_stack_exhausted_gprs_fprs(i64 %a, float %b, i64 %c, float %d, i64 %e, float %f, i64 %g, float %h, float %i, float %j, float %k, float %l, float %m) nounwind {
136 ; RV32-ILP32FD-LABEL: callee_float_on_stack_exhausted_gprs_fprs:
137 ; RV32-ILP32FD: # %bb.0:
138 ; RV32-ILP32FD-NEXT: flw ft0, 0(sp)
139 ; RV32-ILP32FD-NEXT: fcvt.w.s a0, ft0, rtz
140 ; RV32-ILP32FD-NEXT: add a0, a6, a0
141 ; RV32-ILP32FD-NEXT: ret
142 %g_trunc = trunc i64 %g to i32
143 %m_fptosi = fptosi float %m to i32
144 %1 = add i32 %g_trunc, %m_fptosi
145 ret i32 %1
146 }
147
148 define i32 @caller_float_on_stack_exhausted_gprs_fprs() nounwind {
149 ; RV32-ILP32FD-LABEL: caller_float_on_stack_exhausted_gprs_fprs:
150 ; RV32-ILP32FD: # %bb.0:
151 ; RV32-ILP32FD-NEXT: addi sp, sp, -16
152 ; RV32-ILP32FD-NEXT: sw ra, 12(sp)
153 ; RV32-ILP32FD-NEXT: lui a0, 267520
154 ; RV32-ILP32FD-NEXT: sw a0, 0(sp)
155 ; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI7_0)
156 ; RV32-ILP32FD-NEXT: addi a6, a0, %lo(.LCPI7_0)
157 ; RV32-ILP32FD-NEXT: lui a1, %hi(.LCPI7_1)
158 ; RV32-ILP32FD-NEXT: addi a1, a1, %lo(.LCPI7_1)
159 ; RV32-ILP32FD-NEXT: lui a2, %hi(.LCPI7_2)
160 ; RV32-ILP32FD-NEXT: addi a2, a2, %lo(.LCPI7_2)
161 ; RV32-ILP32FD-NEXT: lui a3, %hi(.LCPI7_3)
162 ; RV32-ILP32FD-NEXT: addi a3, a3, %lo(.LCPI7_3)
163 ; RV32-ILP32FD-NEXT: lui a4, %hi(.LCPI7_4)
164 ; RV32-ILP32FD-NEXT: addi a4, a4, %lo(.LCPI7_4)
165 ; RV32-ILP32FD-NEXT: lui a5, %hi(.LCPI7_5)
166 ; RV32-ILP32FD-NEXT: addi a5, a5, %lo(.LCPI7_5)
167 ; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI7_6)
168 ; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI7_6)
169 ; RV32-ILP32FD-NEXT: flw fa0, 0(a0)
170 ; RV32-ILP32FD-NEXT: flw fa1, 0(a5)
171 ; RV32-ILP32FD-NEXT: flw fa2, 0(a4)
172 ; RV32-ILP32FD-NEXT: flw fa3, 0(a3)
173 ; RV32-ILP32FD-NEXT: flw fa4, 0(a2)
174 ; RV32-ILP32FD-NEXT: flw fa5, 0(a1)
175 ; RV32-ILP32FD-NEXT: flw fa6, 0(a6)
176 ; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI7_7)
177 ; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI7_7)
178 ; RV32-ILP32FD-NEXT: flw fa7, 0(a0)
179 ; RV32-ILP32FD-NEXT: addi a0, zero, 1
180 ; RV32-ILP32FD-NEXT: mv a1, zero
181 ; RV32-ILP32FD-NEXT: addi a2, zero, 3
182 ; RV32-ILP32FD-NEXT: mv a3, zero
183 ; RV32-ILP32FD-NEXT: addi a4, zero, 5
184 ; RV32-ILP32FD-NEXT: mv a5, zero
185 ; RV32-ILP32FD-NEXT: addi a6, zero, 7
186 ; RV32-ILP32FD-NEXT: mv a7, zero
187 ; RV32-ILP32FD-NEXT: call callee_float_on_stack_exhausted_gprs_fprs
188 ; RV32-ILP32FD-NEXT: lw ra, 12(sp)
189 ; RV32-ILP32FD-NEXT: addi sp, sp, 16
190 ; RV32-ILP32FD-NEXT: ret
191 %1 = call i32 @callee_float_on_stack_exhausted_gprs_fprs(
192 i64 1, float 2.0, i64 3, float 4.0, i64 5, float 6.0, i64 7, float 8.0,
193 float 9.0, float 10.0, float 11.0, float 12.0, float 13.0)
194 ret i32 %1
195 }
196
197 define float @callee_float_ret() nounwind {
198 ; RV32-ILP32FD-LABEL: callee_float_ret:
199 ; RV32-ILP32FD: # %bb.0:
200 ; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI8_0)
201 ; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI8_0)
202 ; RV32-ILP32FD-NEXT: flw fa0, 0(a0)
203 ; RV32-ILP32FD-NEXT: ret
204 ret float 1.0
205 }
206
207 define i32 @caller_float_ret() nounwind {
208 ; RV32-ILP32FD-LABEL: caller_float_ret:
209 ; RV32-ILP32FD: # %bb.0:
210 ; RV32-ILP32FD-NEXT: addi sp, sp, -16
211 ; RV32-ILP32FD-NEXT: sw ra, 12(sp)
212 ; RV32-ILP32FD-NEXT: call callee_float_ret
213 ; RV32-ILP32FD-NEXT: fmv.x.w a0, fa0
214 ; RV32-ILP32FD-NEXT: lw ra, 12(sp)
215 ; RV32-ILP32FD-NEXT: addi sp, sp, 16
216 ; RV32-ILP32FD-NEXT: ret
217 %1 = call float @callee_float_ret()
218 %2 = bitcast float %1 to i32
219 ret i32 %2
220 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
11 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
2 ; RUN: | FileCheck -check-prefix=RV64I %s
3 ; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi lp64f \
4 ; RUN: -verify-machineinstrs < %s \
25 ; RUN: | FileCheck -check-prefix=RV64I %s
36
47 ; This file contains tests that should have identical output for the lp64 and
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
11 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
2 ; RUN: | FileCheck -check-prefix=RV64I %s
3 ; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi lp64f \
4 ; RUN: -verify-machineinstrs < %s \
5 ; RUN: | FileCheck -check-prefix=RV64I %s
6 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d \
7 ; RUN: -verify-machineinstrs < %s \
28 ; RUN: | FileCheck -check-prefix=RV64I %s
39
410 ; This file contains tests that should have identical output for the lp64,
1313 ; RUN: | FileCheck -check-prefix=CHECK-IMP %s
1414 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64 < %s \
1515 ; RUN: | FileCheck -check-prefix=CHECK-IMP %s
16 ; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f < %s 2>&1 \
17 ; RUN: | FileCheck -check-prefix=CHECK-IMP %s
18 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32f < %s 2>&1 \
19 ; RUN: | FileCheck -check-prefix=CHECK-IMP %s
20 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d < %s 2>&1 \
21 ; RUN: | FileCheck -check-prefix=CHECK-IMP %s
22 ; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi lp64f < %s 2>&1 \
23 ; RUN: | FileCheck -check-prefix=CHECK-IMP %s
24 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64f < %s 2>&1 \
25 ; RUN: | FileCheck -check-prefix=CHECK-IMP %s
26 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d < %s 2>&1 \
27 ; RUN: | FileCheck -check-prefix=CHECK-IMP %s
1628
1729 define void @nothing() nounwind {
1830 ; CHECK-IMP-LABEL: nothing:
2133 ret void
2234 }
2335
24 ; RUN: not llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f < %s 2>&1 \
25 ; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
26 ; RUN: not llc -mtriple=riscv32 -mattr=+d -target-abi ilp32f < %s 2>&1 \
27 ; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
28 ; RUN: not llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d < %s 2>&1 \
29 ; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
3036 ; RUN: not llc -mtriple=riscv32 -target-abi ilp32e < %s 2>&1 \
31 ; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
32 ; RUN: not llc -mtriple=riscv64 -mattr=+f -target-abi lp64f < %s 2>&1 \
33 ; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
34 ; RUN: not llc -mtriple=riscv64 -mattr=+d -target-abi lp64f < %s 2>&1 \
35 ; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
36 ; RUN: not llc -mtriple=riscv64 -mattr=+d -target-abi lp64d < %s 2>&1 \
3737 ; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
3838
3939 ; CHECK-UNIMP: LLVM ERROR: Don't know how to lower this ABI
44 ; RUN: | FileCheck -check-prefix=ILP32-ILP32F-WITHFP %s
55 ; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
66 ; RUN: | FileCheck -check-prefix=RV32D-ILP32-ILP32F-ILP32D-FPELIM %s
7 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32f \
8 ; RUN: -verify-machineinstrs < %s \
9 ; RUN: | FileCheck -check-prefix=RV32D-ILP32-ILP32F-ILP32D-FPELIM %s
10 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
11 ; RUN: -verify-machineinstrs < %s \
12 ; RUN: | FileCheck -check-prefix=RV32D-ILP32-ILP32F-ILP32D-FPELIM %s
713 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
14 ; RUN: | FileCheck -check-prefix=LP64-LP64F-LP64D-FPELIM %s
15 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64f \
16 ; RUN: -verify-machineinstrs < %s \
17 ; RUN: | FileCheck -check-prefix=LP64-LP64F-LP64D-FPELIM %s
18 ; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d \
19 ; RUN: -verify-machineinstrs < %s \
820 ; RUN: | FileCheck -check-prefix=LP64-LP64F-LP64D-FPELIM %s
921 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs -frame-pointer=all < %s \
1022 ; RUN: | FileCheck -check-prefix=LP64-LP64F-LP64D-WITHFP %s
1123
12 ; TODO: RUN lines for ilp32f/ilp32d/lp64f/lp64d must be added when hard float
13 ; ABI Support lands. The same vararg calling convention is used for
14 ; ilp32/ilp32f/ilp32d and for lp64/lp64f/lp64d. Different CHECK lines are
15 ; required for RV32D due to slight codegen differences due to the way the
16 ; f64 load operations are lowered.
24 ; The same vararg calling convention is used for ilp32/ilp32f/ilp32d and for
25 ; lp64/lp64f/lp64d. Different CHECK lines are required for RV32D due to slight
26 ; codegen differences due to the way the f64 load operations are lowered.
1727
1828 declare void @llvm.va_start(i8*)
1929 declare void @llvm.va_end(i8*)