Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/X86/X86InstructionSelector.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- X86InstructionSelector.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 InstructionSelector class for
11
/// X86.
12
/// \todo This should be generated by TableGen.
13
//===----------------------------------------------------------------------===//
14
15
#include "X86InstrBuilder.h"
16
#include "X86InstrInfo.h"
17
#include "X86RegisterBankInfo.h"
18
#include "X86RegisterInfo.h"
19
#include "X86Subtarget.h"
20
#include "X86TargetMachine.h"
21
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
22
#include "llvm/CodeGen/GlobalISel/Utils.h"
23
#include "llvm/CodeGen/MachineBasicBlock.h"
24
#include "llvm/CodeGen/MachineConstantPool.h"
25
#include "llvm/CodeGen/MachineFunction.h"
26
#include "llvm/CodeGen/MachineInstr.h"
27
#include "llvm/CodeGen/MachineInstrBuilder.h"
28
#include "llvm/CodeGen/MachineOperand.h"
29
#include "llvm/CodeGen/MachineRegisterInfo.h"
30
#include "llvm/IR/Type.h"
31
#include "llvm/Support/Debug.h"
32
#include "llvm/Support/raw_ostream.h"
33
34
#define DEBUG_TYPE "X86-isel"
35
36
#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
37
38
using namespace llvm;
39
40
namespace {
41
42
#define GET_GLOBALISEL_PREDICATE_BITSET
43
#include "X86GenGlobalISel.inc"
44
#undef GET_GLOBALISEL_PREDICATE_BITSET
45
46
class X86InstructionSelector : public InstructionSelector {
47
public:
48
  X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
49
                         const X86RegisterBankInfo &RBI);
50
51
  bool select(MachineInstr &I) const override;
52
53
private:
54
  /// tblgen-erated 'select' implementation, used as the initial selector for
55
  /// the patterns that don't require complex C++.
56
  bool selectImpl(MachineInstr &I) const;
57
58
  // TODO: remove after supported by Tablegen-erated instruction selection.
59
  unsigned getLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc,
60
                          uint64_t Alignment) const;
61
62
  bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
63
                         MachineFunction &MF) const;
64
  bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI,
65
                             MachineFunction &MF) const;
66
  bool selectGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI,
67
                         MachineFunction &MF) const;
68
  bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
69
                      MachineFunction &MF) const;
70
  bool selectTrunc(MachineInstr &I, MachineRegisterInfo &MRI,
71
                   MachineFunction &MF) const;
72
  bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
73
                  MachineFunction &MF) const;
74
  bool selectAnyext(MachineInstr &I, MachineRegisterInfo &MRI,
75
                    MachineFunction &MF) const;
76
  bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
77
                 MachineFunction &MF) const;
78
  bool selectUadde(MachineInstr &I, MachineRegisterInfo &MRI,
79
                   MachineFunction &MF) const;
80
  bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const;
81
  bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
82
                           MachineFunction &MF) const;
83
  bool selectMergeValues(MachineInstr &I, MachineRegisterInfo &MRI,
84
                         MachineFunction &MF) const;
85
  bool selectInsert(MachineInstr &I, MachineRegisterInfo &MRI,
86
                    MachineFunction &MF) const;
87
  bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI,
88
                     MachineFunction &MF) const;
89
  bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
90
                        MachineFunction &MF) const;
91
  bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
92
                     MachineFunction &MF) const;
93
  bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
94
95
  // emit insert subreg instruction and insert it before MachineInstr &I
96
  bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
97
                        MachineRegisterInfo &MRI, MachineFunction &MF) const;
98
  // emit extract subreg instruction and insert it before MachineInstr &I
99
  bool emitExtractSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
100
                         MachineRegisterInfo &MRI, MachineFunction &MF) const;
101
102
  const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank &RB) const;
103
  const TargetRegisterClass *getRegClass(LLT Ty, unsigned Reg,
104
                                         MachineRegisterInfo &MRI) const;
105
106
  const X86TargetMachine &TM;
107
  const X86Subtarget &STI;
108
  const X86InstrInfo &TII;
109
  const X86RegisterInfo &TRI;
110
  const X86RegisterBankInfo &RBI;
111
112
#define GET_GLOBALISEL_PREDICATES_DECL
113
#include "X86GenGlobalISel.inc"
114
#undef GET_GLOBALISEL_PREDICATES_DECL
115
116
#define GET_GLOBALISEL_TEMPORARIES_DECL
117
#include "X86GenGlobalISel.inc"
118
#undef GET_GLOBALISEL_TEMPORARIES_DECL
119
};
120
121
} // end anonymous namespace
122
123
#define GET_GLOBALISEL_IMPL
124
#include "X86GenGlobalISel.inc"
125
#undef GET_GLOBALISEL_IMPL
126
127
X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
128
                                               const X86Subtarget &STI,
129
                                               const X86RegisterBankInfo &RBI)
130
    : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
131
      TRI(*STI.getRegisterInfo()), RBI(RBI),
132
#define GET_GLOBALISEL_PREDICATES_INIT
133
#include "X86GenGlobalISel.inc"
134
#undef GET_GLOBALISEL_PREDICATES_INIT
135
#define GET_GLOBALISEL_TEMPORARIES_INIT
136
#include "X86GenGlobalISel.inc"
137
#undef GET_GLOBALISEL_TEMPORARIES_INIT
138
9.64k
{
139
9.64k
}
140
141
// FIXME: This should be target-independent, inferred from the types declared
142
// for each class in the bank.
143
const TargetRegisterClass *
144
1.50k
X86InstructionSelector::getRegClass(LLT Ty, const RegisterBank &RB) const {
145
1.50k
  if (
RB.getID() == X86::GPRRegBankID1.50k
) {
146
791
    if (Ty.getSizeInBits() <= 8)
147
159
      return &X86::GR8RegClass;
148
632
    
if (632
Ty.getSizeInBits() == 16632
)
149
68
      return &X86::GR16RegClass;
150
564
    
if (564
Ty.getSizeInBits() == 32564
)
151
268
      return &X86::GR32RegClass;
152
296
    
if (296
Ty.getSizeInBits() == 64296
)
153
296
      return &X86::GR64RegClass;
154
713
  }
155
713
  
if (713
RB.getID() == X86::VECRRegBankID713
) {
156
713
    if (Ty.getSizeInBits() == 32)
157
85
      
return STI.hasAVX512() ? 85
&X86::FR32XRegClass30
:
&X86::FR32RegClass55
;
158
628
    
if (628
Ty.getSizeInBits() == 64628
)
159
72
      
return STI.hasAVX512() ? 72
&X86::FR64XRegClass28
:
&X86::FR64RegClass44
;
160
556
    
if (556
Ty.getSizeInBits() == 128556
)
161
269
      
return STI.hasAVX512() ? 269
&X86::VR128XRegClass117
:
&X86::VR128RegClass152
;
162
287
    
if (287
Ty.getSizeInBits() == 256287
)
163
213
      
return STI.hasAVX512() ? 213
&X86::VR256XRegClass86
:
&X86::VR256RegClass127
;
164
74
    
if (74
Ty.getSizeInBits() == 51274
)
165
74
      return &X86::VR512RegClass;
166
0
  }
167
0
168
0
  
llvm_unreachable0
("Unknown RegBank!");
169
0
}
170
171
const TargetRegisterClass *
172
X86InstructionSelector::getRegClass(LLT Ty, unsigned Reg,
173
168
                                    MachineRegisterInfo &MRI) const {
174
168
  const RegisterBank &RegBank = *RBI.getRegBank(Reg, MRI, TRI);
175
168
  return getRegClass(Ty, RegBank);
176
168
}
177
178
78
static unsigned getSubRegIndex(const TargetRegisterClass *RC) {
179
78
  unsigned SubIdx = X86::NoSubRegister;
180
78
  if (
RC == &X86::GR32RegClass78
) {
181
2
    SubIdx = X86::sub_32bit;
182
78
  } else 
if (76
RC == &X86::GR16RegClass76
) {
183
31
    SubIdx = X86::sub_16bit;
184
76
  } else 
if (45
RC == &X86::GR8RegClass45
) {
185
45
    SubIdx = X86::sub_8bit;
186
45
  }
187
78
188
78
  return SubIdx;
189
78
}
190
191
74
static const TargetRegisterClass *getRegClassFromGRPhysReg(unsigned Reg) {
192
74
  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
193
74
  if (X86::GR64RegClass.contains(Reg))
194
1
    return &X86::GR64RegClass;
195
73
  
if (73
X86::GR32RegClass.contains(Reg)73
)
196
63
    return &X86::GR32RegClass;
197
10
  
if (10
X86::GR16RegClass.contains(Reg)10
)
198
2
    return &X86::GR16RegClass;
199
8
  
if (8
X86::GR8RegClass.contains(Reg)8
)
200
8
    return &X86::GR8RegClass;
201
0
202
0
  
llvm_unreachable0
("Unknown RegClass for PhysReg!");
203
0
}
204
205
// Set X86 Opcode and constrain DestReg.
206
bool X86InstructionSelector::selectCopy(MachineInstr &I,
207
1.95k
                                        MachineRegisterInfo &MRI) const {
208
1.95k
209
1.95k
  unsigned DstReg = I.getOperand(0).getReg();
210
1.95k
  const unsigned DstSize = RBI.getSizeInBits(DstReg, MRI, TRI);
211
1.95k
  const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
212
1.95k
213
1.95k
  unsigned SrcReg = I.getOperand(1).getReg();
214
1.95k
  const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI);
215
1.95k
  const RegisterBank &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI);
216
1.95k
217
1.95k
  if (
TargetRegisterInfo::isPhysicalRegister(DstReg)1.95k
) {
218
758
    assert(I.isCopy() && "Generic operators do not allow physical registers");
219
758
220
758
    if (
DstSize > SrcSize && 758
SrcRegBank.getID() == X86::GPRRegBankID111
&&
221
758
        
DstRegBank.getID() == X86::GPRRegBankID30
) {
222
12
223
12
      const TargetRegisterClass *SrcRC =
224
12
          getRegClass(MRI.getType(SrcReg), SrcRegBank);
225
12
      const TargetRegisterClass *DstRC = getRegClassFromGRPhysReg(DstReg);
226
12
227
12
      if (
SrcRC != DstRC12
) {
228
6
        // This case can be generated by ABI lowering, performe anyext
229
6
        unsigned ExtSrc = MRI.createVirtualRegister(DstRC);
230
6
        BuildMI(*I.getParent(), I, I.getDebugLoc(),
231
6
                TII.get(TargetOpcode::SUBREG_TO_REG))
232
6
            .addDef(ExtSrc)
233
6
            .addImm(0)
234
6
            .addReg(SrcReg)
235
6
            .addImm(getSubRegIndex(SrcRC));
236
6
237
6
        I.getOperand(1).setReg(ExtSrc);
238
6
      }
239
12
    }
240
758
241
758
    return true;
242
758
  }
243
1.19k
244
1.95k
  assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) &&
245
1.19k
         "No phys reg on generic operators");
246
1.19k
  assert((DstSize == SrcSize ||
247
1.19k
          // Copies are a mean to setup initial types, the number of
248
1.19k
          // bits may not exactly match.
249
1.19k
          (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
250
1.19k
           DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) &&
251
1.19k
         "Copy with different width?!");
252
1.19k
253
1.19k
  const TargetRegisterClass *DstRC =
254
1.19k
      getRegClass(MRI.getType(DstReg), DstRegBank);
255
1.19k
256
1.19k
  if (SrcRegBank.getID() == X86::GPRRegBankID &&
257
1.19k
      
DstRegBank.getID() == X86::GPRRegBankID579
&&
SrcSize > DstSize576
&&
258
1.19k
      
TargetRegisterInfo::isPhysicalRegister(SrcReg)62
) {
259
62
    // Change the physical register to performe truncate.
260
62
261
62
    const TargetRegisterClass *SrcRC = getRegClassFromGRPhysReg(SrcReg);
262
62
263
62
    if (
DstRC != SrcRC62
) {
264
60
      I.getOperand(1).setSubReg(getSubRegIndex(DstRC));
265
60
      I.getOperand(1).substPhysReg(SrcReg, TRI);
266
60
    }
267
62
  }
268
1.19k
269
1.19k
  // No need to constrain SrcReg. It will get constrained when
270
1.19k
  // we hit another of its use or its defs.
271
1.19k
  // Copies do not have constraints.
272
1.19k
  const TargetRegisterClass *OldRC = MRI.getRegClassOrNull(DstReg);
273
1.19k
  if (
!OldRC || 1.19k
!DstRC->hasSubClassEq(OldRC)1.10k
) {
274
86
    if (
!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)86
) {
275
0
      DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
276
0
                   << " operand\n");
277
0
      return false;
278
0
    }
279
1.19k
  }
280
1.19k
  I.setDesc(TII.get(X86::COPY));
281
1.19k
  return true;
282
1.19k
}
283
284
4.13k
bool X86InstructionSelector::select(MachineInstr &I) const {
285
4.13k
  assert(I.getParent() && "Instruction should be in a basic block!");
286
4.13k
  assert(I.getParent()->getParent() && "Instruction should be in a function!");
287
4.13k
288
4.13k
  MachineBasicBlock &MBB = *I.getParent();
289
4.13k
  MachineFunction &MF = *MBB.getParent();
290
4.13k
  MachineRegisterInfo &MRI = MF.getRegInfo();
291
4.13k
292
4.13k
  unsigned Opcode = I.getOpcode();
293
4.13k
  if (
!isPreISelGenericOpcode(Opcode)4.13k
) {
294
2.79k
    // Certain non-generic instructions also need some special handling.
295
2.79k
296
2.79k
    if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
297
0
      return false;
298
2.79k
299
2.79k
    
if (2.79k
I.isCopy()2.79k
)
300
1.95k
      return selectCopy(I, MRI);
301
845
302
845
    return true;
303
845
  }
304
1.34k
305
4.13k
  assert(I.getNumOperands() == I.getNumExplicitOperands() &&
306
1.34k
         "Generic instruction has unexpected implicit operands\n");
307
1.34k
308
1.34k
  if (selectImpl(I))
309
495
    return true;
310
845
311
845
  
DEBUG845
(dbgs() << " C++ instruction selection: "; I.print(dbgs()));
312
845
313
845
  // TODO: This should be implemented by tblgen.
314
845
  switch (I.getOpcode()) {
315
0
  default:
316
0
    return false;
317
399
  case TargetOpcode::G_STORE:
318
399
  case TargetOpcode::G_LOAD:
319
399
    return selectLoadStoreOp(I, MRI, MF);
320
31
  case TargetOpcode::G_GEP:
321
31
  case TargetOpcode::G_FRAME_INDEX:
322
31
    return selectFrameIndexOrGep(I, MRI, MF);
323
25
  case TargetOpcode::G_GLOBAL_VALUE:
324
25
    return selectGlobalValue(I, MRI, MF);
325
26
  case TargetOpcode::G_CONSTANT:
326
26
    return selectConstant(I, MRI, MF);
327
15
  case TargetOpcode::G_FCONSTANT:
328
15
    return materializeFP(I, MRI, MF);
329
42
  case TargetOpcode::G_TRUNC:
330
42
    return selectTrunc(I, MRI, MF);
331
50
  case TargetOpcode::G_ZEXT:
332
50
    return selectZext(I, MRI, MF);
333
24
  case TargetOpcode::G_ANYEXT:
334
24
    return selectAnyext(I, MRI, MF);
335
45
  case TargetOpcode::G_ICMP:
336
45
    return selectCmp(I, MRI, MF);
337
4
  case TargetOpcode::G_UADDE:
338
4
    return selectUadde(I, MRI, MF);
339
28
  case TargetOpcode::G_UNMERGE_VALUES:
340
28
    return selectUnmergeValues(I, MRI, MF);
341
16
  case TargetOpcode::G_MERGE_VALUES:
342
16
    return selectMergeValues(I, MRI, MF);
343
70
  case TargetOpcode::G_EXTRACT:
344
70
    return selectExtract(I, MRI, MF);
345
34
  case TargetOpcode::G_INSERT:
346
34
    return selectInsert(I, MRI, MF);
347
18
  case TargetOpcode::G_BRCOND:
348
18
    return selectCondBranch(I, MRI, MF);
349
18
  case TargetOpcode::G_IMPLICIT_DEF:
350
18
  case TargetOpcode::G_PHI:
351
18
    return selectImplicitDefOrPHI(I, MRI);
352
0
  }
353
0
354
0
  return false;
355
0
}
356
357
unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
358
                                                const RegisterBank &RB,
359
                                                unsigned Opc,
360
414
                                                uint64_t Alignment) const {
361
414
  bool Isload = (Opc == TargetOpcode::G_LOAD);
362
414
  bool HasAVX = STI.hasAVX();
363
414
  bool HasAVX512 = STI.hasAVX512();
364
414
  bool HasVLX = STI.hasVLX();
365
414
366
414
  if (
Ty == LLT::scalar(8)414
) {
367
42
    if (X86::GPRRegBankID == RB.getID())
368
42
      
return Isload ? 42
X86::MOV8rm34
:
X86::MOV8mr8
;
369
372
  } else 
if (372
Ty == LLT::scalar(16)372
) {
370
20
    if (X86::GPRRegBankID == RB.getID())
371
20
      
return Isload ? 20
X86::MOV16rm17
:
X86::MOV16mr3
;
372
352
  } else 
if (352
Ty == LLT::scalar(32) || 352
Ty == LLT::pointer(0, 32)175
) {
373
228
    if (X86::GPRRegBankID == RB.getID())
374
209
      
return Isload ? 209
X86::MOV32rm134
:
X86::MOV32mr75
;
375
19
    
if (19
X86::VECRRegBankID == RB.getID()19
)
376
19
      
return Isload ? 19
(HasAVX512 ? 14
X86::VMOVSSZrm2
377
14
                                 : 
HasAVX ? 12
X86::VMOVSSrm1
:
X86::MOVSSrm11
)
378
5
                    : 
(HasAVX512 ? 5
X86::VMOVSSZmr2
379
19
                                 : 
HasAVX ? 3
X86::VMOVSSmr1
:
X86::MOVSSmr2
);
380
124
  } else 
if (124
Ty == LLT::scalar(64) || 124
Ty == LLT::pointer(0, 64)85
) {
381
66
    if (X86::GPRRegBankID == RB.getID())
382
52
      
return Isload ? 52
X86::MOV64rm29
:
X86::MOV64mr23
;
383
14
    
if (14
X86::VECRRegBankID == RB.getID()14
)
384
14
      
return Isload ? 14
(HasAVX512 ? 9
X86::VMOVSDZrm2
385
9
                                 : 
HasAVX ? 7
X86::VMOVSDrm1
:
X86::MOVSDrm6
)
386
5
                    : 
(HasAVX512 ? 5
X86::VMOVSDZmr2
387
14
                                 : 
HasAVX ? 3
X86::VMOVSDmr1
:
X86::MOVSDmr2
);
388
58
  } else 
if (58
Ty.isVector() && 58
Ty.getSizeInBits() == 12858
) {
389
26
    if (Alignment >= 16)
390
12
      
return Isload ? 12
(HasVLX ? 6
X86::VMOVAPSZ128rm3
391
3
                              : HasAVX512
392
1
                                    ? X86::VMOVAPSZ128rm_NOVLX
393
6
                                    : 
HasAVX ? 2
X86::VMOVAPSrm1
:
X86::MOVAPSrm1
)
394
6
                    : 
(HasVLX ? 6
X86::VMOVAPSZ128mr3
395
3
                              : HasAVX512
396
1
                                    ? X86::VMOVAPSZ128mr_NOVLX
397
12
                                    : 
HasAVX ? 2
X86::VMOVAPSmr1
:
X86::MOVAPSmr1
);
398
26
    else
399
14
      
return Isload ? 14
(HasVLX ? 8
X86::VMOVUPSZ128rm3
400
5
                              : HasAVX512
401
1
                                    ? X86::VMOVUPSZ128rm_NOVLX
402
8
                                    : 
HasAVX ? 4
X86::VMOVUPSrm1
:
X86::MOVUPSrm3
)
403
6
                    : 
(HasVLX ? 6
X86::VMOVUPSZ128mr3
404
3
                              : HasAVX512
405
1
                                    ? X86::VMOVUPSZ128mr_NOVLX
406
14
                                    : 
HasAVX ? 2
X86::VMOVUPSmr1
:
X86::MOVUPSmr1
);
407
32
  } else 
if (32
Ty.isVector() && 32
Ty.getSizeInBits() == 25632
) {
408
20
    if (Alignment >= 32)
409
10
      
return Isload ? 10
(HasVLX ? 5
X86::VMOVAPSZ256rm3
410
2
                              : 
HasAVX512 ? 2
X86::VMOVAPSZ256rm_NOVLX1
411
5
                                          : X86::VMOVAPSYrm)
412
5
                    : 
(HasVLX ? 5
X86::VMOVAPSZ256mr3
413
2
                              : 
HasAVX512 ? 2
X86::VMOVAPSZ256mr_NOVLX1
414
10
                                          : X86::VMOVAPSYmr);
415
20
    else
416
10
      
return Isload ? 10
(HasVLX ? 5
X86::VMOVUPSZ256rm3
417
2
                              : 
HasAVX512 ? 2
X86::VMOVUPSZ256rm_NOVLX1
418
5
                                          : X86::VMOVUPSYrm)
419
5
                    : 
(HasVLX ? 5
X86::VMOVUPSZ256mr3
420
2
                              : 
HasAVX512 ? 2
X86::VMOVUPSZ256mr_NOVLX1
421
10
                                          : X86::VMOVUPSYmr);
422
12
  } else 
if (12
Ty.isVector() && 12
Ty.getSizeInBits() == 51212
) {
423
12
    if (Alignment >= 64)
424
2
      
return Isload ? 2
X86::VMOVAPSZrm0
:
X86::VMOVAPSZmr2
;
425
12
    else
426
10
      
return Isload ? 10
X86::VMOVUPSZrm6
:
X86::VMOVUPSZmr4
;
427
0
  }
428
0
  return Opc;
429
0
}
430
431
// Fill in an address from the given instruction.
432
static void X86SelectAddress(const MachineInstr &I,
433
                             const MachineRegisterInfo &MRI,
434
399
                             X86AddressMode &AM) {
435
399
436
399
  assert(I.getOperand(0).isReg() && "unsupported opperand.");
437
399
  assert(MRI.getType(I.getOperand(0).getReg()).isPointer() &&
438
399
         "unsupported type.");
439
399
440
399
  if (
I.getOpcode() == TargetOpcode::G_GEP399
) {
441
46
    if (auto 
COff46
= getConstantVRegVal(I.getOperand(2).getReg(), MRI)) {
442
46
      int64_t Imm = *COff;
443
46
      if (
isInt<32>(Imm)46
) { // Check for displacement overflow.
444
34
        AM.Disp = static_cast<int32_t>(Imm);
445
34
        AM.Base.Reg = I.getOperand(1).getReg();
446
34
        return;
447
34
      }
448
399
    }
449
353
  } else 
if (353
I.getOpcode() == TargetOpcode::G_FRAME_INDEX353
) {
450
132
    AM.Base.FrameIndex = I.getOperand(1).getIndex();
451
132
    AM.BaseType = X86AddressMode::FrameIndexBase;
452
132
    return;
453
132
  }
454
233
455
233
  // Default behavior.
456
233
  AM.Base.Reg = I.getOperand(0).getReg();
457
233
  return;
458
233
}
459
460
bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
461
                                               MachineRegisterInfo &MRI,
462
399
                                               MachineFunction &MF) const {
463
399
464
399
  unsigned Opc = I.getOpcode();
465
399
466
399
  assert((Opc == TargetOpcode::G_STORE || Opc == TargetOpcode::G_LOAD) &&
467
399
         "unexpected instruction");
468
399
469
399
  const unsigned DefReg = I.getOperand(0).getReg();
470
399
  LLT Ty = MRI.getType(DefReg);
471
399
  const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
472
399
473
399
  auto &MemOp = **I.memoperands_begin();
474
399
  if (
MemOp.getOrdering() != AtomicOrdering::NotAtomic399
) {
475
0
    DEBUG(dbgs() << "Atomic load/store not supported yet\n");
476
0
    return false;
477
0
  }
478
399
479
399
  unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment());
480
399
  if (NewOpc == Opc)
481
0
    return false;
482
399
483
399
  X86AddressMode AM;
484
399
  X86SelectAddress(*MRI.getVRegDef(I.getOperand(1).getReg()), MRI, AM);
485
399
486
399
  I.setDesc(TII.get(NewOpc));
487
399
  MachineInstrBuilder MIB(MF, I);
488
399
  if (
Opc == TargetOpcode::G_LOAD399
) {
489
252
    I.RemoveOperand(1);
490
252
    addFullAddress(MIB, AM);
491
399
  } else {
492
147
    // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL)
493
147
    I.RemoveOperand(1);
494
147
    I.RemoveOperand(0);
495
147
    addFullAddress(MIB, AM).addUse(DefReg);
496
147
  }
497
399
  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
498
399
}
499
500
56
static unsigned getLeaOP(LLT Ty, const X86Subtarget &STI) {
501
56
  if (Ty == LLT::pointer(0, 64))
502
43
    return X86::LEA64r;
503
13
  else 
if (13
Ty == LLT::pointer(0, 32)13
)
504
13
    
return STI.isTarget64BitILP32() ? 13
X86::LEA64_32r6
:
X86::LEA32r7
;
505
13
  else
506
13
    llvm_unreachable("Can't get LEA opcode. Unsupported type.");
507
56
}
508
509
bool X86InstructionSelector::selectFrameIndexOrGep(MachineInstr &I,
510
                                                   MachineRegisterInfo &MRI,
511
31
                                                   MachineFunction &MF) const {
512
31
  unsigned Opc = I.getOpcode();
513
31
514
31
  assert((Opc == TargetOpcode::G_FRAME_INDEX || Opc == TargetOpcode::G_GEP) &&
515
31
         "unexpected instruction");
516
31
517
31
  const unsigned DefReg = I.getOperand(0).getReg();
518
31
  LLT Ty = MRI.getType(DefReg);
519
31
520
31
  // Use LEA to calculate frame index and GEP
521
31
  unsigned NewOpc = getLeaOP(Ty, STI);
522
31
  I.setDesc(TII.get(NewOpc));
523
31
  MachineInstrBuilder MIB(MF, I);
524
31
525
31
  if (
Opc == TargetOpcode::G_FRAME_INDEX31
) {
526
6
    addOffset(MIB, 0);
527
31
  } else {
528
25
    MachineOperand &InxOp = I.getOperand(2);
529
25
    I.addOperand(InxOp);        // set IndexReg
530
25
    InxOp.ChangeToImmediate(1); // set Scale
531
25
    MIB.addImm(0).addReg(0);
532
25
  }
533
31
534
31
  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
535
31
}
536
537
bool X86InstructionSelector::selectGlobalValue(MachineInstr &I,
538
                                               MachineRegisterInfo &MRI,
539
25
                                               MachineFunction &MF) const {
540
25
541
25
  assert((I.getOpcode() == TargetOpcode::G_GLOBAL_VALUE) &&
542
25
         "unexpected instruction");
543
25
544
25
  auto GV = I.getOperand(1).getGlobal();
545
25
  if (
GV->isThreadLocal()25
) {
546
0
    return false; // TODO: we don't support TLS yet.
547
0
  }
548
25
549
25
  // Can't handle alternate code models yet.
550
25
  
if (25
TM.getCodeModel() != CodeModel::Small25
)
551
0
    return 0;
552
25
553
25
  X86AddressMode AM;
554
25
  AM.GV = GV;
555
25
  AM.GVOpFlags = STI.classifyGlobalReference(GV);
556
25
557
25
  // TODO: The ABI requires an extra load. not supported yet.
558
25
  if (isGlobalStubReference(AM.GVOpFlags))
559
0
    return false;
560
25
561
25
  // TODO: This reference is relative to the pic base. not supported yet.
562
25
  
if (25
isGlobalRelativeToPICBase(AM.GVOpFlags)25
)
563
0
    return false;
564
25
565
25
  
if (25
STI.isPICStyleRIPRel()25
) {
566
13
    // Use rip-relative addressing.
567
13
    assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
568
13
    AM.Base.Reg = X86::RIP;
569
13
  }
570
25
571
25
  const unsigned DefReg = I.getOperand(0).getReg();
572
25
  LLT Ty = MRI.getType(DefReg);
573
25
  unsigned NewOpc = getLeaOP(Ty, STI);
574
25
575
25
  I.setDesc(TII.get(NewOpc));
576
25
  MachineInstrBuilder MIB(MF, I);
577
25
578
25
  I.RemoveOperand(1);
579
25
  addFullAddress(MIB, AM);
580
25
581
25
  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
582
25
}
583
584
bool X86InstructionSelector::selectConstant(MachineInstr &I,
585
                                            MachineRegisterInfo &MRI,
586
26
                                            MachineFunction &MF) const {
587
26
588
26
  assert((I.getOpcode() == TargetOpcode::G_CONSTANT) &&
589
26
         "unexpected instruction");
590
26
591
26
  const unsigned DefReg = I.getOperand(0).getReg();
592
26
  LLT Ty = MRI.getType(DefReg);
593
26
594
26
  if (RBI.getRegBank(DefReg, MRI, TRI)->getID() != X86::GPRRegBankID)
595
0
    return false;
596
26
597
26
  uint64_t Val = 0;
598
26
  if (
I.getOperand(1).isCImm()26
) {
599
26
    Val = I.getOperand(1).getCImm()->getZExtValue();
600
26
    I.getOperand(1).ChangeToImmediate(Val);
601
26
  } else 
if (0
I.getOperand(1).isImm()0
) {
602
0
    Val = I.getOperand(1).getImm();
603
0
  } else
604
0
    llvm_unreachable("Unsupported operand type.");
605
26
606
26
  unsigned NewOpc;
607
26
  switch (Ty.getSizeInBits()) {
608
0
  case 8:
609
0
    NewOpc = X86::MOV8ri;
610
0
    break;
611
0
  case 16:
612
0
    NewOpc = X86::MOV16ri;
613
0
    break;
614
15
  case 32:
615
15
    NewOpc = X86::MOV32ri;
616
15
    break;
617
11
  case 64: {
618
11
    // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
619
11
    if (isInt<32>(Val))
620
2
      NewOpc = X86::MOV64ri32;
621
11
    else
622
9
      NewOpc = X86::MOV64ri;
623
11
    break;
624
26
  }
625
0
  default:
626
0
    llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
627
26
  }
628
26
629
26
  I.setDesc(TII.get(NewOpc));
630
26
  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
631
26
}
632
633
bool X86InstructionSelector::selectTrunc(MachineInstr &I,
634
                                         MachineRegisterInfo &MRI,
635
42
                                         MachineFunction &MF) const {
636
42
637
42
  assert((I.getOpcode() == TargetOpcode::G_TRUNC) && "unexpected instruction");
638
42
639
42
  const unsigned DstReg = I.getOperand(0).getReg();
640
42
  const unsigned SrcReg = I.getOperand(1).getReg();
641
42
642
42
  const LLT DstTy = MRI.getType(DstReg);
643
42
  const LLT SrcTy = MRI.getType(SrcReg);
644
42
645
42
  const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
646
42
  const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
647
42
648
42
  if (
DstRB.getID() != SrcRB.getID()42
) {
649
0
    DEBUG(dbgs() << "G_TRUNC input/output on different banks\n");
650
0
    return false;
651
0
  }
652
42
653
42
  
if (42
DstRB.getID() != X86::GPRRegBankID42
)
654
0
    return false;
655
42
656
42
  const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
657
42
  if (!DstRC)
658
0
    return false;
659
42
660
42
  const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
661
42
  if (!SrcRC)
662
0
    return false;
663
42
664
42
  unsigned SubIdx;
665
42
  if (
DstRC == SrcRC42
) {
666
12
    // Nothing to be done
667
12
    SubIdx = X86::NoSubRegister;
668
42
  } else 
if (30
DstRC == &X86::GR32RegClass30
) {
669
3
    SubIdx = X86::sub_32bit;
670
30
  } else 
if (27
DstRC == &X86::GR16RegClass27
) {
671
3
    SubIdx = X86::sub_16bit;
672
27
  } else 
if (24
DstRC == &X86::GR8RegClass24
) {
673
24
    SubIdx = X86::sub_8bit;
674
24
  } else {
675
0
    return false;
676
0
  }
677
42
678
42
  SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
679
42
680
42
  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
681
42
      
!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)42
) {
682
0
    DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
683
0
    return false;
684
0
  }
685
42
686
42
  I.getOperand(1).setSubReg(SubIdx);
687
42
688
42
  I.setDesc(TII.get(X86::COPY));
689
42
  return true;
690
42
}
691
692
bool X86InstructionSelector::selectZext(MachineInstr &I,
693
                                        MachineRegisterInfo &MRI,
694
50
                                        MachineFunction &MF) const {
695
50
696
50
  assert((I.getOpcode() == TargetOpcode::G_ZEXT) && "unexpected instruction");
697
50
698
50
  const unsigned DstReg = I.getOperand(0).getReg();
699
50
  const unsigned SrcReg = I.getOperand(1).getReg();
700
50
701
50
  const LLT DstTy = MRI.getType(DstReg);
702
50
  const LLT SrcTy = MRI.getType(SrcReg);
703
50
704
50
  if (SrcTy != LLT::scalar(1))
705
0
    return false;
706
50
707
50
  unsigned AndOpc;
708
50
  if (DstTy == LLT::scalar(8))
709
6
    AndOpc = X86::AND8ri;
710
44
  else 
if (44
DstTy == LLT::scalar(16)44
)
711
4
    AndOpc = X86::AND16ri8;
712
40
  else 
if (40
DstTy == LLT::scalar(32)40
)
713
38
    AndOpc = X86::AND32ri8;
714
2
  else 
if (2
DstTy == LLT::scalar(64)2
)
715
2
    AndOpc = X86::AND64ri8;
716
2
  else
717
0
    return false;
718
50
719
50
  unsigned DefReg = SrcReg;
720
50
  if (
DstTy != LLT::scalar(8)50
) {
721
44
    DefReg = MRI.createVirtualRegister(getRegClass(DstTy, DstReg, MRI));
722
44
    BuildMI(*I.getParent(), I, I.getDebugLoc(),
723
44
            TII.get(TargetOpcode::SUBREG_TO_REG), DefReg)
724
44
        .addImm(0)
725
44
        .addReg(SrcReg)
726
44
        .addImm(X86::sub_8bit);
727
44
  }
728
50
729
50
  MachineInstr &AndInst =
730
50
      *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AndOpc), DstReg)
731
50
           .addReg(DefReg)
732
50
           .addImm(1);
733
50
734
50
  constrainSelectedInstRegOperands(AndInst, TII, TRI, RBI);
735
50
736
50
  I.eraseFromParent();
737
50
  return true;
738
50
}
739
740
bool X86InstructionSelector::selectAnyext(MachineInstr &I,
741
                                          MachineRegisterInfo &MRI,
742
24
                                          MachineFunction &MF) const {
743
24
744
24
  assert((I.getOpcode() == TargetOpcode::G_ANYEXT) && "unexpected instruction");
745
24
746
24
  const unsigned DstReg = I.getOperand(0).getReg();
747
24
  const unsigned SrcReg = I.getOperand(1).getReg();
748
24
749
24
  const LLT DstTy = MRI.getType(DstReg);
750
24
  const LLT SrcTy = MRI.getType(SrcReg);
751
24
752
24
  const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
753
24
  const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
754
24
755
24
  assert(DstRB.getID() == SrcRB.getID() &&
756
24
         "G_ANYEXT input/output on different banks\n");
757
24
758
24
  assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
759
24
         "G_ANYEXT incorrect operand size");
760
24
761
24
  if (DstRB.getID() != X86::GPRRegBankID)
762
0
    return false;
763
24
764
24
  const TargetRegisterClass *DstRC = getRegClass(DstTy, DstRB);
765
24
  const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcRB);
766
24
767
24
  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
768
24
      
!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)24
) {
769
0
    DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
770
0
                 << " operand\n");
771
0
    return false;
772
0
  }
773
24
774
24
  
if (24
SrcRC == DstRC24
) {
775
12
    I.setDesc(TII.get(X86::COPY));
776
12
    return true;
777
12
  }
778
12
779
12
  BuildMI(*I.getParent(), I, I.getDebugLoc(),
780
12
          TII.get(TargetOpcode::SUBREG_TO_REG))
781
12
      .addDef(DstReg)
782
12
      .addImm(0)
783
12
      .addReg(SrcReg)
784
12
      .addImm(getSubRegIndex(SrcRC));
785
12
786
12
  I.eraseFromParent();
787
12
  return true;
788
12
}
789
790
bool X86InstructionSelector::selectCmp(MachineInstr &I,
791
                                       MachineRegisterInfo &MRI,
792
45
                                       MachineFunction &MF) const {
793
45
794
45
  assert((I.getOpcode() == TargetOpcode::G_ICMP) && "unexpected instruction");
795
45
796
45
  X86::CondCode CC;
797
45
  bool SwapArgs;
798
45
  std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
799
45
      (CmpInst::Predicate)I.getOperand(1).getPredicate());
800
45
  unsigned OpSet = X86::getSETFromCond(CC);
801
45
802
45
  unsigned LHS = I.getOperand(2).getReg();
803
45
  unsigned RHS = I.getOperand(3).getReg();
804
45
805
45
  if (SwapArgs)
806
0
    std::swap(LHS, RHS);
807
45
808
45
  unsigned OpCmp;
809
45
  LLT Ty = MRI.getType(LHS);
810
45
811
45
  switch (Ty.getSizeInBits()) {
812
0
  default:
813
0
    return false;
814
2
  case 8:
815
2
    OpCmp = X86::CMP8rr;
816
2
    break;
817
2
  case 16:
818
2
    OpCmp = X86::CMP16rr;
819
2
    break;
820
39
  case 32:
821
39
    OpCmp = X86::CMP32rr;
822
39
    break;
823
2
  case 64:
824
2
    OpCmp = X86::CMP64rr;
825
2
    break;
826
45
  }
827
45
828
45
  MachineInstr &CmpInst =
829
45
      *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
830
45
           .addReg(LHS)
831
45
           .addReg(RHS);
832
45
833
45
  MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
834
45
                                   TII.get(OpSet), I.getOperand(0).getReg());
835
45
836
45
  constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
837
45
  constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI);
838
45
839
45
  I.eraseFromParent();
840
45
  return true;
841
45
}
842
843
bool X86InstructionSelector::selectUadde(MachineInstr &I,
844
                                         MachineRegisterInfo &MRI,
845
4
                                         MachineFunction &MF) const {
846
4
847
4
  assert((I.getOpcode() == TargetOpcode::G_UADDE) && "unexpected instruction");
848
4
849
4
  const unsigned DstReg = I.getOperand(0).getReg();
850
4
  const unsigned CarryOutReg = I.getOperand(1).getReg();
851
4
  const unsigned Op0Reg = I.getOperand(2).getReg();
852
4
  const unsigned Op1Reg = I.getOperand(3).getReg();
853
4
  unsigned CarryInReg = I.getOperand(4).getReg();
854
4
855
4
  const LLT DstTy = MRI.getType(DstReg);
856
4
857
4
  if (DstTy != LLT::scalar(32))
858
0
    return false;
859
4
860
4
  // find CarryIn def instruction.
861
4
  MachineInstr *Def = MRI.getVRegDef(CarryInReg);
862
6
  while (
Def->getOpcode() == TargetOpcode::G_TRUNC6
) {
863
2
    CarryInReg = Def->getOperand(1).getReg();
864
2
    Def = MRI.getVRegDef(CarryInReg);
865
2
  }
866
4
867
4
  unsigned Opcode;
868
4
  if (
Def->getOpcode() == TargetOpcode::G_UADDE4
) {
869
2
    // carry set by prev ADD.
870
2
871
2
    BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS)
872
2
        .addReg(CarryInReg);
873
2
874
2
    if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI))
875
0
      return false;
876
2
877
2
    Opcode = X86::ADC32rr;
878
4
  } else 
if (auto 2
val2
= getConstantVRegVal(CarryInReg, MRI)) {
879
2
    // carry is constant, support only 0.
880
2
    if (*val != 0)
881
0
      return false;
882
2
883
2
    Opcode = X86::ADD32rr;
884
2
  } else
885
0
    return false;
886
4
887
4
  MachineInstr &AddInst =
888
4
      *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
889
4
           .addReg(Op0Reg)
890
4
           .addReg(Op1Reg);
891
4
892
4
  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg)
893
4
      .addReg(X86::EFLAGS);
894
4
895
4
  if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) ||
896
4
      !RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI))
897
0
    return false;
898
4
899
4
  I.eraseFromParent();
900
4
  return true;
901
4
}
902
903
bool X86InstructionSelector::selectExtract(MachineInstr &I,
904
                                           MachineRegisterInfo &MRI,
905
70
                                           MachineFunction &MF) const {
906
70
907
70
  assert((I.getOpcode() == TargetOpcode::G_EXTRACT) &&
908
70
         "unexpected instruction");
909
70
910
70
  const unsigned DstReg = I.getOperand(0).getReg();
911
70
  const unsigned SrcReg = I.getOperand(1).getReg();
912
70
  int64_t Index = I.getOperand(2).getImm();
913
70
914
70
  const LLT DstTy = MRI.getType(DstReg);
915
70
  const LLT SrcTy = MRI.getType(SrcReg);
916
70
917
70
  // Meanwile handle vector type only.
918
70
  if (!DstTy.isVector())
919
0
    return false;
920
70
921
70
  
if (70
Index % DstTy.getSizeInBits() != 070
)
922
0
    return false; // Not extract subvector.
923
70
924
70
  
if (70
Index == 070
) {
925
34
    // Replace by extract subreg copy.
926
34
    if (!emitExtractSubreg(DstReg, SrcReg, I, MRI, MF))
927
0
      return false;
928
34
929
34
    I.eraseFromParent();
930
34
    return true;
931
34
  }
932
36
933
36
  bool HasAVX = STI.hasAVX();
934
36
  bool HasAVX512 = STI.hasAVX512();
935
36
  bool HasVLX = STI.hasVLX();
936
36
937
36
  if (
SrcTy.getSizeInBits() == 256 && 36
DstTy.getSizeInBits() == 12828
) {
938
28
    if (HasVLX)
939
2
      I.setDesc(TII.get(X86::VEXTRACTF32x4Z256rr));
940
26
    else 
if (26
HasAVX26
)
941
26
      I.setDesc(TII.get(X86::VEXTRACTF128rr));
942
26
    else
943
0
      return false;
944
8
  } else 
if (8
SrcTy.getSizeInBits() == 512 && 8
HasAVX5128
) {
945
8
    if (DstTy.getSizeInBits() == 128)
946
5
      I.setDesc(TII.get(X86::VEXTRACTF32x4Zrr));
947
3
    else 
if (3
DstTy.getSizeInBits() == 2563
)
948
3
      I.setDesc(TII.get(X86::VEXTRACTF64x4Zrr));
949
3
    else
950
0
      return false;
951
8
  } else
952
0
    return false;
953
36
954
36
  // Convert to X86 VEXTRACT immediate.
955
36
  Index = Index / DstTy.getSizeInBits();
956
36
  I.getOperand(2).setImm(Index);
957
36
958
36
  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
959
36
}
960
961
bool X86InstructionSelector::emitExtractSubreg(unsigned DstReg, unsigned SrcReg,
962
                                               MachineInstr &I,
963
                                               MachineRegisterInfo &MRI,
964
34
                                               MachineFunction &MF) const {
965
34
966
34
  const LLT DstTy = MRI.getType(DstReg);
967
34
  const LLT SrcTy = MRI.getType(SrcReg);
968
34
  unsigned SubIdx = X86::NoSubRegister;
969
34
970
34
  if (
!DstTy.isVector() || 34
!SrcTy.isVector()34
)
971
0
    return false;
972
34
973
34
  assert(SrcTy.getSizeInBits() > DstTy.getSizeInBits() &&
974
34
         "Incorrect Src/Dst register size");
975
34
976
34
  if (DstTy.getSizeInBits() == 128)
977
31
    SubIdx = X86::sub_xmm;
978
3
  else 
if (3
DstTy.getSizeInBits() == 2563
)
979
3
    SubIdx = X86::sub_ymm;
980
3
  else
981
0
    return false;
982
34
983
34
  const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
984
34
  const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
985
34
986
34
  SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubIdx);
987
34
988
34
  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
989
34
      
!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)34
) {
990
0
    DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
991
0
    return false;
992
0
  }
993
34
994
34
  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), DstReg)
995
34
      .addReg(SrcReg, 0, SubIdx);
996
34
997
34
  return true;
998
34
}
999
1000
bool X86InstructionSelector::emitInsertSubreg(unsigned DstReg, unsigned SrcReg,
1001
                                              MachineInstr &I,
1002
                                              MachineRegisterInfo &MRI,
1003
20
                                              MachineFunction &MF) const {
1004
20
1005
20
  const LLT DstTy = MRI.getType(DstReg);
1006
20
  const LLT SrcTy = MRI.getType(SrcReg);
1007
20
  unsigned SubIdx = X86::NoSubRegister;
1008
20
1009
20
  // TODO: support scalar types
1010
20
  if (
!DstTy.isVector() || 20
!SrcTy.isVector()20
)
1011
0
    return false;
1012
20
1013
20
  assert(SrcTy.getSizeInBits() < DstTy.getSizeInBits() &&
1014
20
         "Incorrect Src/Dst register size");
1015
20
1016
20
  if (SrcTy.getSizeInBits() == 128)
1017
18
    SubIdx = X86::sub_xmm;
1018
2
  else 
if (2
SrcTy.getSizeInBits() == 2562
)
1019
2
    SubIdx = X86::sub_ymm;
1020
2
  else
1021
0
    return false;
1022
20
1023
20
  const TargetRegisterClass *SrcRC = getRegClass(SrcTy, SrcReg, MRI);
1024
20
  const TargetRegisterClass *DstRC = getRegClass(DstTy, DstReg, MRI);
1025
20
1026
20
  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
1027
20
      
!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)20
) {
1028
0
    DEBUG(dbgs() << "Failed to constrain INSERT_SUBREG\n");
1029
0
    return false;
1030
0
  }
1031
20
1032
20
  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY))
1033
20
      .addReg(DstReg, RegState::DefineNoRead, SubIdx)
1034
20
      .addReg(SrcReg);
1035
20
1036
20
  return true;
1037
20
}
1038
1039
bool X86InstructionSelector::selectInsert(MachineInstr &I,
1040
                                          MachineRegisterInfo &MRI,
1041
34
                                          MachineFunction &MF) const {
1042
34
1043
34
  assert((I.getOpcode() == TargetOpcode::G_INSERT) && "unexpected instruction");
1044
34
1045
34
  const unsigned DstReg = I.getOperand(0).getReg();
1046
34
  const unsigned SrcReg = I.getOperand(1).getReg();
1047
34
  const unsigned InsertReg = I.getOperand(2).getReg();
1048
34
  int64_t Index = I.getOperand(3).getImm();
1049
34
1050
34
  const LLT DstTy = MRI.getType(DstReg);
1051
34
  const LLT InsertRegTy = MRI.getType(InsertReg);
1052
34
1053
34
  // Meanwile handle vector type only.
1054
34
  if (!DstTy.isVector())
1055
0
    return false;
1056
34
1057
34
  
if (34
Index % InsertRegTy.getSizeInBits() != 034
)
1058
0
    return false; // Not insert subvector.
1059
34
1060
34
  
if (34
Index == 0 && 34
MRI.getVRegDef(SrcReg)->isImplicitDef()8
) {
1061
4
    // Replace by subreg copy.
1062
4
    if (!emitInsertSubreg(DstReg, InsertReg, I, MRI, MF))
1063
0
      return false;
1064
4
1065
4
    I.eraseFromParent();
1066
4
    return true;
1067
4
  }
1068
30
1069
30
  bool HasAVX = STI.hasAVX();
1070
30
  bool HasAVX512 = STI.hasAVX512();
1071
30
  bool HasVLX = STI.hasVLX();
1072
30
1073
30
  if (
DstTy.getSizeInBits() == 256 && 30
InsertRegTy.getSizeInBits() == 12820
) {
1074
20
    if (HasVLX)
1075
4
      I.setDesc(TII.get(X86::VINSERTF32x4Z256rr));
1076
16
    else 
if (16
HasAVX16
)
1077
16
      I.setDesc(TII.get(X86::VINSERTF128rr));
1078
16
    else
1079
0
      return false;
1080
10
  } else 
if (10
DstTy.getSizeInBits() == 512 && 10
HasAVX51210
) {
1081
10
    if (InsertRegTy.getSizeInBits() == 128)
1082
6
      I.setDesc(TII.get(X86::VINSERTF32x4Zrr));
1083
4
    else 
if (4
InsertRegTy.getSizeInBits() == 2564
)
1084
4
      I.setDesc(TII.get(X86::VINSERTF64x4Zrr));
1085
4
    else
1086
0
      return false;
1087
10
  } else
1088
0
    return false;
1089
30
1090
30
  // Convert to X86 VINSERT immediate.
1091
30
  Index = Index / InsertRegTy.getSizeInBits();
1092
30
1093
30
  I.getOperand(3).setImm(Index);
1094
30
1095
30
  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
1096
30
}
1097
1098
bool X86InstructionSelector::selectUnmergeValues(MachineInstr &I,
1099
                                                 MachineRegisterInfo &MRI,
1100
28
                                                 MachineFunction &MF) const {
1101
28
1102
28
  assert((I.getOpcode() == TargetOpcode::G_UNMERGE_VALUES) &&
1103
28
         "unexpected instruction");
1104
28
1105
28
  // Split to extracts.
1106
28
  unsigned NumDefs = I.getNumOperands() - 1;
1107
28
  unsigned SrcReg = I.getOperand(NumDefs).getReg();
1108
28
  unsigned DefSize = MRI.getType(I.getOperand(0).getReg()).getSizeInBits();
1109
28
1110
86
  for (unsigned Idx = 0; 
Idx < NumDefs86
;
++Idx58
) {
1111
58
1112
58
    MachineInstr &ExtrInst =
1113
58
        *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1114
58
                 TII.get(TargetOpcode::G_EXTRACT), I.getOperand(Idx).getReg())
1115
58
             .addReg(SrcReg)
1116
58
             .addImm(Idx * DefSize);
1117
58
1118
58
    if (!select(ExtrInst))
1119
0
      return false;
1120
58
  }
1121
28
1122
28
  I.eraseFromParent();
1123
28
  return true;
1124
28
}
1125
1126
bool X86InstructionSelector::selectMergeValues(MachineInstr &I,
1127
                                               MachineRegisterInfo &MRI,
1128
16
                                               MachineFunction &MF) const {
1129
16
1130
16
  assert((I.getOpcode() == TargetOpcode::G_MERGE_VALUES) &&
1131
16
         "unexpected instruction");
1132
16
1133
16
  // Split to inserts.
1134
16
  unsigned DstReg = I.getOperand(0).getReg();
1135
16
  unsigned SrcReg0 = I.getOperand(1).getReg();
1136
16
1137
16
  const LLT DstTy = MRI.getType(DstReg);
1138
16
  const LLT SrcTy = MRI.getType(SrcReg0);
1139
16
  unsigned SrcSize = SrcTy.getSizeInBits();
1140
16
1141
16
  const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1142
16
1143
16
  // For the first src use insertSubReg.
1144
16
  unsigned DefReg = MRI.createGenericVirtualRegister(DstTy);
1145
16
  MRI.setRegBank(DefReg, RegBank);
1146
16
  if (!emitInsertSubreg(DefReg, I.getOperand(1).getReg(), I, MRI, MF))
1147
0
    return false;
1148
16
1149
34
  
for (unsigned Idx = 2; 16
Idx < I.getNumOperands()34
;
++Idx18
) {
1150
18
1151
18
    unsigned Tmp = MRI.createGenericVirtualRegister(DstTy);
1152
18
    MRI.setRegBank(Tmp, RegBank);
1153
18
1154
18
    MachineInstr &InsertInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1155
18
                                        TII.get(TargetOpcode::G_INSERT), Tmp)
1156
18
                                    .addReg(DefReg)
1157
18
                                    .addReg(I.getOperand(Idx).getReg())
1158
18
                                    .addImm((Idx - 1) * SrcSize);
1159
18
1160
18
    DefReg = Tmp;
1161
18
1162
18
    if (!select(InsertInst))
1163
0
      return false;
1164
18
  }
1165
16
1166
16
  MachineInstr &CopyInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
1167
16
                                    TII.get(TargetOpcode::COPY), DstReg)
1168
16
                                .addReg(DefReg);
1169
16
1170
16
  if (!select(CopyInst))
1171
0
    return false;
1172
16
1173
16
  I.eraseFromParent();
1174
16
  return true;
1175
16
}
1176
1177
bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
1178
                                              MachineRegisterInfo &MRI,
1179
18
                                              MachineFunction &MF) const {
1180
18
1181
18
  assert((I.getOpcode() == TargetOpcode::G_BRCOND) && "unexpected instruction");
1182
18
1183
18
  const unsigned CondReg = I.getOperand(0).getReg();
1184
18
  MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
1185
18
1186
18
  MachineInstr &TestInst =
1187
18
      *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri))
1188
18
           .addReg(CondReg)
1189
18
           .addImm(1);
1190
18
  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JNE_1))
1191
18
      .addMBB(DestMBB);
1192
18
1193
18
  constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI);
1194
18
1195
18
  I.eraseFromParent();
1196
18
  return true;
1197
18
}
1198
1199
bool X86InstructionSelector::materializeFP(MachineInstr &I,
1200
                                           MachineRegisterInfo &MRI,
1201
15
                                           MachineFunction &MF) const {
1202
15
1203
15
  assert((I.getOpcode() == TargetOpcode::G_FCONSTANT) &&
1204
15
         "unexpected instruction");
1205
15
1206
15
  // Can't handle alternate code models yet.
1207
15
  CodeModel::Model CM = TM.getCodeModel();
1208
15
  if (
CM != CodeModel::Small && 15
CM != CodeModel::Large6
)
1209
0
    return false;
1210
15
1211
15
  const unsigned DstReg = I.getOperand(0).getReg();
1212
15
  const LLT DstTy = MRI.getType(DstReg);
1213
15
  const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
1214
15
  unsigned Align = DstTy.getSizeInBits();
1215
15
  const DebugLoc &DbgLoc = I.getDebugLoc();
1216
15
1217
15
  unsigned Opc = getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Align);
1218
15
1219
15
  // Create the load from the constant pool.
1220
15
  const ConstantFP *CFP = I.getOperand(1).getFPImm();
1221
15
  unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Align);
1222
15
  MachineInstr *LoadInst = nullptr;
1223
15
  unsigned char OpFlag = STI.classifyLocalReference(nullptr);
1224
15
1225
15
  if (
CM == CodeModel::Large && 15
STI.is64Bit()6
) {
1226
3
    // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
1227
3
    // they cannot be folded into immediate fields.
1228
3
1229
3
    unsigned AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass);
1230
3
    BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg)
1231
3
        .addConstantPoolIndex(CPI, 0, OpFlag);
1232
3
1233
3
    MachineMemOperand *MMO = MF.getMachineMemOperand(
1234
3
        MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
1235
3
        MF.getDataLayout().getPointerSize(), Align);
1236
3
1237
3
    LoadInst =
1238
3
        addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg),
1239
3
                     AddrReg)
1240
3
            .addMemOperand(MMO);
1241
3
1242
15
  } else 
if (12
CM == CodeModel::Small || 12
!STI.is64Bit()3
) {
1243
12
    // Handle the case when globals fit in our immediate field.
1244
12
    // This is true for X86-32 always and X86-64 when in -mcmodel=small mode.
1245
12
1246
12
    // x86-32 PIC requires a PIC base register for constant pools.
1247
12
    unsigned PICBase = 0;
1248
12
    if (
OpFlag == X86II::MO_PIC_BASE_OFFSET || 12
OpFlag == X86II::MO_GOTOFF12
) {
1249
0
      // PICBase can be allocated by TII.getGlobalBaseReg(&MF).
1250
0
      // In DAGISEL the code that initialize it generated by the CGBR pass.
1251
0
      return false; // TODO support the mode.
1252
12
    } else 
if (12
STI.is64Bit() && 12
TM.getCodeModel() == CodeModel::Small6
)
1253
6
      PICBase = X86::RIP;
1254
12
1255
12
    LoadInst = addConstantPoolReference(
1256
12
        BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase,
1257
12
        OpFlag);
1258
12
  } else
1259
0
    return false;
1260
15
1261
15
  constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI);
1262
15
  I.eraseFromParent();
1263
15
  return true;
1264
15
}
1265
1266
bool X86InstructionSelector::selectImplicitDefOrPHI(
1267
18
    MachineInstr &I, MachineRegisterInfo &MRI) const {
1268
18
1269
18
  assert((I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF ||
1270
18
          I.getOpcode() == TargetOpcode::G_PHI) &&
1271
18
         "unexpected instruction");
1272
18
1273
18
  unsigned DstReg = I.getOperand(0).getReg();
1274
18
1275
18
  if (
!MRI.getRegClassOrNull(DstReg)18
) {
1276
16
    const LLT DstTy = MRI.getType(DstReg);
1277
16
    const TargetRegisterClass *RC = getRegClass(DstTy, DstReg, MRI);
1278
16
1279
16
    if (
!RBI.constrainGenericRegister(DstReg, *RC, MRI)16
) {
1280
0
      DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
1281
0
                   << " operand\n");
1282
0
      return false;
1283
0
    }
1284
18
  }
1285
18
1286
18
  
if (18
I.getOpcode() == TargetOpcode::G_IMPLICIT_DEF18
)
1287
6
    I.setDesc(TII.get(X86::IMPLICIT_DEF));
1288
18
  else
1289
12
    I.setDesc(TII.get(X86::PHI));
1290
18
1291
18
  return true;
1292
18
}
1293
1294
InstructionSelector *
1295
llvm::createX86InstructionSelector(const X86TargetMachine &TM,
1296
                                   X86Subtarget &Subtarget,
1297
9.64k
                                   X86RegisterBankInfo &RBI) {
1298
9.64k
  return new X86InstructionSelector(TM, Subtarget, RBI);
1299
9.64k
}