blob: f77d807a69de04cdf7b5c4e9af5e7e0525f7af32 [file] [log] [blame]
Tim Northover69fa84a2016-10-14 22:18:18 +00001//===-- llvm/CodeGen/GlobalISel/LegalizerHelper.cpp -----------------------===//
Tim Northover33b07d62016-07-22 20:03:43 +00002//
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//
Tim Northover69fa84a2016-10-14 22:18:18 +000010/// \file This file implements the LegalizerHelper class to legalize
Tim Northover33b07d62016-07-22 20:03:43 +000011/// individual instructions and the LegalizeMachineIR wrapper pass for the
12/// primary legalization.
13//
14//===----------------------------------------------------------------------===//
15
Tim Northover69fa84a2016-10-14 22:18:18 +000016#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
Tim Northoveredb3c8c2016-08-29 19:07:16 +000017#include "llvm/CodeGen/GlobalISel/CallLowering.h"
Tim Northover69fa84a2016-10-14 22:18:18 +000018#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
Tim Northover33b07d62016-07-22 20:03:43 +000019#include "llvm/CodeGen/MachineRegisterInfo.h"
20#include "llvm/Support/Debug.h"
21#include "llvm/Support/raw_ostream.h"
Tim Northoveredb3c8c2016-08-29 19:07:16 +000022#include "llvm/Target/TargetLowering.h"
Tim Northover33b07d62016-07-22 20:03:43 +000023#include "llvm/Target/TargetSubtargetInfo.h"
24
25#include <sstream>
26
27#define DEBUG_TYPE "legalize-mir"
28
29using namespace llvm;
30
Tim Northover69fa84a2016-10-14 22:18:18 +000031LegalizerHelper::LegalizerHelper(MachineFunction &MF)
Tim Northover33b07d62016-07-22 20:03:43 +000032 : MRI(MF.getRegInfo()) {
33 MIRBuilder.setMF(MF);
34}
35
Tim Northover69fa84a2016-10-14 22:18:18 +000036LegalizerHelper::LegalizeResult
37LegalizerHelper::legalizeInstrStep(MachineInstr &MI,
38 const LegalizerInfo &LegalizerInfo) {
39 auto Action = LegalizerInfo.getAction(MI, MRI);
Tim Northovera01bece2016-08-23 19:30:42 +000040 switch (std::get<0>(Action)) {
Tim Northover69fa84a2016-10-14 22:18:18 +000041 case LegalizerInfo::Legal:
Tim Northover33b07d62016-07-22 20:03:43 +000042 return AlreadyLegal;
Tim Northover69fa84a2016-10-14 22:18:18 +000043 case LegalizerInfo::Libcall:
Tim Northoveredb3c8c2016-08-29 19:07:16 +000044 return libcall(MI);
Tim Northover69fa84a2016-10-14 22:18:18 +000045 case LegalizerInfo::NarrowScalar:
Tim Northovera01bece2016-08-23 19:30:42 +000046 return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action));
Tim Northover69fa84a2016-10-14 22:18:18 +000047 case LegalizerInfo::WidenScalar:
Tim Northovera01bece2016-08-23 19:30:42 +000048 return widenScalar(MI, std::get<1>(Action), std::get<2>(Action));
Tim Northover69fa84a2016-10-14 22:18:18 +000049 case LegalizerInfo::Lower:
Tim Northovercecee562016-08-26 17:46:13 +000050 return lower(MI, std::get<1>(Action), std::get<2>(Action));
Tim Northover69fa84a2016-10-14 22:18:18 +000051 case LegalizerInfo::FewerElements:
Tim Northovera01bece2016-08-23 19:30:42 +000052 return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action));
Tim Northover33b07d62016-07-22 20:03:43 +000053 default:
54 return UnableToLegalize;
55 }
56}
57
Tim Northover69fa84a2016-10-14 22:18:18 +000058LegalizerHelper::LegalizeResult
59LegalizerHelper::legalizeInstr(MachineInstr &MI,
60 const LegalizerInfo &LegalizerInfo) {
Tim Northoverac5148e2016-08-29 19:27:20 +000061 SmallVector<MachineInstr *, 4> WorkList;
62 MIRBuilder.recordInsertions(
63 [&](MachineInstr *MI) { WorkList.push_back(MI); });
64 WorkList.push_back(&MI);
Tim Northover438c77c2016-08-25 17:37:32 +000065
66 bool Changed = false;
67 LegalizeResult Res;
Tim Northoverac5148e2016-08-29 19:27:20 +000068 unsigned Idx = 0;
Tim Northover438c77c2016-08-25 17:37:32 +000069 do {
Tim Northover69fa84a2016-10-14 22:18:18 +000070 Res = legalizeInstrStep(*WorkList[Idx], LegalizerInfo);
Tim Northover438c77c2016-08-25 17:37:32 +000071 if (Res == UnableToLegalize) {
72 MIRBuilder.stopRecordingInsertions();
73 return UnableToLegalize;
74 }
75 Changed |= Res == Legalized;
Tim Northoverac5148e2016-08-29 19:27:20 +000076 ++Idx;
77 } while (Idx < WorkList.size());
Tim Northover438c77c2016-08-25 17:37:32 +000078
79 MIRBuilder.stopRecordingInsertions();
80
81 return Changed ? Legalized : AlreadyLegal;
82}
83
Tim Northover69fa84a2016-10-14 22:18:18 +000084void LegalizerHelper::extractParts(unsigned Reg, LLT Ty, int NumParts,
85 SmallVectorImpl<unsigned> &VRegs) {
Tim Northover33b07d62016-07-22 20:03:43 +000086 unsigned Size = Ty.getSizeInBits();
Tim Northover6f80b082016-08-19 17:47:05 +000087 SmallVector<uint64_t, 4> Indexes;
Tim Northover33b07d62016-07-22 20:03:43 +000088 for (int i = 0; i < NumParts; ++i) {
Tim Northover0f140c72016-09-09 11:46:34 +000089 VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
Tim Northover33b07d62016-07-22 20:03:43 +000090 Indexes.push_back(i * Size);
91 }
Tim Northover0f140c72016-09-09 11:46:34 +000092 MIRBuilder.buildExtract(VRegs, Indexes, Reg);
Tim Northover33b07d62016-07-22 20:03:43 +000093}
94
Tim Northover69fa84a2016-10-14 22:18:18 +000095LegalizerHelper::LegalizeResult
96LegalizerHelper::libcall(MachineInstr &MI) {
Tim Northover0f140c72016-09-09 11:46:34 +000097 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
98 unsigned Size = Ty.getSizeInBits();
Tim Northoveredb3c8c2016-08-29 19:07:16 +000099 MIRBuilder.setInstr(MI);
100
101 switch (MI.getOpcode()) {
102 default:
103 return UnableToLegalize;
104 case TargetOpcode::G_FREM: {
Tim Northover11a23542016-08-31 21:24:02 +0000105 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
106 Type *Ty = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx);
Tim Northoveredb3c8c2016-08-29 19:07:16 +0000107 auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
108 auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
109 const char *Name =
110 TLI.getLibcallName(Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32);
111
Tim Northover9a467182016-09-21 12:57:45 +0000112 CLI.lowerCall(
113 MIRBuilder, MachineOperand::CreateES(Name),
114 {MI.getOperand(0).getReg(), Ty},
115 {{MI.getOperand(1).getReg(), Ty}, {MI.getOperand(2).getReg(), Ty}});
Tim Northoveredb3c8c2016-08-29 19:07:16 +0000116 MI.eraseFromParent();
117 return Legalized;
118 }
119 }
120}
121
Tim Northover69fa84a2016-10-14 22:18:18 +0000122LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
123 unsigned TypeIdx,
124 LLT NarrowTy) {
Quentin Colombet5e60bcd2016-08-27 02:38:21 +0000125 // FIXME: Don't know how to handle secondary types yet.
126 if (TypeIdx != 0)
127 return UnableToLegalize;
Justin Bognerfde01042017-01-18 17:29:54 +0000128
129 MIRBuilder.setInstr(MI);
130
Tim Northover9656f142016-08-04 20:54:13 +0000131 switch (MI.getOpcode()) {
132 default:
133 return UnableToLegalize;
134 case TargetOpcode::G_ADD: {
135 // Expand in terms of carry-setting/consuming G_ADDE instructions.
136 unsigned NarrowSize = NarrowTy.getSizeInBits();
Tim Northover0f140c72016-09-09 11:46:34 +0000137 int NumParts = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() /
138 NarrowTy.getSizeInBits();
Tim Northover9656f142016-08-04 20:54:13 +0000139
Tim Northoverb18ea162016-09-20 15:20:36 +0000140 SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
141 SmallVector<uint64_t, 2> Indexes;
Tim Northover9656f142016-08-04 20:54:13 +0000142 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
143 extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
144
Tim Northover0f140c72016-09-09 11:46:34 +0000145 unsigned CarryIn = MRI.createGenericVirtualRegister(LLT::scalar(1));
146 MIRBuilder.buildConstant(CarryIn, 0);
Tim Northover9656f142016-08-04 20:54:13 +0000147
148 for (int i = 0; i < NumParts; ++i) {
Tim Northover0f140c72016-09-09 11:46:34 +0000149 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
150 unsigned CarryOut = MRI.createGenericVirtualRegister(LLT::scalar(1));
Tim Northover9656f142016-08-04 20:54:13 +0000151
Tim Northover0f140c72016-09-09 11:46:34 +0000152 MIRBuilder.buildUAdde(DstReg, CarryOut, Src1Regs[i],
Tim Northover91c81732016-08-19 17:17:06 +0000153 Src2Regs[i], CarryIn);
Tim Northover9656f142016-08-04 20:54:13 +0000154
155 DstRegs.push_back(DstReg);
Tim Northover91c81732016-08-19 17:17:06 +0000156 Indexes.push_back(i * NarrowSize);
Tim Northover9656f142016-08-04 20:54:13 +0000157 CarryIn = CarryOut;
158 }
Tim Northover0f140c72016-09-09 11:46:34 +0000159 unsigned DstReg = MI.getOperand(0).getReg();
160 MIRBuilder.buildSequence(DstReg, DstRegs, Indexes);
Tim Northover9656f142016-08-04 20:54:13 +0000161 MI.eraseFromParent();
162 return Legalized;
163 }
Justin Bognerd09c3ce2017-01-19 01:05:48 +0000164 case TargetOpcode::G_LOAD: {
165 unsigned NarrowSize = NarrowTy.getSizeInBits();
166 int NumParts =
167 MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() / NarrowSize;
168 LLT NarrowPtrTy = LLT::pointer(
169 MRI.getType(MI.getOperand(1).getReg()).getAddressSpace(), NarrowSize);
170
171 SmallVector<unsigned, 2> DstRegs;
172 SmallVector<uint64_t, 2> Indexes;
173 for (int i = 0; i < NumParts; ++i) {
174 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
175 unsigned SrcReg = MRI.createGenericVirtualRegister(NarrowPtrTy);
176 unsigned Offset = MRI.createGenericVirtualRegister(LLT::scalar(64));
177
178 MIRBuilder.buildConstant(Offset, i * NarrowSize / 8);
179 MIRBuilder.buildGEP(SrcReg, MI.getOperand(1).getReg(), Offset);
Justin Bognere094cc42017-01-20 00:30:17 +0000180 // TODO: This is conservatively correct, but we probably want to split the
181 // memory operands in the future.
Justin Bognerd09c3ce2017-01-19 01:05:48 +0000182 MIRBuilder.buildLoad(DstReg, SrcReg, **MI.memoperands_begin());
183
184 DstRegs.push_back(DstReg);
185 Indexes.push_back(i * NarrowSize);
186 }
187 unsigned DstReg = MI.getOperand(0).getReg();
188 MIRBuilder.buildSequence(DstReg, DstRegs, Indexes);
189 MI.eraseFromParent();
190 return Legalized;
191 }
Justin Bognerfde01042017-01-18 17:29:54 +0000192 case TargetOpcode::G_STORE: {
193 unsigned NarrowSize = NarrowTy.getSizeInBits();
194 int NumParts =
195 MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() / NarrowSize;
196 LLT NarrowPtrTy = LLT::pointer(
197 MRI.getType(MI.getOperand(1).getReg()).getAddressSpace(), NarrowSize);
198
199 SmallVector<unsigned, 2> SrcRegs;
200 extractParts(MI.getOperand(0).getReg(), NarrowTy, NumParts, SrcRegs);
201
202 for (int i = 0; i < NumParts; ++i) {
203 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowPtrTy);
204 unsigned Offset = MRI.createGenericVirtualRegister(LLT::scalar(64));
205 MIRBuilder.buildConstant(Offset, i * NarrowSize / 8);
206 MIRBuilder.buildGEP(DstReg, MI.getOperand(1).getReg(), Offset);
Justin Bognere094cc42017-01-20 00:30:17 +0000207 // TODO: This is conservatively correct, but we probably want to split the
208 // memory operands in the future.
Justin Bognerfde01042017-01-18 17:29:54 +0000209 MIRBuilder.buildStore(SrcRegs[i], DstReg, **MI.memoperands_begin());
210 }
211 MI.eraseFromParent();
212 return Legalized;
213 }
Tim Northover9656f142016-08-04 20:54:13 +0000214 }
Tim Northover33b07d62016-07-22 20:03:43 +0000215}
216
Tim Northover69fa84a2016-10-14 22:18:18 +0000217LegalizerHelper::LegalizeResult
218LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
Tim Northover3c73e362016-08-23 18:20:09 +0000219 MIRBuilder.setInstr(MI);
220
Tim Northover32335812016-08-04 18:35:11 +0000221 switch (MI.getOpcode()) {
222 default:
223 return UnableToLegalize;
Tim Northover61c16142016-08-04 21:39:49 +0000224 case TargetOpcode::G_ADD:
225 case TargetOpcode::G_AND:
226 case TargetOpcode::G_MUL:
227 case TargetOpcode::G_OR:
228 case TargetOpcode::G_XOR:
Justin Bognerddb80ae2017-01-19 07:51:17 +0000229 case TargetOpcode::G_SUB:
230 case TargetOpcode::G_SHL: {
Tim Northover32335812016-08-04 18:35:11 +0000231 // Perform operation at larger width (any extension is fine here, high bits
232 // don't affect the result) and then truncate the result back to the
233 // original type.
Tim Northover0f140c72016-09-09 11:46:34 +0000234 unsigned Src1Ext = MRI.createGenericVirtualRegister(WideTy);
235 unsigned Src2Ext = MRI.createGenericVirtualRegister(WideTy);
236 MIRBuilder.buildAnyExt(Src1Ext, MI.getOperand(1).getReg());
237 MIRBuilder.buildAnyExt(Src2Ext, MI.getOperand(2).getReg());
Tim Northover32335812016-08-04 18:35:11 +0000238
Tim Northover0f140c72016-09-09 11:46:34 +0000239 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
240 MIRBuilder.buildInstr(MI.getOpcode())
241 .addDef(DstExt)
242 .addUse(Src1Ext)
243 .addUse(Src2Ext);
Tim Northover32335812016-08-04 18:35:11 +0000244
Tim Northover0f140c72016-09-09 11:46:34 +0000245 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
Tim Northover32335812016-08-04 18:35:11 +0000246 MI.eraseFromParent();
247 return Legalized;
248 }
Tim Northover7a753d92016-08-26 17:46:06 +0000249 case TargetOpcode::G_SDIV:
Justin Bognerddb80ae2017-01-19 07:51:17 +0000250 case TargetOpcode::G_UDIV:
251 case TargetOpcode::G_ASHR:
252 case TargetOpcode::G_LSHR: {
253 unsigned ExtOp = MI.getOpcode() == TargetOpcode::G_SDIV ||
254 MI.getOpcode() == TargetOpcode::G_ASHR
255 ? TargetOpcode::G_SEXT
256 : TargetOpcode::G_ZEXT;
Tim Northover7a753d92016-08-26 17:46:06 +0000257
Tim Northover0f140c72016-09-09 11:46:34 +0000258 unsigned LHSExt = MRI.createGenericVirtualRegister(WideTy);
259 MIRBuilder.buildInstr(ExtOp).addDef(LHSExt).addUse(
260 MI.getOperand(1).getReg());
Tim Northover7a753d92016-08-26 17:46:06 +0000261
Tim Northover0f140c72016-09-09 11:46:34 +0000262 unsigned RHSExt = MRI.createGenericVirtualRegister(WideTy);
263 MIRBuilder.buildInstr(ExtOp).addDef(RHSExt).addUse(
264 MI.getOperand(2).getReg());
Tim Northover7a753d92016-08-26 17:46:06 +0000265
Tim Northover0f140c72016-09-09 11:46:34 +0000266 unsigned ResExt = MRI.createGenericVirtualRegister(WideTy);
267 MIRBuilder.buildInstr(MI.getOpcode())
Tim Northover7a753d92016-08-26 17:46:06 +0000268 .addDef(ResExt)
269 .addUse(LHSExt)
270 .addUse(RHSExt);
271
Tim Northover0f140c72016-09-09 11:46:34 +0000272 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), ResExt);
Tim Northover7a753d92016-08-26 17:46:06 +0000273 MI.eraseFromParent();
274 return Legalized;
275 }
Ahmed Bougachad2948232017-01-20 01:37:24 +0000276 case TargetOpcode::G_SITOFP:
277 case TargetOpcode::G_UITOFP: {
278 if (TypeIdx != 1)
279 return UnableToLegalize;
280
281 unsigned Src = MI.getOperand(1).getReg();
282 unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy);
283
284 if (MI.getOpcode() == TargetOpcode::G_SITOFP) {
285 MIRBuilder.buildSExt(SrcExt, Src);
286 } else {
287 assert(MI.getOpcode() == TargetOpcode::G_UITOFP && "Unexpected conv op");
288 MIRBuilder.buildZExt(SrcExt, Src);
289 }
290
291 MIRBuilder.buildInstr(MI.getOpcode())
292 .addDef(MI.getOperand(0).getReg())
293 .addUse(SrcExt);
294
295 MI.eraseFromParent();
296 return Legalized;
297 }
Tim Northover3c73e362016-08-23 18:20:09 +0000298 case TargetOpcode::G_LOAD: {
Rui Ueyamaa5edf652016-09-09 18:37:08 +0000299 assert(alignTo(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(), 8) ==
300 WideTy.getSizeInBits() &&
Tim Northover3c73e362016-08-23 18:20:09 +0000301 "illegal to increase number of bytes loaded");
302
Tim Northover0f140c72016-09-09 11:46:34 +0000303 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
304 MIRBuilder.buildLoad(DstExt, MI.getOperand(1).getReg(),
305 **MI.memoperands_begin());
306 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
Tim Northover3c73e362016-08-23 18:20:09 +0000307 MI.eraseFromParent();
308 return Legalized;
309 }
310 case TargetOpcode::G_STORE: {
Rui Ueyamaa5edf652016-09-09 18:37:08 +0000311 assert(alignTo(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(), 8) ==
312 WideTy.getSizeInBits() &&
Tim Northover3c73e362016-08-23 18:20:09 +0000313 "illegal to increase number of bytes modified by a store");
314
Tim Northover0f140c72016-09-09 11:46:34 +0000315 unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy);
316 MIRBuilder.buildAnyExt(SrcExt, MI.getOperand(0).getReg());
317 MIRBuilder.buildStore(SrcExt, MI.getOperand(1).getReg(),
318 **MI.memoperands_begin());
Tim Northover3c73e362016-08-23 18:20:09 +0000319 MI.eraseFromParent();
320 return Legalized;
321 }
Tim Northoverea904f92016-08-19 22:40:00 +0000322 case TargetOpcode::G_CONSTANT: {
Tim Northover0f140c72016-09-09 11:46:34 +0000323 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
Tim Northover9267ac52016-12-05 21:47:07 +0000324 MIRBuilder.buildConstant(DstExt, *MI.getOperand(1).getCImm());
Tim Northover0f140c72016-09-09 11:46:34 +0000325 MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
Tim Northoverea904f92016-08-19 22:40:00 +0000326 MI.eraseFromParent();
327 return Legalized;
328 }
Tim Northovera11be042016-08-19 22:40:08 +0000329 case TargetOpcode::G_FCONSTANT: {
Tim Northover0f140c72016-09-09 11:46:34 +0000330 unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
331 MIRBuilder.buildFConstant(DstExt, *MI.getOperand(1).getFPImm());
332 MIRBuilder.buildFPTrunc(MI.getOperand(0).getReg(), DstExt);
Tim Northovera11be042016-08-19 22:40:08 +0000333 MI.eraseFromParent();
334 return Legalized;
335 }
Tim Northoverb3a0be42016-08-23 21:01:20 +0000336 case TargetOpcode::G_BRCOND: {
Tim Northover0f140c72016-09-09 11:46:34 +0000337 unsigned TstExt = MRI.createGenericVirtualRegister(WideTy);
338 MIRBuilder.buildAnyExt(TstExt, MI.getOperand(0).getReg());
339 MIRBuilder.buildBrCond(TstExt, *MI.getOperand(1).getMBB());
Tim Northoverb3a0be42016-08-23 21:01:20 +0000340 MI.eraseFromParent();
341 return Legalized;
342 }
Tim Northover6cd4b232016-08-23 21:01:26 +0000343 case TargetOpcode::G_ICMP: {
Tim Northover051b8ad2016-08-26 17:46:17 +0000344 assert(TypeIdx == 1 && "unable to legalize predicate");
345 bool IsSigned = CmpInst::isSigned(
346 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()));
Tim Northover0f140c72016-09-09 11:46:34 +0000347 unsigned Op0Ext = MRI.createGenericVirtualRegister(WideTy);
348 unsigned Op1Ext = MRI.createGenericVirtualRegister(WideTy);
Tim Northover051b8ad2016-08-26 17:46:17 +0000349 if (IsSigned) {
Tim Northover0f140c72016-09-09 11:46:34 +0000350 MIRBuilder.buildSExt(Op0Ext, MI.getOperand(2).getReg());
351 MIRBuilder.buildSExt(Op1Ext, MI.getOperand(3).getReg());
Tim Northover6cd4b232016-08-23 21:01:26 +0000352 } else {
Tim Northover0f140c72016-09-09 11:46:34 +0000353 MIRBuilder.buildZExt(Op0Ext, MI.getOperand(2).getReg());
354 MIRBuilder.buildZExt(Op1Ext, MI.getOperand(3).getReg());
Tim Northover6cd4b232016-08-23 21:01:26 +0000355 }
Tim Northover051b8ad2016-08-26 17:46:17 +0000356 MIRBuilder.buildICmp(
Tim Northover051b8ad2016-08-26 17:46:17 +0000357 static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
358 MI.getOperand(0).getReg(), Op0Ext, Op1Ext);
359 MI.eraseFromParent();
360 return Legalized;
Tim Northover6cd4b232016-08-23 21:01:26 +0000361 }
Tim Northover22d82cf2016-09-15 11:02:19 +0000362 case TargetOpcode::G_GEP: {
363 assert(TypeIdx == 1 && "unable to legalize pointer of GEP");
364 unsigned OffsetExt = MRI.createGenericVirtualRegister(WideTy);
365 MIRBuilder.buildSExt(OffsetExt, MI.getOperand(2).getReg());
366 MI.getOperand(2).setReg(OffsetExt);
367 return Legalized;
368 }
Tim Northover32335812016-08-04 18:35:11 +0000369 }
Tim Northover33b07d62016-07-22 20:03:43 +0000370}
371
Tim Northover69fa84a2016-10-14 22:18:18 +0000372LegalizerHelper::LegalizeResult
373LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
Tim Northovercecee562016-08-26 17:46:13 +0000374 using namespace TargetOpcode;
Tim Northovercecee562016-08-26 17:46:13 +0000375 MIRBuilder.setInstr(MI);
376
377 switch(MI.getOpcode()) {
378 default:
379 return UnableToLegalize;
380 case TargetOpcode::G_SREM:
381 case TargetOpcode::G_UREM: {
Tim Northover0f140c72016-09-09 11:46:34 +0000382 unsigned QuotReg = MRI.createGenericVirtualRegister(Ty);
383 MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV)
Tim Northovercecee562016-08-26 17:46:13 +0000384 .addDef(QuotReg)
385 .addUse(MI.getOperand(1).getReg())
386 .addUse(MI.getOperand(2).getReg());
387
Tim Northover0f140c72016-09-09 11:46:34 +0000388 unsigned ProdReg = MRI.createGenericVirtualRegister(Ty);
389 MIRBuilder.buildMul(ProdReg, QuotReg, MI.getOperand(2).getReg());
390 MIRBuilder.buildSub(MI.getOperand(0).getReg(), MI.getOperand(1).getReg(),
391 ProdReg);
Tim Northovercecee562016-08-26 17:46:13 +0000392 MI.eraseFromParent();
393 return Legalized;
394 }
395 }
396}
397
Tim Northover69fa84a2016-10-14 22:18:18 +0000398LegalizerHelper::LegalizeResult
399LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
400 LLT NarrowTy) {
Quentin Colombet5e60bcd2016-08-27 02:38:21 +0000401 // FIXME: Don't know how to handle secondary types yet.
402 if (TypeIdx != 0)
403 return UnableToLegalize;
Tim Northover33b07d62016-07-22 20:03:43 +0000404 switch (MI.getOpcode()) {
405 default:
406 return UnableToLegalize;
407 case TargetOpcode::G_ADD: {
408 unsigned NarrowSize = NarrowTy.getSizeInBits();
Tim Northover0f140c72016-09-09 11:46:34 +0000409 unsigned DstReg = MI.getOperand(0).getReg();
410 int NumParts = MRI.getType(DstReg).getSizeInBits() / NarrowSize;
Tim Northover33b07d62016-07-22 20:03:43 +0000411
412 MIRBuilder.setInstr(MI);
413
Tim Northoverb18ea162016-09-20 15:20:36 +0000414 SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
415 SmallVector<uint64_t, 2> Indexes;
Tim Northover33b07d62016-07-22 20:03:43 +0000416 extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
417 extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
418
419 for (int i = 0; i < NumParts; ++i) {
Tim Northover0f140c72016-09-09 11:46:34 +0000420 unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
421 MIRBuilder.buildAdd(DstReg, Src1Regs[i], Src2Regs[i]);
Tim Northover33b07d62016-07-22 20:03:43 +0000422 DstRegs.push_back(DstReg);
Tim Northover91c81732016-08-19 17:17:06 +0000423 Indexes.push_back(i * NarrowSize);
Tim Northover33b07d62016-07-22 20:03:43 +0000424 }
425
Tim Northover0f140c72016-09-09 11:46:34 +0000426 MIRBuilder.buildSequence(DstReg, DstRegs, Indexes);
Tim Northover33b07d62016-07-22 20:03:43 +0000427 MI.eraseFromParent();
428 return Legalized;
429 }
430 }
431}