1 //===- ARMLegalizerInfo.cpp --------------------------------------*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file implements the targeting of the Machinelegalizer class for ARM.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
14 #include "ARMLegalizerInfo.h"
15 #include "ARMCallLowering.h"
16 #include "ARMSubtarget.h"
17 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
18 #include "llvm/CodeGen/LowLevelType.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/ValueTypes.h"
21 #include "llvm/IR/DerivedTypes.h"
22 #include "llvm/IR/Type.h"
23 #include "llvm/Target/TargetOpcodes.h"
27 #ifndef LLVM_BUILD_GLOBAL_ISEL
28 #error "You shouldn't build this"
31 static bool AEABI(const ARMSubtarget &ST) {
32 return ST.isTargetAEABI() || ST.isTargetGNUAEABI() || ST.isTargetMuslAEABI();
35 ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
36 using namespace TargetOpcode;
38 const LLT p0 = LLT::pointer(0, 32);
40 const LLT s1 = LLT::scalar(1);
41 const LLT s8 = LLT::scalar(8);
42 const LLT s16 = LLT::scalar(16);
43 const LLT s32 = LLT::scalar(32);
44 const LLT s64 = LLT::scalar(64);
46 setAction({G_FRAME_INDEX, p0}, Legal);
48 for (unsigned Op : {G_LOAD, G_STORE}) {
49 for (auto Ty : {s1, s8, s16, s32, p0})
50 setAction({Op, Ty}, Legal);
51 setAction({Op, 1, p0}, Legal);
54 for (unsigned Op : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) {
55 for (auto Ty : {s1, s8, s16})
56 setAction({Op, Ty}, WidenScalar);
57 setAction({Op, s32}, Legal);
60 for (unsigned Op : {G_SDIV, G_UDIV}) {
61 for (auto Ty : {s8, s16})
62 setAction({Op, Ty}, WidenScalar);
63 if (ST.hasDivideInARMMode())
64 setAction({Op, s32}, Legal);
66 setAction({Op, s32}, Libcall);
69 for (unsigned Op : {G_SREM, G_UREM}) {
70 for (auto Ty : {s8, s16})
71 setAction({Op, Ty}, WidenScalar);
72 if (ST.hasDivideInARMMode())
73 setAction({Op, s32}, Lower);
75 setAction({Op, s32}, Custom);
77 setAction({Op, s32}, Libcall);
80 for (unsigned Op : {G_SEXT, G_ZEXT}) {
81 setAction({Op, s32}, Legal);
82 for (auto Ty : {s1, s8, s16})
83 setAction({Op, 1, Ty}, Legal);
86 setAction({G_GEP, p0}, Legal);
87 setAction({G_GEP, 1, s32}, Legal);
89 setAction({G_SELECT, s32}, Legal);
90 setAction({G_SELECT, p0}, Legal);
91 setAction({G_SELECT, 1, s1}, Legal);
93 setAction({G_BRCOND, s1}, Legal);
95 setAction({G_CONSTANT, s32}, Legal);
96 for (auto Ty : {s1, s8, s16})
97 setAction({G_CONSTANT, Ty}, WidenScalar);
99 setAction({G_ICMP, s1}, Legal);
100 for (auto Ty : {s8, s16})
101 setAction({G_ICMP, 1, Ty}, WidenScalar);
102 for (auto Ty : {s32, p0})
103 setAction({G_ICMP, 1, Ty}, Legal);
105 if (!ST.useSoftFloat() && ST.hasVFP2()) {
106 setAction({G_FADD, s32}, Legal);
107 setAction({G_FADD, s64}, Legal);
109 setAction({G_LOAD, s64}, Legal);
110 setAction({G_STORE, s64}, Legal);
112 setAction({G_FCMP, s1}, Legal);
113 setAction({G_FCMP, 1, s32}, Legal);
114 setAction({G_FCMP, 1, s64}, Legal);
116 for (auto Ty : {s32, s64})
117 setAction({G_FADD, Ty}, Libcall);
119 setAction({G_FCMP, s1}, Legal);
120 setAction({G_FCMP, 1, s32}, Custom);
121 setAction({G_FCMP, 1, s64}, Custom);
124 setFCmpLibcallsAEABI();
126 setFCmpLibcallsGNU();
129 for (unsigned Op : {G_FREM, G_FPOW})
130 for (auto Ty : {s32, s64})
131 setAction({Op, Ty}, Libcall);
136 void ARMLegalizerInfo::setFCmpLibcallsAEABI() {
137 // FCMP_TRUE and FCMP_FALSE don't need libcalls, they should be
138 // default-initialized.
139 FCmp32Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
140 FCmp32Libcalls[CmpInst::FCMP_OEQ] = {
141 {RTLIB::OEQ_F32, CmpInst::BAD_ICMP_PREDICATE}};
142 FCmp32Libcalls[CmpInst::FCMP_OGE] = {
143 {RTLIB::OGE_F32, CmpInst::BAD_ICMP_PREDICATE}};
144 FCmp32Libcalls[CmpInst::FCMP_OGT] = {
145 {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE}};
146 FCmp32Libcalls[CmpInst::FCMP_OLE] = {
147 {RTLIB::OLE_F32, CmpInst::BAD_ICMP_PREDICATE}};
148 FCmp32Libcalls[CmpInst::FCMP_OLT] = {
149 {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}};
150 FCmp32Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F32, CmpInst::ICMP_EQ}};
151 FCmp32Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F32, CmpInst::ICMP_EQ}};
152 FCmp32Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F32, CmpInst::ICMP_EQ}};
153 FCmp32Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F32, CmpInst::ICMP_EQ}};
154 FCmp32Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F32, CmpInst::ICMP_EQ}};
155 FCmp32Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F32, CmpInst::ICMP_EQ}};
156 FCmp32Libcalls[CmpInst::FCMP_UNO] = {
157 {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}};
158 FCmp32Libcalls[CmpInst::FCMP_ONE] = {
159 {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE},
160 {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}};
161 FCmp32Libcalls[CmpInst::FCMP_UEQ] = {
162 {RTLIB::OEQ_F32, CmpInst::BAD_ICMP_PREDICATE},
163 {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}};
165 FCmp64Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
166 FCmp64Libcalls[CmpInst::FCMP_OEQ] = {
167 {RTLIB::OEQ_F64, CmpInst::BAD_ICMP_PREDICATE}};
168 FCmp64Libcalls[CmpInst::FCMP_OGE] = {
169 {RTLIB::OGE_F64, CmpInst::BAD_ICMP_PREDICATE}};
170 FCmp64Libcalls[CmpInst::FCMP_OGT] = {
171 {RTLIB::OGT_F64, CmpInst::BAD_ICMP_PREDICATE}};
172 FCmp64Libcalls[CmpInst::FCMP_OLE] = {
173 {RTLIB::OLE_F64, CmpInst::BAD_ICMP_PREDICATE}};
174 FCmp64Libcalls[CmpInst::FCMP_OLT] = {
175 {RTLIB::OLT_F64, CmpInst::BAD_ICMP_PREDICATE}};
176 FCmp64Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F64, CmpInst::ICMP_EQ}};
177 FCmp64Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F64, CmpInst::ICMP_EQ}};
178 FCmp64Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F64, CmpInst::ICMP_EQ}};
179 FCmp64Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F64, CmpInst::ICMP_EQ}};
180 FCmp64Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F64, CmpInst::ICMP_EQ}};
181 FCmp64Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F64, CmpInst::ICMP_EQ}};
182 FCmp64Libcalls[CmpInst::FCMP_UNO] = {
183 {RTLIB::UO_F64, CmpInst::BAD_ICMP_PREDICATE}};
184 FCmp64Libcalls[CmpInst::FCMP_ONE] = {
185 {RTLIB::OGT_F64, CmpInst::BAD_ICMP_PREDICATE},
186 {RTLIB::OLT_F64, CmpInst::BAD_ICMP_PREDICATE}};
187 FCmp64Libcalls[CmpInst::FCMP_UEQ] = {
188 {RTLIB::OEQ_F64, CmpInst::BAD_ICMP_PREDICATE},
189 {RTLIB::UO_F64, CmpInst::BAD_ICMP_PREDICATE}};
192 void ARMLegalizerInfo::setFCmpLibcallsGNU() {
193 // FCMP_TRUE and FCMP_FALSE don't need libcalls, they should be
194 // default-initialized.
195 FCmp32Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
196 FCmp32Libcalls[CmpInst::FCMP_OEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ}};
197 FCmp32Libcalls[CmpInst::FCMP_OGE] = {{RTLIB::OGE_F32, CmpInst::ICMP_SGE}};
198 FCmp32Libcalls[CmpInst::FCMP_OGT] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT}};
199 FCmp32Libcalls[CmpInst::FCMP_OLE] = {{RTLIB::OLE_F32, CmpInst::ICMP_SLE}};
200 FCmp32Libcalls[CmpInst::FCMP_OLT] = {{RTLIB::OLT_F32, CmpInst::ICMP_SLT}};
201 FCmp32Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F32, CmpInst::ICMP_EQ}};
202 FCmp32Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F32, CmpInst::ICMP_SGE}};
203 FCmp32Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F32, CmpInst::ICMP_SGT}};
204 FCmp32Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SLE}};
205 FCmp32Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F32, CmpInst::ICMP_SLT}};
206 FCmp32Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F32, CmpInst::ICMP_NE}};
207 FCmp32Libcalls[CmpInst::FCMP_UNO] = {{RTLIB::UO_F32, CmpInst::ICMP_NE}};
208 FCmp32Libcalls[CmpInst::FCMP_ONE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT},
209 {RTLIB::OLT_F32, CmpInst::ICMP_SLT}};
210 FCmp32Libcalls[CmpInst::FCMP_UEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ},
211 {RTLIB::UO_F32, CmpInst::ICMP_NE}};
213 FCmp64Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
214 FCmp64Libcalls[CmpInst::FCMP_OEQ] = {{RTLIB::OEQ_F64, CmpInst::ICMP_EQ}};
215 FCmp64Libcalls[CmpInst::FCMP_OGE] = {{RTLIB::OGE_F64, CmpInst::ICMP_SGE}};
216 FCmp64Libcalls[CmpInst::FCMP_OGT] = {{RTLIB::OGT_F64, CmpInst::ICMP_SGT}};
217 FCmp64Libcalls[CmpInst::FCMP_OLE] = {{RTLIB::OLE_F64, CmpInst::ICMP_SLE}};
218 FCmp64Libcalls[CmpInst::FCMP_OLT] = {{RTLIB::OLT_F64, CmpInst::ICMP_SLT}};
219 FCmp64Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F64, CmpInst::ICMP_EQ}};
220 FCmp64Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F64, CmpInst::ICMP_SGE}};
221 FCmp64Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F64, CmpInst::ICMP_SGT}};
222 FCmp64Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F64, CmpInst::ICMP_SLE}};
223 FCmp64Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F64, CmpInst::ICMP_SLT}};
224 FCmp64Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F64, CmpInst::ICMP_NE}};
225 FCmp64Libcalls[CmpInst::FCMP_UNO] = {{RTLIB::UO_F64, CmpInst::ICMP_NE}};
226 FCmp64Libcalls[CmpInst::FCMP_ONE] = {{RTLIB::OGT_F64, CmpInst::ICMP_SGT},
227 {RTLIB::OLT_F64, CmpInst::ICMP_SLT}};
228 FCmp64Libcalls[CmpInst::FCMP_UEQ] = {{RTLIB::OEQ_F64, CmpInst::ICMP_EQ},
229 {RTLIB::UO_F64, CmpInst::ICMP_NE}};
232 ARMLegalizerInfo::FCmpLibcallsList
233 ARMLegalizerInfo::getFCmpLibcalls(CmpInst::Predicate Predicate,
234 unsigned Size) const {
235 assert(CmpInst::isFPPredicate(Predicate) && "Unsupported FCmp predicate");
237 return FCmp32Libcalls[Predicate];
239 return FCmp64Libcalls[Predicate];
240 llvm_unreachable("Unsupported size for FCmp predicate");
243 bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI,
244 MachineRegisterInfo &MRI,
245 MachineIRBuilder &MIRBuilder) const {
246 using namespace TargetOpcode;
248 MIRBuilder.setInstr(MI);
250 switch (MI.getOpcode()) {
255 unsigned OriginalResult = MI.getOperand(0).getReg();
256 auto Size = MRI.getType(OriginalResult).getSizeInBits();
261 MI.getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
263 // Our divmod libcalls return a struct containing the quotient and the
264 // remainder. We need to create a virtual register for it.
265 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
266 Type *ArgTy = Type::getInt32Ty(Ctx);
267 StructType *RetTy = StructType::get(Ctx, {ArgTy, ArgTy}, /* Packed */ true);
268 auto RetVal = MRI.createGenericVirtualRegister(
269 getLLTForType(*RetTy, MIRBuilder.getMF().getDataLayout()));
271 auto Status = createLibcall(MIRBuilder, Libcall, {RetVal, RetTy},
272 {{MI.getOperand(1).getReg(), ArgTy},
273 {MI.getOperand(2).getReg(), ArgTy}});
274 if (Status != LegalizerHelper::Legalized)
277 // The remainder is the second result of divmod. Split the return value into
278 // a new, unused register for the quotient and the destination of the
279 // original instruction for the remainder.
280 MIRBuilder.buildUnmerge(
281 {MRI.createGenericVirtualRegister(LLT::scalar(32)), OriginalResult},
286 assert(MRI.getType(MI.getOperand(2).getReg()) ==
287 MRI.getType(MI.getOperand(3).getReg()) &&
288 "Mismatched operands for G_FCMP");
289 auto OpSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
291 auto OriginalResult = MI.getOperand(0).getReg();
293 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
294 auto Libcalls = getFCmpLibcalls(Predicate, OpSize);
296 if (Libcalls.empty()) {
297 assert((Predicate == CmpInst::FCMP_TRUE ||
298 Predicate == CmpInst::FCMP_FALSE) &&
299 "Predicate needs libcalls, but none specified");
300 MIRBuilder.buildConstant(OriginalResult,
301 Predicate == CmpInst::FCMP_TRUE ? 1 : 0);
302 MI.eraseFromParent();
306 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
307 assert((OpSize == 32 || OpSize == 64) && "Unsupported operand size");
308 auto *ArgTy = OpSize == 32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
309 auto *RetTy = Type::getInt32Ty(Ctx);
311 SmallVector<unsigned, 2> Results;
312 for (auto Libcall : Libcalls) {
313 auto LibcallResult = MRI.createGenericVirtualRegister(LLT::scalar(32));
315 createLibcall(MIRBuilder, Libcall.LibcallID, {LibcallResult, RetTy},
316 {{MI.getOperand(2).getReg(), ArgTy},
317 {MI.getOperand(3).getReg(), ArgTy}});
319 if (Status != LegalizerHelper::Legalized)
322 auto ProcessedResult =
325 : MRI.createGenericVirtualRegister(MRI.getType(OriginalResult));
327 // We have a result, but we need to transform it into a proper 1-bit 0 or
328 // 1, taking into account the different peculiarities of the values
329 // returned by the comparison functions.
330 CmpInst::Predicate ResultPred = Libcall.Predicate;
331 if (ResultPred == CmpInst::BAD_ICMP_PREDICATE) {
332 // We have a nice 0 or 1, and we just need to truncate it back to 1 bit
333 // to keep the types consistent.
334 MIRBuilder.buildTrunc(ProcessedResult, LibcallResult);
336 // We need to compare against 0.
337 assert(CmpInst::isIntPredicate(ResultPred) && "Unsupported predicate");
338 auto Zero = MRI.createGenericVirtualRegister(LLT::scalar(32));
339 MIRBuilder.buildConstant(Zero, 0);
340 MIRBuilder.buildICmp(ResultPred, ProcessedResult, LibcallResult, Zero);
342 Results.push_back(ProcessedResult);
345 if (Results.size() != 1) {
346 assert(Results.size() == 2 && "Unexpected number of results");
347 MIRBuilder.buildOr(OriginalResult, Results[0], Results[1]);
353 MI.eraseFromParent();