blob: 695e0f6326d07a3bee11b44666a0980b4cccf0cb [file] [log] [blame]
Diana Picus22274932016-11-11 08:27:37 +00001//===- 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"
Diana Picus02e11012017-06-15 10:53:31 +000015#include "ARMCallLowering.h"
Diana Picus7cab0782017-02-17 11:25:17 +000016#include "ARMSubtarget.h"
Diana Picusf53865d2017-04-24 09:12:19 +000017#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
Diana Picus02e11012017-06-15 10:53:31 +000018#include "llvm/CodeGen/LowLevelType.h"
Diana Picusf53865d2017-04-24 09:12:19 +000019#include "llvm/CodeGen/MachineRegisterInfo.h"
Diana Picus22274932016-11-11 08:27:37 +000020#include "llvm/CodeGen/ValueTypes.h"
21#include "llvm/IR/DerivedTypes.h"
22#include "llvm/IR/Type.h"
23#include "llvm/Target/TargetOpcodes.h"
24
25using namespace llvm;
26
Diana Picus3e8851a2017-07-05 11:53:51 +000027static bool AEABI(const ARMSubtarget &ST) {
28 return ST.isTargetAEABI() || ST.isTargetGNUAEABI() || ST.isTargetMuslAEABI();
29}
30
Diana Picus7cab0782017-02-17 11:25:17 +000031ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
Diana Picus812caee2016-12-16 12:54:46 +000032 using namespace TargetOpcode;
Diana Picus5a724452016-12-19 14:07:56 +000033
Diana Picus519807f2016-12-19 11:26:31 +000034 const LLT p0 = LLT::pointer(0, 32);
Diana Picus5a724452016-12-19 14:07:56 +000035
Diana Picusd83df5d2017-01-25 08:47:40 +000036 const LLT s1 = LLT::scalar(1);
Diana Picus5a724452016-12-19 14:07:56 +000037 const LLT s8 = LLT::scalar(8);
38 const LLT s16 = LLT::scalar(16);
Diana Picus812caee2016-12-16 12:54:46 +000039 const LLT s32 = LLT::scalar(32);
Diana Picus21c3d8e2017-02-16 09:09:49 +000040 const LLT s64 = LLT::scalar(64);
Diana Picus812caee2016-12-16 12:54:46 +000041
Diana Picusb1fd7842017-07-26 09:25:15 +000042 setAction({G_GLOBAL_VALUE, p0}, Legal);
Diana Picus519807f2016-12-19 11:26:31 +000043 setAction({G_FRAME_INDEX, p0}, Legal);
44
Diana Picusa2b632a2017-02-24 11:28:24 +000045 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 }
Diana Picus519807f2016-12-19 11:26:31 +000050
Diana Picus01964272017-06-07 11:57:30 +000051 for (unsigned Op : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) {
Diana Picus9cfbc6d2017-05-11 09:45:57 +000052 for (auto Ty : {s1, s8, s16})
53 setAction({Op, Ty}, WidenScalar);
54 setAction({Op, s32}, Legal);
55 }
Diana Picus812caee2016-12-16 12:54:46 +000056
Diana Picusb70e88b2017-04-24 08:20:05 +000057 for (unsigned Op : {G_SDIV, G_UDIV}) {
Diana Picusf53865d2017-04-24 09:12:19 +000058 for (auto Ty : {s8, s16})
Kristof Beylsb539ea52017-06-30 08:26:20 +000059 setAction({Op, Ty}, WidenScalar);
Diana Picusb70e88b2017-04-24 08:20:05 +000060 if (ST.hasDivideInARMMode())
61 setAction({Op, s32}, Legal);
62 else
63 setAction({Op, s32}, Libcall);
64 }
65
Diana Picusda25d5b2017-07-18 10:07:01 +000066 for (unsigned Op : {G_SREM, G_UREM}) {
67 for (auto Ty : {s8, s16})
68 setAction({Op, Ty}, WidenScalar);
Diana Picus02e11012017-06-15 10:53:31 +000069 if (ST.hasDivideInARMMode())
70 setAction({Op, s32}, Lower);
Diana Picus3e8851a2017-07-05 11:53:51 +000071 else if (AEABI(ST))
Diana Picus02e11012017-06-15 10:53:31 +000072 setAction({Op, s32}, Custom);
73 else
74 setAction({Op, s32}, Libcall);
Diana Picusda25d5b2017-07-18 10:07:01 +000075 }
Diana Picus02e11012017-06-15 10:53:31 +000076
Quentin Colombet89dbea02017-01-27 01:30:46 +000077 for (unsigned Op : {G_SEXT, G_ZEXT}) {
Diana Picus8b6c6be2017-01-25 08:10:40 +000078 setAction({Op, s32}, Legal);
Diana Picusd83df5d2017-01-25 08:47:40 +000079 for (auto Ty : {s1, s8, s16})
Diana Picus8b6c6be2017-01-25 08:10:40 +000080 setAction({Op, 1, Ty}, Legal);
81 }
82
Diana Picus2c957302017-10-06 14:30:05 +000083 for (unsigned Op : {G_ASHR, G_LSHR, G_SHL})
84 setAction({Op, s32}, Legal);
85
Diana Picus8598b172017-02-28 09:02:42 +000086 setAction({G_GEP, p0}, Legal);
87 setAction({G_GEP, 1, s32}, Legal);
88
Diana Picus7145d222017-06-27 09:19:51 +000089 setAction({G_SELECT, s32}, Legal);
Diana Picus0e74a132017-06-27 10:29:50 +000090 setAction({G_SELECT, p0}, Legal);
Diana Picus7145d222017-06-27 09:19:51 +000091 setAction({G_SELECT, 1, s1}, Legal);
92
Diana Picus87a70672017-07-14 09:46:06 +000093 setAction({G_BRCOND, s1}, Legal);
94
Diana Picuse6beac62017-02-28 11:33:46 +000095 setAction({G_CONSTANT, s32}, Legal);
Diana Picuscd460c82017-07-06 08:04:16 +000096 for (auto Ty : {s1, s8, s16})
97 setAction({G_CONSTANT, Ty}, WidenScalar);
Diana Picuse6beac62017-02-28 11:33:46 +000098
Diana Picus621894a2017-06-19 09:40:51 +000099 setAction({G_ICMP, s1}, Legal);
Diana Picus78aaf7d2017-06-19 11:47:28 +0000100 for (auto Ty : {s8, s16})
101 setAction({G_ICMP, 1, Ty}, WidenScalar);
Diana Picus621894a2017-06-19 09:40:51 +0000102 for (auto Ty : {s32, p0})
103 setAction({G_ICMP, 1, Ty}, Legal);
104
Diana Picusa5bab612017-04-07 09:41:39 +0000105 if (!ST.useSoftFloat() && ST.hasVFP2()) {
Diana Picus7cab0782017-02-17 11:25:17 +0000106 setAction({G_FADD, s32}, Legal);
107 setAction({G_FADD, s64}, Legal);
108
109 setAction({G_LOAD, s64}, Legal);
Diana Picusa2b632a2017-02-24 11:28:24 +0000110 setAction({G_STORE, s64}, Legal);
Diana Picusd0104ea2017-07-06 09:09:33 +0000111
112 setAction({G_FCMP, s1}, Legal);
113 setAction({G_FCMP, 1, s32}, Legal);
Diana Picusb57bba82017-07-11 08:50:01 +0000114 setAction({G_FCMP, 1, s64}, Legal);
Diana Picus1314a282017-04-11 10:52:34 +0000115 } else {
116 for (auto Ty : {s32, s64})
117 setAction({G_FADD, Ty}, Libcall);
Diana Picusd0104ea2017-07-06 09:09:33 +0000118
119 setAction({G_FCMP, s1}, Legal);
120 setAction({G_FCMP, 1, s32}, Custom);
Diana Picusb57bba82017-07-11 08:50:01 +0000121 setAction({G_FCMP, 1, s64}, Custom);
Diana Picusd0104ea2017-07-06 09:09:33 +0000122
123 if (AEABI(ST))
124 setFCmpLibcallsAEABI();
125 else
126 setFCmpLibcallsGNU();
Diana Picus7cab0782017-02-17 11:25:17 +0000127 }
Diana Picus4fa83c02017-02-08 13:23:04 +0000128
Diana Picus3ff82c82017-04-10 09:27:39 +0000129 for (unsigned Op : {G_FREM, G_FPOW})
130 for (auto Ty : {s32, s64})
131 setAction({Op, Ty}, Libcall);
Diana Picusa5bab612017-04-07 09:41:39 +0000132
Diana Picus22274932016-11-11 08:27:37 +0000133 computeTables();
134}
Diana Picusf53865d2017-04-24 09:12:19 +0000135
Diana Picusd0104ea2017-07-06 09:09:33 +0000136void 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}};
Diana Picusb57bba82017-07-11 08:50:01 +0000164
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}};
Diana Picusd0104ea2017-07-06 09:09:33 +0000190}
191
192void 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}};
Diana Picusb57bba82017-07-11 08:50:01 +0000212
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}};
Diana Picusd0104ea2017-07-06 09:09:33 +0000230}
231
232ARMLegalizerInfo::FCmpLibcallsList
Diana Picusb57bba82017-07-11 08:50:01 +0000233ARMLegalizerInfo::getFCmpLibcalls(CmpInst::Predicate Predicate,
234 unsigned Size) const {
Diana Picusd0104ea2017-07-06 09:09:33 +0000235 assert(CmpInst::isFPPredicate(Predicate) && "Unsupported FCmp predicate");
Diana Picusb57bba82017-07-11 08:50:01 +0000236 if (Size == 32)
237 return FCmp32Libcalls[Predicate];
238 if (Size == 64)
239 return FCmp64Libcalls[Predicate];
240 llvm_unreachable("Unsupported size for FCmp predicate");
Diana Picusd0104ea2017-07-06 09:09:33 +0000241}
242
Diana Picusf53865d2017-04-24 09:12:19 +0000243bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI,
244 MachineRegisterInfo &MRI,
245 MachineIRBuilder &MIRBuilder) const {
246 using namespace TargetOpcode;
247
Diana Picusfc1675e2017-07-05 12:57:24 +0000248 MIRBuilder.setInstr(MI);
249
Diana Picusf53865d2017-04-24 09:12:19 +0000250 switch (MI.getOpcode()) {
251 default:
252 return false;
Diana Picus02e11012017-06-15 10:53:31 +0000253 case G_SREM:
254 case G_UREM: {
255 unsigned OriginalResult = MI.getOperand(0).getReg();
256 auto Size = MRI.getType(OriginalResult).getSizeInBits();
257 if (Size != 32)
258 return false;
259
260 auto Libcall =
261 MI.getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
262
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()));
270
Diana Picusfc1675e2017-07-05 12:57:24 +0000271 auto Status = createLibcall(MIRBuilder, Libcall, {RetVal, RetTy},
272 {{MI.getOperand(1).getReg(), ArgTy},
273 {MI.getOperand(2).getReg(), ArgTy}});
Diana Picus02e11012017-06-15 10:53:31 +0000274 if (Status != LegalizerHelper::Legalized)
275 return false;
276
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},
282 RetVal);
Diana Picusd0104ea2017-07-06 09:09:33 +0000283 break;
284 }
285 case G_FCMP: {
Diana Picusb57bba82017-07-11 08:50:01 +0000286 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();
Diana Picus02e11012017-06-15 10:53:31 +0000290
Diana Picusd0104ea2017-07-06 09:09:33 +0000291 auto OriginalResult = MI.getOperand(0).getReg();
292 auto Predicate =
293 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
Diana Picusb57bba82017-07-11 08:50:01 +0000294 auto Libcalls = getFCmpLibcalls(Predicate, OpSize);
Diana Picusd0104ea2017-07-06 09:09:33 +0000295
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);
Diana Picus443135c2017-07-11 09:43:51 +0000302 MI.eraseFromParent();
Diana Picusd0104ea2017-07-06 09:09:33 +0000303 return true;
304 }
305
306 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
Diana Picusb57bba82017-07-11 08:50:01 +0000307 assert((OpSize == 32 || OpSize == 64) && "Unsupported operand size");
308 auto *ArgTy = OpSize == 32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
Diana Picusd0104ea2017-07-06 09:09:33 +0000309 auto *RetTy = Type::getInt32Ty(Ctx);
310
311 SmallVector<unsigned, 2> Results;
312 for (auto Libcall : Libcalls) {
313 auto LibcallResult = MRI.createGenericVirtualRegister(LLT::scalar(32));
314 auto Status =
315 createLibcall(MIRBuilder, Libcall.LibcallID, {LibcallResult, RetTy},
316 {{MI.getOperand(2).getReg(), ArgTy},
317 {MI.getOperand(3).getReg(), ArgTy}});
318
319 if (Status != LegalizerHelper::Legalized)
320 return false;
321
322 auto ProcessedResult =
323 Libcalls.size() == 1
324 ? OriginalResult
325 : MRI.createGenericVirtualRegister(MRI.getType(OriginalResult));
326
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);
335 } else {
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);
341 }
342 Results.push_back(ProcessedResult);
343 }
344
345 if (Results.size() != 1) {
346 assert(Results.size() == 2 && "Unexpected number of results");
347 MIRBuilder.buildOr(OriginalResult, Results[0], Results[1]);
348 }
Diana Picusfc1675e2017-07-05 12:57:24 +0000349 break;
Diana Picus02e11012017-06-15 10:53:31 +0000350 }
Diana Picusf53865d2017-04-24 09:12:19 +0000351 }
Diana Picusfc1675e2017-07-05 12:57:24 +0000352
353 MI.eraseFromParent();
354 return true;
Diana Picusf53865d2017-04-24 09:12:19 +0000355}