blob: 63117bafbb3d68ef0d98abb67d857a1e89148f0a [file] [log] [blame]
Alex Bradbury89718422017-10-19 21:37:38 +00001//===-- RISCVISelLowering.cpp - RISCV DAG Lowering Implementation --------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Alex Bradbury89718422017-10-19 21:37:38 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that RISCV uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "RISCVISelLowering.h"
15#include "RISCV.h"
Alex Bradburyc85be0d2018-01-10 19:41:03 +000016#include "RISCVMachineFunctionInfo.h"
Alex Bradbury89718422017-10-19 21:37:38 +000017#include "RISCVRegisterInfo.h"
18#include "RISCVSubtarget.h"
19#include "RISCVTargetMachine.h"
Alex Bradburyb9e78c32019-03-22 10:45:03 +000020#include "llvm/ADT/SmallSet.h"
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +000021#include "llvm/ADT/Statistic.h"
Alex Bradbury89718422017-10-19 21:37:38 +000022#include "llvm/CodeGen/CallingConvLower.h"
23#include "llvm/CodeGen/MachineFrameInfo.h"
24#include "llvm/CodeGen/MachineFunction.h"
25#include "llvm/CodeGen/MachineInstrBuilder.h"
26#include "llvm/CodeGen/MachineRegisterInfo.h"
27#include "llvm/CodeGen/SelectionDAGISel.h"
28#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
Craig Topper2fa14362018-03-29 17:21:10 +000029#include "llvm/CodeGen/ValueTypes.h"
Alex Bradbury89718422017-10-19 21:37:38 +000030#include "llvm/IR/DiagnosticInfo.h"
31#include "llvm/IR/DiagnosticPrinter.h"
32#include "llvm/Support/Debug.h"
33#include "llvm/Support/ErrorHandling.h"
34#include "llvm/Support/raw_ostream.h"
35
36using namespace llvm;
37
38#define DEBUG_TYPE "riscv-lower"
39
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +000040STATISTIC(NumTailCalls, "Number of tail calls");
41
Alex Bradbury89718422017-10-19 21:37:38 +000042RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
43 const RISCVSubtarget &STI)
44 : TargetLowering(TM), Subtarget(STI) {
45
Alex Bradburydab1f6f2019-03-22 11:21:40 +000046 if (Subtarget.isRV32E())
47 report_fatal_error("Codegen not yet implemented for RV32E");
48
Alex Bradburyfea49572019-03-09 09:28:06 +000049 RISCVABI::ABI ABI = Subtarget.getTargetABI();
50 assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI");
51
Alex Bradbury0b2803e2019-03-30 17:59:30 +000052 switch (ABI) {
53 default:
Alex Bradburyfea49572019-03-09 09:28:06 +000054 report_fatal_error("Don't know how to lower this ABI");
Alex Bradbury0b2803e2019-03-30 17:59:30 +000055 case RISCVABI::ABI_ILP32:
56 case RISCVABI::ABI_ILP32F:
57 case RISCVABI::ABI_ILP32D:
58 case RISCVABI::ABI_LP64:
59 case RISCVABI::ABI_LP64F:
60 case RISCVABI::ABI_LP64D:
61 break;
62 }
Alex Bradburyfea49572019-03-09 09:28:06 +000063
Alex Bradbury89718422017-10-19 21:37:38 +000064 MVT XLenVT = Subtarget.getXLenVT();
65
66 // Set up the register classes.
67 addRegisterClass(XLenVT, &RISCV::GPRRegClass);
68
Alex Bradbury76c29ee2018-03-20 12:45:35 +000069 if (Subtarget.hasStdExtF())
70 addRegisterClass(MVT::f32, &RISCV::FPR32RegClass);
Alex Bradbury0b4175f2018-04-12 05:34:25 +000071 if (Subtarget.hasStdExtD())
72 addRegisterClass(MVT::f64, &RISCV::FPR64RegClass);
Alex Bradbury76c29ee2018-03-20 12:45:35 +000073
Alex Bradbury89718422017-10-19 21:37:38 +000074 // Compute derived properties from the register classes.
75 computeRegisterProperties(STI.getRegisterInfo());
76
77 setStackPointerRegisterToSaveRestore(RISCV::X2);
78
Alex Bradburycfa62912017-11-08 12:20:01 +000079 for (auto N : {ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD})
80 setLoadExtAction(N, XLenVT, MVT::i1, Promote);
81
Alex Bradbury89718422017-10-19 21:37:38 +000082 // TODO: add all necessary setOperationAction calls.
Alex Bradburybfb00d42017-12-11 12:38:17 +000083 setOperationAction(ISD::DYNAMIC_STACKALLOC, XLenVT, Expand);
84
Alex Bradburyffc435e2017-11-21 08:11:03 +000085 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
Alex Bradbury74913e12017-11-08 13:31:40 +000086 setOperationAction(ISD::BR_CC, XLenVT, Expand);
Alex Bradbury65385162017-11-21 07:51:32 +000087 setOperationAction(ISD::SELECT, XLenVT, Custom);
88 setOperationAction(ISD::SELECT_CC, XLenVT, Expand);
89
Alex Bradburybfb00d42017-12-11 12:38:17 +000090 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
91 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
92
Alex Bradburyc85be0d2018-01-10 19:41:03 +000093 setOperationAction(ISD::VASTART, MVT::Other, Custom);
94 setOperationAction(ISD::VAARG, MVT::Other, Expand);
95 setOperationAction(ISD::VACOPY, MVT::Other, Expand);
96 setOperationAction(ISD::VAEND, MVT::Other, Expand);
97
Alex Bradburyffc435e2017-11-21 08:11:03 +000098 for (auto VT : {MVT::i1, MVT::i8, MVT::i16})
99 setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand);
100
Alex Bradburyd05eae72019-01-12 07:32:31 +0000101 if (Subtarget.is64Bit()) {
Alex Bradbury299d6902019-01-25 05:04:00 +0000102 setOperationAction(ISD::SHL, MVT::i32, Custom);
103 setOperationAction(ISD::SRA, MVT::i32, Custom);
104 setOperationAction(ISD::SRL, MVT::i32, Custom);
Alex Bradburyd05eae72019-01-12 07:32:31 +0000105 }
106
Alex Bradbury92138382018-01-18 12:36:38 +0000107 if (!Subtarget.hasStdExtM()) {
108 setOperationAction(ISD::MUL, XLenVT, Expand);
109 setOperationAction(ISD::MULHS, XLenVT, Expand);
110 setOperationAction(ISD::MULHU, XLenVT, Expand);
111 setOperationAction(ISD::SDIV, XLenVT, Expand);
112 setOperationAction(ISD::UDIV, XLenVT, Expand);
113 setOperationAction(ISD::SREM, XLenVT, Expand);
114 setOperationAction(ISD::UREM, XLenVT, Expand);
115 }
Alex Bradburyffc435e2017-11-21 08:11:03 +0000116
Alex Bradbury456d3792019-01-25 05:11:34 +0000117 if (Subtarget.is64Bit() && Subtarget.hasStdExtM()) {
118 setOperationAction(ISD::SDIV, MVT::i32, Custom);
119 setOperationAction(ISD::UDIV, MVT::i32, Custom);
120 setOperationAction(ISD::UREM, MVT::i32, Custom);
121 }
122
Alex Bradbury92138382018-01-18 12:36:38 +0000123 setOperationAction(ISD::SDIVREM, XLenVT, Expand);
124 setOperationAction(ISD::UDIVREM, XLenVT, Expand);
Alex Bradburyffc435e2017-11-21 08:11:03 +0000125 setOperationAction(ISD::SMUL_LOHI, XLenVT, Expand);
126 setOperationAction(ISD::UMUL_LOHI, XLenVT, Expand);
Alex Bradburyffc435e2017-11-21 08:11:03 +0000127
128 setOperationAction(ISD::SHL_PARTS, XLenVT, Expand);
129 setOperationAction(ISD::SRL_PARTS, XLenVT, Expand);
130 setOperationAction(ISD::SRA_PARTS, XLenVT, Expand);
131
132 setOperationAction(ISD::ROTL, XLenVT, Expand);
133 setOperationAction(ISD::ROTR, XLenVT, Expand);
134 setOperationAction(ISD::BSWAP, XLenVT, Expand);
135 setOperationAction(ISD::CTTZ, XLenVT, Expand);
136 setOperationAction(ISD::CTLZ, XLenVT, Expand);
137 setOperationAction(ISD::CTPOP, XLenVT, Expand);
138
Alex Bradbury21d28fe2018-04-12 05:50:06 +0000139 ISD::CondCode FPCCToExtend[] = {
Luis Marques30918842019-04-01 09:54:14 +0000140 ISD::SETOGT, ISD::SETOGE, ISD::SETONE, ISD::SETUEQ, ISD::SETUGT,
141 ISD::SETUGE, ISD::SETULT, ISD::SETULE, ISD::SETUNE, ISD::SETGT,
142 ISD::SETGE, ISD::SETNE};
Alex Bradbury21d28fe2018-04-12 05:50:06 +0000143
Alex Bradbury52c27782018-11-02 19:50:38 +0000144 ISD::NodeType FPOpToExtend[] = {
Alex Bradbury919f5fb2018-12-13 10:49:05 +0000145 ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOW, ISD::FREM};
Alex Bradbury52c27782018-11-02 19:50:38 +0000146
Alex Bradbury76c29ee2018-03-20 12:45:35 +0000147 if (Subtarget.hasStdExtF()) {
148 setOperationAction(ISD::FMINNUM, MVT::f32, Legal);
149 setOperationAction(ISD::FMAXNUM, MVT::f32, Legal);
Alex Bradbury21d28fe2018-04-12 05:50:06 +0000150 for (auto CC : FPCCToExtend)
Alex Bradbury65d6ea52018-03-21 15:11:02 +0000151 setCondCodeAction(CC, MVT::f32, Expand);
152 setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
153 setOperationAction(ISD::SELECT, MVT::f32, Custom);
154 setOperationAction(ISD::BR_CC, MVT::f32, Expand);
Alex Bradbury52c27782018-11-02 19:50:38 +0000155 for (auto Op : FPOpToExtend)
156 setOperationAction(Op, MVT::f32, Expand);
Alex Bradbury76c29ee2018-03-20 12:45:35 +0000157 }
158
Alex Bradburyd834d832019-01-31 22:48:38 +0000159 if (Subtarget.hasStdExtF() && Subtarget.is64Bit())
160 setOperationAction(ISD::BITCAST, MVT::i32, Custom);
161
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000162 if (Subtarget.hasStdExtD()) {
163 setOperationAction(ISD::FMINNUM, MVT::f64, Legal);
164 setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
Alex Bradbury21d28fe2018-04-12 05:50:06 +0000165 for (auto CC : FPCCToExtend)
166 setCondCodeAction(CC, MVT::f64, Expand);
167 setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
168 setOperationAction(ISD::SELECT, MVT::f64, Custom);
169 setOperationAction(ISD::BR_CC, MVT::f64, Expand);
Alex Bradbury0b4175f2018-04-12 05:34:25 +0000170 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
Alex Bradbury60baa2e2018-04-12 05:47:15 +0000171 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
Alex Bradbury52c27782018-11-02 19:50:38 +0000172 for (auto Op : FPOpToExtend)
173 setOperationAction(Op, MVT::f64, Expand);
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000174 }
Alex Bradbury0b4175f2018-04-12 05:34:25 +0000175
Alex Bradburyffc435e2017-11-21 08:11:03 +0000176 setOperationAction(ISD::GlobalAddress, XLenVT, Custom);
177 setOperationAction(ISD::BlockAddress, XLenVT, Custom);
Alex Bradbury80c8eb72018-03-20 13:26:12 +0000178 setOperationAction(ISD::ConstantPool, XLenVT, Custom);
Alex Bradburyffc435e2017-11-21 08:11:03 +0000179
Alex Bradbury21aea512018-09-19 10:54:22 +0000180 if (Subtarget.hasStdExtA()) {
Alex Bradbury96f492d2018-06-13 12:04:51 +0000181 setMaxAtomicSizeInBitsSupported(Subtarget.getXLen());
Alex Bradbury21aea512018-09-19 10:54:22 +0000182 setMinCmpXchgSizeInBits(32);
183 } else {
Alex Bradbury96f492d2018-06-13 12:04:51 +0000184 setMaxAtomicSizeInBitsSupported(0);
Alex Bradbury21aea512018-09-19 10:54:22 +0000185 }
Alex Bradburydc790dd2018-06-13 11:58:46 +0000186
Alex Bradbury89718422017-10-19 21:37:38 +0000187 setBooleanContents(ZeroOrOneBooleanContent);
188
189 // Function alignments (log2).
Shiva Chenb48b0272018-04-12 11:30:59 +0000190 unsigned FunctionAlignment = Subtarget.hasStdExtC() ? 1 : 2;
191 setMinFunctionAlignment(FunctionAlignment);
192 setPrefFunctionAlignment(FunctionAlignment);
Alex Bradburyffc435e2017-11-21 08:11:03 +0000193
194 // Effectively disable jump table generation.
195 setMinimumJumpTableEntries(INT_MAX);
Alex Bradbury89718422017-10-19 21:37:38 +0000196}
197
Shiva Chenbbf4c5c2018-02-02 02:43:18 +0000198EVT RISCVTargetLowering::getSetCCResultType(const DataLayout &DL, LLVMContext &,
199 EVT VT) const {
200 if (!VT.isVector())
201 return getPointerTy(DL);
202 return VT.changeVectorElementTypeToInteger();
203}
204
Alex Bradbury21aea512018-09-19 10:54:22 +0000205bool RISCVTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
206 const CallInst &I,
207 MachineFunction &MF,
208 unsigned Intrinsic) const {
209 switch (Intrinsic) {
210 default:
211 return false;
212 case Intrinsic::riscv_masked_atomicrmw_xchg_i32:
213 case Intrinsic::riscv_masked_atomicrmw_add_i32:
214 case Intrinsic::riscv_masked_atomicrmw_sub_i32:
215 case Intrinsic::riscv_masked_atomicrmw_nand_i32:
216 case Intrinsic::riscv_masked_atomicrmw_max_i32:
217 case Intrinsic::riscv_masked_atomicrmw_min_i32:
218 case Intrinsic::riscv_masked_atomicrmw_umax_i32:
219 case Intrinsic::riscv_masked_atomicrmw_umin_i32:
Alex Bradbury66d9a752018-11-29 20:43:42 +0000220 case Intrinsic::riscv_masked_cmpxchg_i32:
Alex Bradbury21aea512018-09-19 10:54:22 +0000221 PointerType *PtrTy = cast<PointerType>(I.getArgOperand(0)->getType());
222 Info.opc = ISD::INTRINSIC_W_CHAIN;
223 Info.memVT = MVT::getVT(PtrTy->getElementType());
224 Info.ptrVal = I.getArgOperand(0);
225 Info.offset = 0;
226 Info.align = 4;
227 Info.flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore |
228 MachineMemOperand::MOVolatile;
229 return true;
230 }
231}
232
Alex Bradbury09926292018-04-26 12:13:48 +0000233bool RISCVTargetLowering::isLegalAddressingMode(const DataLayout &DL,
234 const AddrMode &AM, Type *Ty,
235 unsigned AS,
236 Instruction *I) const {
237 // No global is ever allowed as a base.
238 if (AM.BaseGV)
239 return false;
240
241 // Require a 12-bit signed offset.
242 if (!isInt<12>(AM.BaseOffs))
243 return false;
244
245 switch (AM.Scale) {
246 case 0: // "r+i" or just "i", depending on HasBaseReg.
247 break;
248 case 1:
249 if (!AM.HasBaseReg) // allow "r+i".
250 break;
251 return false; // disallow "r+r" or "r+r+i".
252 default:
253 return false;
254 }
255
256 return true;
257}
258
Alex Bradburydcbff632018-04-26 13:15:17 +0000259bool RISCVTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
260 return isInt<12>(Imm);
261}
262
Alex Bradbury5c41ece2018-04-26 13:00:37 +0000263bool RISCVTargetLowering::isLegalAddImmediate(int64_t Imm) const {
264 return isInt<12>(Imm);
265}
266
Alex Bradbury130b8b32018-04-26 13:37:00 +0000267// On RV32, 64-bit integers are split into their high and low parts and held
268// in two different registers, so the trunc is free since the low register can
269// just be used.
270bool RISCVTargetLowering::isTruncateFree(Type *SrcTy, Type *DstTy) const {
271 if (Subtarget.is64Bit() || !SrcTy->isIntegerTy() || !DstTy->isIntegerTy())
272 return false;
273 unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
274 unsigned DestBits = DstTy->getPrimitiveSizeInBits();
275 return (SrcBits == 64 && DestBits == 32);
276}
277
278bool RISCVTargetLowering::isTruncateFree(EVT SrcVT, EVT DstVT) const {
279 if (Subtarget.is64Bit() || SrcVT.isVector() || DstVT.isVector() ||
280 !SrcVT.isInteger() || !DstVT.isInteger())
281 return false;
282 unsigned SrcBits = SrcVT.getSizeInBits();
283 unsigned DestBits = DstVT.getSizeInBits();
284 return (SrcBits == 64 && DestBits == 32);
285}
286
Alex Bradbury15e894b2018-04-26 14:04:18 +0000287bool RISCVTargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
288 // Zexts are free if they can be combined with a load.
289 if (auto *LD = dyn_cast<LoadSDNode>(Val)) {
290 EVT MemVT = LD->getMemoryVT();
291 if ((MemVT == MVT::i8 || MemVT == MVT::i16 ||
292 (Subtarget.is64Bit() && MemVT == MVT::i32)) &&
293 (LD->getExtensionType() == ISD::NON_EXTLOAD ||
294 LD->getExtensionType() == ISD::ZEXTLOAD))
295 return true;
296 }
297
298 return TargetLowering::isZExtFree(Val, VT2);
299}
300
Alex Bradburye0e62e92018-11-30 09:56:54 +0000301bool RISCVTargetLowering::isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const {
302 return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
303}
304
Alex Bradbury65385162017-11-21 07:51:32 +0000305// Changes the condition code and swaps operands if necessary, so the SetCC
306// operation matches one of the comparisons supported directly in the RISC-V
307// ISA.
308static void normaliseSetCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC) {
309 switch (CC) {
310 default:
311 break;
312 case ISD::SETGT:
313 case ISD::SETLE:
314 case ISD::SETUGT:
315 case ISD::SETULE:
316 CC = ISD::getSetCCSwappedOperands(CC);
317 std::swap(LHS, RHS);
318 break;
319 }
320}
321
322// Return the RISC-V branch opcode that matches the given DAG integer
323// condition code. The CondCode must be one of those supported by the RISC-V
324// ISA (see normaliseSetCC).
325static unsigned getBranchOpcodeForIntCondCode(ISD::CondCode CC) {
326 switch (CC) {
327 default:
328 llvm_unreachable("Unsupported CondCode");
329 case ISD::SETEQ:
330 return RISCV::BEQ;
331 case ISD::SETNE:
332 return RISCV::BNE;
333 case ISD::SETLT:
334 return RISCV::BLT;
335 case ISD::SETGE:
336 return RISCV::BGE;
337 case ISD::SETULT:
338 return RISCV::BLTU;
339 case ISD::SETUGE:
340 return RISCV::BGEU;
341 }
342}
343
Alex Bradbury89718422017-10-19 21:37:38 +0000344SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
345 SelectionDAG &DAG) const {
346 switch (Op.getOpcode()) {
347 default:
348 report_fatal_error("unimplemented operand");
Alex Bradburyec8aa912017-11-08 13:24:21 +0000349 case ISD::GlobalAddress:
350 return lowerGlobalAddress(Op, DAG);
Alex Bradburyffc435e2017-11-21 08:11:03 +0000351 case ISD::BlockAddress:
352 return lowerBlockAddress(Op, DAG);
Alex Bradbury80c8eb72018-03-20 13:26:12 +0000353 case ISD::ConstantPool:
354 return lowerConstantPool(Op, DAG);
Alex Bradbury65385162017-11-21 07:51:32 +0000355 case ISD::SELECT:
356 return lowerSELECT(Op, DAG);
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000357 case ISD::VASTART:
358 return lowerVASTART(Op, DAG);
Alex Bradbury70f137b2018-01-10 20:12:00 +0000359 case ISD::FRAMEADDR:
Alex Bradbury0e167662018-10-04 05:27:50 +0000360 return lowerFRAMEADDR(Op, DAG);
Alex Bradbury70f137b2018-01-10 20:12:00 +0000361 case ISD::RETURNADDR:
Alex Bradbury0e167662018-10-04 05:27:50 +0000362 return lowerRETURNADDR(Op, DAG);
Alex Bradburyd834d832019-01-31 22:48:38 +0000363 case ISD::BITCAST: {
364 assert(Subtarget.is64Bit() && Subtarget.hasStdExtF() &&
365 "Unexpected custom legalisation");
366 SDLoc DL(Op);
367 SDValue Op0 = Op.getOperand(0);
368 if (Op.getValueType() != MVT::f32 || Op0.getValueType() != MVT::i32)
369 return SDValue();
370 SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0);
371 SDValue FPConv = DAG.getNode(RISCVISD::FMV_W_X_RV64, DL, MVT::f32, NewOp0);
372 return FPConv;
373 }
Alex Bradburyec8aa912017-11-08 13:24:21 +0000374 }
375}
376
377SDValue RISCVTargetLowering::lowerGlobalAddress(SDValue Op,
378 SelectionDAG &DAG) const {
379 SDLoc DL(Op);
380 EVT Ty = Op.getValueType();
381 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
382 const GlobalValue *GV = N->getGlobal();
383 int64_t Offset = N->getOffset();
Sameer AbuAsal1dc0a8f2018-05-17 18:14:53 +0000384 MVT XLenVT = Subtarget.getXLenVT();
Alex Bradburyec8aa912017-11-08 13:24:21 +0000385
Alex Bradbury5bf3b202018-10-04 14:30:03 +0000386 if (isPositionIndependent())
Alex Bradburyec8aa912017-11-08 13:24:21 +0000387 report_fatal_error("Unable to lowerGlobalAddress");
Sameer AbuAsal1dc0a8f2018-05-17 18:14:53 +0000388 // In order to maximise the opportunity for common subexpression elimination,
389 // emit a separate ADD node for the global address offset instead of folding
390 // it in the global address node. Later peephole optimisations may choose to
391 // fold it back in when profitable.
392 SDValue GAHi = DAG.getTargetGlobalAddress(GV, DL, Ty, 0, RISCVII::MO_HI);
393 SDValue GALo = DAG.getTargetGlobalAddress(GV, DL, Ty, 0, RISCVII::MO_LO);
Alex Bradburyffc435e2017-11-21 08:11:03 +0000394 SDValue MNHi = SDValue(DAG.getMachineNode(RISCV::LUI, DL, Ty, GAHi), 0);
395 SDValue MNLo =
396 SDValue(DAG.getMachineNode(RISCV::ADDI, DL, Ty, MNHi, GALo), 0);
Sameer AbuAsal1dc0a8f2018-05-17 18:14:53 +0000397 if (Offset != 0)
398 return DAG.getNode(ISD::ADD, DL, Ty, MNLo,
399 DAG.getConstant(Offset, DL, XLenVT));
Alex Bradburyffc435e2017-11-21 08:11:03 +0000400 return MNLo;
401}
402
403SDValue RISCVTargetLowering::lowerBlockAddress(SDValue Op,
404 SelectionDAG &DAG) const {
405 SDLoc DL(Op);
406 EVT Ty = Op.getValueType();
407 BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
408 const BlockAddress *BA = N->getBlockAddress();
409 int64_t Offset = N->getOffset();
410
Alex Bradbury5bf3b202018-10-04 14:30:03 +0000411 if (isPositionIndependent())
Alex Bradburyffc435e2017-11-21 08:11:03 +0000412 report_fatal_error("Unable to lowerBlockAddress");
413
414 SDValue BAHi = DAG.getTargetBlockAddress(BA, Ty, Offset, RISCVII::MO_HI);
415 SDValue BALo = DAG.getTargetBlockAddress(BA, Ty, Offset, RISCVII::MO_LO);
416 SDValue MNHi = SDValue(DAG.getMachineNode(RISCV::LUI, DL, Ty, BAHi), 0);
417 SDValue MNLo =
418 SDValue(DAG.getMachineNode(RISCV::ADDI, DL, Ty, MNHi, BALo), 0);
419 return MNLo;
420}
421
Alex Bradbury80c8eb72018-03-20 13:26:12 +0000422SDValue RISCVTargetLowering::lowerConstantPool(SDValue Op,
423 SelectionDAG &DAG) const {
424 SDLoc DL(Op);
425 EVT Ty = Op.getValueType();
426 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
427 const Constant *CPA = N->getConstVal();
428 int64_t Offset = N->getOffset();
429 unsigned Alignment = N->getAlignment();
430
431 if (!isPositionIndependent()) {
432 SDValue CPAHi =
433 DAG.getTargetConstantPool(CPA, Ty, Alignment, Offset, RISCVII::MO_HI);
434 SDValue CPALo =
435 DAG.getTargetConstantPool(CPA, Ty, Alignment, Offset, RISCVII::MO_LO);
436 SDValue MNHi = SDValue(DAG.getMachineNode(RISCV::LUI, DL, Ty, CPAHi), 0);
437 SDValue MNLo =
438 SDValue(DAG.getMachineNode(RISCV::ADDI, DL, Ty, MNHi, CPALo), 0);
439 return MNLo;
440 } else {
441 report_fatal_error("Unable to lowerConstantPool");
442 }
443}
444
Alex Bradbury65385162017-11-21 07:51:32 +0000445SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
446 SDValue CondV = Op.getOperand(0);
447 SDValue TrueV = Op.getOperand(1);
448 SDValue FalseV = Op.getOperand(2);
449 SDLoc DL(Op);
450 MVT XLenVT = Subtarget.getXLenVT();
451
452 // If the result type is XLenVT and CondV is the output of a SETCC node
453 // which also operated on XLenVT inputs, then merge the SETCC node into the
454 // lowered RISCVISD::SELECT_CC to take advantage of the integer
455 // compare+branch instructions. i.e.:
456 // (select (setcc lhs, rhs, cc), truev, falsev)
457 // -> (riscvisd::select_cc lhs, rhs, cc, truev, falsev)
458 if (Op.getSimpleValueType() == XLenVT && CondV.getOpcode() == ISD::SETCC &&
459 CondV.getOperand(0).getSimpleValueType() == XLenVT) {
460 SDValue LHS = CondV.getOperand(0);
461 SDValue RHS = CondV.getOperand(1);
462 auto CC = cast<CondCodeSDNode>(CondV.getOperand(2));
463 ISD::CondCode CCVal = CC->get();
464
465 normaliseSetCC(LHS, RHS, CCVal);
466
467 SDValue TargetCC = DAG.getConstant(CCVal, DL, XLenVT);
468 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
469 SDValue Ops[] = {LHS, RHS, TargetCC, TrueV, FalseV};
470 return DAG.getNode(RISCVISD::SELECT_CC, DL, VTs, Ops);
471 }
472
473 // Otherwise:
474 // (select condv, truev, falsev)
475 // -> (riscvisd::select_cc condv, zero, setne, truev, falsev)
476 SDValue Zero = DAG.getConstant(0, DL, XLenVT);
477 SDValue SetNE = DAG.getConstant(ISD::SETNE, DL, XLenVT);
478
479 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
480 SDValue Ops[] = {CondV, Zero, SetNE, TrueV, FalseV};
481
482 return DAG.getNode(RISCVISD::SELECT_CC, DL, VTs, Ops);
483}
484
Alex Bradburyc85be0d2018-01-10 19:41:03 +0000485SDValue RISCVTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const {
486 MachineFunction &MF = DAG.getMachineFunction();
487 RISCVMachineFunctionInfo *FuncInfo = MF.getInfo<RISCVMachineFunctionInfo>();
488
489 SDLoc DL(Op);
490 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
491 getPointerTy(MF.getDataLayout()));
492
493 // vastart just stores the address of the VarArgsFrameIndex slot into the
494 // memory location argument.
495 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
496 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
497 MachinePointerInfo(SV));
498}
499
Alex Bradbury0e167662018-10-04 05:27:50 +0000500SDValue RISCVTargetLowering::lowerFRAMEADDR(SDValue Op,
Alex Bradbury70f137b2018-01-10 20:12:00 +0000501 SelectionDAG &DAG) const {
502 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
503 MachineFunction &MF = DAG.getMachineFunction();
504 MachineFrameInfo &MFI = MF.getFrameInfo();
505 MFI.setFrameAddressIsTaken(true);
506 unsigned FrameReg = RI.getFrameRegister(MF);
507 int XLenInBytes = Subtarget.getXLen() / 8;
508
509 EVT VT = Op.getValueType();
510 SDLoc DL(Op);
511 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameReg, VT);
512 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
513 while (Depth--) {
514 int Offset = -(XLenInBytes * 2);
515 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
516 DAG.getIntPtrConstant(Offset, DL));
517 FrameAddr =
518 DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
519 }
520 return FrameAddr;
521}
522
Alex Bradbury0e167662018-10-04 05:27:50 +0000523SDValue RISCVTargetLowering::lowerRETURNADDR(SDValue Op,
Alex Bradbury70f137b2018-01-10 20:12:00 +0000524 SelectionDAG &DAG) const {
525 const RISCVRegisterInfo &RI = *Subtarget.getRegisterInfo();
526 MachineFunction &MF = DAG.getMachineFunction();
527 MachineFrameInfo &MFI = MF.getFrameInfo();
528 MFI.setReturnAddressIsTaken(true);
529 MVT XLenVT = Subtarget.getXLenVT();
530 int XLenInBytes = Subtarget.getXLen() / 8;
531
532 if (verifyReturnAddressArgumentIsConstant(Op, DAG))
533 return SDValue();
534
535 EVT VT = Op.getValueType();
536 SDLoc DL(Op);
537 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
538 if (Depth) {
539 int Off = -XLenInBytes;
Alex Bradbury0e167662018-10-04 05:27:50 +0000540 SDValue FrameAddr = lowerFRAMEADDR(Op, DAG);
Alex Bradbury70f137b2018-01-10 20:12:00 +0000541 SDValue Offset = DAG.getConstant(Off, DL, VT);
542 return DAG.getLoad(VT, DL, DAG.getEntryNode(),
543 DAG.getNode(ISD::ADD, DL, VT, FrameAddr, Offset),
544 MachinePointerInfo());
545 }
546
547 // Return the value of the return address register, marking it an implicit
548 // live-in.
549 unsigned Reg = MF.addLiveIn(RI.getRARegister(), getRegClassFor(XLenVT));
550 return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, XLenVT);
551}
552
Alex Bradbury299d6902019-01-25 05:04:00 +0000553// Returns the opcode of the target-specific SDNode that implements the 32-bit
554// form of the given Opcode.
555static RISCVISD::NodeType getRISCVWOpcode(unsigned Opcode) {
556 switch (Opcode) {
Alex Bradburyd05eae72019-01-12 07:32:31 +0000557 default:
Alex Bradbury299d6902019-01-25 05:04:00 +0000558 llvm_unreachable("Unexpected opcode");
559 case ISD::SHL:
560 return RISCVISD::SLLW;
561 case ISD::SRA:
562 return RISCVISD::SRAW;
563 case ISD::SRL:
564 return RISCVISD::SRLW;
Alex Bradbury456d3792019-01-25 05:11:34 +0000565 case ISD::SDIV:
566 return RISCVISD::DIVW;
567 case ISD::UDIV:
568 return RISCVISD::DIVUW;
569 case ISD::UREM:
570 return RISCVISD::REMUW;
Alex Bradbury299d6902019-01-25 05:04:00 +0000571 }
572}
573
574// Converts the given 32-bit operation to a target-specific SelectionDAG node.
575// Because i32 isn't a legal type for RV64, these operations would otherwise
576// be promoted to i64, making it difficult to select the SLLW/DIVUW/.../*W
577// later one because the fact the operation was originally of type i32 is
578// lost.
579static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG) {
580 SDLoc DL(N);
581 RISCVISD::NodeType WOpcode = getRISCVWOpcode(N->getOpcode());
582 SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0));
583 SDValue NewOp1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
584 SDValue NewRes = DAG.getNode(WOpcode, DL, MVT::i64, NewOp0, NewOp1);
585 // ReplaceNodeResults requires we maintain the same type for the return value.
586 return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewRes);
587}
588
589void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
590 SmallVectorImpl<SDValue> &Results,
591 SelectionDAG &DAG) const {
592 SDLoc DL(N);
593 switch (N->getOpcode()) {
594 default:
595 llvm_unreachable("Don't know how to custom type legalize this operation!");
Alex Bradburyd05eae72019-01-12 07:32:31 +0000596 case ISD::SHL:
597 case ISD::SRA:
598 case ISD::SRL:
Alex Bradbury299d6902019-01-25 05:04:00 +0000599 assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
600 "Unexpected custom legalisation");
601 if (N->getOperand(1).getOpcode() == ISD::Constant)
602 return;
603 Results.push_back(customLegalizeToWOp(N, DAG));
604 break;
Alex Bradbury61aa9402019-01-12 07:43:06 +0000605 case ISD::SDIV:
606 case ISD::UDIV:
607 case ISD::UREM:
Alex Bradbury456d3792019-01-25 05:11:34 +0000608 assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
609 Subtarget.hasStdExtM() && "Unexpected custom legalisation");
610 if (N->getOperand(0).getOpcode() == ISD::Constant ||
611 N->getOperand(1).getOpcode() == ISD::Constant)
612 return;
613 Results.push_back(customLegalizeToWOp(N, DAG));
614 break;
Alex Bradburyd834d832019-01-31 22:48:38 +0000615 case ISD::BITCAST: {
616 assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
617 Subtarget.hasStdExtF() && "Unexpected custom legalisation");
618 SDLoc DL(N);
619 SDValue Op0 = N->getOperand(0);
620 if (Op0.getValueType() != MVT::f32)
621 return;
622 SDValue FPConv =
623 DAG.getNode(RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64, Op0);
624 Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, FPConv));
625 break;
626 }
Alex Bradbury61aa9402019-01-12 07:43:06 +0000627 }
628}
629
Alex Bradbury5ac0a2f2018-10-03 23:30:16 +0000630SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
631 DAGCombinerInfo &DCI) const {
Alex Bradbury0092df02019-01-25 21:55:48 +0000632 SelectionDAG &DAG = DCI.DAG;
633
Alex Bradbury5ac0a2f2018-10-03 23:30:16 +0000634 switch (N->getOpcode()) {
635 default:
636 break;
637 case RISCVISD::SplitF64: {
Alex Bradbury0092df02019-01-25 21:55:48 +0000638 SDValue Op0 = N->getOperand(0);
Alex Bradbury5ac0a2f2018-10-03 23:30:16 +0000639 // If the input to SplitF64 is just BuildPairF64 then the operation is
640 // redundant. Instead, use BuildPairF64's operands directly.
Alex Bradbury0092df02019-01-25 21:55:48 +0000641 if (Op0->getOpcode() == RISCVISD::BuildPairF64)
642 return DCI.CombineTo(N, Op0.getOperand(0), Op0.getOperand(1));
643
644 SDLoc DL(N);
Alex Bradbury9681b012019-03-30 09:15:47 +0000645
646 // It's cheaper to materialise two 32-bit integers than to load a double
647 // from the constant pool and transfer it to integer registers through the
648 // stack.
649 if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Op0)) {
650 APInt V = C->getValueAPF().bitcastToAPInt();
651 SDValue Lo = DAG.getConstant(V.trunc(32), DL, MVT::i32);
652 SDValue Hi = DAG.getConstant(V.lshr(32).trunc(32), DL, MVT::i32);
653 return DCI.CombineTo(N, Lo, Hi);
654 }
655
Alex Bradbury0092df02019-01-25 21:55:48 +0000656 // This is a target-specific version of a DAGCombine performed in
657 // DAGCombiner::visitBITCAST. It performs the equivalent of:
658 // fold (bitconvert (fneg x)) -> (xor (bitconvert x), signbit)
659 // fold (bitconvert (fabs x)) -> (and (bitconvert x), (not signbit))
660 if (!(Op0.getOpcode() == ISD::FNEG || Op0.getOpcode() == ISD::FABS) ||
661 !Op0.getNode()->hasOneUse())
Alex Bradbury5ac0a2f2018-10-03 23:30:16 +0000662 break;
Alex Bradbury0092df02019-01-25 21:55:48 +0000663 SDValue NewSplitF64 =
664 DAG.getNode(RISCVISD::SplitF64, DL, DAG.getVTList(MVT::i32, MVT::i32),
665 Op0.getOperand(0));
666 SDValue Lo = NewSplitF64.getValue(0);
667 SDValue Hi = NewSplitF64.getValue(1);
668 APInt SignBit = APInt::getSignMask(32);
669 if (Op0.getOpcode() == ISD::FNEG) {
670 SDValue NewHi = DAG.getNode(ISD::XOR, DL, MVT::i32, Hi,
671 DAG.getConstant(SignBit, DL, MVT::i32));
672 return DCI.CombineTo(N, Lo, NewHi);
673 }
674 assert(Op0.getOpcode() == ISD::FABS);
675 SDValue NewHi = DAG.getNode(ISD::AND, DL, MVT::i32, Hi,
676 DAG.getConstant(~SignBit, DL, MVT::i32));
677 return DCI.CombineTo(N, Lo, NewHi);
Alex Bradbury5ac0a2f2018-10-03 23:30:16 +0000678 }
Alex Bradbury299d6902019-01-25 05:04:00 +0000679 case RISCVISD::SLLW:
680 case RISCVISD::SRAW:
681 case RISCVISD::SRLW: {
682 // Only the lower 32 bits of LHS and lower 5 bits of RHS are read.
683 SDValue LHS = N->getOperand(0);
684 SDValue RHS = N->getOperand(1);
685 APInt LHSMask = APInt::getLowBitsSet(LHS.getValueSizeInBits(), 32);
686 APInt RHSMask = APInt::getLowBitsSet(RHS.getValueSizeInBits(), 5);
687 if ((SimplifyDemandedBits(N->getOperand(0), LHSMask, DCI)) ||
688 (SimplifyDemandedBits(N->getOperand(1), RHSMask, DCI)))
689 return SDValue();
690 break;
691 }
Alex Bradburyd834d832019-01-31 22:48:38 +0000692 case RISCVISD::FMV_X_ANYEXTW_RV64: {
693 SDLoc DL(N);
694 SDValue Op0 = N->getOperand(0);
695 // If the input to FMV_X_ANYEXTW_RV64 is just FMV_W_X_RV64 then the
696 // conversion is unnecessary and can be replaced with an ANY_EXTEND
697 // of the FMV_W_X_RV64 operand.
698 if (Op0->getOpcode() == RISCVISD::FMV_W_X_RV64) {
699 SDValue AExtOp =
700 DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op0.getOperand(0));
701 return DCI.CombineTo(N, AExtOp);
702 }
703
704 // This is a target-specific version of a DAGCombine performed in
705 // DAGCombiner::visitBITCAST. It performs the equivalent of:
706 // fold (bitconvert (fneg x)) -> (xor (bitconvert x), signbit)
707 // fold (bitconvert (fabs x)) -> (and (bitconvert x), (not signbit))
708 if (!(Op0.getOpcode() == ISD::FNEG || Op0.getOpcode() == ISD::FABS) ||
709 !Op0.getNode()->hasOneUse())
710 break;
711 SDValue NewFMV = DAG.getNode(RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64,
712 Op0.getOperand(0));
713 APInt SignBit = APInt::getSignMask(32).sext(64);
714 if (Op0.getOpcode() == ISD::FNEG) {
715 return DCI.CombineTo(N,
716 DAG.getNode(ISD::XOR, DL, MVT::i64, NewFMV,
717 DAG.getConstant(SignBit, DL, MVT::i64)));
718 }
719 assert(Op0.getOpcode() == ISD::FABS);
720 return DCI.CombineTo(N,
721 DAG.getNode(ISD::AND, DL, MVT::i64, NewFMV,
722 DAG.getConstant(~SignBit, DL, MVT::i64)));
723 }
Alex Bradbury5ac0a2f2018-10-03 23:30:16 +0000724 }
725
726 return SDValue();
727}
728
Alex Bradbury299d6902019-01-25 05:04:00 +0000729unsigned RISCVTargetLowering::ComputeNumSignBitsForTargetNode(
730 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
731 unsigned Depth) const {
732 switch (Op.getOpcode()) {
733 default:
734 break;
735 case RISCVISD::SLLW:
736 case RISCVISD::SRAW:
737 case RISCVISD::SRLW:
Alex Bradbury456d3792019-01-25 05:11:34 +0000738 case RISCVISD::DIVW:
739 case RISCVISD::DIVUW:
740 case RISCVISD::REMUW:
Alex Bradbury299d6902019-01-25 05:04:00 +0000741 // TODO: As the result is sign-extended, this is conservatively correct. A
742 // more precise answer could be calculated for SRAW depending on known
743 // bits in the shift amount.
744 return 33;
745 }
746
747 return 1;
748}
749
Alex Bradbury0b4175f2018-04-12 05:34:25 +0000750static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
751 MachineBasicBlock *BB) {
752 assert(MI.getOpcode() == RISCV::SplitF64Pseudo && "Unexpected instruction");
753
754 MachineFunction &MF = *BB->getParent();
755 DebugLoc DL = MI.getDebugLoc();
756 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
757 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
758 unsigned LoReg = MI.getOperand(0).getReg();
759 unsigned HiReg = MI.getOperand(1).getReg();
760 unsigned SrcReg = MI.getOperand(2).getReg();
761 const TargetRegisterClass *SrcRC = &RISCV::FPR64RegClass;
762 int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex();
763
764 TII.storeRegToStackSlot(*BB, MI, SrcReg, MI.getOperand(2).isKill(), FI, SrcRC,
765 RI);
766 MachineMemOperand *MMO =
767 MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(MF, FI),
768 MachineMemOperand::MOLoad, 8, 8);
769 BuildMI(*BB, MI, DL, TII.get(RISCV::LW), LoReg)
770 .addFrameIndex(FI)
771 .addImm(0)
772 .addMemOperand(MMO);
773 BuildMI(*BB, MI, DL, TII.get(RISCV::LW), HiReg)
774 .addFrameIndex(FI)
775 .addImm(4)
776 .addMemOperand(MMO);
777 MI.eraseFromParent(); // The pseudo instruction is gone now.
778 return BB;
779}
780
781static MachineBasicBlock *emitBuildPairF64Pseudo(MachineInstr &MI,
782 MachineBasicBlock *BB) {
783 assert(MI.getOpcode() == RISCV::BuildPairF64Pseudo &&
784 "Unexpected instruction");
785
786 MachineFunction &MF = *BB->getParent();
787 DebugLoc DL = MI.getDebugLoc();
788 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
789 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
790 unsigned DstReg = MI.getOperand(0).getReg();
791 unsigned LoReg = MI.getOperand(1).getReg();
792 unsigned HiReg = MI.getOperand(2).getReg();
793 const TargetRegisterClass *DstRC = &RISCV::FPR64RegClass;
794 int FI = MF.getInfo<RISCVMachineFunctionInfo>()->getMoveF64FrameIndex();
795
796 MachineMemOperand *MMO =
797 MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(MF, FI),
798 MachineMemOperand::MOStore, 8, 8);
799 BuildMI(*BB, MI, DL, TII.get(RISCV::SW))
800 .addReg(LoReg, getKillRegState(MI.getOperand(1).isKill()))
801 .addFrameIndex(FI)
802 .addImm(0)
803 .addMemOperand(MMO);
804 BuildMI(*BB, MI, DL, TII.get(RISCV::SW))
805 .addReg(HiReg, getKillRegState(MI.getOperand(2).isKill()))
806 .addFrameIndex(FI)
807 .addImm(4)
808 .addMemOperand(MMO);
809 TII.loadRegFromStackSlot(*BB, MI, DstReg, FI, DstRC, RI);
810 MI.eraseFromParent(); // The pseudo instruction is gone now.
811 return BB;
812}
813
Alex Bradburyb9e78c32019-03-22 10:45:03 +0000814static bool isSelectPseudo(MachineInstr &MI) {
815 switch (MI.getOpcode()) {
816 default:
817 return false;
818 case RISCV::Select_GPR_Using_CC_GPR:
819 case RISCV::Select_FPR32_Using_CC_GPR:
820 case RISCV::Select_FPR64_Using_CC_GPR:
821 return true;
822 }
823}
824
Alex Bradburybd0eff32019-03-09 09:30:14 +0000825static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
826 MachineBasicBlock *BB) {
Alex Bradburyb9e78c32019-03-22 10:45:03 +0000827 // To "insert" Select_* instructions, we actually have to insert the triangle
828 // control-flow pattern. The incoming instructions know the destination vreg
Alex Bradbury65385162017-11-21 07:51:32 +0000829 // to set, the condition code register to branch on, the true/false values to
830 // select between, and the condcode to use to select the appropriate branch.
831 //
832 // We produce the following control flow:
833 // HeadMBB
834 // | \
835 // | IfFalseMBB
836 // | /
837 // TailMBB
Alex Bradburyb9e78c32019-03-22 10:45:03 +0000838 //
839 // When we find a sequence of selects we attempt to optimize their emission
840 // by sharing the control flow. Currently we only handle cases where we have
841 // multiple selects with the exact same condition (same LHS, RHS and CC).
842 // The selects may be interleaved with other instructions if the other
843 // instructions meet some requirements we deem safe:
844 // - They are debug instructions. Otherwise,
845 // - They do not have side-effects, do not access memory and their inputs do
846 // not depend on the results of the select pseudo-instructions.
847 // The TrueV/FalseV operands of the selects cannot depend on the result of
848 // previous selects in the sequence.
849 // These conditions could be further relaxed. See the X86 target for a
850 // related approach and more information.
851 unsigned LHS = MI.getOperand(1).getReg();
852 unsigned RHS = MI.getOperand(2).getReg();
853 auto CC = static_cast<ISD::CondCode>(MI.getOperand(3).getImm());
854
855 SmallVector<MachineInstr *, 4> SelectDebugValues;
856 SmallSet<unsigned, 4> SelectDests;
857 SelectDests.insert(MI.getOperand(0).getReg());
858
859 MachineInstr *LastSelectPseudo = &MI;
860
861 for (auto E = BB->end(), SequenceMBBI = MachineBasicBlock::iterator(MI);
862 SequenceMBBI != E; ++SequenceMBBI) {
863 if (SequenceMBBI->isDebugInstr())
864 continue;
865 else if (isSelectPseudo(*SequenceMBBI)) {
866 if (SequenceMBBI->getOperand(1).getReg() != LHS ||
867 SequenceMBBI->getOperand(2).getReg() != RHS ||
868 SequenceMBBI->getOperand(3).getImm() != CC ||
869 SelectDests.count(SequenceMBBI->getOperand(4).getReg()) ||
870 SelectDests.count(SequenceMBBI->getOperand(5).getReg()))
871 break;
872 LastSelectPseudo = &*SequenceMBBI;
873 SequenceMBBI->collectDebugValues(SelectDebugValues);
874 SelectDests.insert(SequenceMBBI->getOperand(0).getReg());
875 } else {
876 if (SequenceMBBI->hasUnmodeledSideEffects() ||
877 SequenceMBBI->mayLoadOrStore())
878 break;
879 if (llvm::any_of(SequenceMBBI->operands(), [&](MachineOperand &MO) {
880 return MO.isReg() && MO.isUse() && SelectDests.count(MO.getReg());
881 }))
882 break;
883 }
884 }
885
Alex Bradbury0b4175f2018-04-12 05:34:25 +0000886 const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
Alex Bradbury65385162017-11-21 07:51:32 +0000887 const BasicBlock *LLVM_BB = BB->getBasicBlock();
Alex Bradbury0b4175f2018-04-12 05:34:25 +0000888 DebugLoc DL = MI.getDebugLoc();
Alex Bradbury65385162017-11-21 07:51:32 +0000889 MachineFunction::iterator I = ++BB->getIterator();
890
891 MachineBasicBlock *HeadMBB = BB;
892 MachineFunction *F = BB->getParent();
893 MachineBasicBlock *TailMBB = F->CreateMachineBasicBlock(LLVM_BB);
894 MachineBasicBlock *IfFalseMBB = F->CreateMachineBasicBlock(LLVM_BB);
895
896 F->insert(I, IfFalseMBB);
897 F->insert(I, TailMBB);
Alex Bradburyb9e78c32019-03-22 10:45:03 +0000898
899 // Transfer debug instructions associated with the selects to TailMBB.
900 for (MachineInstr *DebugInstr : SelectDebugValues) {
901 TailMBB->push_back(DebugInstr->removeFromParent());
902 }
903
904 // Move all instructions after the sequence to TailMBB.
905 TailMBB->splice(TailMBB->end(), HeadMBB,
906 std::next(LastSelectPseudo->getIterator()), HeadMBB->end());
Alex Bradbury65385162017-11-21 07:51:32 +0000907 // Update machine-CFG edges by transferring all successors of the current
Alex Bradburyb9e78c32019-03-22 10:45:03 +0000908 // block to the new block which will contain the Phi nodes for the selects.
Alex Bradbury65385162017-11-21 07:51:32 +0000909 TailMBB->transferSuccessorsAndUpdatePHIs(HeadMBB);
910 // Set the successors for HeadMBB.
911 HeadMBB->addSuccessor(IfFalseMBB);
912 HeadMBB->addSuccessor(TailMBB);
913
914 // Insert appropriate branch.
Alex Bradbury65385162017-11-21 07:51:32 +0000915 unsigned Opcode = getBranchOpcodeForIntCondCode(CC);
916
917 BuildMI(HeadMBB, DL, TII.get(Opcode))
918 .addReg(LHS)
919 .addReg(RHS)
920 .addMBB(TailMBB);
921
922 // IfFalseMBB just falls through to TailMBB.
923 IfFalseMBB->addSuccessor(TailMBB);
924
Alex Bradburyb9e78c32019-03-22 10:45:03 +0000925 // Create PHIs for all of the select pseudo-instructions.
926 auto SelectMBBI = MI.getIterator();
927 auto SelectEnd = std::next(LastSelectPseudo->getIterator());
928 auto InsertionPoint = TailMBB->begin();
929 while (SelectMBBI != SelectEnd) {
930 auto Next = std::next(SelectMBBI);
931 if (isSelectPseudo(*SelectMBBI)) {
932 // %Result = phi [ %TrueValue, HeadMBB ], [ %FalseValue, IfFalseMBB ]
933 BuildMI(*TailMBB, InsertionPoint, SelectMBBI->getDebugLoc(),
934 TII.get(RISCV::PHI), SelectMBBI->getOperand(0).getReg())
935 .addReg(SelectMBBI->getOperand(4).getReg())
936 .addMBB(HeadMBB)
937 .addReg(SelectMBBI->getOperand(5).getReg())
938 .addMBB(IfFalseMBB);
939 SelectMBBI->eraseFromParent();
940 }
941 SelectMBBI = Next;
942 }
Alex Bradbury65385162017-11-21 07:51:32 +0000943
Alex Bradbury65385162017-11-21 07:51:32 +0000944 return TailMBB;
945}
946
Alex Bradburybd0eff32019-03-09 09:30:14 +0000947MachineBasicBlock *
948RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
949 MachineBasicBlock *BB) const {
950 switch (MI.getOpcode()) {
951 default:
952 llvm_unreachable("Unexpected instr type to insert");
953 case RISCV::Select_GPR_Using_CC_GPR:
954 case RISCV::Select_FPR32_Using_CC_GPR:
955 case RISCV::Select_FPR64_Using_CC_GPR:
956 return emitSelectPseudo(MI, BB);
957 case RISCV::BuildPairF64Pseudo:
958 return emitBuildPairF64Pseudo(MI, BB);
959 case RISCV::SplitF64Pseudo:
960 return emitSplitF64Pseudo(MI, BB);
961 }
962}
963
Alex Bradbury89718422017-10-19 21:37:38 +0000964// Calling Convention Implementation.
Alex Bradburydc31c612017-12-11 12:49:02 +0000965// The expectations for frontend ABI lowering vary from target to target.
966// Ideally, an LLVM frontend would be able to avoid worrying about many ABI
967// details, but this is a longer term goal. For now, we simply try to keep the
968// role of the frontend as simple and well-defined as possible. The rules can
969// be summarised as:
970// * Never split up large scalar arguments. We handle them here.
971// * If a hardfloat calling convention is being used, and the struct may be
972// passed in a pair of registers (fp+fp, int+fp), and both registers are
973// available, then pass as two separate arguments. If either the GPRs or FPRs
974// are exhausted, then pass according to the rule below.
975// * If a struct could never be passed in registers or directly in a stack
976// slot (as it is larger than 2*XLEN and the floating point rules don't
977// apply), then pass it using a pointer with the byval attribute.
978// * If a struct is less than 2*XLEN, then coerce to either a two-element
979// word-sized array or a 2*XLEN scalar (depending on alignment).
980// * The frontend can determine whether a struct is returned by reference or
981// not based on its size and fields. If it will be returned by reference, the
982// frontend must modify the prototype so a pointer with the sret annotation is
983// passed as the first argument. This is not necessary for large scalar
984// returns.
985// * Struct return values and varargs should be coerced to structs containing
986// register-size fields in the same situations they would be for fixed
987// arguments.
988
989static const MCPhysReg ArgGPRs[] = {
990 RISCV::X10, RISCV::X11, RISCV::X12, RISCV::X13,
991 RISCV::X14, RISCV::X15, RISCV::X16, RISCV::X17
992};
Alex Bradbury0b2803e2019-03-30 17:59:30 +0000993static const MCPhysReg ArgFPR32s[] = {
994 RISCV::F10_32, RISCV::F11_32, RISCV::F12_32, RISCV::F13_32,
995 RISCV::F14_32, RISCV::F15_32, RISCV::F16_32, RISCV::F17_32
996};
997static const MCPhysReg ArgFPR64s[] = {
998 RISCV::F10_64, RISCV::F11_64, RISCV::F12_64, RISCV::F13_64,
999 RISCV::F14_64, RISCV::F15_64, RISCV::F16_64, RISCV::F17_64
1000};
Alex Bradburydc31c612017-12-11 12:49:02 +00001001
1002// Pass a 2*XLEN argument that has been split into two XLEN values through
1003// registers or the stack as necessary.
1004static bool CC_RISCVAssign2XLen(unsigned XLen, CCState &State, CCValAssign VA1,
1005 ISD::ArgFlagsTy ArgFlags1, unsigned ValNo2,
1006 MVT ValVT2, MVT LocVT2,
1007 ISD::ArgFlagsTy ArgFlags2) {
1008 unsigned XLenInBytes = XLen / 8;
1009 if (unsigned Reg = State.AllocateReg(ArgGPRs)) {
1010 // At least one half can be passed via register.
1011 State.addLoc(CCValAssign::getReg(VA1.getValNo(), VA1.getValVT(), Reg,
1012 VA1.getLocVT(), CCValAssign::Full));
1013 } else {
1014 // Both halves must be passed on the stack, with proper alignment.
1015 unsigned StackAlign = std::max(XLenInBytes, ArgFlags1.getOrigAlign());
1016 State.addLoc(
1017 CCValAssign::getMem(VA1.getValNo(), VA1.getValVT(),
1018 State.AllocateStack(XLenInBytes, StackAlign),
1019 VA1.getLocVT(), CCValAssign::Full));
1020 State.addLoc(CCValAssign::getMem(
1021 ValNo2, ValVT2, State.AllocateStack(XLenInBytes, XLenInBytes), LocVT2,
1022 CCValAssign::Full));
1023 return false;
1024 }
1025
1026 if (unsigned Reg = State.AllocateReg(ArgGPRs)) {
1027 // The second half can also be passed via register.
1028 State.addLoc(
1029 CCValAssign::getReg(ValNo2, ValVT2, Reg, LocVT2, CCValAssign::Full));
1030 } else {
1031 // The second half is passed via the stack, without additional alignment.
1032 State.addLoc(CCValAssign::getMem(
1033 ValNo2, ValVT2, State.AllocateStack(XLenInBytes, XLenInBytes), LocVT2,
1034 CCValAssign::Full));
1035 }
1036
1037 return false;
1038}
1039
1040// Implements the RISC-V calling convention. Returns true upon failure.
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001041static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo,
1042 MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo,
1043 ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed,
1044 bool IsRet, Type *OrigTy) {
Alex Bradburydc31c612017-12-11 12:49:02 +00001045 unsigned XLen = DL.getLargestLegalIntTypeSizeInBits();
1046 assert(XLen == 32 || XLen == 64);
1047 MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64;
Alex Bradburydc31c612017-12-11 12:49:02 +00001048
1049 // Any return value split in to more than two values can't be returned
1050 // directly.
1051 if (IsRet && ValNo > 1)
1052 return true;
1053
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001054 // UseGPRForF32 if targeting one of the soft-float ABIs, if passing a
1055 // variadic argument, or if no F32 argument registers are available.
1056 bool UseGPRForF32 = true;
1057 // UseGPRForF64 if targeting soft-float ABIs or an FLEN=32 ABI, if passing a
1058 // variadic argument, or if no F64 argument registers are available.
1059 bool UseGPRForF64 = true;
1060
1061 switch (ABI) {
1062 default:
1063 llvm_unreachable("Unexpected ABI");
1064 case RISCVABI::ABI_ILP32:
1065 case RISCVABI::ABI_LP64:
1066 break;
1067 case RISCVABI::ABI_ILP32F:
1068 case RISCVABI::ABI_LP64F:
1069 UseGPRForF32 = !IsFixed;
1070 break;
1071 case RISCVABI::ABI_ILP32D:
1072 case RISCVABI::ABI_LP64D:
1073 UseGPRForF32 = !IsFixed;
1074 UseGPRForF64 = !IsFixed;
1075 break;
1076 }
1077
1078 if (State.getFirstUnallocated(ArgFPR32s) == array_lengthof(ArgFPR32s))
1079 UseGPRForF32 = true;
1080 if (State.getFirstUnallocated(ArgFPR64s) == array_lengthof(ArgFPR64s))
1081 UseGPRForF64 = true;
1082
1083 // From this point on, rely on UseGPRForF32, UseGPRForF64 and similar local
1084 // variables rather than directly checking against the target ABI.
1085
1086 if (UseGPRForF32 && ValVT == MVT::f32) {
Alex Bradbury62c8a572019-03-09 11:16:27 +00001087 LocVT = XLenVT;
1088 LocInfo = CCValAssign::BCvt;
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001089 } else if (UseGPRForF64 && XLen == 64 && ValVT == MVT::f64) {
Alex Bradbury62c8a572019-03-09 11:16:27 +00001090 LocVT = MVT::i64;
1091 LocInfo = CCValAssign::BCvt;
1092 }
1093
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001094 // If this is a variadic argument, the RISC-V calling convention requires
1095 // that it is assigned an 'even' or 'aligned' register if it has 8-byte
1096 // alignment (RV32) or 16-byte alignment (RV64). An aligned register should
1097 // be used regardless of whether the original argument was split during
1098 // legalisation or not. The argument will not be passed by registers if the
1099 // original type is larger than 2*XLEN, so the register alignment rule does
1100 // not apply.
1101 unsigned TwoXLenInBytes = (2 * XLen) / 8;
1102 if (!IsFixed && ArgFlags.getOrigAlign() == TwoXLenInBytes &&
1103 DL.getTypeAllocSize(OrigTy) == TwoXLenInBytes) {
1104 unsigned RegIdx = State.getFirstUnallocated(ArgGPRs);
1105 // Skip 'odd' register if necessary.
1106 if (RegIdx != array_lengthof(ArgGPRs) && RegIdx % 2 == 1)
1107 State.AllocateReg(ArgGPRs);
1108 }
1109
Alex Bradburydc31c612017-12-11 12:49:02 +00001110 SmallVectorImpl<CCValAssign> &PendingLocs = State.getPendingLocs();
1111 SmallVectorImpl<ISD::ArgFlagsTy> &PendingArgFlags =
1112 State.getPendingArgFlags();
1113
1114 assert(PendingLocs.size() == PendingArgFlags.size() &&
1115 "PendingLocs and PendingArgFlags out of sync");
1116
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001117 // Handle passing f64 on RV32D with a soft float ABI or when floating point
1118 // registers are exhausted.
1119 if (UseGPRForF64 && XLen == 32 && ValVT == MVT::f64) {
Mandeep Singh Grang88a8b262018-04-16 18:56:10 +00001120 assert(!ArgFlags.isSplit() && PendingLocs.empty() &&
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001121 "Can't lower f64 if it is split");
1122 // Depending on available argument GPRS, f64 may be passed in a pair of
1123 // GPRs, split between a GPR and the stack, or passed completely on the
1124 // stack. LowerCall/LowerFormalArguments/LowerReturn must recognise these
1125 // cases.
1126 unsigned Reg = State.AllocateReg(ArgGPRs);
1127 LocVT = MVT::i32;
1128 if (!Reg) {
1129 unsigned StackOffset = State.AllocateStack(8, 8);
1130 State.addLoc(
1131 CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
1132 return false;
1133 }
1134 if (!State.AllocateReg(ArgGPRs))
1135 State.AllocateStack(4, 4);
1136 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
1137 return false;
1138 }
1139
Alex Bradburydc31c612017-12-11 12:49:02 +00001140 // Split arguments might be passed indirectly, so keep track of the pending
1141 // values.
1142 if (ArgFlags.isSplit() || !PendingLocs.empty()) {
1143 LocVT = XLenVT;
1144 LocInfo = CCValAssign::Indirect;
1145 PendingLocs.push_back(
1146 CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo));
1147 PendingArgFlags.push_back(ArgFlags);
1148 if (!ArgFlags.isSplitEnd()) {
1149 return false;
1150 }
1151 }
1152
1153 // If the split argument only had two elements, it should be passed directly
1154 // in registers or on the stack.
1155 if (ArgFlags.isSplitEnd() && PendingLocs.size() <= 2) {
1156 assert(PendingLocs.size() == 2 && "Unexpected PendingLocs.size()");
1157 // Apply the normal calling convention rules to the first half of the
1158 // split argument.
1159 CCValAssign VA = PendingLocs[0];
1160 ISD::ArgFlagsTy AF = PendingArgFlags[0];
1161 PendingLocs.clear();
1162 PendingArgFlags.clear();
1163 return CC_RISCVAssign2XLen(XLen, State, VA, AF, ValNo, ValVT, LocVT,
1164 ArgFlags);
1165 }
1166
1167 // Allocate to a register if possible, or else a stack slot.
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001168 unsigned Reg;
1169 if (ValVT == MVT::f32 && !UseGPRForF32)
1170 Reg = State.AllocateReg(ArgFPR32s, ArgFPR64s);
1171 else if (ValVT == MVT::f64 && !UseGPRForF64)
1172 Reg = State.AllocateReg(ArgFPR64s, ArgFPR32s);
1173 else
1174 Reg = Reg = State.AllocateReg(ArgGPRs);
Alex Bradburydc31c612017-12-11 12:49:02 +00001175 unsigned StackOffset = Reg ? 0 : State.AllocateStack(XLen / 8, XLen / 8);
1176
1177 // If we reach this point and PendingLocs is non-empty, we must be at the
1178 // end of a split argument that must be passed indirectly.
1179 if (!PendingLocs.empty()) {
1180 assert(ArgFlags.isSplitEnd() && "Expected ArgFlags.isSplitEnd()");
1181 assert(PendingLocs.size() > 2 && "Unexpected PendingLocs.size()");
1182
1183 for (auto &It : PendingLocs) {
1184 if (Reg)
1185 It.convertToReg(Reg);
1186 else
1187 It.convertToMem(StackOffset);
1188 State.addLoc(It);
1189 }
1190 PendingLocs.clear();
1191 PendingArgFlags.clear();
1192 return false;
1193 }
1194
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001195 assert((!UseGPRForF32 || !UseGPRForF64 || LocVT == XLenVT) &&
1196 "Expected an XLenVT at this stage");
Alex Bradburydc31c612017-12-11 12:49:02 +00001197
1198 if (Reg) {
1199 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
Alex Bradburye96b7c882018-10-04 07:28:49 +00001200 return false;
Alex Bradburydc31c612017-12-11 12:49:02 +00001201 }
Alex Bradburye96b7c882018-10-04 07:28:49 +00001202
Alex Bradbury7539fa22019-02-01 03:53:30 +00001203 // When an f32 or f64 is passed on the stack, no bit-conversion is needed.
1204 if (ValVT == MVT::f32 || ValVT == MVT::f64) {
1205 LocVT = ValVT;
Alex Bradburye96b7c882018-10-04 07:28:49 +00001206 LocInfo = CCValAssign::Full;
1207 }
1208 State.addLoc(CCValAssign::getMem(ValNo, ValVT, StackOffset, LocVT, LocInfo));
Alex Bradburydc31c612017-12-11 12:49:02 +00001209 return false;
1210}
1211
1212void RISCVTargetLowering::analyzeInputArgs(
1213 MachineFunction &MF, CCState &CCInfo,
1214 const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet) const {
1215 unsigned NumArgs = Ins.size();
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001216 FunctionType *FType = MF.getFunction().getFunctionType();
Alex Bradburydc31c612017-12-11 12:49:02 +00001217
1218 for (unsigned i = 0; i != NumArgs; ++i) {
1219 MVT ArgVT = Ins[i].VT;
1220 ISD::ArgFlagsTy ArgFlags = Ins[i].Flags;
1221
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001222 Type *ArgTy = nullptr;
1223 if (IsRet)
1224 ArgTy = FType->getReturnType();
1225 else if (Ins[i].isOrigArg())
1226 ArgTy = FType->getParamType(Ins[i].getOrigArgIndex());
1227
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001228 RISCVABI::ABI ABI = MF.getSubtarget<RISCVSubtarget>().getTargetABI();
1229 if (CC_RISCV(MF.getDataLayout(), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001230 ArgFlags, CCInfo, /*IsRet=*/true, IsRet, ArgTy)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001231 LLVM_DEBUG(dbgs() << "InputArg #" << i << " has unhandled type "
1232 << EVT(ArgVT).getEVTString() << '\n');
Alex Bradburydc31c612017-12-11 12:49:02 +00001233 llvm_unreachable(nullptr);
1234 }
1235 }
1236}
1237
1238void RISCVTargetLowering::analyzeOutputArgs(
1239 MachineFunction &MF, CCState &CCInfo,
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001240 const SmallVectorImpl<ISD::OutputArg> &Outs, bool IsRet,
1241 CallLoweringInfo *CLI) const {
Alex Bradburydc31c612017-12-11 12:49:02 +00001242 unsigned NumArgs = Outs.size();
1243
1244 for (unsigned i = 0; i != NumArgs; i++) {
1245 MVT ArgVT = Outs[i].VT;
1246 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001247 Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty : nullptr;
Alex Bradburydc31c612017-12-11 12:49:02 +00001248
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001249 RISCVABI::ABI ABI = MF.getSubtarget<RISCVSubtarget>().getTargetABI();
1250 if (CC_RISCV(MF.getDataLayout(), ABI, i, ArgVT, ArgVT, CCValAssign::Full,
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001251 ArgFlags, CCInfo, Outs[i].IsFixed, IsRet, OrigTy)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +00001252 LLVM_DEBUG(dbgs() << "OutputArg #" << i << " has unhandled type "
1253 << EVT(ArgVT).getEVTString() << "\n");
Alex Bradburydc31c612017-12-11 12:49:02 +00001254 llvm_unreachable(nullptr);
1255 }
1256 }
1257}
1258
Alex Bradbury1dbfdeb2018-10-03 22:53:25 +00001259// Convert Val to a ValVT. Should not be called for CCValAssign::Indirect
1260// values.
1261static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
1262 const CCValAssign &VA, const SDLoc &DL) {
1263 switch (VA.getLocInfo()) {
1264 default:
1265 llvm_unreachable("Unexpected CCValAssign::LocInfo");
1266 case CCValAssign::Full:
1267 break;
1268 case CCValAssign::BCvt:
Alex Bradburyd834d832019-01-31 22:48:38 +00001269 if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f32) {
1270 Val = DAG.getNode(RISCVISD::FMV_W_X_RV64, DL, MVT::f32, Val);
1271 break;
1272 }
Alex Bradbury1dbfdeb2018-10-03 22:53:25 +00001273 Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val);
1274 break;
1275 }
1276 return Val;
1277}
1278
Alex Bradburydc31c612017-12-11 12:49:02 +00001279// The caller is responsible for loading the full value if the argument is
1280// passed with CCValAssign::Indirect.
1281static SDValue unpackFromRegLoc(SelectionDAG &DAG, SDValue Chain,
1282 const CCValAssign &VA, const SDLoc &DL) {
1283 MachineFunction &MF = DAG.getMachineFunction();
1284 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1285 EVT LocVT = VA.getLocVT();
1286 SDValue Val;
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001287 const TargetRegisterClass *RC;
Alex Bradburydc31c612017-12-11 12:49:02 +00001288
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001289 switch (LocVT.getSimpleVT().SimpleTy) {
1290 default:
1291 llvm_unreachable("Unexpected register type");
1292 case MVT::i32:
1293 case MVT::i64:
1294 RC = &RISCV::GPRRegClass;
1295 break;
1296 case MVT::f32:
1297 RC = &RISCV::FPR32RegClass;
1298 break;
1299 case MVT::f64:
1300 RC = &RISCV::FPR64RegClass;
1301 break;
1302 }
1303
1304 unsigned VReg = RegInfo.createVirtualRegister(RC);
Alex Bradburydc31c612017-12-11 12:49:02 +00001305 RegInfo.addLiveIn(VA.getLocReg(), VReg);
1306 Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
1307
Alex Bradbury1dbfdeb2018-10-03 22:53:25 +00001308 if (VA.getLocInfo() == CCValAssign::Indirect)
1309 return Val;
1310
1311 return convertLocVTToValVT(DAG, Val, VA, DL);
1312}
1313
1314static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val,
1315 const CCValAssign &VA, const SDLoc &DL) {
1316 EVT LocVT = VA.getLocVT();
1317
Alex Bradburydc31c612017-12-11 12:49:02 +00001318 switch (VA.getLocInfo()) {
1319 default:
1320 llvm_unreachable("Unexpected CCValAssign::LocInfo");
1321 case CCValAssign::Full:
Alex Bradbury76c29ee2018-03-20 12:45:35 +00001322 break;
1323 case CCValAssign::BCvt:
Alex Bradburyd834d832019-01-31 22:48:38 +00001324 if (VA.getLocVT() == MVT::i64 && VA.getValVT() == MVT::f32) {
1325 Val = DAG.getNode(RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64, Val);
1326 break;
1327 }
Alex Bradbury1dbfdeb2018-10-03 22:53:25 +00001328 Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val);
Alex Bradbury76c29ee2018-03-20 12:45:35 +00001329 break;
Alex Bradburydc31c612017-12-11 12:49:02 +00001330 }
Alex Bradbury76c29ee2018-03-20 12:45:35 +00001331 return Val;
Alex Bradburydc31c612017-12-11 12:49:02 +00001332}
1333
1334// The caller is responsible for loading the full value if the argument is
1335// passed with CCValAssign::Indirect.
1336static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain,
1337 const CCValAssign &VA, const SDLoc &DL) {
1338 MachineFunction &MF = DAG.getMachineFunction();
1339 MachineFrameInfo &MFI = MF.getFrameInfo();
1340 EVT LocVT = VA.getLocVT();
1341 EVT ValVT = VA.getValVT();
1342 EVT PtrVT = MVT::getIntegerVT(DAG.getDataLayout().getPointerSizeInBits(0));
1343 int FI = MFI.CreateFixedObject(ValVT.getSizeInBits() / 8,
1344 VA.getLocMemOffset(), /*Immutable=*/true);
1345 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
1346 SDValue Val;
1347
1348 ISD::LoadExtType ExtType;
1349 switch (VA.getLocInfo()) {
1350 default:
1351 llvm_unreachable("Unexpected CCValAssign::LocInfo");
1352 case CCValAssign::Full:
1353 case CCValAssign::Indirect:
Alex Bradburyd834d832019-01-31 22:48:38 +00001354 case CCValAssign::BCvt:
Alex Bradburydc31c612017-12-11 12:49:02 +00001355 ExtType = ISD::NON_EXTLOAD;
1356 break;
1357 }
1358 Val = DAG.getExtLoad(
1359 ExtType, DL, LocVT, Chain, FIN,
1360 MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), ValVT);
1361 return Val;
1362}
Alex Bradbury89718422017-10-19 21:37:38 +00001363
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001364static SDValue unpackF64OnRV32DSoftABI(SelectionDAG &DAG, SDValue Chain,
1365 const CCValAssign &VA, const SDLoc &DL) {
1366 assert(VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64 &&
1367 "Unexpected VA");
1368 MachineFunction &MF = DAG.getMachineFunction();
1369 MachineFrameInfo &MFI = MF.getFrameInfo();
1370 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1371
1372 if (VA.isMemLoc()) {
1373 // f64 is passed on the stack.
1374 int FI = MFI.CreateFixedObject(8, VA.getLocMemOffset(), /*Immutable=*/true);
1375 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
1376 return DAG.getLoad(MVT::f64, DL, Chain, FIN,
1377 MachinePointerInfo::getFixedStack(MF, FI));
1378 }
1379
1380 assert(VA.isRegLoc() && "Expected register VA assignment");
1381
1382 unsigned LoVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
1383 RegInfo.addLiveIn(VA.getLocReg(), LoVReg);
1384 SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, MVT::i32);
1385 SDValue Hi;
1386 if (VA.getLocReg() == RISCV::X17) {
1387 // Second half of f64 is passed on the stack.
1388 int FI = MFI.CreateFixedObject(4, 0, /*Immutable=*/true);
1389 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
1390 Hi = DAG.getLoad(MVT::i32, DL, Chain, FIN,
1391 MachinePointerInfo::getFixedStack(MF, FI));
1392 } else {
1393 // Second half of f64 is passed in another GPR.
1394 unsigned HiVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
1395 RegInfo.addLiveIn(VA.getLocReg() + 1, HiVReg);
1396 Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32);
1397 }
1398 return DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
1399}
1400
Alex Bradbury89718422017-10-19 21:37:38 +00001401// Transform physical registers into virtual registers.
1402SDValue RISCVTargetLowering::LowerFormalArguments(
1403 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
1404 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
1405 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
1406
1407 switch (CallConv) {
1408 default:
1409 report_fatal_error("Unsupported calling convention");
1410 case CallingConv::C:
Alex Bradburya3376752017-11-08 13:41:21 +00001411 case CallingConv::Fast:
Alex Bradbury89718422017-10-19 21:37:38 +00001412 break;
1413 }
1414
1415 MachineFunction &MF = DAG.getMachineFunction();
Ana Pazos2e4106b2018-07-26 17:49:43 +00001416
1417 const Function &Func = MF.getFunction();
1418 if (Func.hasFnAttribute("interrupt")) {
1419 if (!Func.arg_empty())
1420 report_fatal_error(
1421 "Functions with the interrupt attribute cannot have arguments!");
1422
1423 StringRef Kind =
1424 MF.getFunction().getFnAttribute("interrupt").getValueAsString();
1425
1426 if (!(Kind == "user" || Kind == "supervisor" || Kind == "machine"))
1427 report_fatal_error(
1428 "Function interrupt attribute argument not supported!");
1429 }
1430
Alex Bradburydc31c612017-12-11 12:49:02 +00001431 EVT PtrVT = getPointerTy(DAG.getDataLayout());
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001432 MVT XLenVT = Subtarget.getXLenVT();
1433 unsigned XLenInBytes = Subtarget.getXLen() / 8;
1434 // Used with vargs to acumulate store chains.
1435 std::vector<SDValue> OutChains;
Alex Bradbury89718422017-10-19 21:37:38 +00001436
1437 // Assign locations to all of the incoming arguments.
1438 SmallVector<CCValAssign, 16> ArgLocs;
1439 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
Alex Bradburydc31c612017-12-11 12:49:02 +00001440 analyzeInputArgs(MF, CCInfo, Ins, /*IsRet=*/false);
Alex Bradbury89718422017-10-19 21:37:38 +00001441
Alex Bradburydc31c612017-12-11 12:49:02 +00001442 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1443 CCValAssign &VA = ArgLocs[i];
Alex Bradburydc31c612017-12-11 12:49:02 +00001444 SDValue ArgValue;
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001445 // Passing f64 on RV32D with a soft float ABI must be handled as a special
1446 // case.
1447 if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64)
1448 ArgValue = unpackF64OnRV32DSoftABI(DAG, Chain, VA, DL);
1449 else if (VA.isRegLoc())
Alex Bradburydc31c612017-12-11 12:49:02 +00001450 ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL);
1451 else
1452 ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
Alex Bradbury89718422017-10-19 21:37:38 +00001453
Alex Bradburydc31c612017-12-11 12:49:02 +00001454 if (VA.getLocInfo() == CCValAssign::Indirect) {
1455 // If the original argument was split and passed by reference (e.g. i128
1456 // on RV32), we need to load all parts of it here (using the same
1457 // address).
1458 InVals.push_back(DAG.getLoad(VA.getValVT(), DL, Chain, ArgValue,
1459 MachinePointerInfo()));
1460 unsigned ArgIndex = Ins[i].OrigArgIndex;
1461 assert(Ins[i].PartOffset == 0);
1462 while (i + 1 != e && Ins[i + 1].OrigArgIndex == ArgIndex) {
1463 CCValAssign &PartVA = ArgLocs[i + 1];
1464 unsigned PartOffset = Ins[i + 1].PartOffset;
1465 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, ArgValue,
1466 DAG.getIntPtrConstant(PartOffset, DL));
1467 InVals.push_back(DAG.getLoad(PartVA.getValVT(), DL, Chain, Address,
1468 MachinePointerInfo()));
1469 ++i;
1470 }
1471 continue;
Alex Bradbury89718422017-10-19 21:37:38 +00001472 }
Alex Bradburydc31c612017-12-11 12:49:02 +00001473 InVals.push_back(ArgValue);
Alex Bradbury89718422017-10-19 21:37:38 +00001474 }
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001475
1476 if (IsVarArg) {
1477 ArrayRef<MCPhysReg> ArgRegs = makeArrayRef(ArgGPRs);
1478 unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
1479 const TargetRegisterClass *RC = &RISCV::GPRRegClass;
1480 MachineFrameInfo &MFI = MF.getFrameInfo();
1481 MachineRegisterInfo &RegInfo = MF.getRegInfo();
1482 RISCVMachineFunctionInfo *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
1483
1484 // Offset of the first variable argument from stack pointer, and size of
1485 // the vararg save area. For now, the varargs save area is either zero or
1486 // large enough to hold a0-a7.
1487 int VaArgOffset, VarArgsSaveSize;
1488
1489 // If all registers are allocated, then all varargs must be passed on the
1490 // stack and we don't need to save any argregs.
1491 if (ArgRegs.size() == Idx) {
1492 VaArgOffset = CCInfo.getNextStackOffset();
1493 VarArgsSaveSize = 0;
1494 } else {
1495 VarArgsSaveSize = XLenInBytes * (ArgRegs.size() - Idx);
1496 VaArgOffset = -VarArgsSaveSize;
1497 }
1498
1499 // Record the frame index of the first variable argument
1500 // which is a value necessary to VASTART.
1501 int FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
1502 RVFI->setVarArgsFrameIndex(FI);
1503
1504 // If saving an odd number of registers then create an extra stack slot to
1505 // ensure that the frame pointer is 2*XLEN-aligned, which in turn ensures
1506 // offsets to even-numbered registered remain 2*XLEN-aligned.
1507 if (Idx % 2) {
1508 FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset - (int)XLenInBytes,
1509 true);
1510 VarArgsSaveSize += XLenInBytes;
1511 }
1512
1513 // Copy the integer registers that may have been used for passing varargs
1514 // to the vararg save area.
1515 for (unsigned I = Idx; I < ArgRegs.size();
1516 ++I, VaArgOffset += XLenInBytes) {
1517 const unsigned Reg = RegInfo.createVirtualRegister(RC);
1518 RegInfo.addLiveIn(ArgRegs[I], Reg);
1519 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, XLenVT);
1520 FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
1521 SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
1522 SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
1523 MachinePointerInfo::getFixedStack(MF, FI));
1524 cast<StoreSDNode>(Store.getNode())
1525 ->getMemOperand()
1526 ->setValue((Value *)nullptr);
1527 OutChains.push_back(Store);
1528 }
1529 RVFI->setVarArgsSaveSize(VarArgsSaveSize);
1530 }
1531
1532 // All stores are grouped in one node to allow the matching between
1533 // the size of Ins and InVals. This only happens for vararg functions.
1534 if (!OutChains.empty()) {
1535 OutChains.push_back(Chain);
1536 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1537 }
1538
Alex Bradbury89718422017-10-19 21:37:38 +00001539 return Chain;
1540}
1541
Alex Bradburydb67be82019-02-21 14:31:41 +00001542/// isEligibleForTailCallOptimization - Check whether the call is eligible
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001543/// for tail call optimization.
1544/// Note: This is modelled after ARM's IsEligibleForTailCallOptimization.
Alex Bradburydb67be82019-02-21 14:31:41 +00001545bool RISCVTargetLowering::isEligibleForTailCallOptimization(
1546 CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
1547 const SmallVector<CCValAssign, 16> &ArgLocs) const {
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001548
1549 auto &Callee = CLI.Callee;
1550 auto CalleeCC = CLI.CallConv;
1551 auto IsVarArg = CLI.IsVarArg;
1552 auto &Outs = CLI.Outs;
1553 auto &Caller = MF.getFunction();
1554 auto CallerCC = Caller.getCallingConv();
1555
1556 // Do not tail call opt functions with "disable-tail-calls" attribute.
1557 if (Caller.getFnAttribute("disable-tail-calls").getValueAsString() == "true")
1558 return false;
1559
1560 // Exception-handling functions need a special set of instructions to
1561 // indicate a return to the hardware. Tail-calling another function would
1562 // probably break this.
1563 // TODO: The "interrupt" attribute isn't currently defined by RISC-V. This
1564 // should be expanded as new function attributes are introduced.
1565 if (Caller.hasFnAttribute("interrupt"))
1566 return false;
1567
1568 // Do not tail call opt functions with varargs.
1569 if (IsVarArg)
1570 return false;
1571
1572 // Do not tail call opt if the stack is used to pass parameters.
1573 if (CCInfo.getNextStackOffset() != 0)
1574 return false;
1575
1576 // Do not tail call opt if any parameters need to be passed indirectly.
1577 // Since long doubles (fp128) and i128 are larger than 2*XLEN, they are
1578 // passed indirectly. So the address of the value will be passed in a
1579 // register, or if not available, then the address is put on the stack. In
1580 // order to pass indirectly, space on the stack often needs to be allocated
1581 // in order to store the value. In this case the CCInfo.getNextStackOffset()
1582 // != 0 check is not enough and we need to check if any CCValAssign ArgsLocs
1583 // are passed CCValAssign::Indirect.
1584 for (auto &VA : ArgLocs)
1585 if (VA.getLocInfo() == CCValAssign::Indirect)
1586 return false;
1587
1588 // Do not tail call opt if either caller or callee uses struct return
1589 // semantics.
1590 auto IsCallerStructRet = Caller.hasStructRetAttr();
1591 auto IsCalleeStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
1592 if (IsCallerStructRet || IsCalleeStructRet)
1593 return false;
1594
1595 // Externally-defined functions with weak linkage should not be
1596 // tail-called. The behaviour of branch instructions in this situation (as
1597 // used for tail calls) is implementation-defined, so we cannot rely on the
1598 // linker replacing the tail call with a return.
1599 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1600 const GlobalValue *GV = G->getGlobal();
1601 if (GV->hasExternalWeakLinkage())
1602 return false;
1603 }
1604
1605 // The callee has to preserve all registers the caller needs to preserve.
1606 const RISCVRegisterInfo *TRI = Subtarget.getRegisterInfo();
1607 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
1608 if (CalleeCC != CallerCC) {
1609 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
1610 if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
1611 return false;
1612 }
1613
1614 // Byval parameters hand the function a pointer directly into the stack area
1615 // we want to reuse during a tail call. Working around this *is* possible
1616 // but less efficient and uglier in LowerCall.
1617 for (auto &Arg : Outs)
1618 if (Arg.Flags.isByVal())
1619 return false;
1620
1621 return true;
1622}
1623
Alex Bradburya3376752017-11-08 13:41:21 +00001624// Lower a call to a callseq_start + CALL + callseq_end chain, and add input
1625// and output parameter nodes.
1626SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
1627 SmallVectorImpl<SDValue> &InVals) const {
1628 SelectionDAG &DAG = CLI.DAG;
1629 SDLoc &DL = CLI.DL;
1630 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
1631 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
1632 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
1633 SDValue Chain = CLI.Chain;
1634 SDValue Callee = CLI.Callee;
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001635 bool &IsTailCall = CLI.IsTailCall;
Alex Bradburya3376752017-11-08 13:41:21 +00001636 CallingConv::ID CallConv = CLI.CallConv;
1637 bool IsVarArg = CLI.IsVarArg;
1638 EVT PtrVT = getPointerTy(DAG.getDataLayout());
Alex Bradburydc31c612017-12-11 12:49:02 +00001639 MVT XLenVT = Subtarget.getXLenVT();
Alex Bradburya3376752017-11-08 13:41:21 +00001640
Alex Bradburya3376752017-11-08 13:41:21 +00001641 MachineFunction &MF = DAG.getMachineFunction();
1642
1643 // Analyze the operands of the call, assigning locations to each operand.
1644 SmallVector<CCValAssign, 16> ArgLocs;
1645 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001646 analyzeOutputArgs(MF, ArgCCInfo, Outs, /*IsRet=*/false, &CLI);
Alex Bradburya3376752017-11-08 13:41:21 +00001647
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001648 // Check if it's really possible to do a tail call.
1649 if (IsTailCall)
Alex Bradburydb67be82019-02-21 14:31:41 +00001650 IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs);
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001651
1652 if (IsTailCall)
1653 ++NumTailCalls;
1654 else if (CLI.CS && CLI.CS.isMustTailCall())
1655 report_fatal_error("failed to perform tail call elimination on a call "
1656 "site marked musttail");
1657
Alex Bradburya3376752017-11-08 13:41:21 +00001658 // Get a count of how many bytes are to be pushed on the stack.
1659 unsigned NumBytes = ArgCCInfo.getNextStackOffset();
1660
Alex Bradburydc31c612017-12-11 12:49:02 +00001661 // Create local copies for byval args
1662 SmallVector<SDValue, 8> ByValArgs;
1663 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
1664 ISD::ArgFlagsTy Flags = Outs[i].Flags;
1665 if (!Flags.isByVal())
Alex Bradburya3376752017-11-08 13:41:21 +00001666 continue;
Alex Bradburydc31c612017-12-11 12:49:02 +00001667
1668 SDValue Arg = OutVals[i];
1669 unsigned Size = Flags.getByValSize();
1670 unsigned Align = Flags.getByValAlign();
1671
1672 int FI = MF.getFrameInfo().CreateStackObject(Size, Align, /*isSS=*/false);
1673 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
1674 SDValue SizeNode = DAG.getConstant(Size, DL, XLenVT);
1675
1676 Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Align,
1677 /*IsVolatile=*/false,
1678 /*AlwaysInline=*/false,
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001679 IsTailCall, MachinePointerInfo(),
Alex Bradburydc31c612017-12-11 12:49:02 +00001680 MachinePointerInfo());
1681 ByValArgs.push_back(FIPtr);
Alex Bradburya3376752017-11-08 13:41:21 +00001682 }
1683
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001684 if (!IsTailCall)
1685 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
Alex Bradburya3376752017-11-08 13:41:21 +00001686
1687 // Copy argument values to their designated locations.
1688 SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
Alex Bradburydc31c612017-12-11 12:49:02 +00001689 SmallVector<SDValue, 8> MemOpChains;
Alex Bradburya3376752017-11-08 13:41:21 +00001690 SDValue StackPtr;
Alex Bradburydc31c612017-12-11 12:49:02 +00001691 for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; ++i) {
1692 CCValAssign &VA = ArgLocs[i];
1693 SDValue ArgValue = OutVals[i];
1694 ISD::ArgFlagsTy Flags = Outs[i].Flags;
Alex Bradburya3376752017-11-08 13:41:21 +00001695
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001696 // Handle passing f64 on RV32D with a soft float ABI as a special case.
1697 bool IsF64OnRV32DSoftABI =
1698 VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
1699 if (IsF64OnRV32DSoftABI && VA.isRegLoc()) {
1700 SDValue SplitF64 = DAG.getNode(
1701 RISCVISD::SplitF64, DL, DAG.getVTList(MVT::i32, MVT::i32), ArgValue);
1702 SDValue Lo = SplitF64.getValue(0);
1703 SDValue Hi = SplitF64.getValue(1);
1704
1705 unsigned RegLo = VA.getLocReg();
1706 RegsToPass.push_back(std::make_pair(RegLo, Lo));
1707
1708 if (RegLo == RISCV::X17) {
1709 // Second half of f64 is passed on the stack.
1710 // Work out the address of the stack slot.
1711 if (!StackPtr.getNode())
1712 StackPtr = DAG.getCopyFromReg(Chain, DL, RISCV::X2, PtrVT);
1713 // Emit the store.
1714 MemOpChains.push_back(
1715 DAG.getStore(Chain, DL, Hi, StackPtr, MachinePointerInfo()));
1716 } else {
1717 // Second half of f64 is passed in another GPR.
1718 unsigned RegHigh = RegLo + 1;
1719 RegsToPass.push_back(std::make_pair(RegHigh, Hi));
1720 }
1721 continue;
1722 }
1723
1724 // IsF64OnRV32DSoftABI && VA.isMemLoc() is handled below in the same way
1725 // as any other MemLoc.
1726
Alex Bradburya3376752017-11-08 13:41:21 +00001727 // Promote the value if needed.
Alex Bradburydc31c612017-12-11 12:49:02 +00001728 // For now, only handle fully promoted and indirect arguments.
Alex Bradbury1dbfdeb2018-10-03 22:53:25 +00001729 if (VA.getLocInfo() == CCValAssign::Indirect) {
Alex Bradburydc31c612017-12-11 12:49:02 +00001730 // Store the argument in a stack slot and pass its address.
1731 SDValue SpillSlot = DAG.CreateStackTemporary(Outs[i].ArgVT);
1732 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
1733 MemOpChains.push_back(
1734 DAG.getStore(Chain, DL, ArgValue, SpillSlot,
1735 MachinePointerInfo::getFixedStack(MF, FI)));
1736 // If the original argument was split (e.g. i128), we need
1737 // to store all parts of it here (and pass just one address).
1738 unsigned ArgIndex = Outs[i].OrigArgIndex;
1739 assert(Outs[i].PartOffset == 0);
1740 while (i + 1 != e && Outs[i + 1].OrigArgIndex == ArgIndex) {
1741 SDValue PartValue = OutVals[i + 1];
1742 unsigned PartOffset = Outs[i + 1].PartOffset;
1743 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, SpillSlot,
1744 DAG.getIntPtrConstant(PartOffset, DL));
1745 MemOpChains.push_back(
1746 DAG.getStore(Chain, DL, PartValue, Address,
1747 MachinePointerInfo::getFixedStack(MF, FI)));
1748 ++i;
1749 }
1750 ArgValue = SpillSlot;
Alex Bradbury1dbfdeb2018-10-03 22:53:25 +00001751 } else {
1752 ArgValue = convertValVTToLocVT(DAG, ArgValue, VA, DL);
Alex Bradburya3376752017-11-08 13:41:21 +00001753 }
1754
Alex Bradburydc31c612017-12-11 12:49:02 +00001755 // Use local copy if it is a byval arg.
1756 if (Flags.isByVal())
1757 ArgValue = ByValArgs[j++];
1758
Alex Bradburya3376752017-11-08 13:41:21 +00001759 if (VA.isRegLoc()) {
1760 // Queue up the argument copies and emit them at the end.
1761 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
1762 } else {
1763 assert(VA.isMemLoc() && "Argument not register or memory");
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001764 assert(!IsTailCall && "Tail call not allowed if stack is used "
1765 "for passing parameters");
Alex Bradburydc31c612017-12-11 12:49:02 +00001766
1767 // Work out the address of the stack slot.
1768 if (!StackPtr.getNode())
1769 StackPtr = DAG.getCopyFromReg(Chain, DL, RISCV::X2, PtrVT);
1770 SDValue Address =
1771 DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
1772 DAG.getIntPtrConstant(VA.getLocMemOffset(), DL));
1773
1774 // Emit the store.
1775 MemOpChains.push_back(
1776 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
Alex Bradburya3376752017-11-08 13:41:21 +00001777 }
1778 }
1779
Alex Bradburydc31c612017-12-11 12:49:02 +00001780 // Join the stores, which are independent of one another.
1781 if (!MemOpChains.empty())
1782 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
1783
Alex Bradburya3376752017-11-08 13:41:21 +00001784 SDValue Glue;
1785
1786 // Build a sequence of copy-to-reg nodes, chained and glued together.
1787 for (auto &Reg : RegsToPass) {
1788 Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue);
1789 Glue = Chain.getValue(1);
1790 }
1791
Shiva Chend58bd8d2018-04-25 14:19:12 +00001792 // If the callee is a GlobalAddress/ExternalSymbol node, turn it into a
1793 // TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
1794 // split it and then direct call can be matched by PseudoCALL.
1795 if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
1796 Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0, 0);
1797 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1798 Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, 0);
Alex Bradburya3376752017-11-08 13:41:21 +00001799 }
1800
1801 // The first call operand is the chain and the second is the target address.
1802 SmallVector<SDValue, 8> Ops;
1803 Ops.push_back(Chain);
1804 Ops.push_back(Callee);
1805
1806 // Add argument registers to the end of the list so that they are
1807 // known live into the call.
1808 for (auto &Reg : RegsToPass)
1809 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
1810
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001811 if (!IsTailCall) {
1812 // Add a register mask operand representing the call-preserved registers.
1813 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
1814 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
1815 assert(Mask && "Missing call preserved mask for calling convention");
1816 Ops.push_back(DAG.getRegisterMask(Mask));
1817 }
Alex Bradburya3376752017-11-08 13:41:21 +00001818
1819 // Glue the call to the argument copies, if any.
1820 if (Glue.getNode())
1821 Ops.push_back(Glue);
1822
1823 // Emit the call.
1824 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001825
1826 if (IsTailCall) {
1827 MF.getFrameInfo().setHasTailCall();
1828 return DAG.getNode(RISCVISD::TAIL, DL, NodeTys, Ops);
1829 }
1830
Alex Bradburya3376752017-11-08 13:41:21 +00001831 Chain = DAG.getNode(RISCVISD::CALL, DL, NodeTys, Ops);
1832 Glue = Chain.getValue(1);
1833
1834 // Mark the end of the call, which is glued to the call itself.
1835 Chain = DAG.getCALLSEQ_END(Chain,
1836 DAG.getConstant(NumBytes, DL, PtrVT, true),
1837 DAG.getConstant(0, DL, PtrVT, true),
1838 Glue, DL);
1839 Glue = Chain.getValue(1);
1840
1841 // Assign locations to each value returned by this call.
1842 SmallVector<CCValAssign, 16> RVLocs;
1843 CCState RetCCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
Alex Bradburydc31c612017-12-11 12:49:02 +00001844 analyzeInputArgs(MF, RetCCInfo, Ins, /*IsRet=*/true);
Alex Bradburya3376752017-11-08 13:41:21 +00001845
1846 // Copy all of the result registers out of their specified physreg.
1847 for (auto &VA : RVLocs) {
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001848 // Copy the value out
1849 SDValue RetValue =
1850 DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue);
1851 // Glue the RetValue to the end of the call sequence
Alex Bradburya3376752017-11-08 13:41:21 +00001852 Chain = RetValue.getValue(1);
1853 Glue = RetValue.getValue(2);
Alex Bradbury1dbfdeb2018-10-03 22:53:25 +00001854
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001855 if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
1856 assert(VA.getLocReg() == ArgGPRs[0] && "Unexpected reg assignment");
1857 SDValue RetValue2 =
1858 DAG.getCopyFromReg(Chain, DL, ArgGPRs[1], MVT::i32, Glue);
1859 Chain = RetValue2.getValue(1);
1860 Glue = RetValue2.getValue(2);
1861 RetValue = DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, RetValue,
1862 RetValue2);
1863 }
Alex Bradburya3376752017-11-08 13:41:21 +00001864
Alex Bradbury1dbfdeb2018-10-03 22:53:25 +00001865 RetValue = convertLocVTToValVT(DAG, RetValue, VA, DL);
Alex Bradbury76c29ee2018-03-20 12:45:35 +00001866
Alex Bradburydc31c612017-12-11 12:49:02 +00001867 InVals.push_back(RetValue);
Alex Bradburya3376752017-11-08 13:41:21 +00001868 }
1869
1870 return Chain;
1871}
1872
Alex Bradburydc31c612017-12-11 12:49:02 +00001873bool RISCVTargetLowering::CanLowerReturn(
1874 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
1875 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
1876 SmallVector<CCValAssign, 16> RVLocs;
1877 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
1878 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
1879 MVT VT = Outs[i].VT;
1880 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
Alex Bradbury0b2803e2019-03-30 17:59:30 +00001881 RISCVABI::ABI ABI = MF.getSubtarget<RISCVSubtarget>().getTargetABI();
1882 if (CC_RISCV(MF.getDataLayout(), ABI, i, VT, VT, CCValAssign::Full,
1883 ArgFlags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true, nullptr))
Alex Bradburydc31c612017-12-11 12:49:02 +00001884 return false;
1885 }
1886 return true;
1887}
1888
Alex Bradbury89718422017-10-19 21:37:38 +00001889SDValue
1890RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
1891 bool IsVarArg,
1892 const SmallVectorImpl<ISD::OutputArg> &Outs,
1893 const SmallVectorImpl<SDValue> &OutVals,
1894 const SDLoc &DL, SelectionDAG &DAG) const {
Alex Bradbury89718422017-10-19 21:37:38 +00001895 // Stores the assignment of the return value to a location.
1896 SmallVector<CCValAssign, 16> RVLocs;
1897
1898 // Info about the registers and stack slot.
1899 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
1900 *DAG.getContext());
1901
Alex Bradburyc85be0d2018-01-10 19:41:03 +00001902 analyzeOutputArgs(DAG.getMachineFunction(), CCInfo, Outs, /*IsRet=*/true,
1903 nullptr);
Alex Bradbury89718422017-10-19 21:37:38 +00001904
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001905 SDValue Glue;
Alex Bradbury89718422017-10-19 21:37:38 +00001906 SmallVector<SDValue, 4> RetOps(1, Chain);
1907
1908 // Copy the result values into the output registers.
1909 for (unsigned i = 0, e = RVLocs.size(); i < e; ++i) {
Alex Bradburydc31c612017-12-11 12:49:02 +00001910 SDValue Val = OutVals[i];
Alex Bradbury89718422017-10-19 21:37:38 +00001911 CCValAssign &VA = RVLocs[i];
1912 assert(VA.isRegLoc() && "Can only return in registers!");
1913
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001914 if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
1915 // Handle returning f64 on RV32D with a soft float ABI.
1916 assert(VA.isRegLoc() && "Expected return via registers");
1917 SDValue SplitF64 = DAG.getNode(RISCVISD::SplitF64, DL,
1918 DAG.getVTList(MVT::i32, MVT::i32), Val);
1919 SDValue Lo = SplitF64.getValue(0);
1920 SDValue Hi = SplitF64.getValue(1);
1921 unsigned RegLo = VA.getLocReg();
1922 unsigned RegHi = RegLo + 1;
1923 Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue);
1924 Glue = Chain.getValue(1);
1925 RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));
1926 Chain = DAG.getCopyToReg(Chain, DL, RegHi, Hi, Glue);
1927 Glue = Chain.getValue(1);
1928 RetOps.push_back(DAG.getRegister(RegHi, MVT::i32));
1929 } else {
1930 // Handle a 'normal' return.
Alex Bradbury1dbfdeb2018-10-03 22:53:25 +00001931 Val = convertValVTToLocVT(DAG, Val, VA, DL);
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001932 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue);
Alex Bradbury89718422017-10-19 21:37:38 +00001933
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001934 // Guarantee that all emitted copies are stuck together.
1935 Glue = Chain.getValue(1);
1936 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
1937 }
Alex Bradbury89718422017-10-19 21:37:38 +00001938 }
1939
1940 RetOps[0] = Chain; // Update chain.
1941
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001942 // Add the glue node if we have it.
1943 if (Glue.getNode()) {
1944 RetOps.push_back(Glue);
Alex Bradbury89718422017-10-19 21:37:38 +00001945 }
1946
Ana Pazos2e4106b2018-07-26 17:49:43 +00001947 // Interrupt service routines use different return instructions.
1948 const Function &Func = DAG.getMachineFunction().getFunction();
1949 if (Func.hasFnAttribute("interrupt")) {
1950 if (!Func.getReturnType()->isVoidTy())
1951 report_fatal_error(
1952 "Functions with the interrupt attribute must have void return type!");
1953
1954 MachineFunction &MF = DAG.getMachineFunction();
1955 StringRef Kind =
1956 MF.getFunction().getFnAttribute("interrupt").getValueAsString();
1957
1958 unsigned RetOpc;
1959 if (Kind == "user")
1960 RetOpc = RISCVISD::URET_FLAG;
1961 else if (Kind == "supervisor")
1962 RetOpc = RISCVISD::SRET_FLAG;
1963 else
1964 RetOpc = RISCVISD::MRET_FLAG;
1965
1966 return DAG.getNode(RetOpc, DL, MVT::Other, RetOps);
1967 }
1968
Alex Bradbury89718422017-10-19 21:37:38 +00001969 return DAG.getNode(RISCVISD::RET_FLAG, DL, MVT::Other, RetOps);
1970}
1971
1972const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
1973 switch ((RISCVISD::NodeType)Opcode) {
1974 case RISCVISD::FIRST_NUMBER:
1975 break;
1976 case RISCVISD::RET_FLAG:
1977 return "RISCVISD::RET_FLAG";
Ana Pazos2e4106b2018-07-26 17:49:43 +00001978 case RISCVISD::URET_FLAG:
1979 return "RISCVISD::URET_FLAG";
1980 case RISCVISD::SRET_FLAG:
1981 return "RISCVISD::SRET_FLAG";
1982 case RISCVISD::MRET_FLAG:
1983 return "RISCVISD::MRET_FLAG";
Alex Bradburya3376752017-11-08 13:41:21 +00001984 case RISCVISD::CALL:
1985 return "RISCVISD::CALL";
Alex Bradbury65385162017-11-21 07:51:32 +00001986 case RISCVISD::SELECT_CC:
1987 return "RISCVISD::SELECT_CC";
Alex Bradbury0b4175f2018-04-12 05:34:25 +00001988 case RISCVISD::BuildPairF64:
1989 return "RISCVISD::BuildPairF64";
1990 case RISCVISD::SplitF64:
1991 return "RISCVISD::SplitF64";
Mandeep Singh Grangddcb9562018-05-23 22:44:08 +00001992 case RISCVISD::TAIL:
1993 return "RISCVISD::TAIL";
Alex Bradbury299d6902019-01-25 05:04:00 +00001994 case RISCVISD::SLLW:
1995 return "RISCVISD::SLLW";
1996 case RISCVISD::SRAW:
1997 return "RISCVISD::SRAW";
1998 case RISCVISD::SRLW:
1999 return "RISCVISD::SRLW";
Alex Bradbury456d3792019-01-25 05:11:34 +00002000 case RISCVISD::DIVW:
2001 return "RISCVISD::DIVW";
2002 case RISCVISD::DIVUW:
2003 return "RISCVISD::DIVUW";
2004 case RISCVISD::REMUW:
2005 return "RISCVISD::REMUW";
Alex Bradburyd834d832019-01-31 22:48:38 +00002006 case RISCVISD::FMV_W_X_RV64:
2007 return "RISCVISD::FMV_W_X_RV64";
2008 case RISCVISD::FMV_X_ANYEXTW_RV64:
2009 return "RISCVISD::FMV_X_ANYEXTW_RV64";
Alex Bradbury89718422017-10-19 21:37:38 +00002010 }
2011 return nullptr;
2012}
Alex Bradbury9330e642018-01-10 20:05:09 +00002013
2014std::pair<unsigned, const TargetRegisterClass *>
2015RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2016 StringRef Constraint,
2017 MVT VT) const {
2018 // First, see if this is a constraint that directly corresponds to a
2019 // RISCV register class.
2020 if (Constraint.size() == 1) {
2021 switch (Constraint[0]) {
2022 case 'r':
2023 return std::make_pair(0U, &RISCV::GPRRegClass);
2024 default:
2025 break;
2026 }
2027 }
2028
2029 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
2030}
Alex Bradbury96f492d2018-06-13 12:04:51 +00002031
2032Instruction *RISCVTargetLowering::emitLeadingFence(IRBuilder<> &Builder,
2033 Instruction *Inst,
2034 AtomicOrdering Ord) const {
2035 if (isa<LoadInst>(Inst) && Ord == AtomicOrdering::SequentiallyConsistent)
2036 return Builder.CreateFence(Ord);
2037 if (isa<StoreInst>(Inst) && isReleaseOrStronger(Ord))
2038 return Builder.CreateFence(AtomicOrdering::Release);
2039 return nullptr;
2040}
2041
2042Instruction *RISCVTargetLowering::emitTrailingFence(IRBuilder<> &Builder,
2043 Instruction *Inst,
2044 AtomicOrdering Ord) const {
2045 if (isa<LoadInst>(Inst) && isAcquireOrStronger(Ord))
2046 return Builder.CreateFence(AtomicOrdering::Acquire);
2047 return nullptr;
2048}
Alex Bradbury21aea512018-09-19 10:54:22 +00002049
2050TargetLowering::AtomicExpansionKind
2051RISCVTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
Matt Arsenault39508332019-01-22 18:18:02 +00002052 // atomicrmw {fadd,fsub} must be expanded to use compare-exchange, as floating
2053 // point operations can't be used in an lr/sc sequence without breaking the
2054 // forward-progress guarantee.
2055 if (AI->isFloatingPointOperation())
2056 return AtomicExpansionKind::CmpXChg;
2057
Alex Bradbury21aea512018-09-19 10:54:22 +00002058 unsigned Size = AI->getType()->getPrimitiveSizeInBits();
2059 if (Size == 8 || Size == 16)
2060 return AtomicExpansionKind::MaskedIntrinsic;
2061 return AtomicExpansionKind::None;
2062}
2063
2064static Intrinsic::ID
Alex Bradbury07f1c622019-01-17 10:04:39 +00002065getIntrinsicForMaskedAtomicRMWBinOp(unsigned XLen, AtomicRMWInst::BinOp BinOp) {
2066 if (XLen == 32) {
2067 switch (BinOp) {
2068 default:
2069 llvm_unreachable("Unexpected AtomicRMW BinOp");
2070 case AtomicRMWInst::Xchg:
2071 return Intrinsic::riscv_masked_atomicrmw_xchg_i32;
2072 case AtomicRMWInst::Add:
2073 return Intrinsic::riscv_masked_atomicrmw_add_i32;
2074 case AtomicRMWInst::Sub:
2075 return Intrinsic::riscv_masked_atomicrmw_sub_i32;
2076 case AtomicRMWInst::Nand:
2077 return Intrinsic::riscv_masked_atomicrmw_nand_i32;
2078 case AtomicRMWInst::Max:
2079 return Intrinsic::riscv_masked_atomicrmw_max_i32;
2080 case AtomicRMWInst::Min:
2081 return Intrinsic::riscv_masked_atomicrmw_min_i32;
2082 case AtomicRMWInst::UMax:
2083 return Intrinsic::riscv_masked_atomicrmw_umax_i32;
2084 case AtomicRMWInst::UMin:
2085 return Intrinsic::riscv_masked_atomicrmw_umin_i32;
2086 }
Alex Bradbury21aea512018-09-19 10:54:22 +00002087 }
Alex Bradbury07f1c622019-01-17 10:04:39 +00002088
2089 if (XLen == 64) {
2090 switch (BinOp) {
2091 default:
2092 llvm_unreachable("Unexpected AtomicRMW BinOp");
2093 case AtomicRMWInst::Xchg:
2094 return Intrinsic::riscv_masked_atomicrmw_xchg_i64;
2095 case AtomicRMWInst::Add:
2096 return Intrinsic::riscv_masked_atomicrmw_add_i64;
2097 case AtomicRMWInst::Sub:
2098 return Intrinsic::riscv_masked_atomicrmw_sub_i64;
2099 case AtomicRMWInst::Nand:
2100 return Intrinsic::riscv_masked_atomicrmw_nand_i64;
2101 case AtomicRMWInst::Max:
2102 return Intrinsic::riscv_masked_atomicrmw_max_i64;
2103 case AtomicRMWInst::Min:
2104 return Intrinsic::riscv_masked_atomicrmw_min_i64;
2105 case AtomicRMWInst::UMax:
2106 return Intrinsic::riscv_masked_atomicrmw_umax_i64;
2107 case AtomicRMWInst::UMin:
2108 return Intrinsic::riscv_masked_atomicrmw_umin_i64;
2109 }
2110 }
2111
2112 llvm_unreachable("Unexpected XLen\n");
Alex Bradbury21aea512018-09-19 10:54:22 +00002113}
2114
2115Value *RISCVTargetLowering::emitMaskedAtomicRMWIntrinsic(
2116 IRBuilder<> &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr,
2117 Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const {
Alex Bradbury07f1c622019-01-17 10:04:39 +00002118 unsigned XLen = Subtarget.getXLen();
2119 Value *Ordering =
2120 Builder.getIntN(XLen, static_cast<uint64_t>(AI->getOrdering()));
Alex Bradbury21aea512018-09-19 10:54:22 +00002121 Type *Tys[] = {AlignedAddr->getType()};
2122 Function *LrwOpScwLoop = Intrinsic::getDeclaration(
2123 AI->getModule(),
Alex Bradbury07f1c622019-01-17 10:04:39 +00002124 getIntrinsicForMaskedAtomicRMWBinOp(XLen, AI->getOperation()), Tys);
2125
2126 if (XLen == 64) {
2127 Incr = Builder.CreateSExt(Incr, Builder.getInt64Ty());
2128 Mask = Builder.CreateSExt(Mask, Builder.getInt64Ty());
2129 ShiftAmt = Builder.CreateSExt(ShiftAmt, Builder.getInt64Ty());
2130 }
2131
2132 Value *Result;
Alex Bradbury21aea512018-09-19 10:54:22 +00002133
2134 // Must pass the shift amount needed to sign extend the loaded value prior
2135 // to performing a signed comparison for min/max. ShiftAmt is the number of
2136 // bits to shift the value into position. Pass XLen-ShiftAmt-ValWidth, which
2137 // is the number of bits to left+right shift the value in order to
2138 // sign-extend.
2139 if (AI->getOperation() == AtomicRMWInst::Min ||
2140 AI->getOperation() == AtomicRMWInst::Max) {
2141 const DataLayout &DL = AI->getModule()->getDataLayout();
2142 unsigned ValWidth =
2143 DL.getTypeStoreSizeInBits(AI->getValOperand()->getType());
Alex Bradbury07f1c622019-01-17 10:04:39 +00002144 Value *SextShamt =
2145 Builder.CreateSub(Builder.getIntN(XLen, XLen - ValWidth), ShiftAmt);
2146 Result = Builder.CreateCall(LrwOpScwLoop,
2147 {AlignedAddr, Incr, Mask, SextShamt, Ordering});
2148 } else {
2149 Result =
2150 Builder.CreateCall(LrwOpScwLoop, {AlignedAddr, Incr, Mask, Ordering});
Alex Bradbury21aea512018-09-19 10:54:22 +00002151 }
2152
Alex Bradbury07f1c622019-01-17 10:04:39 +00002153 if (XLen == 64)
2154 Result = Builder.CreateTrunc(Result, Builder.getInt32Ty());
2155 return Result;
Alex Bradbury21aea512018-09-19 10:54:22 +00002156}
Alex Bradbury66d9a752018-11-29 20:43:42 +00002157
2158TargetLowering::AtomicExpansionKind
2159RISCVTargetLowering::shouldExpandAtomicCmpXchgInIR(
2160 AtomicCmpXchgInst *CI) const {
2161 unsigned Size = CI->getCompareOperand()->getType()->getPrimitiveSizeInBits();
2162 if (Size == 8 || Size == 16)
2163 return AtomicExpansionKind::MaskedIntrinsic;
2164 return AtomicExpansionKind::None;
2165}
2166
2167Value *RISCVTargetLowering::emitMaskedAtomicCmpXchgIntrinsic(
2168 IRBuilder<> &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr,
2169 Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const {
Alex Bradbury07f1c622019-01-17 10:04:39 +00002170 unsigned XLen = Subtarget.getXLen();
2171 Value *Ordering = Builder.getIntN(XLen, static_cast<uint64_t>(Ord));
2172 Intrinsic::ID CmpXchgIntrID = Intrinsic::riscv_masked_cmpxchg_i32;
2173 if (XLen == 64) {
2174 CmpVal = Builder.CreateSExt(CmpVal, Builder.getInt64Ty());
2175 NewVal = Builder.CreateSExt(NewVal, Builder.getInt64Ty());
2176 Mask = Builder.CreateSExt(Mask, Builder.getInt64Ty());
2177 CmpXchgIntrID = Intrinsic::riscv_masked_cmpxchg_i64;
2178 }
Alex Bradbury66d9a752018-11-29 20:43:42 +00002179 Type *Tys[] = {AlignedAddr->getType()};
Alex Bradbury07f1c622019-01-17 10:04:39 +00002180 Function *MaskedCmpXchg =
2181 Intrinsic::getDeclaration(CI->getModule(), CmpXchgIntrID, Tys);
2182 Value *Result = Builder.CreateCall(
2183 MaskedCmpXchg, {AlignedAddr, CmpVal, NewVal, Mask, Ordering});
2184 if (XLen == 64)
2185 Result = Builder.CreateTrunc(Result, Builder.getInt32Ty());
2186 return Result;
Alex Bradbury66d9a752018-11-29 20:43:42 +00002187}