Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- AArch64LegalizerInfo.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
11
/// AArch64.
12
/// \todo This should be generated by TableGen.
13
//===----------------------------------------------------------------------===//
14
15
#include "AArch64LegalizerInfo.h"
16
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
17
#include "llvm/CodeGen/MachineInstr.h"
18
#include "llvm/CodeGen/MachineRegisterInfo.h"
19
#include "llvm/CodeGen/ValueTypes.h"
20
#include "llvm/IR/DerivedTypes.h"
21
#include "llvm/IR/Type.h"
22
#include "llvm/Target/TargetOpcodes.h"
23
24
using namespace llvm;
25
26
13.9k
AArch64LegalizerInfo::AArch64LegalizerInfo() {
27
13.9k
  using namespace TargetOpcode;
28
13.9k
  const LLT p0 = LLT::pointer(0, 64);
29
13.9k
  const LLT s1 = LLT::scalar(1);
30
13.9k
  const LLT s8 = LLT::scalar(8);
31
13.9k
  const LLT s16 = LLT::scalar(16);
32
13.9k
  const LLT s32 = LLT::scalar(32);
33
13.9k
  const LLT s64 = LLT::scalar(64);
34
13.9k
  const LLT v2s32 = LLT::vector(2, 32);
35
13.9k
  const LLT v4s32 = LLT::vector(4, 32);
36
13.9k
  const LLT v2s64 = LLT::vector(2, 64);
37
13.9k
38
13.9k
  for (auto Ty : {p0, s1, s8, s16, s32, s64})
39
83.8k
    setAction({G_IMPLICIT_DEF, Ty}, Legal);
40
13.9k
41
13.9k
  for (auto Ty : {s16, s32, s64})
42
41.9k
    setAction({G_PHI, Ty}, Legal);
43
13.9k
44
13.9k
  for (auto Ty : {s1, s8})
45
27.9k
    setAction({G_PHI, Ty}, WidenScalar);
46
13.9k
47
13.9k
  for (auto Ty : { s32, s64 })
48
27.9k
    setAction({G_BSWAP, Ty}, Legal);
49
13.9k
50
97.7k
  for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SHL}) {
51
97.7k
    // These operations naturally get the right answer when used on
52
97.7k
    // GPR32, even if the actual type is narrower.
53
97.7k
    for (auto Ty : {s32, s64, v2s32, v4s32, v2s64})
54
488k
      setAction({BinOp, Ty}, Legal);
55
97.7k
56
97.7k
    for (auto Ty : {s1, s8, s16})
57
293k
      setAction({BinOp, Ty}, WidenScalar);
58
97.7k
  }
59
13.9k
60
13.9k
  setAction({G_GEP, p0}, Legal);
61
13.9k
  setAction({G_GEP, 1, s64}, Legal);
62
13.9k
63
13.9k
  for (auto Ty : {s1, s8, s16, s32})
64
55.8k
    setAction({G_GEP, 1, Ty}, WidenScalar);
65
13.9k
66
13.9k
  setAction({G_PTR_MASK, p0}, Legal);
67
13.9k
68
55.8k
  for (unsigned BinOp : {G_LSHR, G_ASHR, G_SDIV, G_UDIV}) {
69
55.8k
    for (auto Ty : {s32, s64})
70
111k
      setAction({BinOp, Ty}, Legal);
71
55.8k
72
55.8k
    for (auto Ty : {s1, s8, s16})
73
167k
      setAction({BinOp, Ty}, WidenScalar);
74
55.8k
  }
75
13.9k
76
13.9k
  for (unsigned BinOp : {G_SREM, G_UREM})
77
27.9k
    for (auto Ty : { s1, s8, s16, s32, s64 })
78
139k
      setAction({BinOp, Ty}, Lower);
79
13.9k
80
13.9k
  for (unsigned Op : {G_SMULO, G_UMULO})
81
27.9k
      setAction({Op, s64}, Lower);
82
13.9k
83
83.8k
  for (unsigned Op : {G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_SMULH, G_UMULH}) {
84
83.8k
    for (auto Ty : { s32, s64 })
85
167k
      setAction({Op, Ty}, Legal);
86
83.8k
87
83.8k
    setAction({Op, 1, s1}, Legal);
88
83.8k
  }
89
13.9k
90
13.9k
  for (unsigned BinOp : {G_FADD, G_FSUB, G_FMA, G_FMUL, G_FDIV})
91
69.8k
    for (auto Ty : {s32, s64})
92
139k
      setAction({BinOp, Ty}, Legal);
93
13.9k
94
27.9k
  for (unsigned BinOp : {G_FREM, G_FPOW}) {
95
27.9k
    setAction({BinOp, s32}, Libcall);
96
27.9k
    setAction({BinOp, s64}, Libcall);
97
27.9k
  }
98
13.9k
99
41.9k
  for (auto Ty : {s32, s64, p0}) {
100
41.9k
    setAction({G_INSERT, Ty}, Legal);
101
41.9k
    setAction({G_INSERT, 1, Ty}, Legal);
102
41.9k
  }
103
41.9k
  for (auto Ty : {s1, s8, s16}) {
104
41.9k
    setAction({G_INSERT, Ty}, WidenScalar);
105
41.9k
    setAction({G_INSERT, 1, Ty}, Legal);
106
41.9k
    // FIXME: Can't widen the sources because that violates the constraints on
107
41.9k
    // G_INSERT (It seems entirely reasonable that inputs shouldn't overlap).
108
41.9k
  }
109
13.9k
110
13.9k
  for (auto Ty : {s1, s8, s16, s32, s64, p0})
111
83.8k
    setAction({G_EXTRACT, Ty}, Legal);
112
13.9k
113
13.9k
  for (auto Ty : {s32, s64})
114
27.9k
    setAction({G_EXTRACT, 1, Ty}, Legal);
115
13.9k
116
27.9k
  for (unsigned MemOp : {G_LOAD, G_STORE}) {
117
27.9k
    for (auto Ty : {s8, s16, s32, s64, p0, v2s32})
118
167k
      setAction({MemOp, Ty}, Legal);
119
27.9k
120
27.9k
    setAction({MemOp, s1}, WidenScalar);
121
27.9k
122
27.9k
    // And everything's fine in addrspace 0.
123
27.9k
    setAction({MemOp, 1, p0}, Legal);
124
27.9k
  }
125
13.9k
126
13.9k
  // Constants
127
27.9k
  for (auto Ty : {s32, s64}) {
128
27.9k
    setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
129
27.9k
    setAction({TargetOpcode::G_FCONSTANT, Ty}, Legal);
130
27.9k
  }
131
13.9k
132
13.9k
  setAction({G_CONSTANT, p0}, Legal);
133
13.9k
134
13.9k
  for (auto Ty : {s1, s8, s16})
135
41.9k
    setAction({TargetOpcode::G_CONSTANT, Ty}, WidenScalar);
136
13.9k
137
13.9k
  setAction({TargetOpcode::G_FCONSTANT, s16}, WidenScalar);
138
13.9k
139
13.9k
  setAction({G_ICMP, 1, s32}, Legal);
140
13.9k
  setAction({G_ICMP, 1, s64}, Legal);
141
13.9k
  setAction({G_ICMP, 1, p0}, Legal);
142
13.9k
143
41.9k
  for (auto Ty : {s1, s8, s16}) {
144
41.9k
    setAction({G_ICMP, Ty}, WidenScalar);
145
41.9k
    setAction({G_FCMP, Ty}, WidenScalar);
146
41.9k
    setAction({G_ICMP, 1, Ty}, WidenScalar);
147
41.9k
  }
148
13.9k
149
13.9k
  setAction({G_ICMP, s32}, Legal);
150
13.9k
  setAction({G_FCMP, s32}, Legal);
151
13.9k
  setAction({G_FCMP, 1, s32}, Legal);
152
13.9k
  setAction({G_FCMP, 1, s64}, Legal);
153
13.9k
154
13.9k
  // Extensions
155
69.8k
  for (auto Ty : { s1, s8, s16, s32, s64 }) {
156
69.8k
    setAction({G_ZEXT, Ty}, Legal);
157
69.8k
    setAction({G_SEXT, Ty}, Legal);
158
69.8k
    setAction({G_ANYEXT, Ty}, Legal);
159
69.8k
  }
160
13.9k
161
55.8k
  for (auto Ty : { s1, s8, s16, s32 }) {
162
55.8k
    setAction({G_ZEXT, 1, Ty}, Legal);
163
55.8k
    setAction({G_SEXT, 1, Ty}, Legal);
164
55.8k
    setAction({G_ANYEXT, 1, Ty}, Legal);
165
55.8k
  }
166
13.9k
167
13.9k
  // FP conversions
168
27.9k
  for (auto Ty : { s16, s32 }) {
169
27.9k
    setAction({G_FPTRUNC, Ty}, Legal);
170
27.9k
    setAction({G_FPEXT, 1, Ty}, Legal);
171
27.9k
  }
172
13.9k
173
27.9k
  for (auto Ty : { s32, s64 }) {
174
27.9k
    setAction({G_FPTRUNC, 1, Ty}, Legal);
175
27.9k
    setAction({G_FPEXT, Ty}, Legal);
176
27.9k
  }
177
13.9k
178
13.9k
  for (auto Ty : { s1, s8, s16, s32 })
179
55.8k
    setAction({G_TRUNC, Ty}, Legal);
180
13.9k
181
13.9k
  for (auto Ty : { s8, s16, s32, s64 })
182
55.8k
    setAction({G_TRUNC, 1, Ty}, Legal);
183
13.9k
184
13.9k
  // Conversions
185
27.9k
  for (auto Ty : { s32, s64 }) {
186
27.9k
    setAction({G_FPTOSI, 0, Ty}, Legal);
187
27.9k
    setAction({G_FPTOUI, 0, Ty}, Legal);
188
27.9k
    setAction({G_SITOFP, 1, Ty}, Legal);
189
27.9k
    setAction({G_UITOFP, 1, Ty}, Legal);
190
27.9k
  }
191
41.9k
  for (auto Ty : { s1, s8, s16 }) {
192
41.9k
    setAction({G_FPTOSI, 0, Ty}, WidenScalar);
193
41.9k
    setAction({G_FPTOUI, 0, Ty}, WidenScalar);
194
41.9k
    setAction({G_SITOFP, 1, Ty}, WidenScalar);
195
41.9k
    setAction({G_UITOFP, 1, Ty}, WidenScalar);
196
41.9k
  }
197
13.9k
198
27.9k
  for (auto Ty : { s32, s64 }) {
199
27.9k
    setAction({G_FPTOSI, 1, Ty}, Legal);
200
27.9k
    setAction({G_FPTOUI, 1, Ty}, Legal);
201
27.9k
    setAction({G_SITOFP, 0, Ty}, Legal);
202
27.9k
    setAction({G_UITOFP, 0, Ty}, Legal);
203
27.9k
  }
204
13.9k
205
13.9k
  // Control-flow
206
13.9k
  for (auto Ty : {s1, s8, s16, s32})
207
55.8k
    setAction({G_BRCOND, Ty}, Legal);
208
13.9k
  setAction({G_BRINDIRECT, p0}, Legal);
209
13.9k
210
13.9k
  // Select
211
13.9k
  for (auto Ty : {s1, s8, s16})
212
41.9k
    setAction({G_SELECT, Ty}, WidenScalar);
213
13.9k
214
13.9k
  for (auto Ty : {s32, s64, p0})
215
41.9k
    setAction({G_SELECT, Ty}, Legal);
216
13.9k
217
13.9k
  setAction({G_SELECT, 1, s1}, Legal);
218
13.9k
219
13.9k
  // Pointer-handling
220
13.9k
  setAction({G_FRAME_INDEX, p0}, Legal);
221
13.9k
  setAction({G_GLOBAL_VALUE, p0}, Legal);
222
13.9k
223
13.9k
  for (auto Ty : {s1, s8, s16, s32, s64})
224
69.8k
    setAction({G_PTRTOINT, 0, Ty}, Legal);
225
13.9k
226
13.9k
  setAction({G_PTRTOINT, 1, p0}, Legal);
227
13.9k
228
13.9k
  setAction({G_INTTOPTR, 0, p0}, Legal);
229
13.9k
  setAction({G_INTTOPTR, 1, s64}, Legal);
230
13.9k
231
13.9k
  // Casts for 32 and 64-bit width type are just copies.
232
69.8k
  for (auto Ty : {s1, s8, s16, s32, s64}) {
233
69.8k
    setAction({G_BITCAST, 0, Ty}, Legal);
234
69.8k
    setAction({G_BITCAST, 1, Ty}, Legal);
235
69.8k
  }
236
13.9k
237
13.9k
  // For the sake of copying bits around, the type does not really
238
13.9k
  // matter as long as it fits a register.
239
69.8k
  for (int EltSize = 8; 
EltSize <= 6469.8k
;
EltSize *= 255.8k
) {
240
55.8k
    setAction({G_BITCAST, 0, LLT::vector(128/EltSize, EltSize)}, Legal);
241
55.8k
    setAction({G_BITCAST, 1, LLT::vector(128/EltSize, EltSize)}, Legal);
242
55.8k
    if (EltSize >= 64)
243
13.9k
      continue;
244
41.9k
245
41.9k
    setAction({G_BITCAST, 0, LLT::vector(64/EltSize, EltSize)}, Legal);
246
41.9k
    setAction({G_BITCAST, 1, LLT::vector(64/EltSize, EltSize)}, Legal);
247
41.9k
    if (EltSize >= 32)
248
13.9k
      continue;
249
27.9k
250
27.9k
    setAction({G_BITCAST, 0, LLT::vector(32/EltSize, EltSize)}, Legal);
251
27.9k
    setAction({G_BITCAST, 1, LLT::vector(32/EltSize, EltSize)}, Legal);
252
27.9k
  }
253
13.9k
254
13.9k
  setAction({G_VASTART, p0}, Legal);
255
13.9k
256
13.9k
  // va_list must be a pointer, but most sized types are pretty easy to handle
257
13.9k
  // as the destination.
258
13.9k
  setAction({G_VAARG, 1, p0}, Legal);
259
13.9k
260
13.9k
  for (auto Ty : {s8, s16, s32, s64, p0})
261
69.8k
    setAction({G_VAARG, Ty}, Custom);
262
13.9k
263
13.9k
  computeTables();
264
13.9k
}
265
266
bool AArch64LegalizerInfo::legalizeCustom(MachineInstr &MI,
267
                                          MachineRegisterInfo &MRI,
268
34
                                          MachineIRBuilder &MIRBuilder) const {
269
34
  switch (MI.getOpcode()) {
270
0
  default:
271
0
    // No idea what to do.
272
0
    return false;
273
34
  case TargetOpcode::G_VAARG:
274
34
    return legalizeVaArg(MI, MRI, MIRBuilder);
275
0
  }
276
0
277
0
  
llvm_unreachable0
("expected switch to return");
278
0
}
279
280
bool AArch64LegalizerInfo::legalizeVaArg(MachineInstr &MI,
281
                                         MachineRegisterInfo &MRI,
282
34
                                         MachineIRBuilder &MIRBuilder) const {
283
34
  MIRBuilder.setInstr(MI);
284
34
  MachineFunction &MF = MIRBuilder.getMF();
285
34
  unsigned Align = MI.getOperand(2).getImm();
286
34
  unsigned Dst = MI.getOperand(0).getReg();
287
34
  unsigned ListPtr = MI.getOperand(1).getReg();
288
34
289
34
  LLT PtrTy = MRI.getType(ListPtr);
290
34
  LLT IntPtrTy = LLT::scalar(PtrTy.getSizeInBits());
291
34
292
34
  const unsigned PtrSize = PtrTy.getSizeInBits() / 8;
293
34
  unsigned List = MRI.createGenericVirtualRegister(PtrTy);
294
34
  MIRBuilder.buildLoad(
295
34
      List, ListPtr,
296
34
      *MF.getMachineMemOperand(MachinePointerInfo(), MachineMemOperand::MOLoad,
297
34
                               PtrSize, /* Align = */ PtrSize));
298
34
299
34
  unsigned DstPtr;
300
34
  if (
Align > PtrSize34
) {
301
1
    // Realign the list to the actual required alignment.
302
1
    auto AlignMinus1 = MIRBuilder.buildConstant(IntPtrTy, Align - 1);
303
1
304
1
    unsigned ListTmp = MRI.createGenericVirtualRegister(PtrTy);
305
1
    MIRBuilder.buildGEP(ListTmp, List, AlignMinus1->getOperand(0).getReg());
306
1
307
1
    DstPtr = MRI.createGenericVirtualRegister(PtrTy);
308
1
    MIRBuilder.buildPtrMask(DstPtr, ListTmp, Log2_64(Align));
309
1
  } else
310
33
    DstPtr = List;
311
34
312
34
  uint64_t ValSize = MRI.getType(Dst).getSizeInBits() / 8;
313
34
  MIRBuilder.buildLoad(
314
34
      Dst, DstPtr,
315
34
      *MF.getMachineMemOperand(MachinePointerInfo(), MachineMemOperand::MOLoad,
316
34
                               ValSize, std::max(Align, PtrSize)));
317
34
318
34
  unsigned SizeReg = MRI.createGenericVirtualRegister(IntPtrTy);
319
34
  MIRBuilder.buildConstant(SizeReg, alignTo(ValSize, PtrSize));
320
34
321
34
  unsigned NewList = MRI.createGenericVirtualRegister(PtrTy);
322
34
  MIRBuilder.buildGEP(NewList, DstPtr, SizeReg);
323
34
324
34
  MIRBuilder.buildStore(
325
34
      NewList, ListPtr,
326
34
      *MF.getMachineMemOperand(MachinePointerInfo(), MachineMemOperand::MOStore,
327
34
                               PtrSize, /* Align = */ PtrSize));
328
34
329
34
  MI.eraseFromParent();
330
34
  return true;
331
34
}