xref: /llvm-project/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp (revision 5cde1ccb2998fe06e3930c1d5a8f3c4fb93e845d)
1 //===- ARMLegalizerInfo.cpp --------------------------------------*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file implements the targeting of the Machinelegalizer class for ARM.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
13 
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"
24 
25 using namespace llvm;
26 
27 static bool AEABI(const ARMSubtarget &ST) {
28   return ST.isTargetAEABI() || ST.isTargetGNUAEABI() || ST.isTargetMuslAEABI();
29 }
30 
31 ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
32   using namespace TargetOpcode;
33 
34   const LLT p0 = LLT::pointer(0, 32);
35 
36   const LLT s1 = LLT::scalar(1);
37   const LLT s8 = LLT::scalar(8);
38   const LLT s16 = LLT::scalar(16);
39   const LLT s32 = LLT::scalar(32);
40   const LLT s64 = LLT::scalar(64);
41 
42   setAction({G_GLOBAL_VALUE, p0}, Legal);
43   setAction({G_FRAME_INDEX, p0}, Legal);
44 
45   for (unsigned Op : {G_LOAD, G_STORE}) {
46     for (auto Ty : {s1, s8, s16, s32, p0})
47       setAction({Op, Ty}, Legal);
48     setAction({Op, 1, p0}, Legal);
49   }
50 
51   for (unsigned Op : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) {
52     for (auto Ty : {s1, s8, s16})
53       setAction({Op, Ty}, WidenScalar);
54     setAction({Op, s32}, Legal);
55   }
56 
57   for (unsigned Op : {G_SDIV, G_UDIV}) {
58     for (auto Ty : {s8, s16})
59       setAction({Op, Ty}, WidenScalar);
60     if (ST.hasDivideInARMMode())
61       setAction({Op, s32}, Legal);
62     else
63       setAction({Op, s32}, Libcall);
64   }
65 
66   for (unsigned Op : {G_SREM, G_UREM}) {
67     for (auto Ty : {s8, s16})
68       setAction({Op, Ty}, WidenScalar);
69     if (ST.hasDivideInARMMode())
70       setAction({Op, s32}, Lower);
71     else if (AEABI(ST))
72       setAction({Op, s32}, Custom);
73     else
74       setAction({Op, s32}, Libcall);
75   }
76 
77   for (unsigned Op : {G_SEXT, G_ZEXT}) {
78     setAction({Op, s32}, Legal);
79     for (auto Ty : {s1, s8, s16})
80       setAction({Op, 1, Ty}, Legal);
81   }
82 
83   for (unsigned Op : {G_ASHR, G_LSHR, G_SHL})
84     setAction({Op, s32}, Legal);
85 
86   setAction({G_GEP, p0}, Legal);
87   setAction({G_GEP, 1, s32}, Legal);
88 
89   setAction({G_SELECT, s32}, Legal);
90   setAction({G_SELECT, p0}, Legal);
91   setAction({G_SELECT, 1, s1}, Legal);
92 
93   setAction({G_BRCOND, s1}, Legal);
94 
95   setAction({G_CONSTANT, s32}, Legal);
96   for (auto Ty : {s1, s8, s16})
97     setAction({G_CONSTANT, Ty}, WidenScalar);
98 
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);
104 
105   if (!ST.useSoftFloat() && ST.hasVFP2()) {
106     for (unsigned BinOp : {G_FADD, G_FSUB})
107       for (auto Ty : {s32, s64})
108         setAction({BinOp, Ty}, Legal);
109 
110     setAction({G_LOAD, s64}, Legal);
111     setAction({G_STORE, s64}, Legal);
112 
113     setAction({G_FCMP, s1}, Legal);
114     setAction({G_FCMP, 1, s32}, Legal);
115     setAction({G_FCMP, 1, s64}, Legal);
116   } else {
117     for (unsigned BinOp : {G_FADD, G_FSUB})
118       for (auto Ty : {s32, s64})
119         setAction({BinOp, Ty}, Libcall);
120 
121     setAction({G_FCMP, s1}, Legal);
122     setAction({G_FCMP, 1, s32}, Custom);
123     setAction({G_FCMP, 1, s64}, Custom);
124 
125     if (AEABI(ST))
126       setFCmpLibcallsAEABI();
127     else
128       setFCmpLibcallsGNU();
129   }
130 
131   for (unsigned Op : {G_FREM, G_FPOW})
132     for (auto Ty : {s32, s64})
133       setAction({Op, Ty}, Libcall);
134 
135   computeTables();
136 }
137 
138 void ARMLegalizerInfo::setFCmpLibcallsAEABI() {
139   // FCMP_TRUE and FCMP_FALSE don't need libcalls, they should be
140   // default-initialized.
141   FCmp32Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
142   FCmp32Libcalls[CmpInst::FCMP_OEQ] = {
143       {RTLIB::OEQ_F32, CmpInst::BAD_ICMP_PREDICATE}};
144   FCmp32Libcalls[CmpInst::FCMP_OGE] = {
145       {RTLIB::OGE_F32, CmpInst::BAD_ICMP_PREDICATE}};
146   FCmp32Libcalls[CmpInst::FCMP_OGT] = {
147       {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE}};
148   FCmp32Libcalls[CmpInst::FCMP_OLE] = {
149       {RTLIB::OLE_F32, CmpInst::BAD_ICMP_PREDICATE}};
150   FCmp32Libcalls[CmpInst::FCMP_OLT] = {
151       {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}};
152   FCmp32Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F32, CmpInst::ICMP_EQ}};
153   FCmp32Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F32, CmpInst::ICMP_EQ}};
154   FCmp32Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F32, CmpInst::ICMP_EQ}};
155   FCmp32Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F32, CmpInst::ICMP_EQ}};
156   FCmp32Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F32, CmpInst::ICMP_EQ}};
157   FCmp32Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F32, CmpInst::ICMP_EQ}};
158   FCmp32Libcalls[CmpInst::FCMP_UNO] = {
159       {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}};
160   FCmp32Libcalls[CmpInst::FCMP_ONE] = {
161       {RTLIB::OGT_F32, CmpInst::BAD_ICMP_PREDICATE},
162       {RTLIB::OLT_F32, CmpInst::BAD_ICMP_PREDICATE}};
163   FCmp32Libcalls[CmpInst::FCMP_UEQ] = {
164       {RTLIB::OEQ_F32, CmpInst::BAD_ICMP_PREDICATE},
165       {RTLIB::UO_F32, CmpInst::BAD_ICMP_PREDICATE}};
166 
167   FCmp64Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
168   FCmp64Libcalls[CmpInst::FCMP_OEQ] = {
169       {RTLIB::OEQ_F64, CmpInst::BAD_ICMP_PREDICATE}};
170   FCmp64Libcalls[CmpInst::FCMP_OGE] = {
171       {RTLIB::OGE_F64, CmpInst::BAD_ICMP_PREDICATE}};
172   FCmp64Libcalls[CmpInst::FCMP_OGT] = {
173       {RTLIB::OGT_F64, CmpInst::BAD_ICMP_PREDICATE}};
174   FCmp64Libcalls[CmpInst::FCMP_OLE] = {
175       {RTLIB::OLE_F64, CmpInst::BAD_ICMP_PREDICATE}};
176   FCmp64Libcalls[CmpInst::FCMP_OLT] = {
177       {RTLIB::OLT_F64, CmpInst::BAD_ICMP_PREDICATE}};
178   FCmp64Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F64, CmpInst::ICMP_EQ}};
179   FCmp64Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F64, CmpInst::ICMP_EQ}};
180   FCmp64Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F64, CmpInst::ICMP_EQ}};
181   FCmp64Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F64, CmpInst::ICMP_EQ}};
182   FCmp64Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F64, CmpInst::ICMP_EQ}};
183   FCmp64Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F64, CmpInst::ICMP_EQ}};
184   FCmp64Libcalls[CmpInst::FCMP_UNO] = {
185       {RTLIB::UO_F64, CmpInst::BAD_ICMP_PREDICATE}};
186   FCmp64Libcalls[CmpInst::FCMP_ONE] = {
187       {RTLIB::OGT_F64, CmpInst::BAD_ICMP_PREDICATE},
188       {RTLIB::OLT_F64, CmpInst::BAD_ICMP_PREDICATE}};
189   FCmp64Libcalls[CmpInst::FCMP_UEQ] = {
190       {RTLIB::OEQ_F64, CmpInst::BAD_ICMP_PREDICATE},
191       {RTLIB::UO_F64, CmpInst::BAD_ICMP_PREDICATE}};
192 }
193 
194 void ARMLegalizerInfo::setFCmpLibcallsGNU() {
195   // FCMP_TRUE and FCMP_FALSE don't need libcalls, they should be
196   // default-initialized.
197   FCmp32Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
198   FCmp32Libcalls[CmpInst::FCMP_OEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ}};
199   FCmp32Libcalls[CmpInst::FCMP_OGE] = {{RTLIB::OGE_F32, CmpInst::ICMP_SGE}};
200   FCmp32Libcalls[CmpInst::FCMP_OGT] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT}};
201   FCmp32Libcalls[CmpInst::FCMP_OLE] = {{RTLIB::OLE_F32, CmpInst::ICMP_SLE}};
202   FCmp32Libcalls[CmpInst::FCMP_OLT] = {{RTLIB::OLT_F32, CmpInst::ICMP_SLT}};
203   FCmp32Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F32, CmpInst::ICMP_EQ}};
204   FCmp32Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F32, CmpInst::ICMP_SGE}};
205   FCmp32Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F32, CmpInst::ICMP_SGT}};
206   FCmp32Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SLE}};
207   FCmp32Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F32, CmpInst::ICMP_SLT}};
208   FCmp32Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F32, CmpInst::ICMP_NE}};
209   FCmp32Libcalls[CmpInst::FCMP_UNO] = {{RTLIB::UO_F32, CmpInst::ICMP_NE}};
210   FCmp32Libcalls[CmpInst::FCMP_ONE] = {{RTLIB::OGT_F32, CmpInst::ICMP_SGT},
211                                        {RTLIB::OLT_F32, CmpInst::ICMP_SLT}};
212   FCmp32Libcalls[CmpInst::FCMP_UEQ] = {{RTLIB::OEQ_F32, CmpInst::ICMP_EQ},
213                                        {RTLIB::UO_F32, CmpInst::ICMP_NE}};
214 
215   FCmp64Libcalls.resize(CmpInst::LAST_FCMP_PREDICATE + 1);
216   FCmp64Libcalls[CmpInst::FCMP_OEQ] = {{RTLIB::OEQ_F64, CmpInst::ICMP_EQ}};
217   FCmp64Libcalls[CmpInst::FCMP_OGE] = {{RTLIB::OGE_F64, CmpInst::ICMP_SGE}};
218   FCmp64Libcalls[CmpInst::FCMP_OGT] = {{RTLIB::OGT_F64, CmpInst::ICMP_SGT}};
219   FCmp64Libcalls[CmpInst::FCMP_OLE] = {{RTLIB::OLE_F64, CmpInst::ICMP_SLE}};
220   FCmp64Libcalls[CmpInst::FCMP_OLT] = {{RTLIB::OLT_F64, CmpInst::ICMP_SLT}};
221   FCmp64Libcalls[CmpInst::FCMP_ORD] = {{RTLIB::O_F64, CmpInst::ICMP_EQ}};
222   FCmp64Libcalls[CmpInst::FCMP_UGE] = {{RTLIB::OLT_F64, CmpInst::ICMP_SGE}};
223   FCmp64Libcalls[CmpInst::FCMP_UGT] = {{RTLIB::OLE_F64, CmpInst::ICMP_SGT}};
224   FCmp64Libcalls[CmpInst::FCMP_ULE] = {{RTLIB::OGT_F64, CmpInst::ICMP_SLE}};
225   FCmp64Libcalls[CmpInst::FCMP_ULT] = {{RTLIB::OGE_F64, CmpInst::ICMP_SLT}};
226   FCmp64Libcalls[CmpInst::FCMP_UNE] = {{RTLIB::UNE_F64, CmpInst::ICMP_NE}};
227   FCmp64Libcalls[CmpInst::FCMP_UNO] = {{RTLIB::UO_F64, CmpInst::ICMP_NE}};
228   FCmp64Libcalls[CmpInst::FCMP_ONE] = {{RTLIB::OGT_F64, CmpInst::ICMP_SGT},
229                                        {RTLIB::OLT_F64, CmpInst::ICMP_SLT}};
230   FCmp64Libcalls[CmpInst::FCMP_UEQ] = {{RTLIB::OEQ_F64, CmpInst::ICMP_EQ},
231                                        {RTLIB::UO_F64, CmpInst::ICMP_NE}};
232 }
233 
234 ARMLegalizerInfo::FCmpLibcallsList
235 ARMLegalizerInfo::getFCmpLibcalls(CmpInst::Predicate Predicate,
236                                   unsigned Size) const {
237   assert(CmpInst::isFPPredicate(Predicate) && "Unsupported FCmp predicate");
238   if (Size == 32)
239     return FCmp32Libcalls[Predicate];
240   if (Size == 64)
241     return FCmp64Libcalls[Predicate];
242   llvm_unreachable("Unsupported size for FCmp predicate");
243 }
244 
245 bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI,
246                                       MachineRegisterInfo &MRI,
247                                       MachineIRBuilder &MIRBuilder) const {
248   using namespace TargetOpcode;
249 
250   MIRBuilder.setInstr(MI);
251 
252   switch (MI.getOpcode()) {
253   default:
254     return false;
255   case G_SREM:
256   case G_UREM: {
257     unsigned OriginalResult = MI.getOperand(0).getReg();
258     auto Size = MRI.getType(OriginalResult).getSizeInBits();
259     if (Size != 32)
260       return false;
261 
262     auto Libcall =
263         MI.getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
264 
265     // Our divmod libcalls return a struct containing the quotient and the
266     // remainder. We need to create a virtual register for it.
267     auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
268     Type *ArgTy = Type::getInt32Ty(Ctx);
269     StructType *RetTy = StructType::get(Ctx, {ArgTy, ArgTy}, /* Packed */ true);
270     auto RetVal = MRI.createGenericVirtualRegister(
271         getLLTForType(*RetTy, MIRBuilder.getMF().getDataLayout()));
272 
273     auto Status = createLibcall(MIRBuilder, Libcall, {RetVal, RetTy},
274                                 {{MI.getOperand(1).getReg(), ArgTy},
275                                  {MI.getOperand(2).getReg(), ArgTy}});
276     if (Status != LegalizerHelper::Legalized)
277       return false;
278 
279     // The remainder is the second result of divmod. Split the return value into
280     // a new, unused register for the quotient and the destination of the
281     // original instruction for the remainder.
282     MIRBuilder.buildUnmerge(
283         {MRI.createGenericVirtualRegister(LLT::scalar(32)), OriginalResult},
284         RetVal);
285     break;
286   }
287   case G_FCMP: {
288     assert(MRI.getType(MI.getOperand(2).getReg()) ==
289                MRI.getType(MI.getOperand(3).getReg()) &&
290            "Mismatched operands for G_FCMP");
291     auto OpSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits();
292 
293     auto OriginalResult = MI.getOperand(0).getReg();
294     auto Predicate =
295         static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
296     auto Libcalls = getFCmpLibcalls(Predicate, OpSize);
297 
298     if (Libcalls.empty()) {
299       assert((Predicate == CmpInst::FCMP_TRUE ||
300               Predicate == CmpInst::FCMP_FALSE) &&
301              "Predicate needs libcalls, but none specified");
302       MIRBuilder.buildConstant(OriginalResult,
303                                Predicate == CmpInst::FCMP_TRUE ? 1 : 0);
304       MI.eraseFromParent();
305       return true;
306     }
307 
308     auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
309     assert((OpSize == 32 || OpSize == 64) && "Unsupported operand size");
310     auto *ArgTy = OpSize == 32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
311     auto *RetTy = Type::getInt32Ty(Ctx);
312 
313     SmallVector<unsigned, 2> Results;
314     for (auto Libcall : Libcalls) {
315       auto LibcallResult = MRI.createGenericVirtualRegister(LLT::scalar(32));
316       auto Status =
317           createLibcall(MIRBuilder, Libcall.LibcallID, {LibcallResult, RetTy},
318                         {{MI.getOperand(2).getReg(), ArgTy},
319                          {MI.getOperand(3).getReg(), ArgTy}});
320 
321       if (Status != LegalizerHelper::Legalized)
322         return false;
323 
324       auto ProcessedResult =
325           Libcalls.size() == 1
326               ? OriginalResult
327               : MRI.createGenericVirtualRegister(MRI.getType(OriginalResult));
328 
329       // We have a result, but we need to transform it into a proper 1-bit 0 or
330       // 1, taking into account the different peculiarities of the values
331       // returned by the comparison functions.
332       CmpInst::Predicate ResultPred = Libcall.Predicate;
333       if (ResultPred == CmpInst::BAD_ICMP_PREDICATE) {
334         // We have a nice 0 or 1, and we just need to truncate it back to 1 bit
335         // to keep the types consistent.
336         MIRBuilder.buildTrunc(ProcessedResult, LibcallResult);
337       } else {
338         // We need to compare against 0.
339         assert(CmpInst::isIntPredicate(ResultPred) && "Unsupported predicate");
340         auto Zero = MRI.createGenericVirtualRegister(LLT::scalar(32));
341         MIRBuilder.buildConstant(Zero, 0);
342         MIRBuilder.buildICmp(ResultPred, ProcessedResult, LibcallResult, Zero);
343       }
344       Results.push_back(ProcessedResult);
345     }
346 
347     if (Results.size() != 1) {
348       assert(Results.size() == 2 && "Unexpected number of results");
349       MIRBuilder.buildOr(OriginalResult, Results[0], Results[1]);
350     }
351     break;
352   }
353   }
354 
355   MI.eraseFromParent();
356   return true;
357 }
358