X86LegalizerInfo.cpp revision 320397
1//===- X86LegalizerInfo.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 X86.
11/// \todo This should be generated by TableGen.
12//===----------------------------------------------------------------------===//
13
14#include "X86LegalizerInfo.h"
15#include "X86Subtarget.h"
16#include "X86TargetMachine.h"
17#include "llvm/CodeGen/ValueTypes.h"
18#include "llvm/IR/DerivedTypes.h"
19#include "llvm/IR/Type.h"
20#include "llvm/Target/TargetOpcodes.h"
21
22using namespace llvm;
23using namespace TargetOpcode;
24
25#ifndef LLVM_BUILD_GLOBAL_ISEL
26#error "You shouldn't build this"
27#endif
28
29X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
30                                   const X86TargetMachine &TM)
31    : Subtarget(STI), TM(TM) {
32
33  setLegalizerInfo32bit();
34  setLegalizerInfo64bit();
35  setLegalizerInfoSSE1();
36  setLegalizerInfoSSE2();
37  setLegalizerInfoSSE41();
38  setLegalizerInfoAVX();
39  setLegalizerInfoAVX2();
40  setLegalizerInfoAVX512();
41  setLegalizerInfoAVX512DQ();
42  setLegalizerInfoAVX512BW();
43
44  computeTables();
45}
46
47void X86LegalizerInfo::setLegalizerInfo32bit() {
48
49  if (Subtarget.is64Bit())
50    return;
51
52  const LLT p0 = LLT::pointer(0, 32);
53  const LLT s1 = LLT::scalar(1);
54  const LLT s8 = LLT::scalar(8);
55  const LLT s16 = LLT::scalar(16);
56  const LLT s32 = LLT::scalar(32);
57  const LLT s64 = LLT::scalar(64);
58
59  for (unsigned BinOp : {G_ADD, G_SUB, G_MUL})
60    for (auto Ty : {s8, s16, s32})
61      setAction({BinOp, Ty}, Legal);
62
63  for (unsigned Op : {G_UADDE}) {
64    setAction({Op, s32}, Legal);
65    setAction({Op, 1, s1}, Legal);
66  }
67
68  for (unsigned MemOp : {G_LOAD, G_STORE}) {
69    for (auto Ty : {s8, s16, s32, p0})
70      setAction({MemOp, Ty}, Legal);
71
72    // And everything's fine in addrspace 0.
73    setAction({MemOp, 1, p0}, Legal);
74  }
75
76  // Pointer-handling
77  setAction({G_FRAME_INDEX, p0}, Legal);
78
79  setAction({G_GEP, p0}, Legal);
80  setAction({G_GEP, 1, s32}, Legal);
81
82  for (auto Ty : {s1, s8, s16})
83    setAction({G_GEP, 1, Ty}, WidenScalar);
84
85  // Constants
86  for (auto Ty : {s8, s16, s32, p0})
87    setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
88
89  setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar);
90  setAction({TargetOpcode::G_CONSTANT, s64}, NarrowScalar);
91
92  // Extensions
93  setAction({G_ZEXT, s32}, Legal);
94  setAction({G_SEXT, s32}, Legal);
95
96  for (auto Ty : {s1, s8, s16}) {
97    setAction({G_ZEXT, 1, Ty}, Legal);
98    setAction({G_SEXT, 1, Ty}, Legal);
99  }
100
101  // Comparison
102  setAction({G_ICMP, s1}, Legal);
103
104  for (auto Ty : {s8, s16, s32, p0})
105    setAction({G_ICMP, 1, Ty}, Legal);
106}
107
108void X86LegalizerInfo::setLegalizerInfo64bit() {
109
110  if (!Subtarget.is64Bit())
111    return;
112
113  const LLT p0 = LLT::pointer(0, TM.getPointerSize() * 8);
114  const LLT s1 = LLT::scalar(1);
115  const LLT s8 = LLT::scalar(8);
116  const LLT s16 = LLT::scalar(16);
117  const LLT s32 = LLT::scalar(32);
118  const LLT s64 = LLT::scalar(64);
119
120  for (unsigned BinOp : {G_ADD, G_SUB, G_MUL})
121    for (auto Ty : {s8, s16, s32, s64})
122      setAction({BinOp, Ty}, Legal);
123
124  for (unsigned MemOp : {G_LOAD, G_STORE}) {
125    for (auto Ty : {s8, s16, s32, s64, p0})
126      setAction({MemOp, Ty}, Legal);
127
128    // And everything's fine in addrspace 0.
129    setAction({MemOp, 1, p0}, Legal);
130  }
131
132  // Pointer-handling
133  setAction({G_FRAME_INDEX, p0}, Legal);
134
135  setAction({G_GEP, p0}, Legal);
136  setAction({G_GEP, 1, s32}, Legal);
137  setAction({G_GEP, 1, s64}, Legal);
138
139  for (auto Ty : {s1, s8, s16})
140    setAction({G_GEP, 1, Ty}, WidenScalar);
141
142  // Constants
143  for (auto Ty : {s8, s16, s32, s64, p0})
144    setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
145
146  setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar);
147
148  // Extensions
149  for (auto Ty : {s32, s64}) {
150    setAction({G_ZEXT, Ty}, Legal);
151    setAction({G_SEXT, Ty}, Legal);
152  }
153
154  for (auto Ty : {s1, s8, s16, s32}) {
155    setAction({G_ZEXT, 1, Ty}, Legal);
156    setAction({G_SEXT, 1, Ty}, Legal);
157  }
158
159  // Comparison
160  setAction({G_ICMP, s1}, Legal);
161
162  for (auto Ty : {s8, s16, s32, s64, p0})
163    setAction({G_ICMP, 1, Ty}, Legal);
164}
165
166void X86LegalizerInfo::setLegalizerInfoSSE1() {
167  if (!Subtarget.hasSSE1())
168    return;
169
170  const LLT s32 = LLT::scalar(32);
171  const LLT v4s32 = LLT::vector(4, 32);
172  const LLT v2s64 = LLT::vector(2, 64);
173
174  for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
175    for (auto Ty : {s32, v4s32})
176      setAction({BinOp, Ty}, Legal);
177
178  for (unsigned MemOp : {G_LOAD, G_STORE})
179    for (auto Ty : {v4s32, v2s64})
180      setAction({MemOp, Ty}, Legal);
181}
182
183void X86LegalizerInfo::setLegalizerInfoSSE2() {
184  if (!Subtarget.hasSSE2())
185    return;
186
187  const LLT s64 = LLT::scalar(64);
188  const LLT v16s8 = LLT::vector(16, 8);
189  const LLT v8s16 = LLT::vector(8, 16);
190  const LLT v4s32 = LLT::vector(4, 32);
191  const LLT v2s64 = LLT::vector(2, 64);
192
193  for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
194    for (auto Ty : {s64, v2s64})
195      setAction({BinOp, Ty}, Legal);
196
197  for (unsigned BinOp : {G_ADD, G_SUB})
198    for (auto Ty : {v16s8, v8s16, v4s32, v2s64})
199      setAction({BinOp, Ty}, Legal);
200
201  setAction({G_MUL, v8s16}, Legal);
202}
203
204void X86LegalizerInfo::setLegalizerInfoSSE41() {
205  if (!Subtarget.hasSSE41())
206    return;
207
208  const LLT v4s32 = LLT::vector(4, 32);
209
210  setAction({G_MUL, v4s32}, Legal);
211}
212
213void X86LegalizerInfo::setLegalizerInfoAVX() {
214  if (!Subtarget.hasAVX())
215    return;
216
217  const LLT v16s8 = LLT::vector(16, 8);
218  const LLT v8s16 = LLT::vector(8, 16);
219  const LLT v4s32 = LLT::vector(4, 32);
220  const LLT v2s64 = LLT::vector(2, 64);
221
222  const LLT v32s8 = LLT::vector(32, 8);
223  const LLT v16s16 = LLT::vector(16, 16);
224  const LLT v8s32 = LLT::vector(8, 32);
225  const LLT v4s64 = LLT::vector(4, 64);
226
227  for (unsigned MemOp : {G_LOAD, G_STORE})
228    for (auto Ty : {v8s32, v4s64})
229      setAction({MemOp, Ty}, Legal);
230
231  for (auto Ty : {v32s8, v16s16, v8s32, v4s64})
232    setAction({G_INSERT, Ty}, Legal);
233  for (auto Ty : {v16s8, v8s16, v4s32, v2s64})
234    setAction({G_INSERT, 1, Ty}, Legal);
235}
236
237void X86LegalizerInfo::setLegalizerInfoAVX2() {
238  if (!Subtarget.hasAVX2())
239    return;
240
241  const LLT v32s8 = LLT::vector(32, 8);
242  const LLT v16s16 = LLT::vector(16, 16);
243  const LLT v8s32 = LLT::vector(8, 32);
244  const LLT v4s64 = LLT::vector(4, 64);
245
246  for (unsigned BinOp : {G_ADD, G_SUB})
247    for (auto Ty : {v32s8, v16s16, v8s32, v4s64})
248      setAction({BinOp, Ty}, Legal);
249
250  for (auto Ty : {v16s16, v8s32})
251    setAction({G_MUL, Ty}, Legal);
252}
253
254void X86LegalizerInfo::setLegalizerInfoAVX512() {
255  if (!Subtarget.hasAVX512())
256    return;
257
258  const LLT v16s8 = LLT::vector(16, 8);
259  const LLT v8s16 = LLT::vector(8, 16);
260  const LLT v4s32 = LLT::vector(4, 32);
261  const LLT v2s64 = LLT::vector(2, 64);
262
263  const LLT v32s8 = LLT::vector(32, 8);
264  const LLT v16s16 = LLT::vector(16, 16);
265  const LLT v8s32 = LLT::vector(8, 32);
266  const LLT v4s64 = LLT::vector(4, 64);
267
268  const LLT v64s8 = LLT::vector(64, 8);
269  const LLT v32s16 = LLT::vector(32, 16);
270  const LLT v16s32 = LLT::vector(16, 32);
271  const LLT v8s64 = LLT::vector(8, 64);
272
273  for (unsigned BinOp : {G_ADD, G_SUB})
274    for (auto Ty : {v16s32, v8s64})
275      setAction({BinOp, Ty}, Legal);
276
277  setAction({G_MUL, v16s32}, Legal);
278
279  for (unsigned MemOp : {G_LOAD, G_STORE})
280    for (auto Ty : {v16s32, v8s64})
281      setAction({MemOp, Ty}, Legal);
282
283  for (auto Ty : {v64s8, v32s16, v16s32, v8s64})
284    setAction({G_INSERT, Ty}, Legal);
285  for (auto Ty : {v32s8, v16s16, v8s32, v4s64, v16s8, v8s16, v4s32, v2s64})
286    setAction({G_INSERT, 1, Ty}, Legal);
287
288  /************ VLX *******************/
289  if (!Subtarget.hasVLX())
290    return;
291
292  for (auto Ty : {v4s32, v8s32})
293    setAction({G_MUL, Ty}, Legal);
294}
295
296void X86LegalizerInfo::setLegalizerInfoAVX512DQ() {
297  if (!(Subtarget.hasAVX512() && Subtarget.hasDQI()))
298    return;
299
300  const LLT v8s64 = LLT::vector(8, 64);
301
302  setAction({G_MUL, v8s64}, Legal);
303
304  /************ VLX *******************/
305  if (!Subtarget.hasVLX())
306    return;
307
308  const LLT v2s64 = LLT::vector(2, 64);
309  const LLT v4s64 = LLT::vector(4, 64);
310
311  for (auto Ty : {v2s64, v4s64})
312    setAction({G_MUL, Ty}, Legal);
313}
314
315void X86LegalizerInfo::setLegalizerInfoAVX512BW() {
316  if (!(Subtarget.hasAVX512() && Subtarget.hasBWI()))
317    return;
318
319  const LLT v64s8 = LLT::vector(64, 8);
320  const LLT v32s16 = LLT::vector(32, 16);
321
322  for (unsigned BinOp : {G_ADD, G_SUB})
323    for (auto Ty : {v64s8, v32s16})
324      setAction({BinOp, Ty}, Legal);
325
326  setAction({G_MUL, v32s16}, Legal);
327
328  /************ VLX *******************/
329  if (!Subtarget.hasVLX())
330    return;
331
332  const LLT v8s16 = LLT::vector(8, 16);
333  const LLT v16s16 = LLT::vector(16, 16);
334
335  for (auto Ty : {v8s16, v16s16})
336    setAction({G_MUL, Ty}, Legal);
337}
338